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
@@ -1,67 +1,43 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'active_record'
|
3
|
-
require 'activerecord-import'
|
4
2
|
|
5
|
-
|
6
|
-
class Record < ActiveRecord::Base; end
|
3
|
+
class Record < ActiveRecord::Base; end
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
loader.instance_variable_get('@model').must_equal model
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'sets name to active_record_import:<model name>' do
|
21
|
-
loader = Drudgery::Loaders::ActiveRecordImportLoader.new(mock_model)
|
22
|
-
loader.name.must_equal 'active_record_import:Record'
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '#load' do
|
27
|
-
it 'write records using model.import' do
|
28
|
-
record1 = { :a => 1, :b => 2 }
|
29
|
-
record2 = { :a => 3, :b => 4 }
|
5
|
+
module Drudgery
|
6
|
+
module Loaders
|
7
|
+
describe ActiveRecordImportLoader do
|
8
|
+
before do
|
9
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
10
|
+
ActiveRecord::Base.connection.create_table(:records) do |t|
|
11
|
+
t.integer :a
|
12
|
+
t.integer :b
|
13
|
+
end
|
30
14
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
loader = Drudgery::Loaders::ActiveRecordImportLoader.new(model)
|
35
|
-
loader.load([record1, record2])
|
36
|
-
end
|
37
|
-
end
|
15
|
+
@loader = ActiveRecordImportLoader.new(Record)
|
16
|
+
end
|
38
17
|
|
39
|
-
|
40
|
-
|
41
|
-
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
42
|
-
ActiveRecord::Base.connection.create_table(:records) do |t|
|
43
|
-
t.integer :a
|
44
|
-
t.integer :b
|
18
|
+
after do
|
19
|
+
ActiveRecord::Base.clear_active_connections!
|
45
20
|
end
|
46
|
-
end
|
47
21
|
|
48
|
-
|
49
|
-
|
50
|
-
|
22
|
+
describe '#name' do
|
23
|
+
it 'returns active_record_import:<model name>' do
|
24
|
+
@loader.name.must_equal 'active_record_import:Record'
|
25
|
+
end
|
26
|
+
end
|
51
27
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
28
|
+
describe '#load' do
|
29
|
+
it 'writes records using model.import' do
|
30
|
+
record1 = { :a => 1, :b => 2 }
|
31
|
+
record2 = { :a => 3, :b => 4 }
|
56
32
|
|
57
|
-
|
58
|
-
loader.load([record1, record2])
|
33
|
+
@loader.load([record1, record2])
|
59
34
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
35
|
+
records = Record.all.map(&:attributes)
|
36
|
+
records.must_equal([
|
37
|
+
{ 'id' => 1, 'a' => 1, 'b' => 2 },
|
38
|
+
{ 'id' => 2, 'a' => 3, 'b' => 4 }
|
39
|
+
])
|
40
|
+
end
|
65
41
|
end
|
66
42
|
end
|
67
43
|
end
|
@@ -1,73 +1,43 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'active_record'
|
3
2
|
|
4
|
-
|
5
|
-
class Record < ActiveRecord::Base; end
|
3
|
+
class Record < ActiveRecord::Base; end
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
loader.instance_variable_get('@model').must_equal model
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'sets name to active_record:<model name>' do
|
20
|
-
loader = Drudgery::Loaders::ActiveRecordLoader.new(mock_model)
|
21
|
-
loader.name.must_equal 'active_record:Record'
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#load' do
|
26
|
-
it 'write records using model.create' do
|
27
|
-
record1 = { :a => 1 }
|
28
|
-
record2 = { :a => 2 }
|
29
|
-
|
30
|
-
obj1 = mock('obj1')
|
31
|
-
obj2 = mock('obj2')
|
5
|
+
module Drudgery
|
6
|
+
module Loaders
|
7
|
+
describe ActiveRecordLoader do
|
8
|
+
before do
|
9
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
10
|
+
ActiveRecord::Base.connection.create_table(:records) do |t|
|
11
|
+
t.integer :a
|
12
|
+
t.integer :b
|
13
|
+
end
|
32
14
|
|
33
|
-
|
34
|
-
|
35
|
-
model.expects(:new).with(record2).returns(obj2)
|
36
|
-
|
37
|
-
obj1.expects(:save).with(:validate => false)
|
38
|
-
obj2.expects(:save).with(:validate => false)
|
39
|
-
|
40
|
-
loader = Drudgery::Loaders::ActiveRecordLoader.new(model)
|
41
|
-
loader.load([record1, record2])
|
42
|
-
end
|
43
|
-
end
|
15
|
+
@loader = ActiveRecordLoader.new(Record)
|
16
|
+
end
|
44
17
|
|
45
|
-
|
46
|
-
|
47
|
-
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
48
|
-
ActiveRecord::Base.connection.create_table(:records) do |t|
|
49
|
-
t.integer :a
|
50
|
-
t.integer :b
|
18
|
+
after do
|
19
|
+
ActiveRecord::Base.clear_active_connections!
|
51
20
|
end
|
52
|
-
end
|
53
21
|
|
54
|
-
|
55
|
-
|
56
|
-
|
22
|
+
describe '#name' do
|
23
|
+
it 'returns active_record:<model name>' do
|
24
|
+
@loader.name.must_equal 'active_record:Record'
|
25
|
+
end
|
26
|
+
end
|
57
27
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
28
|
+
describe '#load' do
|
29
|
+
it 'writes records using model.create' do
|
30
|
+
record1 = { :a => 1, :b => 2 }
|
31
|
+
record2 = { :a => 3, :b => 4 }
|
62
32
|
|
63
|
-
|
64
|
-
loader.load([record1, record2])
|
33
|
+
@loader.load([record1, record2])
|
65
34
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
35
|
+
records = Record.all.map(&:attributes)
|
36
|
+
records.must_equal([
|
37
|
+
{ 'id' => 1, 'a' => 1, 'b' => 2 },
|
38
|
+
{ 'id' => 2, 'a' => 3, 'b' => 4 }
|
39
|
+
])
|
40
|
+
end
|
71
41
|
end
|
72
42
|
end
|
73
43
|
end
|
@@ -1,78 +1,67 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
loader.instance_variable_get('@write_headers').must_equal true
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'sets options to provided options' do
|
16
|
-
options = { :col_sep => '|' }
|
17
|
-
|
18
|
-
loader = Drudgery::Loaders::CSVLoader.new('file.csv', options)
|
19
|
-
loader.instance_variable_get('@options').must_equal({ :col_sep => '|' })
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'sets name to csv:<file base name>' do
|
23
|
-
loader = Drudgery::Loaders::CSVLoader.new('tmp/file.csv')
|
24
|
-
loader.name.must_equal 'csv:file.csv'
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
describe '#load' do
|
29
|
-
it 'opens CSV file to append records' do
|
30
|
-
CSV.expects(:open).with('file.csv', 'a', :col_sep => '|')
|
31
|
-
|
32
|
-
loader = Drudgery::Loaders::CSVLoader.new('file.csv', :col_sep => '|')
|
33
|
-
loader.load([{}])
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'writes hash keys as header and records as rows' do
|
37
|
-
record1 = { :a => 1, :b => 2 }
|
38
|
-
record2 = { :a => 3, :b => 4 }
|
39
|
-
record3 = { :a => 5, :b => 6 }
|
40
|
-
|
41
|
-
csv = mock('csv')
|
42
|
-
csv.expects(:<<).with([:a, :b])
|
43
|
-
csv.expects(:<<).with([1, 2])
|
44
|
-
csv.expects(:<<).with([3, 4])
|
45
|
-
csv.expects(:<<).with([5, 6])
|
46
|
-
|
47
|
-
CSV.expects(:open).with('file.csv', 'a', {}).yields(csv).times(2)
|
48
|
-
|
49
|
-
loader = Drudgery::Loaders::CSVLoader.new('file.csv')
|
50
|
-
loader.load([record1, record2])
|
51
|
-
loader.load([record3])
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe 'without stubs' do
|
56
|
-
before(:each) do
|
57
|
-
File.delete('file.csv') if File.exists?('file.csv')
|
58
|
-
end
|
59
|
-
|
60
|
-
after(:each) do
|
61
|
-
File.delete('file.csv') if File.exists?('file.csv')
|
62
|
-
end
|
3
|
+
module Drudgery
|
4
|
+
module Loaders
|
5
|
+
describe CSVLoader do
|
6
|
+
describe '#name' do
|
7
|
+
it 'returns csv:<file base name>' do
|
8
|
+
loader = CSVLoader.new('tmp/people.csv')
|
9
|
+
loader.name.must_equal 'csv:people.csv'
|
10
|
+
end
|
11
|
+
end
|
63
12
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
13
|
+
describe '#col_sep' do
|
14
|
+
it 'returns col_sep option' do
|
15
|
+
loader = CSVLoader.new('tmp/people.csv', :col_sep => '|')
|
16
|
+
loader.col_sep.must_equal '|'
|
17
|
+
end
|
18
|
+
end
|
69
19
|
|
70
|
-
|
71
|
-
|
72
|
-
|
20
|
+
describe '#col_sep=' do
|
21
|
+
it 'sets col_sep to provided character' do
|
22
|
+
loader = CSVLoader.new('tmp/people.csv')
|
23
|
+
loader.col_sep = '|'
|
24
|
+
loader.col_sep.must_equal '|'
|
25
|
+
end
|
26
|
+
end
|
73
27
|
|
74
|
-
|
75
|
-
|
28
|
+
describe '#load' do
|
29
|
+
before do
|
30
|
+
@file = 'tmp/test.csv'
|
31
|
+
File.delete(@file) if File.exists?(@file)
|
32
|
+
end
|
33
|
+
|
34
|
+
after do
|
35
|
+
File.delete(@file) if File.exists?(@file)
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'when columns separated by |' do
|
39
|
+
it 'writes hash keys as header and records as rows' do
|
40
|
+
record1 = { :a => 1, :b => 2 }
|
41
|
+
record2 = { :a => 3, :b => 4 }
|
42
|
+
record3 = { :a => 5, :b => 6 }
|
43
|
+
|
44
|
+
loader = CSVLoader.new(@file, :col_sep => '|')
|
45
|
+
loader.load([record1, record2])
|
46
|
+
loader.load([record3])
|
47
|
+
|
48
|
+
records = File.readlines(@file).map { |line| line.strip.split('|') }
|
49
|
+
records.must_equal [%w[a b], %w[1 2], %w[3 4], %w[5 6]]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'writes hash keys as header and records as rows' do
|
54
|
+
record1 = { :a => 1, :b => 2 }
|
55
|
+
record2 = { :a => 3, :b => 4 }
|
56
|
+
record3 = { :a => 5, :b => 6 }
|
57
|
+
|
58
|
+
loader = CSVLoader.new(@file)
|
59
|
+
loader.load([record1, record2])
|
60
|
+
loader.load([record3])
|
61
|
+
|
62
|
+
records = File.readlines(@file).map { |line| line.strip.split(',') }
|
63
|
+
records.must_equal [%w[a b], %w[1 2], %w[3 4], %w[5 6]]
|
64
|
+
end
|
76
65
|
end
|
77
66
|
end
|
78
67
|
end
|
@@ -1,88 +1,53 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'sqlite3'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
describe '#initialize' do
|
11
|
-
it 'sets db to SQLite3 database using provided db name and table to provided table name' do
|
12
|
-
db = mock_db
|
13
|
-
|
14
|
-
loader = Drudgery::Loaders::SQLite3Loader.new(db, 'tablename')
|
15
|
-
loader.instance_variable_get('@db').must_equal db
|
16
|
-
loader.instance_variable_get('@table').must_equal 'tablename'
|
17
|
-
end
|
18
|
-
|
19
|
-
describe 'with in memory db' do
|
20
|
-
it 'sets name to sqlite3:memory:<table name>' do
|
21
|
-
loader = Drudgery::Loaders::SQLite3Loader.new(mock_db, 'tablename')
|
22
|
-
loader.name.must_equal 'sqlite3:memory.tablename'
|
3
|
+
module Drudgery
|
4
|
+
module Loaders
|
5
|
+
describe SQLite3Loader do
|
6
|
+
before do
|
7
|
+
@db = SQLite3::Database.new(':memory:')
|
8
|
+
@db.execute('CREATE TABLE records (a INTEGER, b INTEGER)')
|
23
9
|
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe 'with file based db' do
|
27
|
-
it 'sets name to sqlite3:<main db name>:<table name>' do
|
28
|
-
db = mock_db
|
29
|
-
db.expects(:database_list).returns([{ 'name' => 'main', 'file' => 'db/test.sqlite3.db' }])
|
30
10
|
|
31
|
-
|
32
|
-
|
11
|
+
after do
|
12
|
+
@db.close
|
33
13
|
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe '#load' do
|
38
|
-
it 'writes each record in single transaction' do
|
39
|
-
record1 = { :a => 1, :b => 2 }
|
40
|
-
record2 = { :a => 3, :b => 4 }
|
41
14
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
15
|
+
describe '#name' do
|
16
|
+
describe 'with file based db' do
|
17
|
+
it 'returns sqlite3:<main db name>:<table name>' do
|
18
|
+
db = SQLite3::Database.new('tmp/test.sqlite3')
|
46
19
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
describe 'without stubs' do
|
53
|
-
before(:each) do
|
54
|
-
@db = SQLite3::Database.new(':memory:')
|
55
|
-
@db.execute('CREATE TABLE records (a INTEGER, b INTEGER)')
|
56
|
-
end
|
20
|
+
loader = SQLite3Loader.new(db, 'people')
|
21
|
+
loader.name.must_equal 'sqlite3:test.people'
|
22
|
+
end
|
23
|
+
end
|
57
24
|
|
58
|
-
|
59
|
-
|
60
|
-
|
25
|
+
describe 'with in memory db' do
|
26
|
+
it 'returns sqlite3:memory:<table name>' do
|
27
|
+
loader = SQLite3Loader.new(@db, 'cities')
|
28
|
+
loader.name.must_equal 'sqlite3:memory.cities'
|
29
|
+
end
|
30
|
+
end
|
61
31
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
end
|
32
|
+
describe '#load' do
|
33
|
+
it 'writes each record in single transaction' do
|
34
|
+
record1 = { :a => 1, :b => 2 }
|
35
|
+
record2 = { :a => 3, :b => 4 }
|
68
36
|
|
69
|
-
|
70
|
-
|
71
|
-
record1 = { :a => 1, :b => 2 }
|
72
|
-
record2 = { :a => 3, :b => 4 }
|
37
|
+
loader = SQLite3Loader.new(@db, 'records')
|
38
|
+
loader.load([record1, record2])
|
73
39
|
|
74
|
-
|
75
|
-
|
40
|
+
results = []
|
41
|
+
@db.execute('SELECT * FROM records') do |result|
|
42
|
+
results << result
|
43
|
+
end
|
76
44
|
|
77
|
-
|
78
|
-
|
79
|
-
|
45
|
+
results.must_equal([
|
46
|
+
{ 'a' => 1, 'b' => 2, 0 => 1, 1 => 2 },
|
47
|
+
{ 'a' => 3, 'b' => 4, 0 => 3, 1 => 4}
|
48
|
+
])
|
49
|
+
end
|
80
50
|
end
|
81
|
-
|
82
|
-
results.must_equal([
|
83
|
-
{ 'a' => 1, 'b' => 2, 0 => 1, 1 => 2 },
|
84
|
-
{ 'a' => 3, 'b' => 4, 0 => 3, 1 => 4}
|
85
|
-
])
|
86
51
|
end
|
87
52
|
end
|
88
53
|
end
|
@@ -1,35 +1,39 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
describe '#initialize' do
|
9
|
-
it 'initializes jobs array' do
|
10
|
-
@manager.instance_variable_get('@jobs').must_equal []
|
3
|
+
module Drudgery
|
4
|
+
describe Manager do
|
5
|
+
before do
|
6
|
+
@manager = Manager.new
|
11
7
|
end
|
12
|
-
end
|
13
8
|
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
describe '#prepare' do
|
10
|
+
it 'accepts job as an argument' do
|
11
|
+
job = Job.new
|
17
12
|
|
18
|
-
|
19
|
-
|
13
|
+
@manager.prepare(job)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'allows configuration of job via block' do
|
17
|
+
@manager.prepare do |job|
|
18
|
+
job.extract :csv, 'records.csv'
|
19
|
+
end
|
20
|
+
end
|
20
21
|
end
|
21
|
-
end
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
describe '#run' do
|
24
|
+
it 'performs each prepared job' do
|
25
|
+
job1 = Job.new
|
26
|
+
job2 = Job.new
|
27
|
+
job3 = Job.new
|
28
|
+
|
29
|
+
job1.expects(:perform)
|
30
|
+
job2.expects(:perform)
|
31
|
+
job3.expects(:perform).never
|
29
32
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
@manager.prepare(job1)
|
34
|
+
@manager.prepare(job2)
|
35
|
+
@manager.run
|
36
|
+
end
|
33
37
|
end
|
34
38
|
end
|
35
39
|
end
|
@@ -1,57 +1,51 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
describe '#initialize' do
|
9
|
-
it 'initializes cache hash' do
|
10
|
-
@transformer.instance_variable_get('@cache').must_equal({})
|
3
|
+
module Drudgery
|
4
|
+
describe Transformer do
|
5
|
+
before do
|
6
|
+
@transformer = Transformer.new
|
11
7
|
end
|
12
|
-
end
|
13
|
-
|
14
|
-
describe '#register' do
|
15
|
-
it 'sets processor with provided proc' do
|
16
|
-
processor = Proc.new { |data, cache| data }
|
17
8
|
|
18
|
-
|
9
|
+
describe '#register' do
|
10
|
+
it 'accepts processor as an argument' do
|
11
|
+
processor = Proc.new { |data, cache| data }
|
19
12
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#transform' do
|
26
|
-
it 'symbolizes data keys' do
|
27
|
-
@transformer.transform({ 'a' => 1 }).must_equal({ :a => 1 })
|
13
|
+
@transformer.register(processor)
|
14
|
+
end
|
28
15
|
end
|
29
16
|
|
30
|
-
|
31
|
-
|
17
|
+
describe '#transform' do
|
18
|
+
it 'symbolizes data keys' do
|
19
|
+
@transformer.transform({ 'a' => 1 }).must_equal({ :a => 1 })
|
20
|
+
end
|
32
21
|
|
33
|
-
|
34
|
-
|
35
|
-
end
|
22
|
+
it 'processes data with processor' do
|
23
|
+
processor = Proc.new { |data, cache| data[:b] = 2; data }
|
36
24
|
|
37
|
-
|
38
|
-
|
39
|
-
cache[:a] ||= 0
|
40
|
-
cache[:a] += data[:a]
|
25
|
+
@transformer.register(processor)
|
26
|
+
@transformer.transform({ 'a' => 1 }).must_equal({ :a => 1, :b => 2 })
|
41
27
|
end
|
42
28
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
@transformer.instance_variable_get('@cache').must_equal({ :a => 6 })
|
48
|
-
end
|
29
|
+
it 'allows processor to use cache' do
|
30
|
+
processor = Proc.new do |data, cache|
|
31
|
+
cache[:a] ||= 0
|
32
|
+
cache[:a] += data[:a]
|
49
33
|
|
50
|
-
|
51
|
-
|
34
|
+
{ :a => data[:a], :cached_a => cache[:a] }
|
35
|
+
end
|
52
36
|
|
53
|
-
|
54
|
-
|
37
|
+
@transformer.register(processor)
|
38
|
+
@transformer.transform({ 'a' => 1 }).must_equal({ :a => 1, :cached_a => 1 })
|
39
|
+
@transformer.transform({ 'a' => 2 }).must_equal({ :a => 2, :cached_a => 3 })
|
40
|
+
@transformer.transform({ 'a' => 3 }).must_equal({ :a => 3, :cached_a => 6 })
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns nil if any processor returns nil' do
|
44
|
+
processor = Proc.new { |data, cache| nil }
|
45
|
+
|
46
|
+
@transformer.register(processor)
|
47
|
+
@transformer.transform({ 'a' => 1 }).must_be_nil
|
48
|
+
end
|
55
49
|
end
|
56
50
|
end
|
57
51
|
end
|