diff --git a/Changes.md b/Changes.md index bb7f971..b27f10e 100644 --- a/Changes.md +++ b/Changes.md @@ -1,6 +1,8 @@ Unreleased ---------- +- Internal refactoring of processing engine (should not affect regular use) + 0.6.0 ----- diff --git a/lib/kiba/context.rb b/lib/kiba/context.rb index da41a39..8504c33 100644 --- a/lib/kiba/context.rb +++ b/lib/kiba/context.rb @@ -6,7 +6,7 @@ def initialize(control) end def pre_process(&block) - @control.pre_processes << block + @control.pre_processes << { block: block } end def source(klass, *initialization_params) @@ -14,11 +14,7 @@ def source(klass, *initialization_params) end def transform(klass = nil, *initialization_params, &block) - if klass - @control.transforms << { klass: klass, args: initialization_params } - else - @control.transforms << block - end + @control.transforms << { klass: klass, args: initialization_params, block: block } end def destination(klass, *initialization_params) @@ -26,7 +22,7 @@ def destination(klass, *initialization_params) end def post_process(&block) - @control.post_processes << block + @control.post_processes << { block: block } end end end diff --git a/lib/kiba/runner.rb b/lib/kiba/runner.rb index ed67427..2a667b3 100644 --- a/lib/kiba/runner.rb +++ b/lib/kiba/runner.rb @@ -1,5 +1,10 @@ module Kiba module Runner + # allow to handle a block form just like a regular transform + class AliasingProc < Proc + alias_method :process, :call + end + def run(control) # instantiate early so that error are raised before any processing occurs pre_processes = to_instances(control.pre_processes, true, false) @@ -18,13 +23,7 @@ def process_rows(sources, transforms, destinations) sources.each do |source| source.each do |row| transforms.each do |transform| - # TODO: avoid the case completely by e.g. subclassing Proc - # and aliasing `process` to `call`. Benchmark needed first though. - if transform.is_a?(Proc) - row = transform.call(row) - else - row = transform.process(row) - end + row = transform.process(row) break unless row end next unless row @@ -38,13 +37,15 @@ def process_rows(sources, transforms, destinations) # not using keyword args because JRuby defaults to 1.9 syntax currently def to_instances(definitions, allow_block = false, allow_class = true) definitions.map do |d| - case d - when Proc - fail 'Block form is not allowed here' unless allow_block - d - else + if d[:klass] fail 'Class form is not allowed here' unless allow_class d[:klass].new(*d[:args]) + elsif d[:block] + fail 'Block form is not allowed here' unless allow_block + AliasingProc.new(&d[:block]) + else + # TODO: support block passing to a class form definition? + fail "Class and block form cannot be used together at the moment" end end end diff --git a/test/test_integration.rb b/test/test_integration.rb index 5810157..ec80ce3 100644 --- a/test/test_integration.rb +++ b/test/test_integration.rb @@ -3,6 +3,7 @@ require_relative 'support/test_csv_source' require_relative 'support/test_csv_destination' require_relative 'support/test_rename_field_transform' +require_relative 'support/test_enumerable_source' # End-to-end tests go here class TestIntegration < Kiba::Test diff --git a/test/test_parser.rb b/test/test_parser.rb index 08e2217..fca8b7b 100644 --- a/test/test_parser.rb +++ b/test/test_parser.rb @@ -20,7 +20,7 @@ def test_block_transform_definition transform { |row| row } end - assert_instance_of Proc, control.transforms[0] + assert_instance_of Proc, control.transforms[0][:block] end def test_class_transform_definition @@ -46,7 +46,7 @@ def test_block_post_process_definition post_process {} end - assert_instance_of Proc, control.post_processes[0] + assert_instance_of Proc, control.post_processes[0][:block] end def test_block_pre_process_definition @@ -54,7 +54,7 @@ def test_block_pre_process_definition pre_process {} end - assert_instance_of Proc, control.pre_processes[0] + assert_instance_of Proc, control.pre_processes[0][:block] end def test_source_as_string_parsing diff --git a/test/test_runner.rb b/test/test_runner.rb index fa6996e..9b8d5db 100644 --- a/test/test_runner.rb +++ b/test/test_runner.rb @@ -22,14 +22,14 @@ class TestRunner < Kiba::Test def test_block_transform_processing # is there a better way to assert a block was called in minitest? - control.transforms << lambda { |r| @called = true; r } + control.transforms << { block: lambda { |r| @called = true; r } } Kiba.run(control) assert_equal true, @called end def test_dismissed_row_not_passed_to_next_transform - control.transforms << lambda { |_| nil } - control.transforms << lambda { |_| @called = true; nil } + control.transforms << { block: lambda { |_| nil } } + control.transforms << { block: lambda { |_| @called = true; nil } } Kiba.run(control) assert_nil @called end @@ -37,7 +37,7 @@ def test_dismissed_row_not_passed_to_next_transform def test_post_process_runs_once assert_equal 2, rows.size @called = 0 - control.post_processes << lambda { @called += 1 } + control.post_processes << { block: lambda { @called += 1 } } Kiba.run(control) assert_equal 1, @called end @@ -52,7 +52,7 @@ def test_post_process_not_called_after_row_failure def test_pre_process_runs_once assert_equal 2, rows.size @called = 0 - control.pre_processes << lambda { @called += 1 } + control.pre_processes << { block: lambda { @called += 1 } } Kiba.run(control) assert_equal 1, @called end