dbf 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +22 -0
- data/Gemfile +1 -4
- data/Gemfile.lock +83 -6
- data/README.md +20 -21
- data/Rakefile +9 -46
- data/bin/dbf +0 -0
- data/lib/dbf.rb +6 -11
- data/lib/dbf/column.rb +38 -74
- data/lib/dbf/memo.rb +88 -0
- data/lib/dbf/record.rb +29 -104
- data/lib/dbf/table.rb +54 -142
- data/lib/dbf/version.rb +1 -1
- data/spec/{unit → dbf}/column_spec.rb +37 -46
- data/spec/dbf/file_formats_spec.rb +178 -0
- data/spec/dbf/record_spec.rb +45 -0
- data/spec/{unit → dbf}/table_spec.rb +17 -104
- data/spec/spec_helper.rb +2 -4
- metadata +39 -27
- data/spec/functional/dbf_shared.rb +0 -54
- data/spec/functional/format_03_spec.rb +0 -23
- data/spec/functional/format_30_spec.rb +0 -23
- data/spec/functional/format_31_spec.rb +0 -23
- data/spec/functional/format_83_spec.rb +0 -23
- data/spec/functional/format_8b_spec.rb +0 -23
- data/spec/functional/format_f5_spec.rb +0 -23
- data/spec/unit/record_spec.rb +0 -111
data/lib/dbf/version.rb
CHANGED
@@ -1,37 +1,35 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe DBF::Column do
|
4
4
|
|
5
5
|
context "when initialized" do
|
6
|
-
|
7
|
-
@column = DBF::Column.new "ColumnName", "N", 1, 0
|
8
|
-
end
|
6
|
+
let(:column) { DBF::Column.new "ColumnName", "N", 1, 0 }
|
9
7
|
|
10
8
|
it "sets the #name accessor" do
|
11
|
-
|
9
|
+
column.name.should == "ColumnName"
|
12
10
|
end
|
13
11
|
|
14
12
|
it "sets the #type accessor" do
|
15
|
-
|
13
|
+
column.type.should == "N"
|
16
14
|
end
|
17
15
|
|
18
16
|
it "sets the #length accessor" do
|
19
|
-
|
17
|
+
column.length.should == 1
|
20
18
|
end
|
21
19
|
|
22
20
|
it "sets the #decimal accessor" do
|
23
|
-
|
21
|
+
column.decimal.should == 0
|
24
22
|
end
|
25
23
|
|
26
|
-
|
24
|
+
describe 'with length of 0' do
|
27
25
|
specify { lambda { DBF::Column.new "ColumnName", "N", 0, 0 }.should raise_error(DBF::ColumnLengthError) }
|
28
26
|
end
|
29
27
|
|
30
|
-
|
28
|
+
describe 'with length less than 0' do
|
31
29
|
specify { lambda { DBF::Column.new "ColumnName", "N", -1, 0 }.should raise_error(DBF::ColumnLengthError) }
|
32
30
|
end
|
33
31
|
|
34
|
-
|
32
|
+
describe 'with empty column name' do
|
35
33
|
specify { lambda { DBF::Column.new "\xFF\xFC", "N", 1, 0 }.should raise_error(DBF::ColumnNameError) }
|
36
34
|
end
|
37
35
|
end
|
@@ -75,60 +73,57 @@ describe DBF::Column do
|
|
75
73
|
end
|
76
74
|
|
77
75
|
context 'with type L (logical/boolean)' do
|
76
|
+
let(:column) { DBF::Column.new "ColumnName", "L", 1, 0 }
|
77
|
+
|
78
78
|
it "casts 'y' to true" do
|
79
|
-
|
80
|
-
column = DBF::Column.new "ColumnName", "L", 1, 0
|
81
|
-
column.type_cast(value).should == true
|
79
|
+
column.type_cast('y').should == true
|
82
80
|
end
|
83
81
|
|
84
|
-
it "casts '
|
85
|
-
|
86
|
-
|
87
|
-
|
82
|
+
it "casts 't' to true" do
|
83
|
+
column.type_cast('t').should == true
|
84
|
+
end
|
85
|
+
|
86
|
+
it "casts value other than 't' or 'y' to false" do
|
87
|
+
column.type_cast('n').should == false
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
91
|
context 'with type T (datetime)' do
|
92
|
+
let(:column) { DBF::Column.new "ColumnName", "T", 16, 0 }
|
93
|
+
|
92
94
|
context 'with valid datetime' do
|
93
95
|
it "casts to DateTime" do
|
94
|
-
|
95
|
-
column = DBF::Column.new "ColumnName", "T", 16, 0
|
96
|
-
column.type_cast(value).should == "2002-10-10T17:04:56+00:00"
|
96
|
+
column.type_cast("Nl%\000\300Z\252\003").should == "2002-10-10T17:04:56+00:00"
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
100
|
context 'with invalid datetime' do
|
101
101
|
it "casts to nil" do
|
102
|
-
|
103
|
-
column = DBF::Column.new "ColumnName", "T", 16, 0
|
104
|
-
column.type_cast(value).should be_nil
|
102
|
+
column.type_cast("Nl%\000\000A\000\999").should be_nil
|
105
103
|
end
|
106
104
|
end
|
107
105
|
end
|
108
106
|
|
109
107
|
context 'with type D (date)' do
|
108
|
+
let(:column) { DBF::Column.new "ColumnName", "D", 8, 0 }
|
109
|
+
|
110
110
|
context 'with valid date' do
|
111
111
|
it "casts to Date" do
|
112
|
-
|
113
|
-
column = DBF::Column.new "ColumnName", "D", 8, 0
|
114
|
-
column.type_cast(value).should == Date.new(2005,7,12)
|
112
|
+
column.type_cast("20050712").should == Date.new(2005,7,12)
|
115
113
|
end
|
116
114
|
end
|
117
115
|
|
118
116
|
context 'with invalid date' do
|
119
117
|
it "casts to nil" do
|
120
|
-
|
121
|
-
column = DBF::Column.new "ColumnName", "D", 8, 0
|
122
|
-
column.type_cast(value).should be_nil
|
118
|
+
column.type_cast("0").should be_nil
|
123
119
|
end
|
124
120
|
end
|
125
121
|
end
|
126
122
|
|
127
123
|
context 'with type M (memo)' do
|
128
124
|
it "casts to string" do
|
129
|
-
value = 'abc'
|
130
125
|
column = DBF::Column.new "ColumnName", "M", 3, 0
|
131
|
-
column.type_cast(
|
126
|
+
column.type_cast('abc').should be_a String
|
132
127
|
end
|
133
128
|
end
|
134
129
|
end
|
@@ -172,31 +167,27 @@ describe DBF::Column do
|
|
172
167
|
end
|
173
168
|
end
|
174
169
|
|
175
|
-
context "#
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
it "strips characters below decimal 32 and above decimal 127" do
|
181
|
-
@column.strip_non_ascii_chars("--\x1F-\x68\x65\x6C\x6C\x6F world-\x80--").should == "---hello world---"
|
170
|
+
context "#name" do
|
171
|
+
it "contains only ASCII characters" do
|
172
|
+
column = DBF::Column.new "--\x1F-\x68\x65\x6C\x6C\x6F world-\x80--", "N", 1, 0
|
173
|
+
column.name.should == "---hello world---"
|
182
174
|
end
|
183
175
|
|
184
|
-
it "
|
185
|
-
|
176
|
+
it "is truncated at the null character" do
|
177
|
+
column = DBF::Column.new "--\x1F-\x68\x65\x6C\x6C\x6F \x00 world-\x80--", "N", 1, 0
|
178
|
+
column.name.should == "---hello "
|
186
179
|
end
|
187
180
|
end
|
188
181
|
|
189
182
|
context '#decode_date' do
|
190
|
-
|
191
|
-
@column = DBF::Column.new "ColumnName", "N", 1, 0
|
192
|
-
end
|
183
|
+
let(:column) { DBF::Column.new "ColumnName", "N", 1, 0 }
|
193
184
|
|
194
185
|
it 'is nil if value is blank' do
|
195
|
-
|
186
|
+
column.send(:decode_date, '').should be_nil
|
196
187
|
end
|
197
188
|
|
198
189
|
it 'interperets spaces as zeros' do
|
199
|
-
|
190
|
+
column.send(:decode_date, '2010 715').should == Date.parse('20100715')
|
200
191
|
end
|
201
192
|
end
|
202
193
|
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
shared_examples_for 'DBF' do
|
4
|
+
specify "sum of column lengths should equal record length specified in header plus one" do
|
5
|
+
header_record_length = @table.instance_eval {@record_length}
|
6
|
+
sum_of_column_lengths = 1 + @table.columns.sum {|column| column.length}
|
7
|
+
|
8
|
+
header_record_length.should == sum_of_column_lengths
|
9
|
+
end
|
10
|
+
|
11
|
+
specify "records should be instances of DBF::Record" do
|
12
|
+
@table.all? {|record| record.should be_an_instance_of(DBF::Record)}
|
13
|
+
end
|
14
|
+
|
15
|
+
specify "record count should be the same as reported in the header" do
|
16
|
+
@table.count.should == @table.record_count
|
17
|
+
end
|
18
|
+
|
19
|
+
specify "columns should be instances of DBF::Column" do
|
20
|
+
@table.columns.all? {|column| column.should be_an_instance_of(DBF::Column)}
|
21
|
+
end
|
22
|
+
|
23
|
+
specify "column names should not be blank" do
|
24
|
+
@table.columns.all? {|column| column.name.should_not be_empty}
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "column types should be valid" do
|
28
|
+
valid_column_types = %w(C N L D M F B G P Y T I V X @ O + 0)
|
29
|
+
@table.columns.all? {|column| valid_column_types.should include(column.type)}
|
30
|
+
end
|
31
|
+
|
32
|
+
specify "column lengths should be instances of Fixnum" do
|
33
|
+
@table.columns.all? {|column| column.length.should be_an_instance_of(Fixnum)}
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "column lengths should be larger than 0" do
|
37
|
+
@table.columns.all? {|column| column.length.should > 0}
|
38
|
+
end
|
39
|
+
|
40
|
+
specify "column decimals should be instances of Fixnum" do
|
41
|
+
@table.columns.all? {|column| column.decimal.should be_an_instance_of(Fixnum)}
|
42
|
+
end
|
43
|
+
|
44
|
+
specify "column read accessors should return the attribute after typecast" do
|
45
|
+
@table.columns do |column|
|
46
|
+
record = @table.records.first
|
47
|
+
record.send(column.name).should == record[column.name]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
specify "column attributes should be accessible in underscored form" do
|
52
|
+
@table.columns do |column|
|
53
|
+
record = @table.records.first
|
54
|
+
record.send(column_name).should == record.send(column_name.underscore)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe DBF, "of type 03 (dBase III without memo file)" do
|
61
|
+
before do
|
62
|
+
@table = DBF::Table.new "#{DB_PATH}/dbase_03.dbf"
|
63
|
+
end
|
64
|
+
|
65
|
+
it_should_behave_like "DBF"
|
66
|
+
|
67
|
+
it "should report the correct version number" do
|
68
|
+
@table.version.should == "03"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should report the correct version description" do
|
72
|
+
@table.version_description.should == "dBase III without memo file"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should determine the number of records" do
|
76
|
+
@table.record_count.should == 14
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe DBF, "of type 30 (Visual FoxPro)" do
|
81
|
+
before do
|
82
|
+
@table = DBF::Table.new "#{DB_PATH}/dbase_30.dbf"
|
83
|
+
end
|
84
|
+
|
85
|
+
it_should_behave_like "DBF"
|
86
|
+
|
87
|
+
it "should report the correct version number" do
|
88
|
+
@table.version.should == "30"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should report the correct version description" do
|
92
|
+
@table.version_description.should == "Visual FoxPro"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should determine the number of records" do
|
96
|
+
@table.record_count.should == 34
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe DBF, "of type 31 (Visual FoxPro with AutoIncrement field)" do
|
101
|
+
before do
|
102
|
+
@table = DBF::Table.new "#{DB_PATH}/dbase_31.dbf"
|
103
|
+
end
|
104
|
+
|
105
|
+
it_should_behave_like "DBF"
|
106
|
+
|
107
|
+
it "should have a dBase version of 31" do
|
108
|
+
@table.version.should == "31"
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should report the correct version description" do
|
112
|
+
@table.version_description.should == "Visual FoxPro with AutoIncrement field"
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should determine the number of records" do
|
116
|
+
@table.record_count.should == 77
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe DBF, "of type 83 (dBase III with memo file)" do
|
121
|
+
before do
|
122
|
+
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
123
|
+
end
|
124
|
+
|
125
|
+
it_should_behave_like "DBF"
|
126
|
+
|
127
|
+
it "should report the correct version number" do
|
128
|
+
@table.version.should == "83"
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should report the correct version description" do
|
132
|
+
@table.version_description.should == "dBase III with memo file"
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should determine the number of records" do
|
136
|
+
@table.record_count.should == 67
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe DBF, "of type 8b (dBase IV with memo file)" do
|
141
|
+
before do
|
142
|
+
@table = DBF::Table.new "#{DB_PATH}/dbase_8b.dbf"
|
143
|
+
end
|
144
|
+
|
145
|
+
it_should_behave_like "DBF"
|
146
|
+
|
147
|
+
it "should report the correct version number" do
|
148
|
+
@table.version.should == "8b"
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should report the correct version description" do
|
152
|
+
@table.version_description.should == "dBase IV with memo file"
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should determine the number of records" do
|
156
|
+
@table.record_count.should == 10
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe DBF, "of type f5 (FoxPro with memo file)" do
|
161
|
+
before do
|
162
|
+
@table = DBF::Table.new "#{DB_PATH}/dbase_f5.dbf"
|
163
|
+
end
|
164
|
+
|
165
|
+
it_should_behave_like "DBF"
|
166
|
+
|
167
|
+
it "should report the correct version number" do
|
168
|
+
@table.version.should == "f5"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should report the correct version description" do
|
172
|
+
@table.version_description.should == "FoxPro with memo file"
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should determine the number of records" do
|
176
|
+
@table.record_count.should == 975
|
177
|
+
end
|
178
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe DBF::Record do
|
4
|
+
|
5
|
+
describe '#to_a' do
|
6
|
+
it 'should return an ordered array of attribute values' do
|
7
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_8b.dbf"
|
8
|
+
|
9
|
+
record = table.record(0)
|
10
|
+
record.to_a.should == ["One", 1.0, Date.new(1970, 1, 1), true, 1.23456789012346, "First memo\r\n\037 \037 \037 \037 "]
|
11
|
+
|
12
|
+
record = table.record(9)
|
13
|
+
record.to_a.should == ["Ten records stored in this database", 10.0, nil, false, 0.1, nil]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#==' do
|
18
|
+
before do
|
19
|
+
table = DBF::Table.new "#{DB_PATH}/dbase_8b.dbf"
|
20
|
+
@record = table.record(9)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should be false if other does not have attributes' do
|
24
|
+
(@record == mock('other')).should be_false
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should be true if other attributes match' do
|
28
|
+
attributes = {:x => 1, :y => 2}
|
29
|
+
@record.stub!(:attributes).and_return(attributes)
|
30
|
+
other = mock('object', :attributes => attributes)
|
31
|
+
(@record == other).should be_true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'column accessors' do
|
36
|
+
let(:table) { DBF::Table.new "#{DB_PATH}/dbase_8b.dbf"}
|
37
|
+
|
38
|
+
it 'should define accessor methods for each column' do
|
39
|
+
record = table.find(0)
|
40
|
+
record.should respond_to(:character)
|
41
|
+
record.character.should == 'One'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -1,67 +1,18 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
describe DBF::Table do
|
4
|
-
context "when initialized" do
|
5
|
-
before do
|
6
|
-
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
7
|
-
end
|
8
|
-
|
9
|
-
it "should load the data file" do
|
10
|
-
@table.data.should be_kind_of(File)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should load the memo file" do
|
14
|
-
@table.has_memo_file?.should be_true
|
15
|
-
@table.instance_eval("@memo").should be_kind_of(File)
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should determine the memo file format" do
|
19
|
-
@table.memo_file_format.should == :dbt
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should determine the correct memo block size" do
|
23
|
-
@table.memo_block_size.should == 512
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should determine the number of columns in each record" do
|
27
|
-
@table.columns.size.should == 15
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should determine the number of records in the database" do
|
31
|
-
@table.record_count.should == 67
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should determine the database version" do
|
35
|
-
@table.version.should == "83"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
3
|
+
describe DBF::Table do
|
39
4
|
context "when closed" do
|
40
5
|
before do
|
41
6
|
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
7
|
+
@table.close
|
42
8
|
end
|
43
9
|
|
44
10
|
it "should close the data file" do
|
45
|
-
@table.
|
46
|
-
lambda { @table.record(1) }.should raise_error(IOError)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
describe "#column" do
|
51
|
-
it "should accept a string or symbol as input" do
|
52
|
-
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
53
|
-
table.column(:IMAGE).should be_kind_of(DBF::Column)
|
54
|
-
table.column("IMAGE").should be_kind_of(DBF::Column)
|
11
|
+
@table.instance_eval { @data }.should be_closed
|
55
12
|
end
|
56
13
|
|
57
|
-
it "should
|
58
|
-
table
|
59
|
-
table.column(:IMAGE).should be_kind_of(DBF::Column)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should return nil when the column_name does not exist" do
|
63
|
-
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
64
|
-
table.column(:NOTANIMAGE).should be_nil
|
14
|
+
it "should close the memo file" do
|
15
|
+
@table.instance_eval { @memo }.instance_eval { @data }.should be_closed
|
65
16
|
end
|
66
17
|
end
|
67
18
|
|
@@ -74,33 +25,6 @@ describe DBF::Table do
|
|
74
25
|
end
|
75
26
|
end
|
76
27
|
|
77
|
-
describe "#version_description" do
|
78
|
-
it "should return a text description of the database type" do
|
79
|
-
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
80
|
-
table.version_description.should == "dBase III with memo file"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe '#replace_extname' do
|
85
|
-
it "should change the file extension" do
|
86
|
-
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
87
|
-
table.send(:replace_extname, 'dbase_83.dbf', 'fpt').should == 'dbase_83.fpt'
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
describe '#to_a' do
|
92
|
-
before do
|
93
|
-
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
94
|
-
|
95
|
-
@records = []
|
96
|
-
@table.each {|record| @records << record}
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'should return an array of records' do
|
100
|
-
@table.to_a.should == @records
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
28
|
describe '#to_csv' do
|
105
29
|
before do
|
106
30
|
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
@@ -115,22 +39,21 @@ describe DBF::Table do
|
|
115
39
|
@table.to_csv
|
116
40
|
File.exists?('dbase_83.csv').should be_true
|
117
41
|
end
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
42
|
+
|
43
|
+
describe 'when path param passed' do
|
44
|
+
it 'should create custom csv file' do
|
45
|
+
@table.to_csv('test.csv')
|
46
|
+
File.exists?('test.csv').should be_true
|
47
|
+
end
|
122
48
|
end
|
123
49
|
end
|
124
50
|
|
125
51
|
describe "#record" do
|
126
52
|
before do
|
127
53
|
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
128
|
-
|
129
|
-
@records = []
|
130
|
-
@table.each {|record| @records << record}
|
131
54
|
end
|
132
55
|
|
133
|
-
it "
|
56
|
+
it "return nil for deleted records" do
|
134
57
|
@table.stub!(:deleted_record?).and_return(true)
|
135
58
|
@table.record(5).should be_nil
|
136
59
|
end
|
@@ -145,10 +68,6 @@ describe DBF::Table do
|
|
145
68
|
@table.stub!(:deleted_record?).and_return(true)
|
146
69
|
@table.record(0).should be_nil
|
147
70
|
end
|
148
|
-
|
149
|
-
it 'should return a DBF::Record' do
|
150
|
-
@table.record(0).should be_kind_of(DBF::Record)
|
151
|
-
end
|
152
71
|
end
|
153
72
|
|
154
73
|
describe "#find" do
|
@@ -175,9 +94,6 @@ describe DBF::Table do
|
|
175
94
|
describe "with :all" do
|
176
95
|
before do
|
177
96
|
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
178
|
-
|
179
|
-
@records = []
|
180
|
-
@table.each {|record| @records << record}
|
181
97
|
end
|
182
98
|
|
183
99
|
it "should accept a block" do
|
@@ -189,11 +105,11 @@ describe DBF::Table do
|
|
189
105
|
end
|
190
106
|
|
191
107
|
it "should return all records if options are empty" do
|
192
|
-
@table.find(:all).should == @
|
108
|
+
@table.find(:all).should == @table.to_a
|
193
109
|
end
|
194
110
|
|
195
111
|
it "should return matching records when used with options" do
|
196
|
-
@table.find(:all, "WEIGHT" => 0.0).should == @
|
112
|
+
@table.find(:all, "WEIGHT" => 0.0).should == @table.select {|r| r.attributes["weight"] == 0.0}
|
197
113
|
end
|
198
114
|
|
199
115
|
it "should AND multiple search terms" do
|
@@ -220,17 +136,14 @@ describe DBF::Table do
|
|
220
136
|
describe "with :first" do
|
221
137
|
before do
|
222
138
|
@table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
223
|
-
|
224
|
-
@records = []
|
225
|
-
@table.each {|record| @records << record}
|
226
139
|
end
|
227
140
|
|
228
141
|
it "should return the first record if options are empty" do
|
229
|
-
@table.find(:first).should == @
|
142
|
+
@table.find(:first).should == @table.first
|
230
143
|
end
|
231
144
|
|
232
145
|
it "should return the first matching record when used with options" do
|
233
|
-
@table.find(:first, "CODE" => "C").should == @
|
146
|
+
@table.find(:first, "CODE" => "C").should == @table.record(5)
|
234
147
|
end
|
235
148
|
|
236
149
|
it "should AND multiple search terms" do
|