Files
datapipeline/test/core/chained_test.rb
T

82 lines
3.0 KiB
Ruby

require_relative '../test_helper'
# chained steps: map, filter, header, trailer, context
class ChainedTest < PipelineTest
ROWS = [{ 'a' => 1 }, { 'a' => 2 }, { 'a' => 3 }].freeze
def test_each_step_gets_the_previous_output
out = output(ROWS) { map { |r| r.merge('b' => 1) }; map { |r| r.merge('c' => 2) } }
assert_equal ROWS.map { |r| r.merge('b' => 1, 'c' => 2) }, out
end
def test_one_to_many_then_index
out = output(ROWS) { map { |r| [r, r] }; map { |r, ctx| r.merge('i' => ctx.index) } }
assert_equal (0...6).to_a, out.map { |r| r['i'] }
end
def test_nil_and_empty_array_drop_rows
assert_equal [{ 'a' => 1 }], output(ROWS) { map { |r| r['a'] == 1 ? r : nil } }
assert_equal ROWS, output(ROWS) { map { |r| [r, nil] } }
assert_equal [], output(ROWS) { map { [] } }
end
def test_map_and_filter
out = output(ROWS) do
map { |r| r.merge('d' => r['a'] * 2) }
filter { |r| r['d'] > 2 }
map { |r, ctx| r.merge('i' => ctx.index) }
end
assert_equal [{ 'a' => 2, 'd' => 4, 'i' => 0 }, { 'a' => 3, 'd' => 6, 'i' => 1 }], out
end
def test_header_and_trailer_with_context
out = output(ROWS) do
header { |c| { 'H' => c.read, 'W' => c.written } }
filter { |r| r['a'] > 1 }
map { |r| [r, r] }
trailer { |c| { 'T' => c.written } }
end
assert_equal({ 'H' => 3, 'W' => 4 }, out.first)
assert_equal({ 'T' => 4 }, out.last)
assert_equal 6, out.size
end
def test_several_headers_and_trailers_in_registration_order
out = output(ROWS) { header { { 'h' => 1 } }; trailer { { 't' => 1 } }; header { { 'h' => 2 } }; trailer { { 't' => 2 } } }
assert_equal [{ 'h' => 1 }, { 'h' => 2 }, *ROWS, { 't' => 1 }, { 't' => 2 }], out
end
def test_stable_order_of_many_steps
out = output(ROWS) { 20.times { |k| map { |r| r.merge("k#{k}" => k) } } }
assert_equal (0...20).to_a, out.first.values.drop(1)
end
def test_header_and_trailer_nil_and_arrays
out = output(ROWS) { header { nil }; trailer { [{ 'x' => 1 }, nil, { 'y' => 2 }] }; map { |r| r } }
assert_equal ROWS + [{ 'x' => 1 }, { 'y' => 2 }], out
end
def test_condition_on_map_and_filter
assert_equal [{ 'a' => 1 }], output(ROWS) { map(condition: ->(r) { r['a'] == 1 }) { |r| r } }
assert_equal [{ 'a' => 3 }], output(ROWS) { filter(condition: ->(r) { r['a'] > 1 }) { |r| r['a'] == 3 } }
end
def test_condition_must_be_a_lambda
assert_includes assert_raises(ArgumentError) { output(ROWS) { map(condition: "row['a'] == 1") { |r| r } } }.message, 'lambda'
end
def test_csv_end_to_end
with_tmpdir do |dir|
DataPipeline.new do
logger PipelineHelper::QUIET
read MemoryStorage.new(rows: ROWS)
filter { |r| r['a'].odd? }
map { |r| { 'id' => r['a'], 'x' => 'y' } }
trailer { |c| { 'id' => 'TOTAL', 'x' => c.written } }
write container(:csv, file: "#{dir}/c.csv", columns: %w[id x])
end.run
assert_equal "id,x\n1,y\n3,y\nTOTAL,2\n", File.read("#{dir}/c.csv")
end
end
end