rambling-trie 2.3.0 → 2.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.
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