Commit b041b864 authored by Nick Lewis's avatar Nick Lewis

(maint) Properly handle non-parallel enumerables

For Enumerables containing 0 or 1 items, the #each_in_parallel method
was improperly calling the block without an argument, then calling it
again properly but not returning the result of the block.

The #each method returns the Enumerable that was it was called on,
rather than the value of the block. This needs to be #map instead, to
actually return an array of the one or zero values. The tests weren't
catching this because they were effectively passing `identity` as the
block, nullifying the distinction between #each and #map.
parent 0d5030c3
......@@ -16,9 +16,9 @@ module Enumerable
end
# return the array of values, no need to look up from the map.
return InParallel::InParallelExecutor.wait_for_processes(nil, block.binding, timeout, kill_all_on_error)
else
# If fork is not supported
map(&block)
end
# If fork is not supported
block.call
each(&block)
end
end
......@@ -228,23 +228,36 @@ describe '.each_in_parallel' do
it 'should return correct values' do
start_time = Time.now
items = ['foo', 'bar', 'baz', 'blah', 'foobar'].each_in_parallel do |item|
items = [1,2,3,4,5].each_in_parallel do |item|
sleep(Random.rand(1.0))
item
item * 2
end
# return values should be an array of the returned items in the last line of the block, in correct order
expect(['foo', 'bar', 'baz', 'blah', 'foobar']).to eq(items)
expect(items).to eq([2,4,6,8,10])
# time should be less than combined delay in the 3 block calls
expect(expect(Time.now - start_time).to be < 5)
end
it 'should run each iteration of a map in parallel' do
items = ['foo', 'bar', 'baz'].map.each_in_parallel do |item|
items = [1,2,3].map.each_in_parallel do |item|
puts item
item
item * 2
end
# return values should be an array of the returned items in the last line of the block, in correct order
expect(items).to eq(['foo', 'bar', 'baz'])
expect(items).to eq([2,4,6])
end
it 'should return an empty array and do nothing with an empty enumerator' do
result = [].each_in_parallel do |item|
raise "Incorrectly called the block with an empty enumerator"
end
expect(result).to eq []
end
it 'should return the result of the block with only 1 item in the enumerator' do
expect([1].each_in_parallel do |item|
item * 2
end).to eq([2])
end
it 'should not run in parallel if there is only 1 item in the enumerator' do
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment