rambling-trie 2.3.0 → 2.4.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.
- checksums.yaml +4 -4
- data/Gemfile +6 -0
- data/LICENSE +1 -1
- data/README.md +68 -29
- data/lib/rambling/trie/comparable.rb +2 -3
- data/lib/rambling/trie/compressible.rb +3 -5
- data/lib/rambling/trie/compressor.rb +2 -12
- data/lib/rambling/trie/configuration/properties.rb +8 -14
- data/lib/rambling/trie/configuration/provider_collection.rb +19 -27
- data/lib/rambling/trie/container.rb +28 -42
- data/lib/rambling/trie/enumerable.rb +4 -2
- data/lib/rambling/trie/nodes/compressed.rb +4 -5
- data/lib/rambling/trie/nodes/missing.rb +1 -2
- data/lib/rambling/trie/nodes/node.rb +21 -34
- data/lib/rambling/trie/nodes/raw.rb +2 -2
- data/lib/rambling/trie/readers/plain_text.rb +10 -6
- data/lib/rambling/trie/readers/reader.rb +19 -0
- data/lib/rambling/trie/readers.rb +1 -1
- data/lib/rambling/trie/serializers/file.rb +1 -1
- data/lib/rambling/trie/serializers/marshal.rb +12 -20
- data/lib/rambling/trie/serializers/serializer.rb +27 -0
- data/lib/rambling/trie/serializers/yaml.rb +10 -16
- data/lib/rambling/trie/serializers/zip.rb +9 -5
- data/lib/rambling/trie/serializers.rb +1 -1
- data/lib/rambling/trie/stringifyable.rb +1 -1
- data/lib/rambling/trie/version.rb +1 -1
- data/lib/rambling/trie.rb +19 -22
- data/rambling-trie.gemspec +9 -5
- data/spec/integration/rambling/trie_spec.rb +49 -20
- data/spec/lib/rambling/trie/comparable_spec.rb +29 -39
- data/spec/lib/rambling/trie/compressor_spec.rb +17 -14
- data/spec/lib/rambling/trie/configuration/properties_spec.rb +25 -7
- data/spec/lib/rambling/trie/configuration/provider_collection_spec.rb +44 -16
- data/spec/lib/rambling/trie/container_spec.rb +202 -327
- data/spec/lib/rambling/trie/enumerable_spec.rb +18 -10
- data/spec/lib/rambling/trie/inspectable_spec.rb +9 -3
- data/spec/lib/rambling/trie/nodes/compressed_spec.rb +6 -0
- data/spec/lib/rambling/trie/nodes/node_spec.rb +1 -1
- data/spec/lib/rambling/trie/nodes/raw_spec.rb +32 -27
- data/spec/lib/rambling/trie/readers/plain_text_spec.rb +11 -1
- data/spec/lib/rambling/trie/readers/reader_spec.rb +14 -0
- data/spec/lib/rambling/trie/serializers/file_spec.rb +2 -4
- data/spec/lib/rambling/trie/serializers/marshal_spec.rb +2 -4
- data/spec/lib/rambling/trie/serializers/serializer_spec.rb +21 -0
- data/spec/lib/rambling/trie/serializers/yaml_spec.rb +2 -4
- data/spec/lib/rambling/trie/serializers/zip_spec.rb +24 -16
- data/spec/lib/rambling/trie/stringifyable_spec.rb +17 -13
- data/spec/lib/rambling/trie_spec.rb +107 -45
- data/spec/spec_helper.rb +16 -9
- data/spec/support/shared_examples/a_compressible_trie.rb +9 -3
- data/spec/support/shared_examples/a_container_partial_word.rb +17 -0
- data/spec/support/shared_examples/a_container_scan.rb +14 -0
- data/spec/support/shared_examples/a_container_word.rb +43 -0
- data/spec/support/shared_examples/a_container_words_within.rb +44 -0
- data/spec/support/shared_examples/a_serializable_trie.rb +5 -9
- data/spec/support/shared_examples/a_serializer.rb +37 -14
- data/spec/support/shared_examples/a_trie_data_structure.rb +24 -10
- data/spec/support/shared_examples/a_trie_node.rb +22 -14
- data/spec/support/shared_examples/a_trie_node_implementation.rb +40 -43
- metadata +25 -9
@@ -3,7 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Rambling::Trie::Container do
|
6
|
-
|
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 =
|
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
|
-
|
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 '#
|
132
|
-
let(:
|
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 '
|
139
|
-
|
105
|
+
context 'with a mocked result' do
|
106
|
+
before do
|
107
|
+
allow(compressor).to receive(:compress).and_return node
|
140
108
|
|
141
|
-
|
142
|
-
|
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
|
-
|
148
|
-
|
113
|
+
it 'compresses the trie using the compressor' do
|
114
|
+
container.compress!
|
149
115
|
|
150
|
-
|
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
|
-
|
158
|
-
|
159
|
-
|
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
|
-
|
168
|
-
container.
|
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
|
-
|
172
|
-
|
173
|
-
context 'for a compressed root' do
|
174
|
-
let(:compressed) { false }
|
126
|
+
# rubocop:enable RSpec/MultipleExpectations
|
175
127
|
|
176
|
-
it '
|
177
|
-
container.
|
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
|
-
|
206
|
-
|
207
|
-
|
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
|
-
|
266
|
-
|
267
|
-
|
268
|
-
end
|
269
|
-
end
|
136
|
+
container.compress!
|
137
|
+
expect(compressor).to have_received(:compress).once
|
138
|
+
end
|
270
139
|
|
271
|
-
|
272
|
-
|
273
|
-
|
140
|
+
# rubocop:disable RSpec/MultipleExpectations
|
141
|
+
it 'gets a new root from the compressor' do
|
142
|
+
container.compress!
|
274
143
|
|
275
|
-
|
276
|
-
|
277
|
-
|
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
|
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
|
-
|
305
|
-
|
306
|
-
|
307
|
-
end
|
173
|
+
it_behaves_like 'a propagating node' do
|
174
|
+
let(:method_name) { :word? }
|
175
|
+
end
|
308
176
|
|
309
|
-
|
310
|
-
|
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
|
-
|
315
|
-
before do
|
316
|
-
container.compress!
|
317
|
-
end
|
180
|
+
it_behaves_like 'a matching container#word'
|
318
181
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
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
|
328
|
-
add_word container, 'hello'
|
329
|
-
end
|
189
|
+
context 'when word is not contained' do
|
190
|
+
before { add_word container, 'hello' }
|
330
191
|
|
331
|
-
|
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 '
|
337
|
-
before
|
338
|
-
container.compress!
|
339
|
-
end
|
194
|
+
context 'with compressed root' do
|
195
|
+
before { container.compress! }
|
340
196
|
|
341
|
-
|
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 '
|
351
|
-
|
352
|
-
|
203
|
+
context 'with underlying node' do
|
204
|
+
it_behaves_like 'a propagating node' do
|
205
|
+
let(:method_name) { :partial_word? }
|
353
206
|
end
|
207
|
+
end
|
354
208
|
|
355
|
-
|
356
|
-
|
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
|
-
|
361
|
-
before do
|
362
|
-
container.compress!
|
363
|
-
end
|
212
|
+
it_behaves_like 'a matching container#partial_word'
|
364
213
|
|
365
|
-
|
366
|
-
|
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
|
-
|
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
|
387
|
-
add_word container, 'hello'
|
388
|
-
end
|
221
|
+
context 'when word is not contained' do
|
222
|
+
before { add_word container, 'hello' }
|
389
223
|
|
390
|
-
|
391
|
-
it_behaves_like 'a non matching tree'
|
392
|
-
end
|
224
|
+
it_behaves_like 'a non-matching container#partial_word'
|
393
225
|
|
394
|
-
context '
|
395
|
-
|
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
|
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
|
-
|
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 '
|
412
|
-
before
|
413
|
-
container.compress!
|
414
|
-
end
|
242
|
+
context 'with compressed root' do
|
243
|
+
before { container.compress! }
|
415
244
|
|
416
|
-
|
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
|
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 '
|
433
|
-
before
|
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
|
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 '
|
455
|
-
before
|
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
|
-
|
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 '
|
472
|
-
before
|
473
|
-
container.compress!
|
474
|
-
end
|
286
|
+
context 'with compressed node' do
|
287
|
+
before { container.compress! }
|
475
288
|
|
476
|
-
|
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 '
|
489
|
-
before
|
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
|
-
|
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 '
|
506
|
-
before
|
507
|
-
container.compress!
|
508
|
-
end
|
310
|
+
context 'with compressed node' do
|
311
|
+
before { container.compress! }
|
509
312
|
|
510
|
-
|
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
|
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
|
-
|
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 '
|
530
|
-
|
531
|
-
|
532
|
-
|
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
|
-
let
|
540
|
-
|
332
|
+
let :other_container do
|
333
|
+
described_class.new container.root, compressor
|
541
334
|
end
|
542
335
|
|
543
336
|
it 'returns true' do
|
@@ -547,13 +340,11 @@ describe Rambling::Trie::Container do
|
|
547
340
|
|
548
341
|
context 'when the root nodes are not the same' do
|
549
342
|
let(:other_root) { Rambling::Trie::Nodes::Raw.new }
|
550
|
-
let
|
551
|
-
|
343
|
+
let :other_container do
|
344
|
+
described_class.new other_root, compressor
|
552
345
|
end
|
553
346
|
|
554
|
-
before
|
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
|
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
|
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
|