chars 0.2.1 → 0.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,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