bumblebee 2.1.0 → 3.0.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/.rubocop.yml +2 -2
- data/.travis.yml +1 -1
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/README.md +172 -138
- data/bin/console +2 -6
- data/lib/bumblebee/bumblebee.rb +16 -62
- data/lib/bumblebee/column.rb +41 -63
- data/lib/bumblebee/column_dsl.rb +38 -0
- data/lib/bumblebee/column_set.rb +83 -0
- data/lib/bumblebee/converter.rb +97 -0
- data/lib/bumblebee/core_ext/hash.rb +21 -0
- data/lib/bumblebee/mutator.rb +54 -0
- data/lib/bumblebee/null_converter.rb +17 -0
- data/lib/bumblebee/object_interface.rb +66 -0
- data/lib/bumblebee/simple_converter.rb +109 -0
- data/lib/bumblebee/template.rb +23 -37
- data/lib/bumblebee/version.rb +1 -1
- data/spec/bumblebee/simple_converter_spec.rb +29 -0
- data/spec/bumblebee/template_spec.rb +151 -36
- data/spec/examples/converter_test_case.rb +113 -0
- data/spec/examples/person_template.rb +66 -0
- data/spec/examples/simple_object.rb +27 -0
- data/spec/fixtures/people/data.csv +3 -0
- data/spec/fixtures/people/data.yml +46 -0
- data/spec/fixtures/registrations/columns.yml +35 -0
- data/spec/fixtures/registrations/data.csv +3 -0
- data/spec/fixtures/registrations/data.yml +26 -0
- data/spec/fixtures/simple/columns.yml +4 -0
- data/spec/fixtures/{custom_readme_example.csv → simple/data.csv} +1 -1
- data/spec/fixtures/simple/data.yml +12 -0
- data/spec/spec_helper.rb +29 -3
- metadata +34 -10
- data/spec/bumblebee/bumblebee_spec.rb +0 -167
- data/spec/bumblebee/column_spec.rb +0 -213
- data/spec/fixtures/simple_readme_example.csv +0 -4
@@ -1,167 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#
|
4
|
-
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
5
|
-
#
|
6
|
-
# This source code is licensed under the MIT license found in the
|
7
|
-
# LICENSE file in the root directory of this source tree.
|
8
|
-
#
|
9
|
-
|
10
|
-
require './spec/spec_helper'
|
11
|
-
|
12
|
-
describe ::Bumblebee do
|
13
|
-
let(:columns) do
|
14
|
-
[
|
15
|
-
{ field: :name },
|
16
|
-
{ field: :dob }
|
17
|
-
]
|
18
|
-
end
|
19
|
-
|
20
|
-
let(:reverse_columns) do
|
21
|
-
[
|
22
|
-
{ field: :dob },
|
23
|
-
{ field: :name }
|
24
|
-
]
|
25
|
-
end
|
26
|
-
|
27
|
-
let(:people) do
|
28
|
-
[
|
29
|
-
{ name: 'Matt', dob: '1901-01-03' },
|
30
|
-
{ name: 'Nathan', dob: '1931-09-03' }
|
31
|
-
]
|
32
|
-
end
|
33
|
-
|
34
|
-
let(:csv) { "name,dob\nMatt,1901-01-03\nNathan,1931-09-03\n" }
|
35
|
-
|
36
|
-
let(:quoted_csv) { "\"name\",\"dob\"\n\"Matt\",\"1901-01-03\"\n\"Nathan\",\"1931-09-03\"\n" }
|
37
|
-
|
38
|
-
it 'should generate a csv using column argument' do
|
39
|
-
actual = Bumblebee.generate_csv(columns, people)
|
40
|
-
|
41
|
-
expect(actual).to eq(csv)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'should generate a csv using block' do
|
45
|
-
actual = Bumblebee.generate_csv(people) do |t|
|
46
|
-
columns.each do |column|
|
47
|
-
t.column column[:field]
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
expect(actual).to eq(csv)
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'should generate a csv and accept options' do
|
55
|
-
options = {
|
56
|
-
force_quotes: true
|
57
|
-
}
|
58
|
-
|
59
|
-
actual = ::Bumblebee.generate_csv(columns, people, options)
|
60
|
-
|
61
|
-
expect(actual).to eq(quoted_csv)
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'should parse a csv using columns argument' do
|
65
|
-
objects = Bumblebee.parse_csv(columns, csv)
|
66
|
-
|
67
|
-
expect(objects).to eq(people)
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'should parse a csv using columns block' do
|
71
|
-
objects = Bumblebee.parse_csv(csv) do |t|
|
72
|
-
columns.each do |column|
|
73
|
-
t.column column[:field]
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
expect(objects).to eq(people)
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'should parse a csv with columns in different order than headers' do
|
81
|
-
objects = ::Bumblebee.parse_csv(reverse_columns, csv)
|
82
|
-
|
83
|
-
expect(objects).to eq(people)
|
84
|
-
end
|
85
|
-
|
86
|
-
describe 'README examples' do
|
87
|
-
describe 'the simple 1:1 parsing example' do
|
88
|
-
let(:data) { fixture('simple_readme_example.csv') }
|
89
|
-
|
90
|
-
let(:columns) do
|
91
|
-
[
|
92
|
-
{ field: 'id' },
|
93
|
-
{ field: 'name' },
|
94
|
-
{ field: 'dob' },
|
95
|
-
{ field: 'phone' }
|
96
|
-
]
|
97
|
-
end
|
98
|
-
|
99
|
-
let(:output) do
|
100
|
-
[
|
101
|
-
{ 'id' => '1', 'name' => 'Matt', 'dob' => '2/3/01', 'phone' => '555-555-5555' },
|
102
|
-
{ 'id' => '2', 'name' => 'Nick', 'dob' => '9/3/21', 'phone' => '444-444-4444' },
|
103
|
-
{ 'id' => '3', 'name' => 'Sam', 'dob' => '12/12/32', 'phone' => '333-333-3333' }
|
104
|
-
]
|
105
|
-
end
|
106
|
-
|
107
|
-
specify 'works as advertised' do
|
108
|
-
expect(Bumblebee.parse_csv(columns, data)).to eq output
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
describe 'the custom parsing example' do
|
113
|
-
let(:data) { fixture('custom_readme_example.csv') }
|
114
|
-
|
115
|
-
let(:columns) do
|
116
|
-
[
|
117
|
-
{
|
118
|
-
field: :id,
|
119
|
-
header: 'ID #',
|
120
|
-
to_object: ->(o) { o['ID #'].to_i }
|
121
|
-
},
|
122
|
-
{
|
123
|
-
field: :name,
|
124
|
-
header: 'First Name',
|
125
|
-
to_csv: %i[name first],
|
126
|
-
to_object: ->(o) { { first: o['First Name'] } }
|
127
|
-
},
|
128
|
-
{ field: :demo,
|
129
|
-
header: 'Date of Birth',
|
130
|
-
to_csv: %i[demo dob],
|
131
|
-
to_object: ->(o) { { dob: o['Date of Birth'] } } },
|
132
|
-
{ field: :contact,
|
133
|
-
header: 'Phone #',
|
134
|
-
to_csv: %i[contact phone],
|
135
|
-
to_object: ->(o) { { phone: o['Phone #'] } } }
|
136
|
-
]
|
137
|
-
end
|
138
|
-
|
139
|
-
let(:output) do
|
140
|
-
[
|
141
|
-
{
|
142
|
-
id: 1,
|
143
|
-
name: { first: 'Matt' },
|
144
|
-
demo: { dob: '1901-02-03' },
|
145
|
-
contact: { phone: '555-555-5555' }
|
146
|
-
},
|
147
|
-
{
|
148
|
-
id: 2,
|
149
|
-
name: { first: 'Nick' },
|
150
|
-
demo: { dob: '1921-09-03' },
|
151
|
-
contact: { phone: '444-444-4444' }
|
152
|
-
},
|
153
|
-
{
|
154
|
-
id: 3,
|
155
|
-
name: { first: 'Sam' },
|
156
|
-
demo: { dob: '1932-12-12' },
|
157
|
-
contact: { phone: '333-333-3333' }
|
158
|
-
}
|
159
|
-
]
|
160
|
-
end
|
161
|
-
|
162
|
-
specify 'works as advertised' do
|
163
|
-
expect(Bumblebee.parse_csv(columns, data)).to eq output
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
@@ -1,213 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
#
|
4
|
-
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
5
|
-
#
|
6
|
-
# This source code is licensed under the MIT license found in the
|
7
|
-
# LICENSE file in the root directory of this source tree.
|
8
|
-
#
|
9
|
-
|
10
|
-
require 'spec_helper'
|
11
|
-
|
12
|
-
describe ::Bumblebee::Column do
|
13
|
-
let(:object) do
|
14
|
-
OpenStruct.new(
|
15
|
-
name: 'Mattycakes',
|
16
|
-
dob: '1921-01-02',
|
17
|
-
pizza: 'Pepperoni',
|
18
|
-
license: OpenStruct.new(id: '123456')
|
19
|
-
)
|
20
|
-
end
|
21
|
-
|
22
|
-
let(:hash) do
|
23
|
-
{
|
24
|
-
name: 'Mattycakes',
|
25
|
-
dob: '1921-01-02',
|
26
|
-
pizza: 'Pepperoni',
|
27
|
-
license: { id: '123456' }
|
28
|
-
}
|
29
|
-
end
|
30
|
-
|
31
|
-
describe 'initialization' do
|
32
|
-
it 'should error if field is nil' do
|
33
|
-
expect { ::Bumblebee::Column.new(field: nil) }.to raise_error(ArgumentError)
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'should initialize with just a field' do
|
37
|
-
field = :name
|
38
|
-
|
39
|
-
column = ::Bumblebee::Column.new(field: field)
|
40
|
-
|
41
|
-
expect(column.field).to eq(field)
|
42
|
-
expect(column.header).to eq(field.to_s)
|
43
|
-
expect(column.to_csv).to eq([field])
|
44
|
-
expect(column.to_object).to eq([field.to_s])
|
45
|
-
end
|
46
|
-
|
47
|
-
describe 'header computation' do
|
48
|
-
it 'should compute from single field' do
|
49
|
-
field = :name
|
50
|
-
|
51
|
-
column = ::Bumblebee::Column.new(field: field)
|
52
|
-
|
53
|
-
expect(column.header).to eq(field.to_s)
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'should compute from multiple fields' do
|
57
|
-
field = [:name, 'is', :too, 22.4]
|
58
|
-
|
59
|
-
column = ::Bumblebee::Column.new(field: field)
|
60
|
-
|
61
|
-
expect(column.header).to eq(field.map(&:to_s).join('_'))
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'should compute from a lambda literal' do
|
65
|
-
column = ::Bumblebee::Column.new(field: ->(o) {})
|
66
|
-
expect(column.header).to eq('proc')
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'should compute from a proc' do
|
70
|
-
column = ::Bumblebee::Column.new(field: proc {})
|
71
|
-
expect(column.header).to eq('proc')
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe '#csv_to_object' do
|
77
|
-
it 'should correctly extract the value using field' do
|
78
|
-
record = {
|
79
|
-
'name' => 'Nathan'
|
80
|
-
}
|
81
|
-
|
82
|
-
column = ::Bumblebee::Column.new(field: 'name')
|
83
|
-
|
84
|
-
expect(column.csv_to_object(record)).to eq(record)
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'should correctly extract the value using header' do
|
88
|
-
csv_row = {
|
89
|
-
'First Name' => 'Nathan'
|
90
|
-
}
|
91
|
-
|
92
|
-
record = {
|
93
|
-
'name' => 'Nathan'
|
94
|
-
}
|
95
|
-
|
96
|
-
column = ::Bumblebee::Column.new(field: 'name', header: 'First Name')
|
97
|
-
|
98
|
-
expect(column.csv_to_object(csv_row)).to eq(record)
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'should correctly extract the value using custom to_object value' do
|
102
|
-
csv_row = {
|
103
|
-
'First' => 'Nathan'
|
104
|
-
}
|
105
|
-
|
106
|
-
record = {
|
107
|
-
'name' => 'Nathan'
|
108
|
-
}
|
109
|
-
|
110
|
-
column = ::Bumblebee::Column.new(
|
111
|
-
field: 'name',
|
112
|
-
header: 'First Name',
|
113
|
-
to_object: 'First'
|
114
|
-
)
|
115
|
-
|
116
|
-
expect(column.csv_to_object(csv_row)).to eq(record)
|
117
|
-
end
|
118
|
-
|
119
|
-
it 'should correctly extract the value using to_object with a proc' do
|
120
|
-
record = {
|
121
|
-
'name' => 'Nathan'
|
122
|
-
}
|
123
|
-
|
124
|
-
column = ::Bumblebee::Column.new(field: 'name', to_object: ->(o) { o['name'] })
|
125
|
-
|
126
|
-
expect(column.csv_to_object(record)).to eq(record)
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'should correctly build up a nested hash' do
|
130
|
-
record = {
|
131
|
-
'name' => 'Nathan'
|
132
|
-
}
|
133
|
-
|
134
|
-
column = ::Bumblebee::Column.new(
|
135
|
-
field: :person,
|
136
|
-
to_object: [
|
137
|
-
'name',
|
138
|
-
->(o) { { first: o } }
|
139
|
-
]
|
140
|
-
)
|
141
|
-
|
142
|
-
expect(column.csv_to_object(record)).to eq(person: { first: record['name'] })
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
describe '#object_to_csv' do
|
147
|
-
context 'using field' do
|
148
|
-
context 'for single values' do
|
149
|
-
it 'should get csv value correctly' do
|
150
|
-
column = ::Bumblebee::Column.new(field: :name)
|
151
|
-
|
152
|
-
expect(column.object_to_csv(object)).to eq(object.name)
|
153
|
-
expect(column.object_to_csv(hash)).to eq(hash[:name])
|
154
|
-
end
|
155
|
-
|
156
|
-
it 'should return nil when does not exist' do
|
157
|
-
column = ::Bumblebee::Column.new(field: :doesnt_exist)
|
158
|
-
|
159
|
-
expect(column.object_to_csv(object)).to eq(nil)
|
160
|
-
expect(column.object_to_csv(hash)).to eq(nil)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
context 'for arrays' do
|
165
|
-
it 'should get csv value correctly' do
|
166
|
-
column = ::Bumblebee::Column.new(field: %i[license id])
|
167
|
-
|
168
|
-
expect(column.object_to_csv(object)).to eq(object.license.id)
|
169
|
-
expect(column.object_to_csv(hash)).to eq(hash[:license][:id])
|
170
|
-
end
|
171
|
-
|
172
|
-
it 'should return nil when it hits dead end at beginning' do
|
173
|
-
column = ::Bumblebee::Column.new(field: %i[something that does not exist])
|
174
|
-
|
175
|
-
expect(column.object_to_csv(object)).to eq(nil)
|
176
|
-
expect(column.object_to_csv(hash)).to eq(nil)
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'should return nil when it hits dead end in middle' do
|
180
|
-
column = ::Bumblebee::Column.new(field: %i[license doesnt_exist here])
|
181
|
-
|
182
|
-
expect(column.object_to_csv(object)).to eq(nil)
|
183
|
-
expect(column.object_to_csv(hash)).to eq(nil)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
context 'when mixing in procs' do
|
188
|
-
it 'should get csv value correctly when proc runs against end value' do
|
189
|
-
column = ::Bumblebee::Column.new(field: [:license, :id, ->(o) { "# #{o}" }])
|
190
|
-
|
191
|
-
expect(column.object_to_csv(object)).to eq("# #{object.license.id}")
|
192
|
-
expect(column.object_to_csv(hash)).to eq("# #{hash[:license][:id]}")
|
193
|
-
end
|
194
|
-
|
195
|
-
it 'should get csv value correctly when proc runs against object-based value' do
|
196
|
-
column = ::Bumblebee::Column.new(field: [:license, ->(o) { "# #{o.id}" }])
|
197
|
-
expect(column.object_to_csv(object)).to eq("# #{object.license.id}")
|
198
|
-
|
199
|
-
column = ::Bumblebee::Column.new(field: [:license, ->(o) { "# #{o[:id]}" }])
|
200
|
-
expect(column.object_to_csv(hash)).to eq("# #{hash[:license][:id]}")
|
201
|
-
end
|
202
|
-
|
203
|
-
it 'should not hit proc if ran against nil' do
|
204
|
-
column = ::Bumblebee::Column.new(field: [:doesnt_exist, ->(o) { "# #{o.id}" }])
|
205
|
-
expect(column.object_to_csv(object)).to eq(nil)
|
206
|
-
|
207
|
-
column = ::Bumblebee::Column.new(field: [:doesnt_exist, ->(o) { "# #{o[:id]}" }])
|
208
|
-
expect(column.object_to_csv(hash)).to eq(nil)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|