dbf 5.1.1 → 5.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +4 -2
- data/dbf.gemspec +6 -9
- data/lib/dbf/column.rb +17 -15
- data/lib/dbf/column_builder.rb +31 -0
- data/lib/dbf/column_type.rb +58 -14
- data/lib/dbf/database/foxpro.rb +19 -32
- data/lib/dbf/file_handler.rb +36 -0
- data/lib/dbf/find.rb +54 -0
- data/lib/dbf/header.rb +5 -8
- data/lib/dbf/memo/base.rb +2 -0
- data/lib/dbf/memo/dbase3.rb +2 -2
- data/lib/dbf/memo/dbase4.rb +2 -2
- data/lib/dbf/memo/foxpro.rb +14 -7
- data/lib/dbf/record.rb +60 -34
- data/lib/dbf/record_context.rb +5 -0
- data/lib/dbf/record_iterator.rb +35 -0
- data/lib/dbf/schema.rb +21 -21
- data/lib/dbf/table.rb +42 -178
- data/lib/dbf/version.rb +1 -1
- data/lib/dbf/version_config.rb +79 -0
- data/lib/dbf.rb +6 -0
- metadata +15 -64
- data/spec/dbf/column_spec.rb +0 -287
- data/spec/dbf/database/foxpro_spec.rb +0 -53
- data/spec/dbf/encoding_spec.rb +0 -49
- data/spec/dbf/file_formats_spec.rb +0 -221
- data/spec/dbf/record_spec.rb +0 -116
- data/spec/dbf/table_spec.rb +0 -377
- data/spec/fixtures/cp1251.dbf +0 -0
- data/spec/fixtures/cp1251_summary.txt +0 -12
- data/spec/fixtures/dbase_02.dbf +0 -0
- data/spec/fixtures/dbase_02_summary.txt +0 -23
- data/spec/fixtures/dbase_03.dbf +0 -0
- data/spec/fixtures/dbase_03_cyrillic.dbf +0 -0
- data/spec/fixtures/dbase_03_cyrillic_summary.txt +0 -11
- data/spec/fixtures/dbase_03_summary.txt +0 -40
- data/spec/fixtures/dbase_30.dbf +0 -0
- data/spec/fixtures/dbase_30.fpt +0 -0
- data/spec/fixtures/dbase_30_summary.txt +0 -154
- data/spec/fixtures/dbase_31.dbf +0 -0
- data/spec/fixtures/dbase_31_summary.txt +0 -20
- data/spec/fixtures/dbase_32.dbf +0 -0
- data/spec/fixtures/dbase_32_summary.txt +0 -11
- data/spec/fixtures/dbase_83.dbf +0 -0
- data/spec/fixtures/dbase_83.dbt +0 -0
- data/spec/fixtures/dbase_83_missing_memo.dbf +0 -0
- data/spec/fixtures/dbase_83_missing_memo_record_0.yml +0 -16
- data/spec/fixtures/dbase_83_record_0.yml +0 -16
- data/spec/fixtures/dbase_83_record_9.yml +0 -23
- data/spec/fixtures/dbase_83_schema_ar.txt +0 -19
- data/spec/fixtures/dbase_83_schema_sq.txt +0 -21
- data/spec/fixtures/dbase_83_schema_sq_lim.txt +0 -21
- data/spec/fixtures/dbase_83_summary.txt +0 -24
- data/spec/fixtures/dbase_8b.dbf +0 -0
- data/spec/fixtures/dbase_8b.dbt +0 -0
- data/spec/fixtures/dbase_8b_summary.txt +0 -15
- data/spec/fixtures/dbase_8c.dbf +0 -0
- data/spec/fixtures/dbase_f5.dbf +0 -0
- data/spec/fixtures/dbase_f5.fpt +0 -0
- data/spec/fixtures/dbase_f5_summary.txt +0 -68
- data/spec/fixtures/foxprodb/FOXPRO-DB-TEST.DBC +0 -0
- data/spec/fixtures/foxprodb/FOXPRO-DB-TEST.DCT +0 -0
- data/spec/fixtures/foxprodb/FOXPRO-DB-TEST.DCX +0 -0
- data/spec/fixtures/foxprodb/calls.CDX +0 -0
- data/spec/fixtures/foxprodb/calls.FPT +0 -0
- data/spec/fixtures/foxprodb/calls.dbf +0 -0
- data/spec/fixtures/foxprodb/contacts.CDX +0 -0
- data/spec/fixtures/foxprodb/contacts.FPT +0 -0
- data/spec/fixtures/foxprodb/contacts.dbf +0 -0
- data/spec/fixtures/foxprodb/setup.CDX +0 -0
- data/spec/fixtures/foxprodb/setup.dbf +0 -0
- data/spec/fixtures/foxprodb/types.CDX +0 -0
- data/spec/fixtures/foxprodb/types.dbf +0 -0
- data/spec/fixtures/polygon.dbf +0 -0
- data/spec/spec_helper.rb +0 -35
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dbf
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Keith Morrison
|
|
@@ -29,10 +29,7 @@ email: keithm@infused.org
|
|
|
29
29
|
executables:
|
|
30
30
|
- dbf
|
|
31
31
|
extensions: []
|
|
32
|
-
extra_rdoc_files:
|
|
33
|
-
- CHANGELOG.md
|
|
34
|
-
- LICENSE
|
|
35
|
-
- README.md
|
|
32
|
+
extra_rdoc_files: []
|
|
36
33
|
files:
|
|
37
34
|
- CHANGELOG.md
|
|
38
35
|
- LICENSE
|
|
@@ -41,92 +38,46 @@ files:
|
|
|
41
38
|
- dbf.gemspec
|
|
42
39
|
- lib/dbf.rb
|
|
43
40
|
- lib/dbf/column.rb
|
|
41
|
+
- lib/dbf/column_builder.rb
|
|
44
42
|
- lib/dbf/column_type.rb
|
|
45
43
|
- lib/dbf/database/foxpro.rb
|
|
46
44
|
- lib/dbf/encodings.rb
|
|
45
|
+
- lib/dbf/file_handler.rb
|
|
46
|
+
- lib/dbf/find.rb
|
|
47
47
|
- lib/dbf/header.rb
|
|
48
48
|
- lib/dbf/memo/base.rb
|
|
49
49
|
- lib/dbf/memo/dbase3.rb
|
|
50
50
|
- lib/dbf/memo/dbase4.rb
|
|
51
51
|
- lib/dbf/memo/foxpro.rb
|
|
52
52
|
- lib/dbf/record.rb
|
|
53
|
+
- lib/dbf/record_context.rb
|
|
54
|
+
- lib/dbf/record_iterator.rb
|
|
53
55
|
- lib/dbf/schema.rb
|
|
54
56
|
- lib/dbf/table.rb
|
|
55
57
|
- lib/dbf/version.rb
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
- spec/dbf/encoding_spec.rb
|
|
59
|
-
- spec/dbf/file_formats_spec.rb
|
|
60
|
-
- spec/dbf/record_spec.rb
|
|
61
|
-
- spec/dbf/table_spec.rb
|
|
62
|
-
- spec/fixtures/cp1251.dbf
|
|
63
|
-
- spec/fixtures/cp1251_summary.txt
|
|
64
|
-
- spec/fixtures/dbase_02.dbf
|
|
65
|
-
- spec/fixtures/dbase_02_summary.txt
|
|
66
|
-
- spec/fixtures/dbase_03.dbf
|
|
67
|
-
- spec/fixtures/dbase_03_cyrillic.dbf
|
|
68
|
-
- spec/fixtures/dbase_03_cyrillic_summary.txt
|
|
69
|
-
- spec/fixtures/dbase_03_summary.txt
|
|
70
|
-
- spec/fixtures/dbase_30.dbf
|
|
71
|
-
- spec/fixtures/dbase_30.fpt
|
|
72
|
-
- spec/fixtures/dbase_30_summary.txt
|
|
73
|
-
- spec/fixtures/dbase_31.dbf
|
|
74
|
-
- spec/fixtures/dbase_31_summary.txt
|
|
75
|
-
- spec/fixtures/dbase_32.dbf
|
|
76
|
-
- spec/fixtures/dbase_32_summary.txt
|
|
77
|
-
- spec/fixtures/dbase_83.dbf
|
|
78
|
-
- spec/fixtures/dbase_83.dbt
|
|
79
|
-
- spec/fixtures/dbase_83_missing_memo.dbf
|
|
80
|
-
- spec/fixtures/dbase_83_missing_memo_record_0.yml
|
|
81
|
-
- spec/fixtures/dbase_83_record_0.yml
|
|
82
|
-
- spec/fixtures/dbase_83_record_9.yml
|
|
83
|
-
- spec/fixtures/dbase_83_schema_ar.txt
|
|
84
|
-
- spec/fixtures/dbase_83_schema_sq.txt
|
|
85
|
-
- spec/fixtures/dbase_83_schema_sq_lim.txt
|
|
86
|
-
- spec/fixtures/dbase_83_summary.txt
|
|
87
|
-
- spec/fixtures/dbase_8b.dbf
|
|
88
|
-
- spec/fixtures/dbase_8b.dbt
|
|
89
|
-
- spec/fixtures/dbase_8b_summary.txt
|
|
90
|
-
- spec/fixtures/dbase_8c.dbf
|
|
91
|
-
- spec/fixtures/dbase_f5.dbf
|
|
92
|
-
- spec/fixtures/dbase_f5.fpt
|
|
93
|
-
- spec/fixtures/dbase_f5_summary.txt
|
|
94
|
-
- spec/fixtures/foxprodb/FOXPRO-DB-TEST.DBC
|
|
95
|
-
- spec/fixtures/foxprodb/FOXPRO-DB-TEST.DCT
|
|
96
|
-
- spec/fixtures/foxprodb/FOXPRO-DB-TEST.DCX
|
|
97
|
-
- spec/fixtures/foxprodb/calls.CDX
|
|
98
|
-
- spec/fixtures/foxprodb/calls.FPT
|
|
99
|
-
- spec/fixtures/foxprodb/calls.dbf
|
|
100
|
-
- spec/fixtures/foxprodb/contacts.CDX
|
|
101
|
-
- spec/fixtures/foxprodb/contacts.FPT
|
|
102
|
-
- spec/fixtures/foxprodb/contacts.dbf
|
|
103
|
-
- spec/fixtures/foxprodb/setup.CDX
|
|
104
|
-
- spec/fixtures/foxprodb/setup.dbf
|
|
105
|
-
- spec/fixtures/foxprodb/types.CDX
|
|
106
|
-
- spec/fixtures/foxprodb/types.dbf
|
|
107
|
-
- spec/fixtures/polygon.dbf
|
|
108
|
-
- spec/spec_helper.rb
|
|
109
|
-
homepage: http://github.com/infused/dbf
|
|
58
|
+
- lib/dbf/version_config.rb
|
|
59
|
+
homepage: https://github.com/infused/dbf
|
|
110
60
|
licenses:
|
|
111
61
|
- MIT
|
|
112
62
|
metadata:
|
|
113
63
|
rubygems_mfa_required: 'true'
|
|
114
|
-
|
|
115
|
-
|
|
64
|
+
source_code_uri: https://github.com/infused/dbf
|
|
65
|
+
changelog_uri: https://github.com/infused/dbf/blob/main/CHANGELOG.md
|
|
66
|
+
rdoc_options: []
|
|
116
67
|
require_paths:
|
|
117
68
|
- lib
|
|
118
69
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
119
70
|
requirements:
|
|
120
71
|
- - ">="
|
|
121
72
|
- !ruby/object:Gem::Version
|
|
122
|
-
version: 3.
|
|
73
|
+
version: 3.3.0
|
|
123
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
75
|
requirements:
|
|
125
76
|
- - ">="
|
|
126
77
|
- !ruby/object:Gem::Version
|
|
127
|
-
version:
|
|
78
|
+
version: '0'
|
|
128
79
|
requirements: []
|
|
129
|
-
rubygems_version: 3.
|
|
80
|
+
rubygems_version: 3.7.2
|
|
130
81
|
specification_version: 4
|
|
131
82
|
summary: Read xBase files
|
|
132
83
|
test_files: []
|
data/spec/dbf/column_spec.rb
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
# encoding: ascii-8bit
|
|
3
|
-
|
|
4
|
-
require 'spec_helper'
|
|
5
|
-
|
|
6
|
-
RSpec.describe DBF::Column do
|
|
7
|
-
let(:table) { DBF::Table.new fixture('dbase_30.dbf') }
|
|
8
|
-
|
|
9
|
-
context 'when initialized' do
|
|
10
|
-
let(:column) { DBF::Column.new table, 'ColumnName', 'N', 1, 0 }
|
|
11
|
-
|
|
12
|
-
it 'sets :name accessor' do
|
|
13
|
-
expect(column.name).to eq 'ColumnName'
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it 'sets :type accessor' do
|
|
17
|
-
expect(column.type).to eq 'N'
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it 'sets the #length accessor' do
|
|
21
|
-
expect(column.length).to eq 1
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it 'sets the #decimal accessor' do
|
|
25
|
-
expect(column.decimal).to eq 0
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it 'accepts length of 0' do
|
|
29
|
-
column = DBF::Column.new table, 'ColumnName', 'N', 0, 0
|
|
30
|
-
expect(column.length).to eq 0
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
describe 'with length less than 0' do
|
|
34
|
-
it 'raises DBF::Column::LengthError' do
|
|
35
|
-
expect { DBF::Column.new table, 'ColumnName', 'N', -1, 0 }.to raise_error(DBF::Column::LengthError)
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
describe 'with empty column name' do
|
|
40
|
-
it 'raises DBF::Column::NameError' do
|
|
41
|
-
expect { DBF::Column.new table, '', 'N', 1, 0 }.to raise_error(DBF::Column::NameError)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
describe '#type_cast' do
|
|
47
|
-
context 'with type N (number)' do
|
|
48
|
-
context 'when value is empty' do
|
|
49
|
-
it 'returns nil' do
|
|
50
|
-
value = ''
|
|
51
|
-
column = DBF::Column.new table, 'ColumnName', 'N', 5, 2
|
|
52
|
-
expect(column.type_cast(value)).to be_nil
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
context 'with 0 length' do
|
|
57
|
-
it 'returns nil' do
|
|
58
|
-
column = DBF::Column.new table, 'ColumnName', 'N', 0, 0
|
|
59
|
-
expect(column.type_cast('')).to be_nil
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
context 'with 0 decimals' do
|
|
64
|
-
it 'casts value to Integer' do
|
|
65
|
-
value = '135'
|
|
66
|
-
column = DBF::Column.new table, 'ColumnName', 'N', 3, 0
|
|
67
|
-
expect(column.type_cast(value)).to eq 135
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it 'supports negative Integer' do
|
|
71
|
-
value = '-135'
|
|
72
|
-
column = DBF::Column.new table, 'ColumnName', 'N', 3, 0
|
|
73
|
-
expect(column.type_cast(value)).to eq(-135)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
context 'with more than 0 decimals' do
|
|
78
|
-
it 'casts value to Float' do
|
|
79
|
-
value = '13.5'
|
|
80
|
-
column = DBF::Column.new table, 'ColumnName', 'N', 2, 1
|
|
81
|
-
expect(column.type_cast(value)).to eq 13.5
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it 'casts negative value to Float' do
|
|
85
|
-
value = '-13.5'
|
|
86
|
-
column = DBF::Column.new table, 'ColumnName', 'N', 2, 1
|
|
87
|
-
expect(column.type_cast(value)).to eq(-13.5)
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
context 'with type F (float)' do
|
|
93
|
-
context 'with 0 length' do
|
|
94
|
-
it 'returns nil' do
|
|
95
|
-
column = DBF::Column.new table, 'ColumnName', 'F', 0, 0
|
|
96
|
-
expect(column.type_cast('')).to be_nil
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
it 'casts value to Float' do
|
|
101
|
-
value = '135'
|
|
102
|
-
column = DBF::Column.new table, 'ColumnName', 'F', 3, 0
|
|
103
|
-
expect(column.type_cast(value)).to eq 135.0
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
it 'casts negative value to Float' do
|
|
107
|
-
value = '-135'
|
|
108
|
-
column = DBF::Column.new table, 'ColumnName', 'F', 3, 0
|
|
109
|
-
expect(column.type_cast(value)).to eq(-135.0)
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
context 'with type B (binary)' do
|
|
114
|
-
context 'with Foxpro dbf' do
|
|
115
|
-
it 'casts to float' do
|
|
116
|
-
column = DBF::Column.new table, 'ColumnName', 'B', 1, 2
|
|
117
|
-
expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to be_a(Float)
|
|
118
|
-
expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to eq 17.42
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
it 'stores original precision' do
|
|
122
|
-
column = DBF::Column.new table, 'ColumnName', 'B', 1, 0
|
|
123
|
-
expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to be_a(Float)
|
|
124
|
-
expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to eq 17.42
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
it 'supports negative binary' do
|
|
128
|
-
column = DBF::Column.new table, 'ColumnName', 'B', 1, 2
|
|
129
|
-
expect(column.type_cast("\x00\x00\x00\x00\x00\xC0\x65\xC0")).to be_a(Float)
|
|
130
|
-
expect(column.type_cast("\x00\x00\x00\x00\x00\xC0\x65\xC0")).to eq(-174.0)
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
context 'with type I (integer)' do
|
|
136
|
-
context 'with 0 length' do
|
|
137
|
-
it 'returns nil' do
|
|
138
|
-
column = DBF::Column.new table, 'ColumnName', 'I', 0, 0
|
|
139
|
-
expect(column.type_cast('')).to be_nil
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
it 'casts value to Integer' do
|
|
144
|
-
value = "\203\171\001\000"
|
|
145
|
-
column = DBF::Column.new table, 'ColumnName', 'I', 3, 0
|
|
146
|
-
expect(column.type_cast(value)).to eq 96_643
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
it 'supports negative Integer' do
|
|
150
|
-
value = "\x24\xE1\xFF\xFF"
|
|
151
|
-
column = DBF::Column.new table, 'ColumnName', 'I', 3, 0
|
|
152
|
-
expect(column.type_cast(value)).to eq(-7900)
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
context 'with type L (logical/boolean)' do
|
|
157
|
-
let(:column) { DBF::Column.new table, 'ColumnName', 'L', 1, 0 }
|
|
158
|
-
|
|
159
|
-
it "casts 'y' to true" do
|
|
160
|
-
expect(column.type_cast('y')).to be true
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
it "casts 't' to true" do
|
|
164
|
-
expect(column.type_cast('t')).to be true
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
it "casts value other than 't' or 'y' to false" do
|
|
168
|
-
expect(column.type_cast('n')).to be false
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
context 'with 0 length' do
|
|
172
|
-
it 'returns nil' do
|
|
173
|
-
column = DBF::Column.new table, 'ColumnName', 'L', 0, 0
|
|
174
|
-
expect(column.type_cast('')).to be_nil
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
context 'with type T (datetime)' do
|
|
180
|
-
let(:column) { DBF::Column.new table, 'ColumnName', 'T', 16, 0 }
|
|
181
|
-
|
|
182
|
-
context 'with valid datetime' do
|
|
183
|
-
it 'casts to DateTime' do
|
|
184
|
-
expect(column.type_cast("Nl%\000\300Z\252\003")).to eq Time.parse('2002-10-10T17:04:56+00:00')
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
context 'with invalid datetime' do
|
|
189
|
-
it 'casts to nil' do
|
|
190
|
-
expect(column.type_cast("Nl%\000\000A\000\999")).to be_nil
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
context 'with 0 length' do
|
|
195
|
-
it 'returns nil' do
|
|
196
|
-
column = DBF::Column.new table, 'ColumnName', 'T', 0, 0
|
|
197
|
-
expect(column.type_cast('')).to be_nil
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
context 'with type D (date)' do
|
|
203
|
-
let(:column) { DBF::Column.new table, 'ColumnName', 'D', 8, 0 }
|
|
204
|
-
|
|
205
|
-
context 'with valid date' do
|
|
206
|
-
it 'casts to Date' do
|
|
207
|
-
expect(column.type_cast('20050712')).to eq Date.new(2005, 7, 12)
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
context 'with invalid date' do
|
|
212
|
-
it 'casts to nil' do
|
|
213
|
-
expect(column.type_cast('000000000')).to be_nil
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
context 'with 0 length' do
|
|
218
|
-
it 'returns nil' do
|
|
219
|
-
column = DBF::Column.new table, 'ColumnName', 'D', 0, 0
|
|
220
|
-
expect(column.type_cast('')).to be_nil
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
context 'with type M (memo)' do
|
|
226
|
-
it 'casts to string' do
|
|
227
|
-
column = DBF::Column.new table, 'ColumnName', 'M', 3, 0
|
|
228
|
-
expect(column.type_cast('abc')).to eq 'abc'
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
it 'casts nil to nil' do
|
|
232
|
-
column = DBF::Column.new table, 'ColumnName', 'M', 3, 0
|
|
233
|
-
expect(column.type_cast(nil)).to be_nil
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
context 'with 0 length' do
|
|
237
|
-
it 'returns nil' do
|
|
238
|
-
column = DBF::Column.new table, 'ColumnName', 'M', 0, 0
|
|
239
|
-
expect(column.type_cast('')).to be_nil
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
context 'with type G (memo)' do
|
|
245
|
-
it 'returns binary data' do
|
|
246
|
-
column = DBF::Column.new table, 'ColumnName', 'G', 3, 0
|
|
247
|
-
expect(column.type_cast("\000\013\120")).to eq "\000\013\120"
|
|
248
|
-
expect(column.type_cast("\000\013\120").encoding).to eq Encoding::ASCII_8BIT
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
it 'casts nil to nil' do
|
|
252
|
-
column = DBF::Column.new table, 'ColumnName', 'G', 3, 0
|
|
253
|
-
expect(column.type_cast(nil)).to be_nil
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
context 'with 0 length' do
|
|
257
|
-
it 'returns nil' do
|
|
258
|
-
column = DBF::Column.new table, 'ColumnName', 'G', 0, 0
|
|
259
|
-
expect(column.type_cast('')).to be_nil
|
|
260
|
-
end
|
|
261
|
-
end
|
|
262
|
-
end
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
context 'with type Y (currency)' do
|
|
266
|
-
let(:column) { DBF::Column.new table, 'ColumnName', 'Y', 8, 4 }
|
|
267
|
-
|
|
268
|
-
it 'casts to float' do
|
|
269
|
-
expect(column.type_cast(" \xBF\x02\x00\x00\x00\x00\x00")).to eq 18.0
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
it 'supports negative currency' do
|
|
273
|
-
expect(column.type_cast("\xFC\xF0\xF0\xFE\xFF\xFF\xFF\xFF")).to eq(-1776.41)
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
it 'supports 64bit negative currency' do
|
|
277
|
-
expect(column.type_cast("pN'9\xFF\xFF\xFF\xFF")).to eq(-333_609.0)
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
context 'with 0 length' do
|
|
281
|
-
it 'returns nil' do
|
|
282
|
-
column = DBF::Column.new table, 'ColumnName', 'Y', 0, 0
|
|
283
|
-
expect(column.type_cast('')).to be_nil
|
|
284
|
-
end
|
|
285
|
-
end
|
|
286
|
-
end
|
|
287
|
-
end
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
RSpec.describe DBF::Database::Foxpro do
|
|
6
|
-
let(:dbf_path) { fixture('foxprodb/FOXPRO-DB-TEST.DBC') }
|
|
7
|
-
let(:db) { DBF::Database::Foxpro.new(dbf_path) }
|
|
8
|
-
|
|
9
|
-
describe '#initialize' do
|
|
10
|
-
describe 'when given a path to an existing dbc file' do
|
|
11
|
-
it 'does not raise an error' do
|
|
12
|
-
expect { DBF::Database::Foxpro.new dbf_path }.to_not raise_error
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
describe 'when given a path to a non-existent dbf file' do
|
|
17
|
-
it 'raises a DBF::FileNotFound error' do
|
|
18
|
-
expect { DBF::Database::Foxpro.new 'x' }.to raise_error(DBF::FileNotFoundError, 'file not found: x')
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
describe 'it loads the example db correctly' do
|
|
23
|
-
it 'shows a correct list of tables' do
|
|
24
|
-
expect(db.table_names.sort).to eq(%w[contacts calls setup types].sort)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
describe '#table' do
|
|
30
|
-
describe 'when accessing related tables' do
|
|
31
|
-
let(:db) { DBF::Database::Foxpro.new(dbf_path) }
|
|
32
|
-
|
|
33
|
-
it 'loads an existing related table' do
|
|
34
|
-
expect(db.contacts.record_count).to eq 5
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it 'supports a long table field name' do
|
|
38
|
-
expect(db.contacts.record(1).spouses_interests).to eq 'Tennis, golf'
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it 'loads an existing related table with wrong filename casing' do
|
|
42
|
-
expect(db.calls.record_count).to eq 16
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
describe '#table_path' do
|
|
48
|
-
it 'returns an absolute path' do
|
|
49
|
-
expect(db.table_path('contacts')).to eq File.expand_path('spec/fixtures/foxprodb/contacts.dbf')
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
end
|
data/spec/dbf/encoding_spec.rb
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'spec_helper'
|
|
4
|
-
|
|
5
|
-
RSpec.describe 'DBF::Table' do
|
|
6
|
-
context 'with default encoding' do
|
|
7
|
-
let(:dbf_path) { fixture('dbase_03_cyrillic.dbf') }
|
|
8
|
-
let(:table) { DBF::Table.new dbf_path }
|
|
9
|
-
|
|
10
|
-
it 'defaults to UTF-8 encoding' do
|
|
11
|
-
expect(table.encoding).to eq Encoding::UTF_8
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it 'uses the table encoding for column encoding' do
|
|
15
|
-
column = table.columns.first
|
|
16
|
-
expect(column.encoding).to eq table.encoding
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it 'encodes column names' do
|
|
20
|
-
expect(table.column_names).to eq %w[ШАР ПЛОЩА]
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it 'encodes record values' do
|
|
24
|
-
expect(table.record(0).attributes['ШАР']).to eq 'Номер'
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
context 'with embedded encoding' do
|
|
29
|
-
let(:dbf_path) { fixture('cp1251.dbf') }
|
|
30
|
-
let(:table) { DBF::Table.new dbf_path }
|
|
31
|
-
|
|
32
|
-
it 'defaults to UTF-8 encoding' do
|
|
33
|
-
expect(table.encoding).to eq 'cp1251'
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it 'uses the table encoding for column encoding' do
|
|
37
|
-
column = table.columns.first
|
|
38
|
-
expect(column.encoding).to eq table.encoding
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it 'encodes column names' do
|
|
42
|
-
expect(table.column_names).to eq %w[RN NAME]
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it 'encodes record values' do
|
|
46
|
-
expect(table.record(0).attributes['NAME']).to eq 'амбулаторно-поликлиническое'
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|