rambling-trie 2.3.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -0
  3. data/LICENSE +1 -1
  4. data/README.md +25 -11
  5. data/lib/rambling/trie/comparable.rb +2 -2
  6. data/lib/rambling/trie/compressible.rb +3 -3
  7. data/lib/rambling/trie/configuration/properties.rb +10 -9
  8. data/lib/rambling/trie/configuration/provider_collection.rb +15 -13
  9. data/lib/rambling/trie/container.rb +17 -19
  10. data/lib/rambling/trie/enumerable.rb +3 -0
  11. data/lib/rambling/trie/nodes/compressed.rb +3 -3
  12. data/lib/rambling/trie/nodes/node.rb +14 -14
  13. data/lib/rambling/trie/nodes/raw.rb +2 -2
  14. data/lib/rambling/trie/readers/plain_text.rb +9 -4
  15. data/lib/rambling/trie/readers/reader.rb +21 -0
  16. data/lib/rambling/trie/readers.rb +1 -1
  17. data/lib/rambling/trie/serializers/file.rb +1 -1
  18. data/lib/rambling/trie/serializers/marshal.rb +3 -2
  19. data/lib/rambling/trie/serializers/serializer.rb +27 -0
  20. data/lib/rambling/trie/serializers/yaml.rb +3 -2
  21. data/lib/rambling/trie/serializers/zip.rb +9 -5
  22. data/lib/rambling/trie/serializers.rb +1 -1
  23. data/lib/rambling/trie/stringifyable.rb +1 -1
  24. data/lib/rambling/trie/version.rb +1 -1
  25. data/lib/rambling/trie.rb +11 -9
  26. data/rambling-trie.gemspec +5 -1
  27. data/spec/integration/rambling/trie_spec.rb +13 -16
  28. data/spec/lib/rambling/trie/comparable_spec.rb +29 -39
  29. data/spec/lib/rambling/trie/compressor_spec.rb +17 -14
  30. data/spec/lib/rambling/trie/configuration/properties_spec.rb +25 -7
  31. data/spec/lib/rambling/trie/configuration/provider_collection_spec.rb +42 -14
  32. data/spec/lib/rambling/trie/container_spec.rb +200 -325
  33. data/spec/lib/rambling/trie/enumerable_spec.rb +18 -10
  34. data/spec/lib/rambling/trie/inspectable_spec.rb +9 -3
  35. data/spec/lib/rambling/trie/nodes/node_spec.rb +1 -1
  36. data/spec/lib/rambling/trie/nodes/raw_spec.rb +26 -23
  37. data/spec/lib/rambling/trie/readers/plain_text_spec.rb +11 -1
  38. data/spec/lib/rambling/trie/readers/reader_spec.rb +14 -0
  39. data/spec/lib/rambling/trie/serializers/file_spec.rb +1 -3
  40. data/spec/lib/rambling/trie/serializers/marshal_spec.rb +1 -3
  41. data/spec/lib/rambling/trie/serializers/serializer_spec.rb +21 -0
  42. data/spec/lib/rambling/trie/serializers/yaml_spec.rb +1 -3
  43. data/spec/lib/rambling/trie/serializers/zip_spec.rb +24 -16
  44. data/spec/lib/rambling/trie/stringifyable_spec.rb +17 -13
  45. data/spec/lib/rambling/trie_spec.rb +106 -44
  46. data/spec/spec_helper.rb +15 -8
  47. data/spec/support/shared_examples/a_compressible_trie.rb +9 -3
  48. data/spec/support/shared_examples/a_container_partial_word.rb +17 -0
  49. data/spec/support/shared_examples/a_container_scan.rb +14 -0
  50. data/spec/support/shared_examples/a_container_word.rb +43 -0
  51. data/spec/support/shared_examples/a_container_words_within.rb +44 -0
  52. data/spec/support/shared_examples/a_serializable_trie.rb +4 -8
  53. data/spec/support/shared_examples/a_serializer.rb +36 -13
  54. data/spec/support/shared_examples/a_trie_data_structure.rb +24 -10
  55. data/spec/support/shared_examples/a_trie_node.rb +19 -12
  56. data/spec/support/shared_examples/a_trie_node_implementation.rb +40 -43
  57. metadata +19 -3
@@ -3,7 +3,8 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Rambling::Trie::Container do
6
- let(:container) { Rambling::Trie::Container.new root, compressor }
6
+ subject(:container) { described_class.new root, compressor }
7
+
7
8
  let(:compressor) { Rambling::Trie::Compressor.new }
8
9
  let(:root) { Rambling::Trie::Nodes::Raw.new }
9
10
 
@@ -16,7 +17,7 @@ describe Rambling::Trie::Container do
16
17
  it 'yields the container' do
17
18
  yielded = nil
18
19
 
19
- container = Rambling::Trie::Container.new root, compressor do |c|
20
+ container = described_class.new root, compressor do |c|
20
21
  yielded = c
21
22
  end
22
23
 
@@ -26,15 +27,18 @@ describe Rambling::Trie::Container do
26
27
  end
27
28
 
28
29
  describe '#add' do
30
+ # rubocop:disable RSpec/MultipleExpectations
29
31
  it 'adds the word to the root node' do
30
32
  add_word container, 'hello'
31
33
 
32
34
  expect(root.children.size).to eq 1
33
35
  expect(root.to_a).to eq %w(hello)
34
36
  end
37
+ # rubocop:enable RSpec/MultipleExpectations
35
38
  end
36
39
 
37
40
  describe '#concat' do
41
+ # rubocop:disable RSpec/MultipleExpectations
38
42
  it 'adds all the words to the root node' do
39
43
  container.concat %w(other words)
40
44
 
@@ -48,42 +52,7 @@ describe Rambling::Trie::Container do
48
52
  expect(nodes.first.letter).to eq :o
49
53
  expect(nodes.last.letter).to eq :w
50
54
  end
51
- end
52
-
53
- describe '#compress!' do
54
- let(:node) { Rambling::Trie::Nodes::Compressed.new }
55
-
56
- before do
57
- allow(compressor).to receive(:compress).and_return node
58
-
59
- add_word root, 'yes'
60
- node[:yes] = Rambling::Trie::Nodes::Compressed.new
61
- end
62
-
63
- it 'compresses the trie using the compressor' do
64
- container.compress!
65
-
66
- expect(compressor).to have_received(:compress).with root
67
- end
68
-
69
- it 'changes to the root returned by the compressor' do
70
- container.compress!
71
-
72
- expect(container.root).not_to eq root
73
- expect(container.root).to eq node
74
- end
75
-
76
- it 'returns itself' do
77
- expect(container.compress!).to eq container
78
- end
79
-
80
- it 'does not compress multiple times' do
81
- container.compress!
82
- allow(node).to receive(:compressed?).and_return(true)
83
-
84
- container.compress!
85
- expect(compressor).to have_received(:compress).once
86
- end
55
+ # rubocop:enable RSpec/MultipleExpectations
87
56
  end
88
57
 
89
58
  describe '#compress' do
@@ -102,12 +71,14 @@ describe Rambling::Trie::Container do
102
71
  expect(compressor).to have_received(:compress).with root
103
72
  end
104
73
 
74
+ # rubocop:disable RSpec/MultipleExpectations
105
75
  it 'returns a container with the new root' do
106
76
  new_container = container.compress
107
77
 
108
78
  expect(new_container.root).not_to eq root
109
79
  expect(new_container.root).to eq node
110
80
  end
81
+ # rubocop:enable RSpec/MultipleExpectations
111
82
 
112
83
  it 'returns a new container' do
113
84
  expect(container.compress).not_to eq container
@@ -128,153 +99,53 @@ describe Rambling::Trie::Container do
128
99
  end
129
100
  end
130
101
 
131
- describe '#word?' do
132
- let(:root) do
133
- double :root,
134
- compressed?: compressed,
135
- word?: nil
136
- end
102
+ describe '#compress!' do
103
+ let(:node) { Rambling::Trie::Nodes::Compressed.new }
137
104
 
138
- context 'for an uncompressed root' do
139
- let(:compressed) { true }
105
+ context 'with a mocked result' do
106
+ before do
107
+ allow(compressor).to receive(:compress).and_return node
140
108
 
141
- it 'calls the root with the word characters' do
142
- container.word? 'words'
143
- expect(root).to have_received(:word?).with %w(w o r d s)
109
+ add_word root, 'yes'
110
+ node[:yes] = Rambling::Trie::Nodes::Compressed.new
144
111
  end
145
- end
146
112
 
147
- context 'for a compressed root' do
148
- let(:compressed) { false }
113
+ it 'compresses the trie using the compressor' do
114
+ container.compress!
149
115
 
150
- it 'calls the root with the full word' do
151
- container.word? 'words'
152
- expect(root).to have_received(:word?).with %w(w o r d s)
116
+ expect(compressor).to have_received(:compress).with root
153
117
  end
154
- end
155
- end
156
118
 
157
- describe '#partial_word?' do
158
- let(:root) do
159
- double :root,
160
- compressed?: compressed,
161
- partial_word?: nil
162
- end
163
-
164
- context 'for an uncompressed root' do
165
- let(:compressed) { true }
119
+ # rubocop:disable RSpec/MultipleExpectations
120
+ it 'changes to the root returned by the compressor' do
121
+ container.compress!
166
122
 
167
- it 'calls the root with the word characters' do
168
- container.partial_word? 'words'
169
- expect(root).to have_received(:partial_word?).with %w(w o r d s)
123
+ expect(container.root).not_to eq root
124
+ expect(container.root).to eq node
170
125
  end
171
- end
172
-
173
- context 'for a compressed root' do
174
- let(:compressed) { false }
126
+ # rubocop:enable RSpec/MultipleExpectations
175
127
 
176
- it 'calls the root with the word characters' do
177
- container.partial_word? 'words'
178
- expect(root).to have_received(:partial_word?).with %w(w o r d s)
128
+ it 'returns itself' do
129
+ expect(container.compress!).to eq container
179
130
  end
180
- end
181
- end
182
-
183
- describe 'delegates and aliases' do
184
- before do
185
- allow(root).to receive_messages(
186
- :[] => nil,
187
- add: nil,
188
- as_word: nil,
189
- children: nil,
190
- children_tree: nil,
191
- compressed?: nil,
192
- each: nil,
193
- key?: nil,
194
- inspect: nil,
195
- letter: nil,
196
- parent: nil,
197
- partial_word?: nil,
198
- scan: nil,
199
- size: nil,
200
- to_s: nil,
201
- word?: nil,
202
- )
203
- end
204
131
 
205
- it 'aliases `#include?` to `#word?`' do
206
- container.include? 'words'
207
- expect(root).to have_received(:word?).with %w(w o r d s)
208
- end
209
-
210
- it 'aliases `#match?` to `#partial_word?`' do
211
- container.match? 'words'
212
- expect(root).to have_received(:partial_word?).with %w(w o r d s)
213
- end
214
-
215
- it 'aliases `#words` to `#scan`' do
216
- container.words 'hig'
217
- expect(root).to have_received(:scan).with %w(h i g)
218
- end
219
-
220
- it 'aliases `#<<` to `#add`' do
221
- container << 'words'
222
- expect(root).to have_received(:add).with %i(s d r o w)
223
- end
224
-
225
- it 'delegates `#[]` to the root node' do
226
- container[:yep]
227
- expect(root).to have_received(:[]).with :yep
228
- end
229
-
230
- it 'delegates `#children` to the root node' do
231
- container.children
232
- expect(root).to have_received :children
233
- end
234
-
235
- it 'delegates `#children_tree` to the root node' do
236
- container.children_tree
237
- expect(root).to have_received :children_tree
238
- end
239
-
240
- it 'delegates `#compressed?` to the root node' do
241
- container.compressed?
242
- expect(root).to have_received :compressed?
243
- end
244
-
245
- it 'delegates `#key?` to the root node' do
246
- container.key? :yup
247
- expect(root).to have_received(:key?).with :yup
248
- end
249
-
250
- it 'aliases `#has_key?` to `#key?`' do
251
- container.has_key? :yup
252
- expect(root).to have_received(:key?).with :yup
253
- end
254
-
255
- it 'aliases `#has_letter?` to `#has_key?`' do
256
- container.has_letter? :yup
257
- expect(root).to have_received(:key?).with :yup
258
- end
259
-
260
- it 'delegates `#inspect` to the root node' do
261
- container.inspect
262
- expect(root).to have_received :inspect
263
- end
132
+ it 'does not compress multiple times' do
133
+ container.compress!
134
+ allow(node).to receive(:compressed?).and_return(true)
264
135
 
265
- it 'delegates `#size` to the root node' do
266
- container.size
267
- expect(root).to have_received :size
268
- end
269
- end
136
+ container.compress!
137
+ expect(compressor).to have_received(:compress).once
138
+ end
270
139
 
271
- describe '#compress!' do
272
- it 'gets a new root from the compressor' do
273
- container.compress!
140
+ # rubocop:disable RSpec/MultipleExpectations
141
+ it 'gets a new root from the compressor' do
142
+ container.compress!
274
143
 
275
- expect(container.root).not_to be root
276
- expect(container.root).to be_compressed
277
- expect(root).not_to be_compressed
144
+ expect(container.root).not_to be root
145
+ expect(container.root).to be_compressed
146
+ expect(root).not_to be_compressed
147
+ end
148
+ # rubocop:enable RSpec/MultipleExpectations
278
149
  end
279
150
 
280
151
  it 'generates a new root with the words from the passed root' do
@@ -283,9 +154,7 @@ describe Rambling::Trie::Container do
283
154
  add_words container, words
284
155
  container.compress!
285
156
 
286
- words.each do |word|
287
- expect(container).to include word
288
- end
157
+ words.each { |word| expect(container).to include word }
289
158
  end
290
159
 
291
160
  describe 'and trying to add a word' do
@@ -301,138 +170,91 @@ describe Rambling::Trie::Container do
301
170
  end
302
171
 
303
172
  describe '#word?' do
304
- context 'word is contained' do
305
- before do
306
- add_words container, %w(hello high)
307
- end
173
+ it_behaves_like 'a propagating node' do
174
+ let(:method) { :word? }
175
+ end
308
176
 
309
- it 'matches the whole word' do
310
- expect(container.word? 'hello').to be true
311
- expect(container.word? 'high').to be true
312
- end
177
+ context 'when word is contained' do
178
+ before { add_words container, %w(hello high) }
313
179
 
314
- context 'and the root has been compressed' do
315
- before do
316
- container.compress!
317
- end
180
+ it_behaves_like 'a matching container#word'
318
181
 
319
- it 'matches the whole word' do
320
- expect(container.word? 'hello').to be true
321
- expect(container.word? 'high').to be true
322
- end
182
+ context 'with compressed root' do
183
+ before { container.compress! }
184
+
185
+ it_behaves_like 'a matching container#word'
323
186
  end
324
187
  end
325
188
 
326
- context 'word is not contained' do
327
- before do
328
- add_word container, 'hello'
329
- end
189
+ context 'when word is not contained' do
190
+ before { add_word container, 'hello' }
330
191
 
331
- it 'does not match the whole word' do
332
- expect(container.word? 'halt').to be false
333
- expect(container.word? 'al').to be false
334
- end
192
+ it_behaves_like 'a non-matching container#word'
335
193
 
336
- context 'and the root has been compressed' do
337
- before do
338
- container.compress!
339
- end
194
+ context 'with compressed root' do
195
+ before { container.compress! }
340
196
 
341
- it 'does not match the whole word' do
342
- expect(container.word? 'halt').to be false
343
- expect(container.word? 'al').to be false
344
- end
197
+ it_behaves_like 'a non-matching container#word'
345
198
  end
346
199
  end
347
200
  end
348
201
 
349
202
  describe '#partial_word?' do
350
- context 'word is contained' do
351
- before do
352
- add_words container, %w(hello high)
203
+ context 'with underlying node' do
204
+ it_behaves_like 'a propagating node' do
205
+ let(:method) { :partial_word? }
353
206
  end
207
+ end
354
208
 
355
- it 'matches part of the word' do
356
- expect(container.partial_word? 'hell').to be true
357
- expect(container.partial_word? 'hig').to be true
358
- end
209
+ context 'when word is contained' do
210
+ before { add_words container, %w(hello high) }
359
211
 
360
- context 'and the root has been compressed' do
361
- before do
362
- container.compress!
363
- end
212
+ it_behaves_like 'a matching container#partial_word'
364
213
 
365
- it 'matches part of the word' do
366
- expect(container.partial_word? 'h').to be true
367
- expect(container.partial_word? 'he').to be true
368
- expect(container.partial_word? 'hell').to be true
369
- expect(container.partial_word? 'hello').to be true
370
- expect(container.partial_word? 'hi').to be true
371
- expect(container.partial_word? 'hig').to be true
372
- expect(container.partial_word? 'high').to be true
373
- end
374
- end
375
- end
214
+ context 'with compressed root' do
215
+ before { container.compress! }
376
216
 
377
- shared_examples_for 'a non matching tree' do
378
- it 'does not match any part of the word' do
379
- %w(ha hal al).each do |word|
380
- expect(container.partial_word? word).to be false
381
- end
217
+ it_behaves_like 'a matching container#partial_word'
382
218
  end
383
219
  end
384
220
 
385
- context 'word is not contained' do
386
- before do
387
- add_word container, 'hello'
388
- end
221
+ context 'when word is not contained' do
222
+ before { add_word container, 'hello' }
389
223
 
390
- context 'and the root is uncompressed' do
391
- it_behaves_like 'a non matching tree'
392
- end
224
+ it_behaves_like 'a non-matching container#partial_word'
393
225
 
394
- context 'and the root has been compressed' do
395
- it_behaves_like 'a non matching tree'
226
+ context 'with compressed root' do
227
+ before { container.compress! }
228
+
229
+ it_behaves_like 'a non-matching container#partial_word'
396
230
  end
397
231
  end
398
232
  end
399
233
 
400
234
  describe '#scan' do
401
- context 'words that match are not contained' do
235
+ context 'when words that match are contained' do
402
236
  before do
403
237
  add_words container, %w(hi hello high hell highlight histerical)
404
238
  end
405
239
 
406
- it 'returns an array with the words that match' do
407
- expect(container.scan 'hi').to eq %w(hi high highlight histerical)
408
- expect(container.scan 'hig').to eq %w(high highlight)
409
- end
240
+ it_behaves_like 'a matching container#scan'
410
241
 
411
- context 'and the root has been compressed' do
412
- before do
413
- container.compress!
414
- end
242
+ context 'with compressed root' do
243
+ before { container.compress! }
415
244
 
416
- it 'returns an array with the words that match' do
417
- expect(container.scan 'hi').to eq %w(hi high highlight histerical)
418
- expect(container.scan 'hig').to eq %w(high highlight)
419
- end
245
+ it_behaves_like 'a matching container#scan'
420
246
  end
421
247
  end
422
248
 
423
- context 'words that match are not contained' do
424
- before do
425
- add_word container, 'hello'
426
- end
249
+ context 'when words that match are not contained' do
250
+ before { add_word container, 'hello' }
427
251
 
428
252
  it 'returns an empty array' do
429
253
  expect(container.scan 'hi').to eq %w()
430
254
  end
431
255
 
432
- context 'and the root has been compressed' do
433
- before do
434
- container.compress!
435
- end
256
+ context 'with compressed root' do
257
+ before { container.compress! }
436
258
 
437
259
  it 'returns an empty array' do
438
260
  expect(container.scan 'hi').to eq %w()
@@ -442,19 +264,15 @@ describe Rambling::Trie::Container do
442
264
  end
443
265
 
444
266
  describe '#words_within' do
445
- before do
446
- add_words container, %w(one word and other words)
447
- end
267
+ before { add_words container, %w(one word and other words) }
448
268
 
449
- context 'phrase does not contain any words' do
269
+ context 'when phrase does not contain any words' do
450
270
  it 'returns an empty array' do
451
271
  expect(container.words_within 'xyz').to match_array []
452
272
  end
453
273
 
454
- context 'and the node is compressed' do
455
- before do
456
- container.compress!
457
- end
274
+ context 'with compressed node' do
275
+ before { container.compress! }
458
276
 
459
277
  it 'returns an empty array' do
460
278
  expect(container.words_within 'xyz').to match_array []
@@ -462,33 +280,23 @@ describe Rambling::Trie::Container do
462
280
  end
463
281
  end
464
282
 
465
- context 'phrase contains one word at the start of the phrase' do
466
- it 'returns an array with the word found in the phrase' do
467
- expect(container.words_within 'word').to match_array %w(word)
468
- expect(container.words_within 'wordxyz').to match_array %w(word)
469
- end
283
+ context 'when phrase contains one word at the start of the phrase' do
284
+ it_behaves_like 'a matching container#words_within'
470
285
 
471
- context 'and the node is compressed' do
472
- before do
473
- container.compress!
474
- end
286
+ context 'with compressed node' do
287
+ before { container.compress! }
475
288
 
476
- it 'returns an array with the word found in the phrase' do
477
- expect(container.words_within 'word').to match_array %w(word)
478
- expect(container.words_within 'wordxyz').to match_array %w(word)
479
- end
289
+ it_behaves_like 'a matching container#words_within'
480
290
  end
481
291
  end
482
292
 
483
- context 'phrase contains one word at the end of the phrase' do
293
+ context 'when phrase contains one word at the end of the phrase' do
484
294
  it 'returns an array with the word found in the phrase' do
485
295
  expect(container.words_within 'xyz word').to match_array %w(word)
486
296
  end
487
297
 
488
- context 'and the node is compressed' do
489
- before do
490
- container.compress!
491
- end
298
+ context 'with compressed node' do
299
+ before { container.compress! }
492
300
 
493
301
  it 'returns an array with the word found in the phrase' do
494
302
  expect(container.words_within 'xyz word').to match_array %w(word)
@@ -496,48 +304,33 @@ describe Rambling::Trie::Container do
496
304
  end
497
305
  end
498
306
 
499
- context 'phrase contains a few words' do
500
- it 'returns an array with all words found in the phrase' do
501
- expect(container.words_within 'xyzword otherzxyone')
502
- .to match_array %w(word other one)
503
- end
307
+ context 'when phrase contains a few words' do
308
+ it_behaves_like 'a non-matching container#words_within'
504
309
 
505
- context 'and the node is compressed' do
506
- before do
507
- container.compress!
508
- end
310
+ context 'with compressed node' do
311
+ before { container.compress! }
509
312
 
510
- it 'returns an array with all words found in the phrase' do
511
- expect(container.words_within 'xyzword otherzxyone')
512
- .to match_array %w(word other one)
513
- end
313
+ it_behaves_like 'a non-matching container#words_within'
514
314
  end
515
315
  end
516
316
  end
517
317
 
518
318
  describe '#words_within?' do
519
- before do
520
- add_words container, %w(one word and other words)
521
- end
319
+ before { add_words container, %w(one word and other words) }
522
320
 
523
- context 'phrase does not contain any words' do
524
- it 'returns false' do
525
- expect(container.words_within? 'xyz').to be false
526
- end
527
- end
321
+ it_behaves_like 'a matching container#words_within?'
528
322
 
529
- context 'phrase contains any word' do
530
- it 'returns true' do
531
- expect(container.words_within? 'xyz words').to be true
532
- expect(container.words_within? 'xyzone word').to be true
533
- end
323
+ context 'with compressed node' do
324
+ before { container.compress! }
325
+
326
+ it_behaves_like 'a non-matching container#words_within?'
534
327
  end
535
328
  end
536
329
 
537
330
  describe '#==' do
538
331
  context 'when the root nodes are the same' do
539
332
  let(:other_container) do
540
- Rambling::Trie::Container.new container.root, compressor
333
+ described_class.new container.root, compressor
541
334
  end
542
335
 
543
336
  it 'returns true' do
@@ -548,12 +341,10 @@ describe Rambling::Trie::Container do
548
341
  context 'when the root nodes are not the same' do
549
342
  let(:other_root) { Rambling::Trie::Nodes::Raw.new }
550
343
  let(:other_container) do
551
- Rambling::Trie::Container.new other_root, compressor
344
+ described_class.new other_root, compressor
552
345
  end
553
346
 
554
- before do
555
- add_word other_container, 'hola'
556
- end
347
+ before { add_word other_container, 'hola' }
557
348
 
558
349
  it 'returns false' do
559
350
  expect(container).not_to eq other_container
@@ -562,9 +353,7 @@ describe Rambling::Trie::Container do
562
353
  end
563
354
 
564
355
  describe '#each' do
565
- before do
566
- add_words container, %w(yes no why)
567
- end
356
+ before { add_words container, %w(yes no why) }
568
357
 
569
358
  it 'returns an enumerator when no block is given' do
570
359
  expect(container.each).to be_instance_of Enumerator
@@ -576,9 +365,7 @@ describe Rambling::Trie::Container do
576
365
  end
577
366
 
578
367
  describe '#inspect' do
579
- before do
580
- add_words container, %w(a few words hello hell)
581
- end
368
+ before { add_words container, %w(a few words hello hell) }
582
369
 
583
370
  it 'returns the container class name plus the root inspection' do
584
371
  expect(container.inspect).to eq one_line <<~CONTAINER
@@ -588,4 +375,92 @@ describe Rambling::Trie::Container do
588
375
  CONTAINER
589
376
  end
590
377
  end
378
+
379
+ describe 'delegates and aliases' do
380
+ before do
381
+ allow(root).to receive_messages(
382
+ :[] => nil,
383
+ add: nil,
384
+ as_word: nil,
385
+ children: nil,
386
+ children_tree: nil,
387
+ compressed?: nil,
388
+ each: nil,
389
+ key?: nil,
390
+ inspect: nil,
391
+ letter: nil,
392
+ parent: nil,
393
+ partial_word?: nil,
394
+ scan: nil,
395
+ size: nil,
396
+ to_s: nil,
397
+ word?: nil,
398
+ )
399
+ end
400
+
401
+ it 'aliases `#include?` to `#word?`' do
402
+ container.include? 'words'
403
+ expect(root).to have_received(:word?).with %w(w o r d s)
404
+ end
405
+
406
+ it 'aliases `#match?` to `#partial_word?`' do
407
+ container.match? 'words'
408
+ expect(root).to have_received(:partial_word?).with %w(w o r d s)
409
+ end
410
+
411
+ it 'aliases `#words` to `#scan`' do
412
+ container.words 'hig'
413
+ expect(root).to have_received(:scan).with %w(h i g)
414
+ end
415
+
416
+ it 'aliases `#<<` to `#add`' do
417
+ container << 'words'
418
+ expect(root).to have_received(:add).with %i(s d r o w)
419
+ end
420
+
421
+ it 'delegates `#[]` to the root node' do
422
+ container[:yep]
423
+ expect(root).to have_received(:[]).with :yep
424
+ end
425
+
426
+ it 'delegates `#children` to the root node' do
427
+ container.children
428
+ expect(root).to have_received :children
429
+ end
430
+
431
+ it 'delegates `#children_tree` to the root node' do
432
+ container.children_tree
433
+ expect(root).to have_received :children_tree
434
+ end
435
+
436
+ it 'delegates `#compressed?` to the root node' do
437
+ container.compressed?
438
+ expect(root).to have_received :compressed?
439
+ end
440
+
441
+ it 'delegates `#key?` to the root node' do
442
+ container.key? :yup
443
+ expect(root).to have_received(:key?).with :yup
444
+ end
445
+
446
+ it 'aliases `#has_key?` to `#key?`' do
447
+ container.has_key? :yup
448
+ expect(root).to have_received(:key?).with :yup
449
+ end
450
+
451
+ it 'aliases `#has_letter?` to `#has_key?`' do
452
+ container.has_letter? :yup
453
+ expect(root).to have_received(:key?).with :yup
454
+ end
455
+
456
+ it 'delegates `#inspect` to the root node' do
457
+ container.inspect
458
+ expect(root).to have_received :inspect
459
+ end
460
+
461
+ it 'delegates `#size` to the root node' do
462
+ container.size
463
+ expect(root).to have_received :size
464
+ end
465
+ end
591
466
  end