chars 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,194 +1,707 @@
1
1
  require 'spec_helper'
2
- require 'chars/chars'
2
+ require 'chars/char_set'
3
+
4
+ require 'securerandom'
3
5
 
4
6
  describe Chars::CharSet do
5
- before(:all) do
6
- @integer_range = (0x41..0x43)
7
- @string_range = ('A'..'Z')
8
- @integers = @integer_range.to_a
9
- @strings = @string_range.to_a
7
+ let(:integer_range) { (0x41..0x43) }
8
+ let(:string_range) { ('A'..'Z') }
9
+ let(:integers) { integer_range.to_a }
10
+ let(:strings) { string_range.to_a }
10
11
 
11
- @char_set = described_class.new(*@strings)
12
- end
12
+ subject { described_class.new(*strings) }
13
13
 
14
14
  describe "#initialize" do
15
- it "may be created with String arguments" do
16
- @chars = described_class.new(*@strings)
15
+ context "when given multiple String arguments" do
16
+ subject { described_class.new(*strings) }
17
17
 
18
- @strings.all? { |s| @chars.include_char?(s) }.should == true
18
+ it "must populate the char set with the String's chars" do
19
+ expect(strings.all? { |s| subject.include_char?(s) }).to be(true)
20
+ end
19
21
  end
20
22
 
21
- it "may be created with an Array of Strings" do
22
- @chars = described_class.new(@strings)
23
+ context "when given an Array of Strings" do
24
+ subject { described_class.new(strings) }
23
25
 
24
- @strings.all? { |s| @chars.include_char?(s) }.should == true
26
+ it "must populate the char set with the String's chars" do
27
+ expect(strings.all? { |s| subject.include_char?(s) }).to be(true)
28
+ end
25
29
  end
26
30
 
27
- it "may be created with a Range of Strings" do
28
- @chars = described_class.new(@string_range)
31
+ context "when given a Range of Strings" do
32
+ subject { described_class.new(string_range) }
29
33
 
30
- @strings.all? { |s| @chars.include_char?(s) }.should == true
34
+ it "must populate the char set by enumerating over the String's chars" do
35
+ expect(strings.all? { |s| subject.include_char?(s) }).to be(true)
36
+ end
31
37
  end
32
38
 
33
- it "may be created with Integer arguments" do
34
- @chars = described_class.new(*@integers)
39
+ context "when given multiple Integer arguments" do
40
+ subject { described_class.new(*integers) }
35
41
 
36
- @integers.all? { |i| @chars.include?(i) }.should == true
42
+ it "must populate the char set using the Integers as bytes" do
43
+ expect(integers.all? { |i| subject.include?(i) }).to be(true)
44
+ end
37
45
  end
38
46
 
39
- it "may be created with an Array of Integers" do
40
- @chars = described_class.new(@integers)
47
+ context "when given an Array of Integers" do
48
+ subject { described_class.new(integers) }
41
49
 
42
- @integers.all? { |i| @chars.include?(i) }.should == true
50
+ it "must populate the char set using the Integers as bytes" do
51
+ expect(integers.all? { |i| subject.include?(i) }).to be(true)
52
+ end
43
53
  end
44
54
 
45
- it "may be created with a Range of Integers" do
46
- @chars = described_class.new(@integer_range)
55
+ context "when given a Range of Integers" do
56
+ subject { described_class.new(integer_range) }
47
57
 
48
- @integers.all? { |i| @chars.include?(i) }.should == true
58
+ it "must populate the char set by enumerating over the Integer's bytes" do
59
+ expect(integers.all? { |i| subject.include?(i) }).to be(true)
60
+ end
49
61
  end
50
62
  end
51
63
 
52
- it "should include Strings" do
53
- @char_set.include_char?('A').should == true
64
+ describe "#include_char?" do
65
+ it "should include Strings" do
66
+ expect(subject.include_char?('A')).to be(true)
67
+ end
54
68
  end
55
69
 
56
- it "should include Integers" do
57
- @char_set.should include(0x41)
70
+ describe "#include?" do
71
+ it "should include Integers" do
72
+ expect(subject).to include(0x41)
73
+ end
58
74
  end
59
75
 
60
- it "should be able to select bytes" do
61
- @sub_chars = @char_set.select_bytes { |c| c <= 0x42 }
76
+ describe "#select_bytes" do
77
+ it "should be able to select bytes" do
78
+ sub_set = subject.select_bytes { |c| c <= 0x42 }
62
79
 
63
- @sub_chars.should == [0x41, 0x42]
80
+ expect(sub_set).to be == [0x41, 0x42]
81
+ end
64
82
  end
65
83
 
66
- it "should be able to select chars" do
67
- @sub_chars = @char_set.select_chars { |c| c <= 'B' }
84
+ describe "#select_chars" do
85
+ it "should be able to select chars" do
86
+ sub_set = subject.select_chars { |c| c <= 'B' }
68
87
 
69
- @sub_chars.should == ['A', 'B']
88
+ expect(sub_set).to be == ['A', 'B']
89
+ end
70
90
  end
71
91
 
72
- it "should return a random byte" do
73
- @char_set.should include(@char_set.random_byte)
74
- end
92
+ describe "#random_byte" do
93
+ it "should return a random byte" do
94
+ expect(subject).to include(subject.random_byte)
95
+ end
96
+
97
+ context "when given random: rng" do
98
+ let(:rng) { SecureRandom }
75
99
 
76
- it "should return a random char" do
77
- @char_set.include_char?(@char_set.random_char).should == true
100
+ it "must call the #rand method" do
101
+ expect(rng).to receive(:rand).with(subject.length).and_return(1)
102
+
103
+ subject.random_byte(random: rng)
104
+ end
105
+ end
78
106
  end
79
107
 
80
- it "should iterate over n random bytes" do
81
- @char_set.each_random_byte(10).all? { |b|
82
- @char_set.include?(b)
83
- }.should == true
108
+ describe "#random_char" do
109
+ it "should return a random char" do
110
+ expect(subject.include_char?(subject.random_char)).to be(true)
111
+ end
112
+
113
+ context "when given random: rng" do
114
+ let(:rng) { SecureRandom }
115
+
116
+ it "must call the #rand method" do
117
+ expect(rng).to receive(:rand).with(subject.length).and_return(1)
118
+
119
+ subject.random_char(random: rng)
120
+ end
121
+ end
84
122
  end
85
123
 
86
- it "should iterate over n random chars" do
87
- @char_set.each_random_char(10).all? { |c|
88
- @char_set.include_char?(c)
89
- }.should == true
124
+ describe "#each_random_byte" do
125
+ let(:n) { 10 }
126
+
127
+ it "should iterate over n random bytes" do
128
+ expect(subject.each_random_byte(n).all? { |b|
129
+ subject.include?(b)
130
+ }).to be(true)
131
+ end
132
+
133
+ context "when given random: rng" do
134
+ let(:rng) { SecureRandom }
135
+
136
+ it "must call the #rand method n times" do
137
+ n.times do
138
+ expect(rng).to receive(:rand).with(subject.length).and_return(1)
139
+ end
140
+
141
+ subject.each_random_byte(n, random: rng) { |b| }
142
+ end
143
+ end
90
144
  end
91
145
 
92
- it "should return a random Array of bytes" do
93
- bytes = @char_set.random_bytes(10)
146
+ describe "#each_random_char" do
147
+ let(:n) { 10 }
94
148
 
95
- bytes.all? { |b| @char_set.include?(b) }.should == true
149
+ it "should iterate over n random chars" do
150
+ expect(subject.each_random_char(10).all? { |c|
151
+ subject.include_char?(c)
152
+ }).to be(true)
153
+ end
154
+
155
+ context "when given random: rng" do
156
+ let(:rng) { SecureRandom }
157
+
158
+ it "must call the #rand method n times" do
159
+ n.times do
160
+ expect(rng).to receive(:rand).with(subject.length).and_return(1)
161
+ end
162
+
163
+ subject.each_random_char(n, random: rng) { |c| }
164
+ end
165
+ end
96
166
  end
97
167
 
98
- it "should return a random Array of chars" do
99
- chars = @char_set.random_chars(10)
168
+ describe "#random_bytes" do
169
+ context "when given an Integer" do
170
+ let(:n) { 10 }
171
+
172
+ it "should return a random Array of bytes" do
173
+ random_bytes = subject.random_bytes(n)
174
+
175
+ expect(random_bytes.all? { |b| subject.include?(b) }).to be(true)
176
+ end
177
+
178
+ context "when given random: rng" do
179
+ let(:rng) { SecureRandom }
180
+
181
+ it "must call the #rand method n times" do
182
+ n.times do
183
+ expect(rng).to receive(:rand).with(subject.length).and_return(1)
184
+ end
185
+
186
+ subject.random_bytes(n, random: rng)
187
+ end
188
+ end
189
+ end
190
+
191
+ context "when given a Range of lengths" do
192
+ let(:lengths) { 5..10 }
193
+
194
+ it "should return a random Array of bytes with a varying length" do
195
+ random_bytes = subject.random_bytes(lengths)
100
196
 
101
- chars.all? { |c| @char_set.include_char?(c) }.should == true
197
+ expect(random_bytes.length).to be_between(lengths.begin, lengths.end)
198
+ expect(random_bytes.all? { |b| subject.include?(b) }).to be(true)
199
+ end
200
+
201
+ context "and when given random: rng" do
202
+ let(:rng) { SecureRandom }
203
+
204
+ it "must pass random: to Range#sample" do
205
+ expect(rng).to receive(:rand).and_return(rand(lengths)).at_least(:once)
206
+
207
+ random_bytes = subject.random_bytes(lengths, random: rng)
208
+
209
+ expect(random_bytes.length).to be_between(lengths.begin, lengths.end)
210
+ end
211
+ end
212
+ end
102
213
  end
103
214
 
104
- it "should return a random Array of bytes with a varying length" do
105
- bytes = @char_set.random_bytes(5..10)
215
+ describe "#random_chars" do
216
+ context "when given an Integer" do
217
+ let(:n) { 10 }
218
+
219
+ it "should return a random Array of chars" do
220
+ random_chars = subject.random_chars(n)
221
+
222
+ expect(random_chars.all? { |c| subject.include_char?(c) }).to be(true)
223
+ end
224
+
225
+ context "when given random: rng" do
226
+ let(:rng) { SecureRandom }
227
+
228
+ it "must call the #rand method n times" do
229
+ n.times do
230
+ expect(rng).to receive(:rand).with(subject.length).and_return(rand(n))
231
+ end
106
232
 
107
- bytes.length.should be_between(5, 10)
108
- bytes.all? { |b| @char_set.include?(b) }.should == true
233
+ subject.random_chars(n, random: rng)
234
+ end
235
+ end
236
+ end
237
+
238
+ context "when given a Range of lengths" do
239
+ let(:lengths) { 5..10 }
240
+
241
+ it "should return a random Array of chars with a varying length" do
242
+ random_chars = subject.random_chars(lengths)
243
+
244
+ expect(random_chars.length).to be_between(lengths.begin, lengths.end)
245
+ expect(random_chars.all? { |c| subject.include_char?(c) }).to be(true)
246
+ end
247
+
248
+ context "and when given random: rng" do
249
+ let(:rng) { SecureRandom }
250
+
251
+ it "must pass random: to Range#sample" do
252
+ expect(rng).to receive(:rand).and_return(rand(lengths)).at_least(:once)
253
+
254
+ random_chars = subject.random_chars(lengths, random: rng)
255
+
256
+ expect(random_chars.length).to be_between(lengths.begin, lengths.end)
257
+ end
258
+ end
259
+ end
109
260
  end
110
261
 
111
- it "should return a random Array of chars with a varying length" do
112
- chars = @char_set.random_chars(5..10)
262
+ describe "#random_string" do
263
+ context "when given an Integer" do
264
+ let(:n) { 10 }
113
265
 
114
- chars.length.should be_between(5, 10)
115
- chars.all? { |c| @char_set.include_char?(c) }.should == true
266
+ it "should return a random String of chars" do
267
+ random_string = subject.random_string(n)
268
+
269
+ expect(random_string.chars.all? { |b|
270
+ subject.include_char?(b)
271
+ }).to be(true)
272
+ end
273
+
274
+ context "when given random: rng" do
275
+ let(:rng) { SecureRandom }
276
+
277
+ it "must call the #rand method n times" do
278
+ expect(rng).to receive(:rand).with(subject.length).and_return(rand(n)).at_least(:once)
279
+
280
+ subject.random_chars(n, random: rng)
281
+ end
282
+ end
283
+ end
284
+
285
+ context "when given a Range of lengths" do
286
+ let(:lengths) { 5..10 }
287
+
288
+ it "should return a random String of chars with a varying length" do
289
+ random_string = subject.random_string(lengths)
290
+
291
+ expect(random_string.length).to be_between(lengths.begin, lengths.end)
292
+ expect(random_string.chars.all? { |b|
293
+ subject.include_char?(b)
294
+ }).to be(true)
295
+ end
296
+
297
+ context "and when given random: rng" do
298
+ let(:rng) { SecureRandom }
299
+
300
+ it "must pass random: to Range#sample" do
301
+ expect(rng).to receive(:rand).and_return(rand(lengths)).at_least(:once)
302
+
303
+ random_string = subject.random_string(lengths, random: rng)
304
+
305
+ expect(random_string.length).to be_between(lengths.begin, lengths.end)
306
+ end
307
+ end
308
+ end
116
309
  end
310
+
311
+ describe "#random_distinct_bytes" do
312
+ context "when given an Integer" do
313
+ let(:n) { 10 }
314
+
315
+ it "should return a random Array of unique bytes" do
316
+ random_bytes = subject.random_distinct_bytes(n)
317
+
318
+ expect(random_bytes.length).to eq(n)
319
+ expect(random_bytes.uniq).to be == random_bytes
320
+ expect(random_bytes.all? { |b| subject.include_byte?(b) }).to be(true)
321
+ end
322
+
323
+ context "when given random: rng" do
324
+ let(:rng) { SecureRandom }
117
325
 
118
- it "should return a random String of chars" do
119
- string = @char_set.random_string(10)
120
-
121
- string.chars.all? { |b| @char_set.include_char?(b) }.should == true
326
+ it "must call the Array#shuffle with random: rng" do
327
+ expect_any_instance_of(Array).to receive(:shuffle).with(random: rng).and_return(subject.bytes.shuffle)
328
+
329
+ subject.random_distinct_bytes(n, random: rng)
330
+ end
331
+ end
332
+ end
333
+
334
+ context "with a Range of lengths" do
335
+ let(:lengths) { 5..10 }
336
+
337
+ it "should return a random Array of unique bytes with a varying length" do
338
+ random_bytes = subject.random_distinct_bytes(lengths)
339
+
340
+ expect(random_bytes.uniq).to be == random_bytes
341
+ expect(random_bytes.length).to be_between(lengths.begin, lengths.end)
342
+ expect(random_bytes.all? { |b| subject.include_byte?(b) }).to be(true)
343
+ end
344
+
345
+ context "and when given random: rng" do
346
+ let(:rng) { SecureRandom }
347
+
348
+ it "must pass random: to Range#sample" do
349
+ expect(rng).to receive(:rand).and_return(rand(lengths)).at_least(:once)
350
+
351
+ random_bytes = subject.random_bytes(lengths, random: rng)
352
+
353
+ expect(random_bytes.length).to be_between(lengths.begin, lengths.end)
354
+ end
355
+ end
356
+ end
122
357
  end
123
358
 
124
- it "should return a random String of chars with a varying length" do
125
- string = @char_set.random_string(5..10)
359
+ describe "#random_distinct_chars" do
360
+ let(:n) { 10 }
361
+
362
+ it "should return a random Array of unique chars" do
363
+ random_chars = subject.random_distinct_chars(n)
364
+
365
+ expect(random_chars.uniq).to be == random_chars
366
+ expect(random_chars.all? { |c| subject.include_char?(c) }).to be(true)
367
+ end
368
+
369
+ context "when given random: rng" do
370
+ let(:rng) { SecureRandom }
371
+
372
+ it "must call the Array#shuffle with random: rng" do
373
+ expect_any_instance_of(Array).to receive(:shuffle).with(random: rng).and_return(subject.bytes.shuffle(random: rng))
374
+
375
+ subject.random_distinct_bytes(n, random: rng)
376
+ end
377
+ end
378
+
379
+ context "when given a Range of lengths" do
380
+ let(:lengths) { 5..10 }
126
381
 
127
- string.length.should be_between(5, 10)
128
- string.chars.all? { |b| @char_set.include_char?(b) }.should == true
382
+ it "should return a random Array of unique chars with a varying length" do
383
+ random_chars = subject.random_distinct_chars(lengths)
384
+
385
+ expect(random_chars.uniq).to be == random_chars
386
+ expect(random_chars.length).to be_between(lengths.begin, lengths.end)
387
+ expect(random_chars.all? { |c| subject.include_char?(c) }).to be(true)
388
+ end
389
+
390
+ context "and when given random: rng" do
391
+ let(:rng) { SecureRandom }
392
+
393
+ it "must pass random: to Range#sample" do
394
+ expect(rng).to receive(:rand).and_return(rand(lengths)).at_least(:once)
395
+
396
+ random_bytes = subject.random_bytes(lengths, random: rng)
397
+
398
+ expect(random_bytes.length).to be_between(lengths.begin, lengths.end)
399
+ end
400
+ end
401
+ end
129
402
  end
130
-
131
- it "should return a random Array of unique bytes" do
132
- bytes = @char_set.random_distinct_bytes(10)
133
403
 
134
- bytes.uniq.should == bytes
135
- bytes.all? { |b| @char_set.include?(b) }.should == true
404
+ describe "#==" do
405
+ it "should be able to be compared with another set of chars" do
406
+ expect(subject).to be == described_class['A'..'Z']
407
+ end
136
408
  end
137
409
 
138
- it "should return a random Array of unique chars" do
139
- chars = @char_set.random_distinct_chars(10)
410
+ describe "#|" do
411
+ it "should be able to be unioned with another set of chars" do
412
+ super_set = (subject | described_class['D'])
140
413
 
141
- chars.uniq.should == chars
142
- chars.all? { |c| @char_set.include_char?(c) }.should == true
414
+ expect(super_set).to be_kind_of(described_class)
415
+ expect(super_set).to be == described_class['A'..'Z', 'D']
416
+ end
143
417
  end
144
418
 
145
- it "should return a random Array of unique bytes with a varying length" do
146
- bytes = @char_set.random_distinct_bytes(5..10)
419
+ describe "#-" do
420
+ it "should be able to be removed from another set of chars" do
421
+ sub_set = (subject - described_class['B'])
422
+
423
+ expect(sub_set).to be_kind_of(described_class)
424
+ expect(sub_set).to be_subset(subject)
425
+ end
426
+ end
427
+
428
+ describe "#each_substring_with_index" do
429
+ subject { described_class.new(['A', 'B', 'C']) }
430
+
431
+ let(:string) { "....AAAA....BBBB....CCCC...." }
432
+
433
+ it "must yield each matching substring and index" do
434
+ expect { |b|
435
+ subject.each_substring_with_index(string,&b)
436
+ }.to yield_successive_args(
437
+ ["AAAA", string.index("AAAA")],
438
+ ["BBBB", string.index("BBBB")],
439
+ ["CCCC", string.index("CCCC")]
440
+ )
441
+ end
442
+
443
+ context "when the string begins with a matching substring" do
444
+ let(:string) { "AAAA...." }
147
445
 
148
- bytes.uniq.should == bytes
149
- bytes.length.should be_between(5, 10)
150
- bytes.all? { |b| @char_set.include?(b) }.should == true
446
+ it "must yield the first matching substring" do
447
+ expect(subject.each_substring_with_index(string).first).to eq(
448
+ ["AAAA", 0]
449
+ )
450
+ end
451
+ end
452
+
453
+ context "when the string ends with a matching substring" do
454
+ let(:string) { "AAAA....BBBB....CCCC" }
455
+
456
+ it "must yield the last matching substring" do
457
+ expect(subject.each_substring_with_index(string).to_a.last).to eq(
458
+ ["CCCC", string.rindex("CCCC")]
459
+ )
460
+ end
461
+ end
462
+
463
+ context "when the entire string is a matching substring" do
464
+ let(:string) { "AAAAAAAA" }
465
+
466
+ it "must yield the entire string" do
467
+ expect { |b|
468
+ subject.each_substring_with_index(string,&b)
469
+ }.to yield_successive_args( [string, 0] )
470
+ end
471
+ end
472
+
473
+ context "when the matching substrings are shorter than the min_length" do
474
+ let(:min_length) { 2 }
475
+
476
+ let(:string) { "AA..B...CC.."}
477
+
478
+ it "must ignore the substrings shorter than min_length" do
479
+ expect { |b|
480
+ subject.each_substring_with_index(string, min_length: min_length, &b)
481
+ }.to yield_successive_args(
482
+ ["AA", string.index("AA")],
483
+ ["CC", string.index("CC")]
484
+ )
485
+ end
486
+ end
487
+
488
+ context "when min_length 0" do
489
+ let(:min_length) { 0 }
490
+
491
+ let(:string) { "A.BB..CCC..."}
492
+
493
+ it "must yield all matching substrings, regardless of length" do
494
+ expect { |b|
495
+ subject.each_substring_with_index(string, min_length: min_length, &b)
496
+ }.to yield_successive_args(
497
+ ["A", string.index("A")],
498
+ ["BB", string.index("BB")],
499
+ ["CCC", string.index("CCC")]
500
+ )
501
+ end
502
+ end
151
503
  end
152
504
 
153
- it "should return a random Array of unique chars with a varying length" do
154
- chars = @char_set.random_distinct_chars(5..10)
505
+ describe "#substrings_with_indexes" do
506
+ subject { described_class.new(['A', 'B', 'C']) }
507
+
508
+ let(:string) { "....AAAA....BBBB....CCCC...." }
155
509
 
156
- chars.uniq.should == chars
157
- chars.length.should be_between(5, 10)
158
- chars.all? { |c| @char_set.include_char?(c) }.should == true
510
+ it "must return the Array of substrings and their indexes" do
511
+ expect(subject.substrings_with_indexes(string)).to eq(
512
+ [
513
+ ["AAAA", string.index("AAAA")],
514
+ ["BBBB", string.index("BBBB")],
515
+ ["CCCC", string.index("CCCC")]
516
+ ]
517
+ )
518
+ end
159
519
  end
160
520
 
161
- it "should be able to be compared with another set of chars" do
162
- @char_set.should == described_class['A'..'Z']
521
+ describe "#each_substring(&block : (String) ->)" do
522
+ subject { described_class.new(['A', 'B', 'C']) }
523
+
524
+ let(:string) { "....AAAA....BBBB....CCCC...." }
525
+
526
+ it "must yield each matching substring" do
527
+ expect { |b|
528
+ subject.each_substring(string,&b)
529
+ }.to yield_successive_args(
530
+ "AAAA",
531
+ "BBBB",
532
+ "CCCC"
533
+ )
534
+ end
163
535
  end
164
536
 
165
- it "should be able to be unioned with another set of chars" do
166
- super_set = (@char_set | described_class['D'])
537
+ describe "#substrings" do
538
+ subject { described_class.new(['A', 'B', 'C']) }
539
+
540
+ let(:string) { "....AAAA....BBBB....CCCC...." }
167
541
 
168
- super_set.class.should == described_class
169
- super_set.should == described_class['A'..'Z', 'D']
542
+ it "must return the Array of matching substrings" do
543
+ expect(subject.substrings(string)).to eq(
544
+ [
545
+ "AAAA",
546
+ "BBBB",
547
+ "CCCC"
548
+ ]
549
+ )
550
+ end
170
551
  end
171
552
 
172
- it "should be able to be removed from another set of chars" do
173
- sub_set = (@char_set - described_class['B'])
553
+ describe "#strings_in" do
554
+ subject { described_class.new(['A', 'B', 'C']) }
555
+
556
+ let(:string) { "AAAA....BBBB....CCCC...." }
557
+
558
+ context "when given a block" do
559
+ it "should find sub-strings from a String belonging to the char set" do
560
+ expect { |b|
561
+ subject.strings_in(string,&b)
562
+ }.to yield_successive_args(
563
+ "AAAA",
564
+ "BBBB",
565
+ "CCCC"
566
+ )
567
+ end
568
+
569
+ it "must find sub-strings of a minimum length of 4" do
570
+ expect { |b|
571
+ subject.strings_in("A...BBB...CCCC",&b)
572
+ }.to yield_successive_args("CCCC")
573
+ end
574
+
575
+ context "and when the whole string matches the char set" do
576
+ it "should find one sub-string from a String belonging to the char set" do
577
+ expect { |b|
578
+ subject.strings_in("AAAA",&b)
579
+ }.to yield_successive_args("AAAA")
580
+ end
581
+ end
582
+
583
+ context "when the :length option is given" do
584
+ it "must find sub-strings of the given minimum length" do
585
+ expect { |b|
586
+ subject.strings_in("AAAA...BBBB...CCCCC", :length => 5, &b)
587
+ }.to yield_successive_args("CCCCC")
588
+ end
589
+ end
590
+
591
+ context "and when the block takes two arguments" do
592
+ it "must yield the sub-strings and their indexes" do
593
+ yielded_args = []
594
+
595
+ subject.strings_in(string) do |substring,index|
596
+ yielded_args << [substring, index]
597
+ end
598
+
599
+ expect(yielded_args).to eq(
600
+ [
601
+ ['AAAA', string.index('AAAA')],
602
+ ['BBBB', string.index('BBBB')],
603
+ ['CCCC', string.index('CCCC')]
604
+ ]
605
+ )
606
+ end
607
+ end
608
+ end
174
609
 
175
- sub_set.class.should == described_class
176
- sub_set.should be_subset(@char_set)
610
+ context "when no block is given" do
611
+ it "must return an Array of sub-strings" do
612
+ expect(subject.strings_in(string)).to eq(
613
+ [
614
+ "AAAA",
615
+ "BBBB",
616
+ "CCCC"
617
+ ]
618
+ )
619
+ end
620
+
621
+ context "when given the :offset option" do
622
+ it "must return a Hash of the substrings and their indexes" do
623
+ expect(subject.strings_in(string, :offsets => true)).to eq(
624
+ {
625
+ "AAAA" => string.index("AAAA"),
626
+ "BBBB" => string.index("BBBB"),
627
+ "CCCC" => string.index("CCCC")
628
+ }
629
+ )
630
+ end
631
+ end
632
+ end
177
633
  end
178
634
 
179
- it "should find one sub-string from a String belonging to the char set" do
180
- @char_set.strings_in("AAAA").should == ["AAAA"]
635
+ describe "#each_string" do
636
+ let(:length) { 2 }
637
+
638
+ let(:expected_strings) do
639
+ Chars::StringEnumerator.new(subject,length).to_a
640
+ end
641
+
642
+ context "when a block is given" do
643
+ it "must enumerate through the strings belonging to the character set of the desired length" do
644
+ expect { |b|
645
+ subject.each_string_of_length(length,&b)
646
+ }.to yield_successive_args(*expected_strings)
647
+ end
648
+
649
+ context "when given a Range of lengths" do
650
+ let(:length) { 1..2 }
651
+
652
+ let(:expected_strings) do
653
+ Chars::StringEnumerator.new(subject,1).to_a +
654
+ Chars::StringEnumerator.new(subject,2).to_a
655
+ end
656
+
657
+ it "must yield strings of lengths in the Range of lengths" do
658
+ expect { |b|
659
+ subject.each_string_of_length(length,&b)
660
+ }.to yield_successive_args(*expected_strings)
661
+ end
662
+ end
663
+
664
+ context "when given an Array of lengths" do
665
+ let(:length) { [1,2] }
666
+
667
+ let(:expected_strings) do
668
+ Chars::StringEnumerator.new(subject,1).to_a +
669
+ Chars::StringEnumerator.new(subject,2).to_a
670
+ end
671
+
672
+ it "must yield strings of lengths in the Range of lengths" do
673
+ expect { |b|
674
+ subject.each_string_of_length(length,&b)
675
+ }.to yield_successive_args(*expected_strings)
676
+ end
677
+ end
678
+ end
679
+
680
+ context "when no block is given" do
681
+ it "must return an Enumerator" do
682
+ expect(subject.each_string_of_length(length)).to be_kind_of(Enumerator)
683
+ expect(subject.each_string_of_length(length).to_a).to eq(expected_strings)
684
+ end
685
+ end
181
686
  end
182
687
 
183
- it "should find sub-strings from a String belonging to the char set" do
184
- @char_set.strings_in("AAAA!B!CCCCCC").should == [
185
- "AAAA",
186
- "CCCCCC"
187
- ]
688
+ describe "#strings_of_length" do
689
+ let(:length) { 2 }
690
+
691
+ let(:expected_strings) do
692
+ Chars::StringEnumerator.new(subject,length).to_a
693
+ end
694
+
695
+ it "must return an Enumerator" do
696
+ expect(subject.strings_of_length(length)).to be_kind_of(Enumerator)
697
+ expect(subject.strings_of_length(length).to_a).to eq(expected_strings)
698
+ end
188
699
  end
189
700
 
190
- it "should determine if a String is made up of the characters from the char set" do
191
- @char_set.should === "AABCBAA"
192
- @char_set.should_not === "AA!!EE"
701
+ describe "#===" do
702
+ it "should determine if a String is made up of the characters from the char set" do
703
+ expect(subject).to be === "AABCBAA"
704
+ expect(subject).to_not be === "AA!!EE"
705
+ end
193
706
  end
194
707
  end