dbf 1.3.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|