in_threads 1.2.2 → 1.3.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.
@@ -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