drudgery 0.1.0 → 0.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.
- data/README.md +80 -31
- data/lib/drudgery/extractors/csv_extractor.rb +8 -0
- data/lib/drudgery/job.rb +21 -33
- data/lib/drudgery/loaders/csv_loader.rb +8 -0
- data/lib/drudgery/version.rb +1 -1
- data/lib/drudgery.rb +15 -9
- data/spec/drudgery/extractors/active_record_extractor_spec.rb +39 -82
- data/spec/drudgery/extractors/csv_extractor_spec.rb +55 -87
- data/spec/drudgery/extractors/sqlite3_extractor_spec.rb +116 -171
- data/spec/drudgery/job_spec.rb +224 -321
- data/spec/drudgery/loaders/active_record_import_loader_spec.rb +30 -54
- data/spec/drudgery/loaders/active_record_loader_spec.rb +30 -60
- data/spec/drudgery/loaders/csv_loader_spec.rb +59 -70
- data/spec/drudgery/loaders/sqlite3_loader_spec.rb +37 -72
- data/spec/drudgery/manager_spec.rb +28 -24
- data/spec/drudgery/transformer_spec.rb +35 -41
- data/spec/drudgery_spec.rb +77 -48
- data/spec/spec_helper.rb +4 -3
- metadata +58 -43
- data/lib/drudgery/job_logger.rb +0 -21
- data/lib/drudgery/job_progress.rb +0 -11
- data/spec/drudgery/job_logger_spec.rb +0 -59
- data/spec/drudgery/job_progress_spec.rb +0 -19
data/spec/drudgery/job_spec.rb
CHANGED
@@ -1,413 +1,316 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
describe
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@job = Drudgery::Job.new(:extractor => @extractor, :transformer => @transformer, :loader => @loader)
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'sets job id to nsec time' do
|
17
|
-
@job.id.must_equal @now.nsec
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'sets extractor, transformer, and loader with provided arguments' do
|
21
|
-
@job.instance_variable_get('@extractor').must_equal @extractor
|
22
|
-
@job.instance_variable_get('@transformer').must_equal @transformer
|
23
|
-
@job.instance_variable_get('@loader').must_equal @loader
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'sets batch_size with provided argument' do
|
27
|
-
job = Drudgery::Job.new(:batch_size => 100)
|
28
|
-
job.instance_variable_get('@batch_size').must_equal(100)
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'initializes extractor, transformer, and loader if none provided' do
|
32
|
-
job = Drudgery::Job.new
|
33
|
-
job.instance_variable_get('@extractor').must_be_nil
|
34
|
-
job.instance_variable_get('@transformer').must_be_nil
|
35
|
-
job.instance_variable_get('@loader').must_be_nil
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'initializes records as array' do
|
39
|
-
@job.instance_variable_get('@records').must_equal []
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
it 'initializes batch_size as 1000 if none provided' do
|
44
|
-
@job.instance_variable_get('@batch_size').must_equal 1000
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe '#name' do
|
49
|
-
it 'returns <extractor name> => <loader name>' do
|
50
|
-
extractor = stub('extractor', :name => 'csv:file.csv')
|
51
|
-
loader = stub('loader', :name => 'sqlite3:memory.tablename')
|
52
|
-
|
53
|
-
job = Drudgery::Job.new(:extractor => extractor, :loader => loader)
|
54
|
-
job.name.must_equal 'csv:file.csv => sqlite3:memory.tablename'
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
describe '#batch_size' do
|
59
|
-
it 'sets batch_size to provided value' do
|
60
|
-
job = Drudgery::Job.new
|
61
|
-
job.batch_size 2
|
62
|
-
job.instance_variable_get('@batch_size').must_equal 2
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe '#extract' do
|
67
|
-
describe 'when type and args provided' do
|
68
|
-
it 'instantiates extractor with type and args' do
|
69
|
-
Drudgery::Extractors.expects(:instantiate).with(:csv, 'filename.csv', :col_sep => '|')
|
70
|
-
|
71
|
-
job = Drudgery::Job.new
|
72
|
-
job.extract(:csv, 'filename.csv', :col_sep => '|')
|
3
|
+
module Drudgery
|
4
|
+
describe Job do
|
5
|
+
describe '#initialize' do
|
6
|
+
it 'sets job id to nsec time' do
|
7
|
+
now = Time.now
|
8
|
+
Time.stubs(:now).returns(now)
|
9
|
+
|
10
|
+
job = Job.new
|
11
|
+
job.id.must_equal now.nsec
|
73
12
|
end
|
74
13
|
|
75
|
-
it '
|
76
|
-
extractor =
|
77
|
-
|
14
|
+
it 'sets extractor, transformer, and loader with provided arguments' do
|
15
|
+
extractor = Extractors::CSVExtractor.new('test.csv')
|
16
|
+
transformer = Transformer.new
|
17
|
+
loader = Loaders::CSVLoader.new('test.csv')
|
78
18
|
|
79
|
-
|
19
|
+
job = Job.new(
|
20
|
+
extractor: extractor,
|
21
|
+
transformer: transformer,
|
22
|
+
loader: loader
|
23
|
+
)
|
80
24
|
|
81
|
-
job
|
82
|
-
job.
|
83
|
-
|
84
|
-
end
|
25
|
+
job.extractor.must_equal extractor
|
26
|
+
job.transformer.must_equal transformer
|
27
|
+
job.loader.must_equal loader
|
85
28
|
end
|
86
29
|
|
87
|
-
it 'sets
|
88
|
-
|
30
|
+
it 'sets batch_size with provided argument' do
|
31
|
+
job = Job.new(:batch_size => 100)
|
32
|
+
job.batch_size.must_equal 100
|
33
|
+
end
|
89
34
|
|
90
|
-
|
35
|
+
it 'initializes batch_size as 1000 if none provided' do
|
36
|
+
job = Job.new
|
37
|
+
job.batch_size.must_equal 1000
|
38
|
+
end
|
39
|
+
end
|
91
40
|
|
92
|
-
|
93
|
-
|
41
|
+
describe '#name' do
|
42
|
+
it 'returns <extractor name> => <loader name>' do
|
43
|
+
job = Job.new(
|
44
|
+
:extractor => Extractors::CSVExtractor.new('their-records.csv'),
|
45
|
+
:loader => Loaders::CSVLoader.new('my-records.csv')
|
46
|
+
)
|
94
47
|
|
95
|
-
job.
|
48
|
+
job.name.must_equal 'csv:their-records.csv => csv:my-records.csv'
|
96
49
|
end
|
97
50
|
end
|
98
51
|
|
99
|
-
describe '
|
100
|
-
|
101
|
-
|
52
|
+
describe '#record_count' do
|
53
|
+
describe 'when extractor exists' do
|
54
|
+
it "returns the extractor's record_count" do
|
55
|
+
extractor = Extractors::CSVExtractor.new('test.csv')
|
56
|
+
extractor.stubs(:record_count).returns(1000)
|
102
57
|
|
103
|
-
|
58
|
+
job = Job.new(extractor: extractor)
|
59
|
+
job.record_count.must_equal 1000
|
60
|
+
end
|
104
61
|
|
105
|
-
job = Drudgery::Job.new
|
106
|
-
job.extract(extractor)
|
107
62
|
end
|
108
63
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
job = Drudgery::Job.new
|
114
|
-
job.extract(extractor) do |ext|
|
115
|
-
ext.col_sep '|'
|
64
|
+
describe 'when extractor does not exist' do
|
65
|
+
it 'returns nil' do
|
66
|
+
job = Job.new
|
67
|
+
job.record_count.must_be_nil
|
116
68
|
end
|
117
69
|
end
|
70
|
+
end
|
118
71
|
|
119
|
-
|
120
|
-
|
72
|
+
describe '#extract' do
|
73
|
+
describe 'when type and args provided' do
|
74
|
+
it 'instantiates extractor with type and args' do
|
75
|
+
job = Job.new
|
76
|
+
job.extract(:csv, 'test.csv', :col_sep => '|')
|
121
77
|
|
122
|
-
|
123
|
-
|
78
|
+
job.extractor.name.must_equal 'csv:test.csv'
|
79
|
+
job.extractor.col_sep.must_equal '|'
|
80
|
+
end
|
124
81
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
82
|
+
it 'yields extractor if block_given' do
|
83
|
+
job = Job.new
|
84
|
+
job.extract(:csv, 'test.csv') do |extractor|
|
85
|
+
extractor.col_sep = '|'
|
86
|
+
end
|
129
87
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
transformer = stub('transformer', :register => nil)
|
88
|
+
job.extractor.name.must_equal 'csv:test.csv'
|
89
|
+
job.extractor.col_sep.must_equal '|'
|
90
|
+
end
|
134
91
|
|
135
|
-
|
136
|
-
|
92
|
+
it 'sets extractor' do
|
93
|
+
job = Job.new
|
94
|
+
job.extract(:csv, 'test.csv', :col_sep => '|')
|
137
95
|
|
138
|
-
|
96
|
+
job.extractor.wont_be_nil
|
97
|
+
job.extractor.name.must_equal 'csv:test.csv'
|
98
|
+
job.extractor.col_sep.must_equal '|'
|
99
|
+
end
|
139
100
|
end
|
140
101
|
|
141
|
-
|
142
|
-
|
102
|
+
describe 'when extractor provided' do
|
103
|
+
it 'yields extractor if block_given' do
|
104
|
+
extractor = Extractors::CSVExtractor.new('test.csv')
|
143
105
|
|
144
|
-
|
145
|
-
|
106
|
+
job = Job.new
|
107
|
+
job.extract(extractor) do |ext|
|
108
|
+
ext.col_sep = '|'
|
109
|
+
end
|
146
110
|
|
147
|
-
|
148
|
-
|
149
|
-
|
111
|
+
extractor.name.must_equal 'csv:test.csv'
|
112
|
+
extractor.col_sep.must_equal '|'
|
113
|
+
end
|
150
114
|
|
151
|
-
|
152
|
-
|
153
|
-
transformer.expects(:register).with { |data, cache| data }
|
115
|
+
it 'sets extractor' do
|
116
|
+
extractor = Extractors::CSVExtractor.new('test.csv')
|
154
117
|
|
155
|
-
|
156
|
-
|
118
|
+
job = Job.new
|
119
|
+
job.extract(extractor)
|
120
|
+
job.extractor.must_equal extractor
|
121
|
+
end
|
157
122
|
end
|
158
123
|
end
|
159
124
|
|
160
|
-
describe '
|
161
|
-
|
162
|
-
|
125
|
+
describe '#transform' do
|
126
|
+
describe 'when transformer provided' do
|
127
|
+
it 'registers provided proc with provided transformer' do
|
128
|
+
block = Proc.new { |data, cache| data[:a] += 1; data }
|
163
129
|
|
164
|
-
|
130
|
+
transformer = Transformer.new
|
165
131
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
job.instance_variable_get('@transformer').must_equal transformer
|
170
|
-
end
|
132
|
+
job = Job.new
|
133
|
+
job.transform(transformer, &block)
|
171
134
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
transformer = mock('transformer')
|
176
|
-
transformer.expects(:register).with(block)
|
135
|
+
transformer.transform('a' => 1).must_equal({ :a => 2 })
|
136
|
+
end
|
177
137
|
|
178
|
-
|
138
|
+
it 'registers provided block with provided transformer' do
|
139
|
+
transformer = Transformer.new
|
179
140
|
|
180
|
-
|
181
|
-
|
182
|
-
end
|
141
|
+
job = Job.new
|
142
|
+
job.transform(transformer) { |data, cache| data[:a] += 2; data }
|
183
143
|
|
184
|
-
|
185
|
-
|
186
|
-
transformer.expects(:register).with { |data, cache| data }
|
187
|
-
|
188
|
-
Drudgery::Transformer.stubs(:new).returns(transformer)
|
144
|
+
transformer.transform('a' => 1).must_equal({ :a => 3 })
|
145
|
+
end
|
189
146
|
|
190
|
-
|
191
|
-
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
147
|
+
it 'sets transformer' do
|
148
|
+
transformer = Transformer.new
|
195
149
|
|
196
|
-
|
197
|
-
|
198
|
-
it 'instantiates loader with type with args' do
|
199
|
-
Drudgery::Loaders.expects(:instantiate).with(:sqlite3, 'db.sqlite3', 'tablename')
|
150
|
+
job = Job.new
|
151
|
+
job.transform(transformer)
|
200
152
|
|
201
|
-
|
202
|
-
|
153
|
+
transformer.must_equal transformer
|
154
|
+
end
|
203
155
|
end
|
204
156
|
|
205
|
-
|
206
|
-
|
207
|
-
|
157
|
+
describe 'when no transformer provided' do
|
158
|
+
it 'registers provided proc with default transformer' do
|
159
|
+
block = Proc.new { |data, cache| data[:a] += 1; data }
|
208
160
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
job.load(:sqlite3, 'db.sqlite3', 'tablename') do |loader|
|
213
|
-
loader.select('a', 'b', 'c')
|
161
|
+
job = Job.new
|
162
|
+
job.transform(&block)
|
163
|
+
job.transformer.transform('a' => 1).must_equal({ :a => 2 })
|
214
164
|
end
|
215
|
-
end
|
216
165
|
|
217
|
-
|
218
|
-
|
166
|
+
it 'registers provided block with default transformer' do
|
167
|
+
job = Job.new
|
168
|
+
job.transform { |data, cache| data[:a] += 2; data }
|
169
|
+
job.transformer.transform('a' => 1).must_equal({ :a => 3 })
|
170
|
+
end
|
219
171
|
|
220
|
-
Drudgery::Loaders.expects(:instantiate).with(:sqlite3, 'db.sqlite3', 'tablename').returns(loader)
|
221
172
|
|
222
|
-
|
223
|
-
|
224
|
-
|
173
|
+
it 'sets transformer to default transformer' do
|
174
|
+
job = Job.new
|
175
|
+
job.transform
|
176
|
+
job.transformer.must_be_instance_of Transformer
|
177
|
+
end
|
225
178
|
end
|
226
179
|
end
|
227
180
|
|
228
|
-
describe '
|
229
|
-
|
230
|
-
loader
|
181
|
+
describe '#load' do
|
182
|
+
describe 'when type and args provided' do
|
183
|
+
it 'instantiates loader with type with args' do
|
184
|
+
job = Job.new
|
185
|
+
job.load(:csv, 'test.csv', :col_sep => '|')
|
231
186
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
job.load(loader)
|
236
|
-
end
|
187
|
+
job.loader.name.must_equal 'csv:test.csv'
|
188
|
+
job.loader.col_sep.must_equal '|'
|
189
|
+
end
|
237
190
|
|
238
|
-
|
239
|
-
|
240
|
-
|
191
|
+
it 'yields loader if block_given' do
|
192
|
+
job = Job.new
|
193
|
+
job.load(:csv, 'test.csv') do |loader|
|
194
|
+
loader.col_sep = '|'
|
195
|
+
end
|
241
196
|
|
242
|
-
|
243
|
-
|
244
|
-
loader.select('a', 'b', 'c')
|
197
|
+
job.loader.name.must_equal 'csv:test.csv'
|
198
|
+
job.loader.col_sep.must_equal '|'
|
245
199
|
end
|
246
|
-
end
|
247
200
|
|
248
|
-
|
249
|
-
|
201
|
+
it 'sets loader' do
|
202
|
+
job = Job.new
|
203
|
+
job.load(:csv, 'test.csv', :col_sep => '|')
|
250
204
|
|
251
|
-
|
252
|
-
|
253
|
-
|
205
|
+
job.loader.wont_be_nil
|
206
|
+
job.loader.name.must_equal 'csv:test.csv'
|
207
|
+
job.loader.col_sep.must_equal '|'
|
208
|
+
end
|
254
209
|
end
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
def mock_logger
|
259
|
-
stub('job_logger', :log => nil, :log_with_progress => nil)
|
260
|
-
end
|
261
|
-
|
262
|
-
def stub_logging
|
263
|
-
|
264
|
-
end
|
265
|
-
|
266
|
-
describe '#perform' do
|
267
|
-
before(:each) do
|
268
|
-
Drudgery.show_progress = false
|
269
|
-
Drudgery::JobLogger.stubs(:new).returns(mock_logger)
|
270
|
-
end
|
271
|
-
|
272
|
-
it 'extracts records from extractor' do
|
273
|
-
extractor = stub('extractor', :record_count => 1, :name => 'extractor')
|
274
|
-
extractor.expects(:extract).yields([{ 'a' => 1 }, 0])
|
275
|
-
|
276
|
-
loader = stub('loader', :name => 'loader', :load => nil)
|
277
|
-
|
278
|
-
job = Drudgery::Job.new(:extractor => extractor, :loader => loader)
|
279
|
-
|
280
|
-
job.perform
|
281
|
-
end
|
282
|
-
|
283
|
-
it 'transforms records with transformer' do
|
284
|
-
extractor = stub('extractor', :record_count => 1, :name => 'extractor')
|
285
|
-
extractor.stubs(:extract).yields([{ 'a' => 1 }, 0])
|
286
|
-
|
287
|
-
transformer = mock('transformer')
|
288
|
-
transformer.expects(:transform).with({ 'a' => 1 }).returns({ :a => 1 })
|
289
|
-
|
290
|
-
loader = stub('loader', :name => 'loader', :load => nil)
|
291
|
-
|
292
|
-
job = Drudgery::Job.new(:extractor => extractor, :transformer => transformer, :loader => loader)
|
293
210
|
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
it 'skips nil records' do
|
298
|
-
extractor = stub('extractor', :record_count => 1, :name => 'extractor')
|
299
|
-
extractor.stubs(:extract).yields([{ 'a' => 1 }, 0])
|
300
|
-
|
301
|
-
transformer = mock('transformer')
|
302
|
-
transformer.expects(:transform).with({ 'a' => 1 }).returns(nil)
|
303
|
-
|
304
|
-
loader = stub('loader', :name => 'loader')
|
305
|
-
loader.expects(:load).with([{ '1' => 1 }]).never
|
306
|
-
|
307
|
-
job = Drudgery::Job.new(:extractor => extractor, :transformer => transformer, :loader => loader)
|
308
|
-
|
309
|
-
job.perform
|
310
|
-
end
|
211
|
+
describe 'when loader provided' do
|
212
|
+
it 'yields loader if block_given' do
|
213
|
+
loader = Loaders::CSVLoader.new('test.csv')
|
311
214
|
|
312
|
-
|
313
|
-
|
314
|
-
|
215
|
+
job = Job.new
|
216
|
+
job.load(loader) do |loader|
|
217
|
+
loader.col_sep = '|'
|
218
|
+
end
|
315
219
|
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
job = Drudgery::Job.new(:extractor => extractor, :loader => loader)
|
320
|
-
|
321
|
-
job.perform
|
322
|
-
end
|
323
|
-
|
324
|
-
it 'loads records with loader in batches' do
|
325
|
-
extractor = stub('extractor', :record_count => 3, :name => 'extractor')
|
326
|
-
extractor.stubs(:extract).multiple_yields([{ 'a' => 1 }, 0], [{ 'b' => 2 }, 1], [{ 'c' => 3 }, 2])
|
327
|
-
|
328
|
-
loader = stub('loader', :name => 'loader')
|
329
|
-
loader.expects(:load).with([{ 'a' => 1 }, { 'b' => 2 }])
|
330
|
-
loader.expects(:load).with([{ 'c' => 3 }])
|
220
|
+
loader.name.must_equal 'csv:test.csv'
|
221
|
+
loader.col_sep.must_equal '|'
|
222
|
+
end
|
331
223
|
|
332
|
-
|
333
|
-
|
224
|
+
it 'sets loader' do
|
225
|
+
loader = Loaders::CSVLoader.new('test.csv')
|
334
226
|
|
335
|
-
|
227
|
+
job = Job.new
|
228
|
+
job.load(loader)
|
229
|
+
job.loader.must_equal loader
|
230
|
+
end
|
231
|
+
end
|
336
232
|
end
|
337
233
|
|
338
|
-
describe '
|
339
|
-
|
340
|
-
|
234
|
+
describe '#perform' do
|
235
|
+
before do
|
236
|
+
@source = 'tmp/source.csv'
|
237
|
+
@destination = 'tmp/destination.csv'
|
238
|
+
File.delete(@source) if File.exists?(@source)
|
239
|
+
File.delete(@destination) if File.exists?(@destination)
|
240
|
+
|
241
|
+
File.open(@source, 'w') do |f|
|
242
|
+
f.puts 'a,b'
|
243
|
+
f.puts '1,2'
|
244
|
+
f.puts '3,4'
|
245
|
+
f.puts '5,6'
|
246
|
+
end
|
341
247
|
|
342
|
-
extractor =
|
343
|
-
|
248
|
+
@extractor = Extractors::CSVExtractor.new(@source)
|
249
|
+
@loader = Loaders::CSVLoader.new(@destination)
|
344
250
|
|
345
|
-
|
251
|
+
@job = Job.new(:extractor => @extractor, :loader => @loader, :transformer => @transformer)
|
252
|
+
end
|
346
253
|
|
347
|
-
|
254
|
+
after do
|
255
|
+
File.delete(@source) if File.exists?(@source)
|
256
|
+
File.delete(@destination) if File.exists?(@destination)
|
257
|
+
end
|
348
258
|
|
349
|
-
|
350
|
-
|
351
|
-
expects(:finish)
|
352
|
-
end
|
353
|
-
Drudgery::JobProgress.stubs(:new).with(job.id, 3).returns(progress)
|
259
|
+
it 'sets started_at and completed_at' do
|
260
|
+
@job.perform
|
354
261
|
|
355
|
-
job.
|
262
|
+
@job.started_at.must_be_instance_of Time
|
263
|
+
@job.completed_at.must_be_instance_of Time
|
264
|
+
@job.completed_at.must_be :>, @job.started_at
|
356
265
|
end
|
357
|
-
end
|
358
266
|
|
359
|
-
|
360
|
-
|
361
|
-
extractor = stub('extractor', :record_count => 3, :name => 'extractor')
|
362
|
-
extractor.stubs(:extract).multiple_yields([{ 'a' => 1 }, 0], [{ 'b' => 2 }, 1], [{ 'c' => 3 }, 2])
|
267
|
+
it 'extracts records from extractor and loads records with loader' do
|
268
|
+
@job.perform
|
363
269
|
|
364
|
-
|
270
|
+
records = File.readlines(@destination).map { |line| line.strip.split(',') }
|
271
|
+
records.must_equal [%w[a b], %w[1 2], %w[3 4], %w[5 6]]
|
272
|
+
end
|
365
273
|
|
366
|
-
|
274
|
+
it 'transforms records with transformer' do
|
275
|
+
transformer = Transformer.new
|
276
|
+
transformer.register Proc.new { |data, cache| data[:c] = 99; data }
|
367
277
|
|
368
|
-
|
278
|
+
@job.transformer = transformer
|
279
|
+
@job.perform
|
369
280
|
|
370
|
-
|
281
|
+
records = File.readlines(@destination).map { |line| line.strip.split(',') }
|
282
|
+
records.must_equal [%w[a b c], %w[1 2 99], %w[3 4 99], %w[5 6 99]]
|
371
283
|
end
|
372
|
-
end
|
373
|
-
|
374
|
-
it 'logs job details' do
|
375
|
-
extractor = stub('extractor', :record_count => 3, :name => 'extractor')
|
376
|
-
extractor.stubs(:extract).multiple_yields([{ 'a' => 1 }, 0], [{ 'b' => 2 }, 1], [{ 'c' => 3 }, 2])
|
377
284
|
|
378
|
-
|
285
|
+
it 'skips nil records' do
|
286
|
+
transformer = Transformer.new
|
287
|
+
transformer.register Proc.new { |data, cache| data[:a] == '1' ? nil : data }
|
379
288
|
|
380
|
-
|
381
|
-
|
289
|
+
@job.transformer = transformer
|
290
|
+
@job.perform
|
382
291
|
|
383
|
-
|
292
|
+
records = File.readlines(@destination).map { |line| line.strip.split(',') }
|
293
|
+
records.must_equal [%w[a b], %w[3 4], %w[5 6]]
|
294
|
+
end
|
384
295
|
|
385
|
-
|
386
|
-
|
296
|
+
it 'does not load empty records' do
|
297
|
+
transformer = Transformer.new
|
298
|
+
transformer.register Proc.new { |data, cache| nil}
|
387
299
|
|
388
|
-
|
389
|
-
logger.expects(:log).with(:debug, "#{{ 'a' => 1 }.inspect}")
|
390
|
-
logger.expects(:log).with(:debug, "Transforming Record -- Index: 0")
|
391
|
-
logger.expects(:log).with(:debug, "#{{ 'a' => 1 }.inspect}")
|
392
|
-
logger.expects(:log).with(:debug, "Extracting Record -- Index: 1")
|
393
|
-
logger.expects(:log).with(:debug, "#{{ 'b' => 2 }.inspect}")
|
394
|
-
logger.expects(:log).with(:debug, "Transforming Record -- Index: 1")
|
395
|
-
logger.expects(:log).with(:debug, "#{{ 'b' => 2 }.inspect}")
|
396
|
-
logger.expects(:log).with(:debug, "Loading Records -- Count: 2")
|
397
|
-
logger.expects(:log).with(:debug, "#{[{ 'a' => 1 }, { 'b' => 2 }].inspect}")
|
300
|
+
@loader.expects(:load).never
|
398
301
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
logger.expects(:log).with(:debug, "#{{ 'c' => 3 }.inspect}")
|
403
|
-
logger.expects(:log).with(:debug, "Loading Records -- Count: 1")
|
404
|
-
logger.expects(:log).with(:debug, "#{[{ 'c' => 3 }].inspect}")
|
302
|
+
@job.transformer = transformer
|
303
|
+
@job.perform
|
304
|
+
end
|
405
305
|
|
406
|
-
|
306
|
+
it 'loads records with loader in batches' do
|
307
|
+
@job.batch_size = 2
|
407
308
|
|
408
|
-
|
309
|
+
@loader.expects(:load).with([{ 'a' => '1', 'b' => '2' }, { 'a' => '3', 'b' => '4' }])
|
310
|
+
@loader.expects(:load).with([{ 'a' => '5', 'b' => '6' }])
|
409
311
|
|
410
|
-
|
312
|
+
@job.perform
|
313
|
+
end
|
411
314
|
end
|
412
315
|
end
|
413
316
|
end
|