chars 0.2.4 → 0.3.1
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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +5 -5
- data/ChangeLog.md +32 -11
- data/Gemfile +2 -0
- data/README.md +64 -13
- data/benchmarks/compare.rb +1 -1
- data/benchmarks/substrings.rb +25 -0
- data/gemspec.yml +1 -0
- data/lib/chars/char_set.rb +291 -56
- data/lib/chars/chars.rb +42 -6
- data/lib/chars/string_enumerator.rb +98 -0
- data/lib/chars/version.rb +1 -1
- data/spec/char_set_spec.rb +415 -31
- data/spec/chars_spec.rb +183 -27
- data/spec/extensions/string_spec.rb +1 -1
- data/spec/string_enumerator_spec.rb +99 -0
- metadata +7 -4
- data/benchmarks/strings_in.rb +0 -23
data/spec/char_set_spec.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'chars/char_set'
|
3
3
|
|
4
|
+
require 'securerandom'
|
5
|
+
|
4
6
|
describe Chars::CharSet do
|
5
7
|
let(:integer_range) { (0x41..0x43) }
|
6
8
|
let(:string_range) { ('A'..'Z') }
|
@@ -91,120 +93,311 @@ describe Chars::CharSet do
|
|
91
93
|
it "should return a random byte" do
|
92
94
|
expect(subject).to include(subject.random_byte)
|
93
95
|
end
|
96
|
+
|
97
|
+
context "when given random: rng" do
|
98
|
+
let(:rng) { SecureRandom }
|
99
|
+
|
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
|
94
106
|
end
|
95
107
|
|
96
108
|
describe "#random_char" do
|
97
109
|
it "should return a random char" do
|
98
110
|
expect(subject.include_char?(subject.random_char)).to be(true)
|
99
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
|
100
122
|
end
|
101
123
|
|
102
124
|
describe "#each_random_byte" do
|
125
|
+
let(:n) { 10 }
|
126
|
+
|
103
127
|
it "should iterate over n random bytes" do
|
104
|
-
expect(subject.each_random_byte(
|
128
|
+
expect(subject.each_random_byte(n).all? { |b|
|
105
129
|
subject.include?(b)
|
106
130
|
}).to be(true)
|
107
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
|
108
144
|
end
|
109
145
|
|
110
146
|
describe "#each_random_char" do
|
147
|
+
let(:n) { 10 }
|
148
|
+
|
111
149
|
it "should iterate over n random chars" do
|
112
150
|
expect(subject.each_random_char(10).all? { |c|
|
113
151
|
subject.include_char?(c)
|
114
152
|
}).to be(true)
|
115
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
|
116
166
|
end
|
117
167
|
|
118
168
|
describe "#random_bytes" do
|
119
|
-
|
120
|
-
|
169
|
+
context "when given an Integer" do
|
170
|
+
let(:n) { 10 }
|
121
171
|
|
122
|
-
|
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
|
123
189
|
end
|
124
190
|
|
125
|
-
context "
|
191
|
+
context "when given a Range of lengths" do
|
192
|
+
let(:lengths) { 5..10 }
|
193
|
+
|
126
194
|
it "should return a random Array of bytes with a varying length" do
|
127
|
-
random_bytes = subject.random_bytes(
|
195
|
+
random_bytes = subject.random_bytes(lengths)
|
128
196
|
|
129
|
-
expect(random_bytes.length).to be_between(
|
197
|
+
expect(random_bytes.length).to be_between(lengths.begin, lengths.end)
|
130
198
|
expect(random_bytes.all? { |b| subject.include?(b) }).to be(true)
|
131
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
|
132
212
|
end
|
133
213
|
end
|
134
214
|
|
135
215
|
describe "#random_chars" do
|
136
|
-
|
137
|
-
|
216
|
+
context "when given an Integer" do
|
217
|
+
let(:n) { 10 }
|
138
218
|
|
139
|
-
|
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
|
232
|
+
|
233
|
+
subject.random_chars(n, random: rng)
|
234
|
+
end
|
235
|
+
end
|
140
236
|
end
|
141
237
|
|
142
|
-
context "
|
238
|
+
context "when given a Range of lengths" do
|
239
|
+
let(:lengths) { 5..10 }
|
240
|
+
|
143
241
|
it "should return a random Array of chars with a varying length" do
|
144
|
-
random_chars = subject.random_chars(
|
242
|
+
random_chars = subject.random_chars(lengths)
|
145
243
|
|
146
|
-
expect(random_chars.length).to be_between(
|
244
|
+
expect(random_chars.length).to be_between(lengths.begin, lengths.end)
|
147
245
|
expect(random_chars.all? { |c| subject.include_char?(c) }).to be(true)
|
148
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
|
149
259
|
end
|
150
260
|
end
|
151
261
|
|
152
262
|
describe "#random_string" do
|
153
|
-
|
154
|
-
|
263
|
+
context "when given an Integer" do
|
264
|
+
let(:n) { 10 }
|
155
265
|
|
156
|
-
|
157
|
-
subject.
|
158
|
-
|
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
|
159
283
|
end
|
160
284
|
|
161
|
-
context "
|
285
|
+
context "when given a Range of lengths" do
|
286
|
+
let(:lengths) { 5..10 }
|
287
|
+
|
162
288
|
it "should return a random String of chars with a varying length" do
|
163
|
-
random_string = subject.random_string(
|
289
|
+
random_string = subject.random_string(lengths)
|
164
290
|
|
165
|
-
expect(random_string.length).to be_between(
|
291
|
+
expect(random_string.length).to be_between(lengths.begin, lengths.end)
|
166
292
|
expect(random_string.chars.all? { |b|
|
167
293
|
subject.include_char?(b)
|
168
294
|
}).to be(true)
|
169
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
|
170
308
|
end
|
171
309
|
end
|
172
310
|
|
173
311
|
describe "#random_distinct_bytes" do
|
174
|
-
|
175
|
-
|
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 }
|
325
|
+
|
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)
|
176
328
|
|
177
|
-
|
178
|
-
|
329
|
+
subject.random_distinct_bytes(n, random: rng)
|
330
|
+
end
|
331
|
+
end
|
179
332
|
end
|
180
333
|
|
181
334
|
context "with a Range of lengths" do
|
335
|
+
let(:lengths) { 5..10 }
|
336
|
+
|
182
337
|
it "should return a random Array of unique bytes with a varying length" do
|
183
|
-
random_bytes = subject.random_distinct_bytes(
|
338
|
+
random_bytes = subject.random_distinct_bytes(lengths)
|
184
339
|
|
185
340
|
expect(random_bytes.uniq).to be == random_bytes
|
186
|
-
expect(random_bytes.length).to be_between(
|
341
|
+
expect(random_bytes.length).to be_between(lengths.begin, lengths.end)
|
187
342
|
expect(random_bytes.all? { |b| subject.include_byte?(b) }).to be(true)
|
188
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
|
189
356
|
end
|
190
357
|
end
|
191
358
|
|
192
359
|
describe "#random_distinct_chars" do
|
360
|
+
let(:n) { 10 }
|
361
|
+
|
193
362
|
it "should return a random Array of unique chars" do
|
194
|
-
random_chars = subject.random_distinct_chars(
|
363
|
+
random_chars = subject.random_distinct_chars(n)
|
195
364
|
|
196
365
|
expect(random_chars.uniq).to be == random_chars
|
197
366
|
expect(random_chars.all? { |c| subject.include_char?(c) }).to be(true)
|
198
367
|
end
|
199
368
|
|
200
|
-
context "
|
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 }
|
381
|
+
|
201
382
|
it "should return a random Array of unique chars with a varying length" do
|
202
|
-
random_chars = subject.random_distinct_chars(
|
383
|
+
random_chars = subject.random_distinct_chars(lengths)
|
203
384
|
|
204
385
|
expect(random_chars.uniq).to be == random_chars
|
205
|
-
expect(random_chars.length).to be_between(
|
386
|
+
expect(random_chars.length).to be_between(lengths.begin, lengths.end)
|
206
387
|
expect(random_chars.all? { |c| subject.include_char?(c) }).to be(true)
|
207
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
|
208
401
|
end
|
209
402
|
end
|
210
403
|
|
@@ -232,6 +425,131 @@ describe Chars::CharSet do
|
|
232
425
|
end
|
233
426
|
end
|
234
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...." }
|
445
|
+
|
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
|
503
|
+
end
|
504
|
+
|
505
|
+
describe "#substrings_with_indexes" do
|
506
|
+
subject { described_class.new(['A', 'B', 'C']) }
|
507
|
+
|
508
|
+
let(:string) { "....AAAA....BBBB....CCCC...." }
|
509
|
+
|
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
|
519
|
+
end
|
520
|
+
|
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
|
535
|
+
end
|
536
|
+
|
537
|
+
describe "#substrings" do
|
538
|
+
subject { described_class.new(['A', 'B', 'C']) }
|
539
|
+
|
540
|
+
let(:string) { "....AAAA....BBBB....CCCC...." }
|
541
|
+
|
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
|
551
|
+
end
|
552
|
+
|
235
553
|
describe "#strings_in" do
|
236
554
|
subject { described_class.new(['A', 'B', 'C']) }
|
237
555
|
|
@@ -314,6 +632,72 @@ describe Chars::CharSet do
|
|
314
632
|
end
|
315
633
|
end
|
316
634
|
|
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
|
686
|
+
end
|
687
|
+
|
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
|
699
|
+
end
|
700
|
+
|
317
701
|
describe "#===" do
|
318
702
|
it "should determine if a String is made up of the characters from the char set" do
|
319
703
|
expect(subject).to be === "AABCBAA"
|