in_threads 1.2.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,29 +1,38 @@
1
- $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
- require 'rspec'
1
+ require 'spec_helper'
3
2
  require 'in_threads'
4
3
 
5
- class Item
6
- def initialize(i)
7
- @i, @value = i, Kernel.rand
4
+ # Test item with value
5
+ class ValueItem
6
+ # Use fast_check? for matching
7
+ module FastCheckMatcher
8
+ def self.===(item)
9
+ unless item.respond_to?(:fast_check?)
10
+ fail "#{item.inspect} doesn't respont to fast_check?"
11
+ end
12
+ item.fast_check?
13
+ end
8
14
  end
9
15
 
10
- def ==(other)
11
- self.id == other.id
16
+ def initialize(i, value)
17
+ @i, @value = i, value
12
18
  end
13
19
 
14
- class HalfMatcher
15
- def ===(item)
16
- raise "#{item.inspect} is not an Item" unless item.is_a?(Item)
17
- (0.25..0.75) === item.instance_variable_get(:@value)
18
- end
20
+ def ==(other)
21
+ id == other.id
19
22
  end
20
23
 
21
24
  def value
22
- sleep; @value
25
+ sleep
26
+ @value
23
27
  end
24
28
 
25
29
  def check?
26
- value < 0.5
30
+ sleep
31
+ fast_check?
32
+ end
33
+
34
+ def fast_check?
35
+ !!@value
27
36
  end
28
37
 
29
38
  def touch_n_value(*args)
@@ -47,35 +56,48 @@ private
47
56
  end
48
57
  end
49
58
 
50
- class ValueItem < Item
51
- def initialize(i, value)
52
- @i, @value = i, value
59
+ # Test item with random value
60
+ class RandItem < ValueItem
61
+ def initialize(i)
62
+ super(i, Kernel.rand)
53
63
  end
54
64
 
55
- def value
56
- sleep; @value
65
+ def fast_check?
66
+ @value < 0.5
57
67
  end
68
+ end
58
69
 
59
- def check?
60
- !!value
70
+ # Create custom Enumerables
71
+ module CustomEnum
72
+ def self.new(&block)
73
+ Class.new do
74
+ include Enumerable
75
+ define_method :each, &block
76
+ end.new
61
77
  end
62
78
  end
63
79
 
80
+ class TestException < StandardError; end
81
+
64
82
  def describe_enum_method(method, &block)
65
83
  @enum_methods ||= Enumerable.instance_methods.map(&:to_s)
66
84
  if @enum_methods.include?(method)
67
85
  describe(method, &block)
68
86
  else
69
- it "should not be defined" do
70
- exception_regexp = /^undefined method `#{Regexp.escape(method)}' .*\bInThreads\b/
71
- expect{ enum.in_threads.send(method) }.to raise_error(NoMethodError, exception_regexp)
87
+ it 'should not be defined' do
88
+ exception_regexp =
89
+ /^undefined method `#{Regexp.escape(method)}' .*\bInThreads\b/
90
+ expect{ enum.in_threads.send(method) }.
91
+ to raise_error(NoMethodError, exception_regexp)
72
92
  end
73
93
  end
74
94
  end
75
95
 
76
- describe "in_threads" do
77
- let(:enum){ 30.times.map{ |i| Item.new(i) } }
78
- let(:speed_coef){ 0.666 } # small coefficient, should be more if sleep time coefficient is bigger
96
+ describe 'in_threads' do
97
+ let(:enum){ 30.times.map{ |i| RandItem.new(i) } }
98
+
99
+ # small coefficient, should be more if sleep time coefficient is bigger
100
+ let(:speed_coef){ 0.666 }
79
101
 
80
102
  def measure
81
103
  start = Time.now
@@ -83,34 +105,35 @@ describe "in_threads" do
83
105
  Time.now - start
84
106
  end
85
107
 
86
- describe "consistency" do
87
- describe "verifying params" do
88
- it "should complain about using with non enumerable" do
108
+ describe 'consistency' do
109
+ describe 'verifying params' do
110
+ it 'should complain about using with non enumerable' do
89
111
  expect{ InThreads.new(1) }.to raise_error(ArgumentError)
90
112
  end
91
113
 
92
114
  [1..10, 10.times, {}, []].each do |o|
93
- it "should complain about using with #{o.class}" do
115
+ it "should not complain about using with #{o.class}" do
94
116
  expect{ InThreads.new(o) }.not_to raise_error
95
117
  end
96
118
  end
97
119
 
98
- it "should complain about using less than 2 threads" do
120
+ it 'should complain about using less than 2 threads' do
99
121
  expect{ 10.times.in_threads(1) }.to raise_error(ArgumentError)
100
122
  end
101
123
 
102
- it "should not complain about using 2 or more threads" do
124
+ it 'should not complain about using 2 or more threads' do
103
125
  expect{ 10.times.in_threads(2) }.not_to raise_error
104
126
  end
105
127
  end
106
128
 
107
- describe "in_threads method" do
108
- it "should not change existing instance" do
129
+ describe 'in_threads method' do
130
+ it 'should not change existing instance' do
109
131
  threaded = enum.in_threads(10)
110
132
  expect{ threaded.in_threads(20) }.not_to change(threaded, :thread_count)
111
133
  end
112
134
 
113
- it "should create new instance with different title when called on WithProgress" do
135
+ it 'should create new instance with different title when called on '\
136
+ 'WithProgress' do
114
137
  threaded = enum.in_threads(10)
115
138
  tthreaded = threaded.in_threads(20)
116
139
  expect(threaded.thread_count).to eq(10)
@@ -121,7 +144,7 @@ describe "in_threads" do
121
144
  end
122
145
  end
123
146
 
124
- describe "thread count" do
147
+ describe 'thread count' do
125
148
  let(:enum){ 100.times.map{ |i| ValueItem.new(i, i < 50) } }
126
149
 
127
150
  %w[each map all?].each do |method|
@@ -146,104 +169,113 @@ describe "in_threads" do
146
169
  end
147
170
  end
148
171
 
149
- describe "underlying enumerable usage" do
150
- class CheckEachCalls
151
- include Enumerable
152
-
153
- def each
154
- each_started
155
- 100.times.each do |i|
156
- yield ValueItem.new(i, i < 50)
172
+ describe 'underlying enumerable usage' do
173
+ %w[each map all?].each do |method|
174
+ it "should call underlying enumerable.each only once for #{method}" do
175
+ enum = CustomEnum.new do |&block|
176
+ 100.times.each do |i|
177
+ block[ValueItem.new(i, i < 50)]
178
+ end
157
179
  end
180
+
181
+ expect(enum).to receive(:each).once.and_call_original
182
+ enum.in_threads(13).send(method, &:check?)
158
183
  end
159
184
  end
160
- let(:enum){ CheckEachCalls.new }
161
185
 
162
- %w[each map all?].each do |method|
163
- it "should call underlying enumerable.each only once for #{method}" do
164
- expect(enum).to receive(:each_started).once
165
- enum.in_threads(13).send(method, &:check?)
186
+ it 'should not yield all elements when not needed' do
187
+ enum = CustomEnum.new do |&block|
188
+ 100.times{ block[1] }
189
+ fail
166
190
  end
191
+
192
+ enum.in_threads(13).all?{ false }
167
193
  end
168
194
  end
169
195
  end
170
196
 
171
- describe "methods" do
172
- (Enumerable.instance_methods - 10.times.in_threads.class.instance_methods).each do |method|
197
+ describe 'methods' do
198
+ enumerable_methods = Enumerable.instance_methods
199
+ in_threads_methods = 10.times.in_threads.class.instance_methods
200
+ (enumerable_methods - in_threads_methods).each do |method|
173
201
  pending method
174
202
  end
175
203
 
176
- class TestException < StandardError; end
177
-
178
204
  def check_test_exception(enum, &block)
179
205
  expect{ block[enum.in_threads] }.to raise_exception(TestException)
180
206
  expect{ block[enum.in_threads(1000)] }.to raise_exception(TestException)
181
207
  end
182
208
 
183
- describe "each" do
184
- it "should return same enum after running" do
209
+ describe 'each' do
210
+ it 'should return same enum after running' do
185
211
  expect(enum.in_threads.each(&:value)).to eq(enum)
186
212
  end
187
213
 
188
- it "should execute block for each element" do
214
+ it 'should execute block for each element' do
189
215
  enum.each{ |o| expect(o).to receive(:touch).once }
190
216
  enum.in_threads.each(&:touch_n_value)
191
217
  end
192
218
 
193
- it "should run faster with threads" do
194
- expect(measure{ enum.in_threads.each(&:value) }).to be < measure{ enum.each(&:value) } * speed_coef
219
+ it 'should run faster with threads' do
220
+ expect(measure{ enum.in_threads.each(&:value) }).
221
+ to be < measure{ enum.each(&:value) } * speed_coef
195
222
  end
196
223
 
197
- it "should run faster with more threads" do
198
- expect(measure{ enum.in_threads(10).each(&:value) }).to be < measure{ enum.in_threads(2).each(&:value) } * speed_coef
224
+ it 'should run faster with more threads' do
225
+ expect(measure{ enum.in_threads(10).each(&:value) }).
226
+ to be < measure{ enum.in_threads(2).each(&:value) } * speed_coef
199
227
  end
200
228
 
201
- it "should return same enum without block" do
229
+ it 'should return same enum without block' do
202
230
  expect(enum.in_threads.each.to_a).to eq(enum.each.to_a)
203
231
  end
204
232
 
205
- it "should raise exception in outer thread" do
233
+ it 'should raise exception in outer thread' do
206
234
  check_test_exception(enum) do |threaded|
207
- threaded.each{ raise TestException }
235
+ threaded.each{ fail TestException }
208
236
  end
209
237
  end
210
238
  end
211
239
 
212
240
  %w[each_with_index enum_with_index].each do |method|
213
241
  describe_enum_method method do
214
- let(:runner){ proc{ |o, i| o.value } }
242
+ let(:runner){ proc{ |o, _i| o.value } }
215
243
 
216
- it "should return same result with threads" do
217
- expect(enum.in_threads.send(method, &runner)).to eq(enum.send(method, &runner))
244
+ it 'should return same result with threads' do
245
+ expect(enum.in_threads.send(method, &runner)).
246
+ to eq(enum.send(method, &runner))
218
247
  end
219
248
 
220
- it "should fire same objects" do
249
+ it 'should fire same objects' do
221
250
  enum.send(method){ |o, i| expect(o).to receive(:touch).with(i).once }
222
251
  enum.in_threads.send(method){ |o, i| o.touch_n_value(i) }
223
252
  end
224
253
 
225
- it "should run faster with threads" do
226
- expect(measure{ enum.in_threads.send(method, &runner) }).to be < measure{ enum.send(method, &runner) } * speed_coef
254
+ it 'should run faster with threads' do
255
+ expect(measure{ enum.in_threads.send(method, &runner) }).
256
+ to be < measure{ enum.send(method, &runner) } * speed_coef
227
257
  end
228
258
 
229
- it "should return same enum without block" do
230
- expect(enum.in_threads.send(method).to_a).to eq(enum.send(method).to_a)
259
+ it 'should return same enum without block' do
260
+ expect(enum.in_threads.send(method).to_a).
261
+ to eq(enum.send(method).to_a)
231
262
  end
232
263
 
233
- it "should raise exception in outer thread" do
264
+ it 'should raise exception in outer thread' do
234
265
  check_test_exception(enum) do |threaded|
235
- threaded.send(method){ raise TestException }
266
+ threaded.send(method){ fail TestException }
236
267
  end
237
268
  end
238
269
  end
239
270
  end
240
271
 
241
- describe "reverse_each" do
242
- it "should return same result with threads" do
243
- expect(enum.in_threads.reverse_each(&:value)).to eq(enum.reverse_each(&:value))
272
+ describe 'reverse_each' do
273
+ it 'should return same result with threads' do
274
+ expect(enum.in_threads.reverse_each(&:value)).
275
+ to eq(enum.reverse_each(&:value))
244
276
  end
245
277
 
246
- it "should fire same objects in reverse order" do
278
+ it 'should fire same objects in reverse order' do
247
279
  @order = double('order', :notify => nil)
248
280
  expect(@order).to receive(:notify).with(enum.last).ordered
249
281
  expect(@order).to receive(:notify).with(enum[enum.length / 2]).ordered
@@ -256,17 +288,18 @@ describe "in_threads" do
256
288
  end
257
289
  end
258
290
 
259
- it "should run faster with threads" do
260
- expect(measure{ enum.in_threads.reverse_each(&:value) }).to be < measure{ enum.reverse_each(&:value) } * speed_coef
291
+ it 'should run faster with threads' do
292
+ expect(measure{ enum.in_threads.reverse_each(&:value) }).
293
+ to be < measure{ enum.reverse_each(&:value) } * speed_coef
261
294
  end
262
295
 
263
- it "should return same enum without block" do
296
+ it 'should return same enum without block' do
264
297
  expect(enum.in_threads.reverse_each.to_a).to eq(enum.reverse_each.to_a)
265
298
  end
266
299
 
267
- it "should raise exception in outer thread" do
300
+ it 'should raise exception in outer thread' do
268
301
  check_test_exception(enum) do |threaded|
269
- threaded.reverse_each{ raise TestException }
302
+ threaded.reverse_each{ fail TestException }
270
303
  end
271
304
  end
272
305
  end
@@ -276,13 +309,14 @@ describe "in_threads" do
276
309
  detect find find_index drop_while take_while
277
310
  ].each do |method|
278
311
  describe method do
279
- let(:enum){ 100.times.map{ |i| ValueItem.new(i, i % 2 == 1) } }
312
+ let(:enum){ 100.times.map{ |i| ValueItem.new(i, i.odd?) } }
280
313
 
281
- it "should return same result with threads" do
282
- expect(enum.in_threads.send(method, &:check?)).to eq(enum.send(method, &:check?))
314
+ it 'should return same result with threads' do
315
+ expect(enum.in_threads.send(method, &:check?)).
316
+ to eq(enum.send(method, &:check?))
283
317
  end
284
318
 
285
- it "should fire same objects but not all" do
319
+ it 'should fire same objects but not all' do
286
320
  a = []
287
321
  enum.send(method) do |o|
288
322
  a << o
@@ -291,21 +325,25 @@ describe "in_threads" do
291
325
 
292
326
  @a = []
293
327
  @mutex = Mutex.new
294
- enum.in_threads.send(method){ |o| @mutex.synchronize{ @a << o }; o.check? }
328
+ enum.in_threads.send(method) do |o|
329
+ @mutex.synchronize{ @a << o }
330
+ o.check?
331
+ end
295
332
 
296
333
  expect(@a.length).to be >= a.length
297
334
  expect(@a.length).to be <= enum.length * 0.5
298
335
  end
299
336
 
300
- it "should run faster with threads" do
337
+ it 'should run faster with threads' do
301
338
  boolean = %w[all? drop_while take_while].include?(method)
302
339
  enum = 30.times.map{ |i| ValueItem.new(i, boolean) }
303
- expect(measure{ enum.in_threads.send(method, &:check?) }).to be < measure{ enum.send(method, &:check?) } * speed_coef
340
+ expect(measure{ enum.in_threads.send(method, &:check?) }).
341
+ to be < measure{ enum.send(method, &:check?) } * speed_coef
304
342
  end
305
343
 
306
- it "should raise exception in outer thread" do
344
+ it 'should raise exception in outer thread' do
307
345
  check_test_exception(enum) do |threaded|
308
- threaded.send(method){ raise TestException }
346
+ threaded.send(method){ fail TestException }
309
347
  end
310
348
  end
311
349
  end
@@ -313,22 +351,24 @@ describe "in_threads" do
313
351
 
314
352
  %w[partition find_all select reject count].each do |method|
315
353
  describe method do
316
- it "should return same result with threads" do
317
- expect(enum.in_threads.send(method, &:check?)).to eq(enum.send(method, &:check?))
354
+ it 'should return same result with threads' do
355
+ expect(enum.in_threads.send(method, &:check?)).
356
+ to eq(enum.send(method, &:check?))
318
357
  end
319
358
 
320
- it "should fire same objects" do
359
+ it 'should fire same objects' do
321
360
  enum.send(method){ |o| expect(o).to receive(:touch).once }
322
361
  enum.in_threads.send(method, &:touch_n_check?)
323
362
  end
324
363
 
325
- it "should run faster with threads" do
326
- expect(measure{ enum.in_threads.send(method, &:check?) }).to be < measure{ enum.send(method, &:check?) } * speed_coef
364
+ it 'should run faster with threads' do
365
+ expect(measure{ enum.in_threads.send(method, &:check?) }).
366
+ to be < measure{ enum.send(method, &:check?) } * speed_coef
327
367
  end
328
368
 
329
- it "should raise exception in outer thread" do
369
+ it 'should raise exception in outer thread' do
330
370
  check_test_exception(enum) do |threaded|
331
- threaded.send(method){ raise TestException }
371
+ threaded.send(method){ fail TestException }
332
372
  end
333
373
  end
334
374
  end
@@ -336,22 +376,24 @@ describe "in_threads" do
336
376
 
337
377
  %w[collect map group_by max_by min_by minmax_by sort_by].each do |method|
338
378
  describe method do
339
- it "should return same result with threads" do
340
- expect(enum.in_threads.send(method, &:value)).to eq(enum.send(method, &:value))
379
+ it 'should return same result with threads' do
380
+ expect(enum.in_threads.send(method, &:value)).
381
+ to eq(enum.send(method, &:value))
341
382
  end
342
383
 
343
- it "should fire same objects" do
384
+ it 'should fire same objects' do
344
385
  enum.send(method){ |o| expect(o).to receive(:touch).once; 0 }
345
386
  enum.in_threads.send(method, &:touch_n_value)
346
387
  end
347
388
 
348
- it "should run faster with threads" do
349
- expect(measure{ enum.in_threads.send(method, &:value) }).to be < measure{ enum.send(method, &:value) } * speed_coef
389
+ it 'should run faster with threads' do
390
+ expect(measure{ enum.in_threads.send(method, &:value) }).
391
+ to be < measure{ enum.send(method, &:value) } * speed_coef
350
392
  end
351
393
 
352
- it "should raise exception in outer thread" do
394
+ it 'should raise exception in outer thread' do
353
395
  check_test_exception(enum) do |threaded|
354
- threaded.send(method){ raise TestException }
396
+ threaded.send(method){ fail TestException }
355
397
  end
356
398
  end
357
399
  end
@@ -361,191 +403,220 @@ describe "in_threads" do
361
403
  describe_enum_method method do
362
404
  let(:runner){ proc{ |a| a.each(&:value) } }
363
405
 
364
- it "should fire same objects" do
365
- enum.send(method, 3){ |a| expect(a.first).to receive(:touch).with(a).once }
406
+ it 'should fire same objects' do
407
+ enum.send(method, 3) do |a|
408
+ expect(a.first).to receive(:touch).with(a).once
409
+ end
366
410
  enum.in_threads.send(method, 3){ |a| a.first.touch_n_value(a) }
367
411
  end
368
412
 
369
- it "should return same with block" do
370
- expect(enum.in_threads.send(method, 3, &runner)).to eq(enum.send(method, 3, &runner))
413
+ it 'should return same with block' do
414
+ expect(enum.in_threads.send(method, 3, &runner)).
415
+ to eq(enum.send(method, 3, &runner))
371
416
  end
372
417
 
373
- it "should run faster with threads" do
374
- expect(measure{ enum.in_threads.send(method, 3, &runner) }).to be < measure{ enum.send(method, 3, &runner) } * speed_coef
418
+ it 'should run faster with threads' do
419
+ expect(measure{ enum.in_threads.send(method, 3, &runner) }).
420
+ to be < measure{ enum.send(method, 3, &runner) } * speed_coef
375
421
  end
376
422
 
377
- it "should return same without block" do
378
- expect(enum.in_threads.send(method, 3).to_a).to eq(enum.send(method, 3).to_a)
423
+ it 'should return same without block' do
424
+ expect(enum.in_threads.send(method, 3).to_a).
425
+ to eq(enum.send(method, 3).to_a)
379
426
  end
380
427
 
381
- it "should raise exception in outer thread" do
428
+ it 'should raise exception in outer thread' do
382
429
  check_test_exception(enum) do |threaded|
383
- threaded.send(method, 3){ raise TestException }
430
+ threaded.send(method, 3){ fail TestException }
384
431
  end
385
432
  end
386
433
  end
387
434
  end
388
435
 
389
- describe "zip" do
436
+ describe 'zip' do
390
437
  let(:runner){ proc{ |a| a.each(&:value) } }
391
438
 
392
- it "should fire same objects" do
393
- enum.zip(enum, enum){ |a| expect(a.first).to receive(:touch).with(a).once }
394
- enum.in_threads.zip(enum, enum){ |a| a.first.touch_n_value(a) }
439
+ it 'should fire same objects' do
440
+ enum.zip(enum, enum) do |a|
441
+ expect(a.first).to receive(:touch).with(a).once
442
+ end
443
+
444
+ enum.in_threads.zip(enum, enum) do |a|
445
+ a.first.touch_n_value(a)
446
+ end
395
447
  end
396
448
 
397
- it "should return same with block" do
398
- expect(enum.in_threads.zip(enum, enum, &runner)).to eq(enum.zip(enum, enum, &runner))
449
+ it 'should return same with block' do
450
+ expect(enum.in_threads.zip(enum, enum, &runner)).
451
+ to eq(enum.zip(enum, enum, &runner))
399
452
  end
400
453
 
401
- it "should run faster with threads" do
402
- expect(measure{ enum.in_threads.zip(enum, enum, &runner) }).to be < measure{ enum.zip(enum, enum, &runner) } * speed_coef
454
+ it 'should run faster with threads' do
455
+ expect(measure{ enum.in_threads.zip(enum, enum, &runner) }).
456
+ to be < measure{ enum.zip(enum, enum, &runner) } * speed_coef
403
457
  end
404
458
 
405
- it "should return same without block" do
459
+ it 'should return same without block' do
406
460
  expect(enum.in_threads.zip(enum, enum)).to eq(enum.zip(enum, enum))
407
461
  end
408
462
 
409
- it "should raise exception in outer thread" do
463
+ it 'should raise exception in outer thread' do
410
464
  check_test_exception(enum) do |threaded|
411
- threaded.zip(enum, enum){ raise TestException }
465
+ threaded.zip(enum, enum){ fail TestException }
412
466
  end
413
467
  end
414
468
  end
415
469
 
416
- describe "cycle" do
417
- it "should fire same objects" do
470
+ describe 'cycle' do
471
+ it 'should fire same objects' do
418
472
  enum.cycle(1){ |o| expect(o).to receive(:touch).exactly(3).times }
419
473
  enum.in_threads.cycle(3, &:touch_n_value)
420
474
  end
421
475
 
422
- it "should run faster with threads" do
423
- expect(measure{ enum.in_threads.cycle(3, &:value) }).to be < measure{ enum.cycle(3, &:value) } * speed_coef
476
+ it 'should run faster with threads' do
477
+ expect(measure{ enum.in_threads.cycle(3, &:value) }).
478
+ to be < measure{ enum.cycle(3, &:value) } * speed_coef
424
479
  end
425
480
 
426
- it "should return same enum without block" do
481
+ it 'should return same enum without block' do
427
482
  expect(enum.in_threads.cycle(3).to_a).to eq(enum.cycle(3).to_a)
428
483
  end
429
484
 
430
- it "should raise exception in outer thread" do
485
+ it 'should raise exception in outer thread' do
431
486
  check_test_exception(enum) do |threaded|
432
- threaded.cycle{ raise TestException }
487
+ threaded.cycle{ fail TestException }
433
488
  end
434
489
  end
435
490
  end
436
491
 
437
- describe "grep" do
438
- let(:matcher){ Item::HalfMatcher.new }
492
+ describe 'grep' do
493
+ let(:matcher){ ValueItem::FastCheckMatcher }
439
494
 
440
- it "should fire same objects" do
441
- enum.each{ |o| expect(o).to receive(:touch).exactly(matcher === o ? 1 : 0).times }
495
+ it 'should fire same objects' do
496
+ enum.each do |o|
497
+ expect(o).to receive(:touch).exactly(o.fast_check? ? 1 : 0).times
498
+ end
442
499
  enum.in_threads.grep(matcher, &:touch_n_value)
443
500
  end
444
501
 
445
- it "should return same with block" do
446
- expect(enum.in_threads.grep(matcher, &:value)).to eq(enum.grep(matcher, &:value))
502
+ it 'should return same with block' do
503
+ expect(enum.in_threads.grep(matcher, &:value)).
504
+ to eq(enum.grep(matcher, &:value))
447
505
  end
448
506
 
449
- it "should run faster with threads" do
450
- expect(measure{ enum.in_threads.grep(matcher, &:value) }).to be < measure{ enum.grep(matcher, &:value) } * speed_coef
507
+ it 'should run faster with threads' do
508
+ expect(measure{ enum.in_threads.grep(matcher, &:value) }).
509
+ to be < measure{ enum.grep(matcher, &:value) } * speed_coef
451
510
  end
452
511
 
453
- it "should return same without block" do
512
+ it 'should return same without block' do
454
513
  expect(enum.in_threads.grep(matcher)).to eq(enum.grep(matcher))
455
514
  end
456
515
 
457
- it "should raise exception in outer thread" do
516
+ it 'should raise exception in outer thread' do
458
517
  check_test_exception(enum) do |threaded|
459
- threaded.grep(matcher){ raise TestException }
518
+ threaded.grep(matcher){ fail TestException }
460
519
  end
461
520
  end
462
521
  end
463
522
 
464
- describe_enum_method "each_entry" do
465
- class EachEntryYielder
466
- include Enumerable
467
- def each
468
- 10.times{ yield 1 }
469
- 10.times{ yield 2, 3 }
470
- 10.times{ yield 4, 5, 6 }
523
+ describe_enum_method 'each_entry' do
524
+ let(:enum) do
525
+ CustomEnum.new do |&block|
526
+ 10.times{ block[1] }
527
+ 10.times{ block[2, 3] }
528
+ 10.times{ block[4, 5, 6] }
471
529
  end
472
530
  end
473
-
474
- let(:enum){ EachEntryYielder.new }
475
531
  let(:runner){ proc{ |o| ValueItem.new(0, o).value } }
476
532
 
477
- it "should return same result with threads" do
478
- expect(enum.in_threads.each_entry(&runner)).to eq(enum.each_entry(&runner))
533
+ it 'should return same result with threads' do
534
+ expect(enum.in_threads.each_entry(&runner)).
535
+ to eq(enum.each_entry(&runner))
479
536
  end
480
537
 
481
- it "should execute block for each element" do
482
- @order = double('order')
483
- expect(@order).to receive(:notify).with(1).exactly(10).times.ordered
484
- expect(@order).to receive(:notify).with([2, 3]).exactly(10).times.ordered
485
- expect(@order).to receive(:notify).with([4, 5, 6]).exactly(10).times.ordered
538
+ it 'should execute block for each element' do
539
+ @o = double('order')
540
+ expect(@o).to receive(:notify).with(1).exactly(10).times.ordered
541
+ expect(@o).to receive(:notify).with([2, 3]).exactly(10).times.ordered
542
+ expect(@o).to receive(:notify).with([4, 5, 6]).exactly(10).times.ordered
486
543
  @mutex = Mutex.new
487
544
  enum.in_threads.each_entry do |o|
488
- @mutex.synchronize{ @order.notify(o) }
545
+ @mutex.synchronize{ @o.notify(o) }
489
546
  runner[]
490
547
  end
491
548
  end
492
549
 
493
- it "should run faster with threads" do
494
- expect(measure{ enum.in_threads.each_entry(&runner) }).to be < measure{ enum.each_entry(&runner) } * speed_coef
550
+ it 'should run faster with threads' do
551
+ expect(measure{ enum.in_threads.each_entry(&runner) }).
552
+ to be < measure{ enum.each_entry(&runner) } * speed_coef
495
553
  end
496
554
 
497
- it "should return same enum without block" do
555
+ it 'should return same enum without block' do
498
556
  expect(enum.in_threads.each_entry.to_a).to eq(enum.each_entry.to_a)
499
557
  end
500
558
 
501
- it "should raise exception in outer thread" do
559
+ it 'should raise exception in outer thread' do
502
560
  check_test_exception(enum) do |threaded|
503
- threaded.each_entry{ raise TestException }
561
+ threaded.each_entry{ fail TestException }
504
562
  end
505
563
  end
506
564
  end
507
565
 
508
566
  %w[flat_map collect_concat].each do |method|
509
567
  describe_enum_method method do
510
- let(:enum){ 20.times.map{ |i| Item.new(i) }.each_slice(3) }
568
+ let(:enum){ 20.times.map{ |i| RandItem.new(i) }.each_slice(3) }
511
569
  let(:runner){ proc{ |a| a.map(&:value) } }
512
570
 
513
- it "should return same result with threads" do
514
- expect(enum.in_threads.send(method, &runner)).to eq(enum.send(method, &runner))
571
+ it 'should return same result with threads' do
572
+ expect(enum.in_threads.send(method, &runner)).
573
+ to eq(enum.send(method, &runner))
515
574
  end
516
575
 
517
- it "should fire same objects" do
518
- enum.send(method){ |a| a.each{ |o| expect(o).to receive(:touch).with(a).once } }
519
- enum.in_threads.send(method){ |a| a.each{ |o| o.touch_n_value(a) } }
576
+ it 'should fire same objects' do
577
+ enum.send(method) do |a|
578
+ a.each do |o|
579
+ expect(o).to receive(:touch).with(a).once
580
+ end
581
+ end
582
+
583
+ enum.in_threads.send(method) do |a|
584
+ a.each do |o|
585
+ o.touch_n_value(a)
586
+ end
587
+ end
520
588
  end
521
589
 
522
- it "should run faster with threads" do
523
- expect(measure{ enum.in_threads.send(method, &runner) }).to be < measure{ enum.send(method, &runner) } * speed_coef
590
+ it 'should run faster with threads' do
591
+ expect(measure{ enum.in_threads.send(method, &runner) }).
592
+ to be < measure{ enum.send(method, &runner) } * speed_coef
524
593
  end
525
594
 
526
- it "should return same enum without block" do
527
- expect(enum.in_threads.send(method).to_a).to eq(enum.send(method).to_a)
595
+ it 'should return same enum without block' do
596
+ expect(enum.in_threads.send(method).to_a).
597
+ to eq(enum.send(method).to_a)
528
598
  end
529
599
 
530
- it "should raise exception in outer thread" do
600
+ it 'should raise exception in outer thread' do
531
601
  check_test_exception(enum) do |threaded|
532
- threaded.send(method){ raise TestException }
602
+ threaded.send(method){ fail TestException }
533
603
  end
534
604
  end
535
605
  end
536
606
  end
537
607
 
538
- context "unthreaded" do
608
+ context 'unthreaded' do
539
609
  %w[inject reduce].each do |method|
540
610
  describe method do
541
- it "should return same result" do
611
+ it 'should return same result' do
542
612
  combiner = proc{ |memo, o| memo + o.value }
543
- expect(enum.in_threads.send(method, 0, &combiner)).to eq(enum.send(method, 0, &combiner))
613
+ expect(enum.in_threads.send(method, 0, &combiner)).
614
+ to eq(enum.send(method, 0, &combiner))
544
615
  end
545
616
 
546
- it "should raise exception in outer thread" do
617
+ it 'should raise exception in outer thread' do
547
618
  check_test_exception(enum) do |threaded|
548
- threaded.send(method){ raise TestException }
619
+ threaded.send(method){ fail TestException }
549
620
  end
550
621
  end
551
622
  end
@@ -553,14 +624,15 @@ describe "in_threads" do
553
624
 
554
625
  %w[max min minmax sort].each do |method|
555
626
  describe method do
556
- it "should return same result" do
627
+ it 'should return same result' do
557
628
  comparer = proc{ |a, b| a.value <=> b.value }
558
- expect(enum.in_threads.send(method, &comparer)).to eq(enum.send(method, &comparer))
629
+ expect(enum.in_threads.send(method, &comparer)).
630
+ to eq(enum.send(method, &comparer))
559
631
  end
560
632
 
561
- it "should raise exception in outer thread" do
633
+ it 'should raise exception in outer thread' do
562
634
  check_test_exception(enum) do |threaded|
563
- threaded.send(method){ raise TestException }
635
+ threaded.send(method){ fail TestException }
564
636
  end
565
637
  end
566
638
  end
@@ -568,7 +640,7 @@ describe "in_threads" do
568
640
 
569
641
  %w[to_a entries].each do |method|
570
642
  describe method do
571
- it "should return same result" do
643
+ it 'should return same result' do
572
644
  expect(enum.in_threads.send(method)).to eq(enum.send(method))
573
645
  end
574
646
  end
@@ -576,7 +648,7 @@ describe "in_threads" do
576
648
 
577
649
  %w[drop take].each do |method|
578
650
  describe method do
579
- it "should return same result" do
651
+ it 'should return same result' do
580
652
  expect(enum.in_threads.send(method, 2)).to eq(enum.send(method, 2))
581
653
  end
582
654
  end
@@ -584,7 +656,7 @@ describe "in_threads" do
584
656
 
585
657
  %w[first].each do |method|
586
658
  describe method do
587
- it "should return same result" do
659
+ it 'should return same result' do
588
660
  expect(enum.in_threads.send(method)).to eq(enum.send(method))
589
661
  expect(enum.in_threads.send(method, 3)).to eq(enum.send(method, 3))
590
662
  end
@@ -593,35 +665,38 @@ describe "in_threads" do
593
665
 
594
666
  %w[include? member?].each do |method|
595
667
  describe method do
596
- it "should return same result" do
597
- expect(enum.in_threads.send(method, enum[10])).to eq(enum.send(method, enum[10]))
668
+ it 'should return same result' do
669
+ expect(enum.in_threads.send(method, enum[10])).
670
+ to eq(enum.send(method, enum[10]))
598
671
  end
599
672
  end
600
673
  end
601
674
 
602
- describe_enum_method "each_with_object" do
675
+ describe_enum_method 'each_with_object' do
603
676
  let(:runner){ proc{ |o, h| h[o.value] = true } }
604
677
 
605
- it "should return same result" do
606
- expect(enum.in_threads.each_with_object({}, &runner)).to eq(enum.each_with_object({}, &runner))
678
+ it 'should return same result' do
679
+ expect(enum.in_threads.each_with_object({}, &runner)).
680
+ to eq(enum.each_with_object({}, &runner))
607
681
  end
608
682
 
609
- it "should raise exception in outer thread" do
683
+ it 'should raise exception in outer thread' do
610
684
  check_test_exception(enum) do |threaded|
611
- threaded.each_with_object({}){ raise TestException }
685
+ threaded.each_with_object({}){ fail TestException }
612
686
  end
613
687
  end
614
688
  end
615
689
 
616
690
  %w[chunk slice_before].each do |method|
617
691
  describe_enum_method method do
618
- it "should return same result" do
619
- expect(enum.in_threads.send(method, &:check?).to_a).to eq(enum.send(method, &:check?).to_a)
692
+ it 'should return same result' do
693
+ expect(enum.in_threads.send(method, &:check?).to_a).
694
+ to eq(enum.send(method, &:check?).to_a)
620
695
  end
621
696
 
622
- it "should raise exception in outer thread" do
697
+ it 'should raise exception in outer thread' do
623
698
  check_test_exception(enum) do |threaded|
624
- threaded.send(method){ raise TestException }.to_a
699
+ threaded.send(method){ fail TestException }.to_a
625
700
  end
626
701
  end
627
702
  end