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.
- checksums.yaml +4 -4
- data/Gemfile +4 -0
- data/LICENSE +1 -1
- data/README.md +25 -11
- data/lib/rambling/trie/comparable.rb +2 -2
- data/lib/rambling/trie/compressible.rb +3 -3
- data/lib/rambling/trie/configuration/properties.rb +10 -9
- data/lib/rambling/trie/configuration/provider_collection.rb +15 -13
- data/lib/rambling/trie/container.rb +17 -19
- data/lib/rambling/trie/enumerable.rb +3 -0
- data/lib/rambling/trie/nodes/compressed.rb +3 -3
- data/lib/rambling/trie/nodes/node.rb +14 -14
- data/lib/rambling/trie/nodes/raw.rb +2 -2
- data/lib/rambling/trie/readers/plain_text.rb +9 -4
- data/lib/rambling/trie/readers/reader.rb +21 -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 +3 -2
- data/lib/rambling/trie/serializers/serializer.rb +27 -0
- data/lib/rambling/trie/serializers/yaml.rb +3 -2
- 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 +11 -9
- data/rambling-trie.gemspec +5 -1
- data/spec/integration/rambling/trie_spec.rb +13 -16
- 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 +42 -14
- data/spec/lib/rambling/trie/container_spec.rb +200 -325
- 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/node_spec.rb +1 -1
- data/spec/lib/rambling/trie/nodes/raw_spec.rb +26 -23
- 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 +1 -3
- data/spec/lib/rambling/trie/serializers/marshal_spec.rb +1 -3
- data/spec/lib/rambling/trie/serializers/serializer_spec.rb +21 -0
- data/spec/lib/rambling/trie/serializers/yaml_spec.rb +1 -3
- 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 +106 -44
- data/spec/spec_helper.rb +15 -8
- 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 +4 -8
- data/spec/support/shared_examples/a_serializer.rb +36 -13
- data/spec/support/shared_examples/a_trie_data_structure.rb +24 -10
- data/spec/support/shared_examples/a_trie_node.rb +19 -12
- data/spec/support/shared_examples/a_trie_node_implementation.rb +40 -43
- metadata +19 -3
@@ -15,20 +15,22 @@ describe Rambling::Trie do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'returns a new instance of the trie container' do
|
18
|
-
expect(
|
18
|
+
expect(described_class.create).to eq container
|
19
19
|
end
|
20
20
|
|
21
21
|
context 'with a block' do
|
22
22
|
it 'yields the new container' do
|
23
23
|
yielded = nil
|
24
|
-
|
24
|
+
described_class.create { |trie| yielded = trie }
|
25
25
|
expect(yielded).to eq container
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
context 'with a filepath' do
|
30
30
|
let(:filepath) { 'a test filepath' }
|
31
|
-
let(:reader)
|
31
|
+
let(:reader) do
|
32
|
+
instance_double 'Rambling::Trie::Readers::PlainText', :reader
|
33
|
+
end
|
32
34
|
let(:words) { %w(a couple of test words over here) }
|
33
35
|
|
34
36
|
before do
|
@@ -42,7 +44,7 @@ describe Rambling::Trie do
|
|
42
44
|
end
|
43
45
|
|
44
46
|
it 'loads every word' do
|
45
|
-
|
47
|
+
described_class.create filepath, reader
|
46
48
|
|
47
49
|
words.each do |word|
|
48
50
|
expect(container).to have_received(:<<).with word
|
@@ -52,17 +54,23 @@ describe Rambling::Trie do
|
|
52
54
|
|
53
55
|
context 'without any reader' do
|
54
56
|
let(:filepath) { 'a test filepath' }
|
55
|
-
let(:reader)
|
57
|
+
let(:reader) do
|
58
|
+
instance_double(
|
59
|
+
'Rambling::Trie::Readers::PlainText',
|
60
|
+
:reader,
|
61
|
+
each_word: nil,
|
62
|
+
)
|
63
|
+
end
|
56
64
|
|
57
65
|
before do
|
58
|
-
|
66
|
+
described_class.config do |c|
|
59
67
|
c.readers.add :default, reader
|
60
68
|
c.readers.default = reader
|
61
69
|
end
|
62
70
|
end
|
63
71
|
|
64
72
|
it 'defaults to a plain text reader' do
|
65
|
-
|
73
|
+
described_class.create filepath, nil
|
66
74
|
|
67
75
|
expect(reader).to have_received(:each_word).with filepath
|
68
76
|
end
|
@@ -70,29 +78,53 @@ describe Rambling::Trie do
|
|
70
78
|
end
|
71
79
|
|
72
80
|
describe '.load' do
|
81
|
+
let(:filepath) { 'a path to a file' }
|
73
82
|
let(:root) { Rambling::Trie::Nodes::Raw.new }
|
74
83
|
let(:compressor) { Rambling::Trie::Compressor.new }
|
75
84
|
let(:container) { Rambling::Trie::Container.new root, compressor }
|
76
|
-
let(:serializer)
|
77
|
-
|
85
|
+
let(:serializer) do
|
86
|
+
instance_double(
|
87
|
+
'Rambling::True::Serializers::File',
|
88
|
+
:serializer,
|
89
|
+
load: root,
|
90
|
+
)
|
91
|
+
end
|
78
92
|
|
79
93
|
it 'returns a new container with the loaded root node' do
|
80
|
-
trie =
|
94
|
+
trie = described_class.load filepath, serializer
|
81
95
|
expect(trie).to eq container
|
82
96
|
end
|
83
97
|
|
84
98
|
it 'uses the serializer to load the root node from the given filepath' do
|
85
|
-
|
99
|
+
described_class.load filepath, serializer
|
86
100
|
expect(serializer).to have_received(:load).with filepath
|
87
101
|
end
|
88
102
|
|
89
103
|
context 'without a serializer' do
|
90
|
-
let(:marshal_serializer)
|
91
|
-
|
92
|
-
|
104
|
+
let(:marshal_serializer) do
|
105
|
+
instance_double(
|
106
|
+
'Rambling::Trie::Serializers::Marshal',
|
107
|
+
:marshal_serializer,
|
108
|
+
load: nil,
|
109
|
+
)
|
110
|
+
end
|
111
|
+
let(:default_serializer) do
|
112
|
+
instance_double(
|
113
|
+
'Rambling::Trie::Serializers::File',
|
114
|
+
:default_serializer,
|
115
|
+
load: nil,
|
116
|
+
)
|
117
|
+
end
|
118
|
+
let(:yaml_serializer) do
|
119
|
+
instance_double(
|
120
|
+
'Rambling::Trie::Serializers::Yaml',
|
121
|
+
:yaml_serializer,
|
122
|
+
load: nil,
|
123
|
+
)
|
124
|
+
end
|
93
125
|
|
94
126
|
before do
|
95
|
-
|
127
|
+
described_class.config do |c|
|
96
128
|
c.serializers.add :default, default_serializer
|
97
129
|
c.serializers.add :marshal, marshal_serializer
|
98
130
|
c.serializers.add :yml, yaml_serializer
|
@@ -102,18 +134,21 @@ describe Rambling::Trie do
|
|
102
134
|
end
|
103
135
|
end
|
104
136
|
|
105
|
-
|
106
|
-
|
107
|
-
|
137
|
+
[
|
138
|
+
['.marshal', :marshal_serializer],
|
139
|
+
['.yml', :yaml_serializer],
|
140
|
+
['.yaml', :yaml_serializer],
|
141
|
+
['', :default_serializer],
|
142
|
+
].each do |test_params|
|
143
|
+
extension, serializer = test_params
|
144
|
+
filepath = "test#{extension}"
|
108
145
|
|
109
|
-
|
110
|
-
|
146
|
+
it "uses extension-based serializer (#{filepath} -> #{serializer})" do
|
147
|
+
serializer_instance = public_send serializer
|
111
148
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
Rambling::Trie.load 'test'
|
116
|
-
expect(default_serializer).to have_received(:load).with 'test'
|
149
|
+
described_class.load filepath
|
150
|
+
expect(serializer_instance).to have_received(:load).with filepath
|
151
|
+
end
|
117
152
|
end
|
118
153
|
end
|
119
154
|
|
@@ -121,7 +156,7 @@ describe Rambling::Trie do
|
|
121
156
|
it 'yields the new container' do
|
122
157
|
yielded = nil
|
123
158
|
|
124
|
-
|
159
|
+
described_class.load filepath, serializer do |trie|
|
125
160
|
yielded = trie
|
126
161
|
end
|
127
162
|
|
@@ -132,16 +167,36 @@ describe Rambling::Trie do
|
|
132
167
|
|
133
168
|
describe '.dump' do
|
134
169
|
let(:filename) { 'a trie' }
|
135
|
-
let(:root) {
|
136
|
-
let(:compressor)
|
170
|
+
let(:root) { instance_double 'Rambling::Trie::Serializers::Marshal', :root }
|
171
|
+
let(:compressor) do
|
172
|
+
instance_double 'Rambling::Trie::Serializers::Marshal', :compressor
|
173
|
+
end
|
137
174
|
let(:trie) { Rambling::Trie::Container.new root, compressor }
|
138
175
|
|
139
|
-
let(:marshal_serializer)
|
140
|
-
|
141
|
-
|
176
|
+
let(:marshal_serializer) do
|
177
|
+
instance_double(
|
178
|
+
'Rambling::Trie::Serializers::Marshal',
|
179
|
+
:marshal_serializer,
|
180
|
+
dump: nil,
|
181
|
+
)
|
182
|
+
end
|
183
|
+
let(:yaml_serializer) do
|
184
|
+
instance_double(
|
185
|
+
'Rambling::Trie::Serializers::Yaml',
|
186
|
+
:yaml_serializer,
|
187
|
+
dump: nil,
|
188
|
+
)
|
189
|
+
end
|
190
|
+
let(:default_serializer) do
|
191
|
+
instance_double(
|
192
|
+
'Rambling::Trie::Serializers::File',
|
193
|
+
:default_serializer,
|
194
|
+
dump: nil,
|
195
|
+
)
|
196
|
+
end
|
142
197
|
|
143
198
|
before do
|
144
|
-
|
199
|
+
described_class.config do |c|
|
145
200
|
c.serializers.add :default, default_serializer
|
146
201
|
c.serializers.add :marshal, marshal_serializer
|
147
202
|
c.serializers.add :yml, yaml_serializer
|
@@ -151,32 +206,39 @@ describe Rambling::Trie do
|
|
151
206
|
end
|
152
207
|
|
153
208
|
it 'uses the configured default serializer by default' do
|
154
|
-
|
209
|
+
described_class.dump trie, filename
|
155
210
|
expect(default_serializer).to have_received(:dump).with root, filename
|
156
211
|
end
|
157
212
|
|
158
213
|
context 'when provided with a format' do
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
214
|
+
[
|
215
|
+
['.marshal', :marshal_serializer],
|
216
|
+
['.yml', :yaml_serializer],
|
217
|
+
['', :default_serializer],
|
218
|
+
].each do |test_params|
|
219
|
+
extension, serializer = test_params
|
220
|
+
|
221
|
+
it 'uses the corresponding serializer' do
|
222
|
+
filepath = "#{filename}#{extension}"
|
223
|
+
serializer_instance = public_send serializer
|
224
|
+
|
225
|
+
described_class.dump trie, filepath
|
226
|
+
expect(serializer_instance).to have_received(:dump)
|
227
|
+
.with root, filepath
|
228
|
+
end
|
167
229
|
end
|
168
230
|
end
|
169
231
|
end
|
170
232
|
|
171
233
|
describe '.config' do
|
172
234
|
it 'returns the properties' do
|
173
|
-
expect(
|
235
|
+
expect(described_class.config).to eq described_class.send :properties
|
174
236
|
end
|
175
237
|
|
176
238
|
it 'yields the properties' do
|
177
239
|
yielded = nil
|
178
|
-
|
179
|
-
expect(yielded).to eq
|
240
|
+
described_class.config { |c| yielded = c }
|
241
|
+
expect(yielded).to eq described_class.send :properties
|
180
242
|
end
|
181
243
|
end
|
182
244
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'yaml'
|
3
4
|
require 'simplecov'
|
4
|
-
require 'coveralls'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
Coveralls::SimpleCov::Formatter,
|
9
|
-
]
|
6
|
+
if ENV.key? 'COVERALLS_REPO_TOKEN'
|
7
|
+
require 'coveralls'
|
10
8
|
|
11
|
-
|
12
|
-
|
9
|
+
SimpleCov.formatters = [
|
10
|
+
SimpleCov::Formatter::HTMLFormatter,
|
11
|
+
Coveralls::SimpleCov::Formatter,
|
12
|
+
]
|
13
|
+
|
14
|
+
Coveralls.wear! do
|
15
|
+
add_filter '/spec/'
|
16
|
+
end
|
17
|
+
else
|
18
|
+
SimpleCov.start
|
13
19
|
end
|
14
20
|
|
15
21
|
require 'rspec'
|
@@ -29,7 +35,8 @@ require 'support/config'
|
|
29
35
|
|
30
36
|
%w(
|
31
37
|
a_compressible_trie a_serializable_trie a_serializer a_trie_data_structure
|
32
|
-
a_trie_node a_trie_node_implementation
|
38
|
+
a_trie_node a_trie_node_implementation a_container_scan a_container_word
|
39
|
+
a_container_partial_word a_container_words_within
|
33
40
|
).each do |name|
|
34
41
|
require File.join('support', 'shared_examples', name)
|
35
42
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
shared_examples_for 'a compressible trie' do
|
4
|
-
context '
|
4
|
+
context 'with an uncompressed trie' do
|
5
5
|
it_behaves_like 'a trie data structure'
|
6
6
|
|
7
7
|
it 'does not alter the input' do
|
@@ -16,7 +16,7 @@ shared_examples_for 'a compressible trie' do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
context '
|
19
|
+
context 'with an compressed trie' do
|
20
20
|
let!(:original_root) { trie.root }
|
21
21
|
let!(:original_keys) { original_root.children_tree.keys }
|
22
22
|
let!(:original_values) { original_root.children_tree.values }
|
@@ -31,9 +31,15 @@ shared_examples_for 'a compressible trie' do
|
|
31
31
|
expect(trie).to be_compressed
|
32
32
|
end
|
33
33
|
|
34
|
-
it 'leaves the original root intact' do
|
34
|
+
it 'leaves the original root keys intact' do
|
35
35
|
expect(original_root.children_tree.keys).to eq original_keys
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'leaves the original trie keys intact' do
|
36
39
|
expect(trie.children_tree.keys).to eq original_keys
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'leaves the original trie values intact' do
|
37
43
|
expect(trie.children_tree.values).not_to eq original_values
|
38
44
|
end
|
39
45
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
shared_examples_for 'a matching container#partial_word' do
|
4
|
+
%w(h he hell hello hi hig high).each do |prefix|
|
5
|
+
it 'matches part of the word' do
|
6
|
+
expect(container.partial_word? prefix).to be true
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
shared_examples_for 'a non-matching container#partial_word' do
|
12
|
+
it 'does not match any part of the word' do
|
13
|
+
%w(ha hal al).each do |word|
|
14
|
+
expect(container.partial_word? word).to be false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
shared_examples_for 'a matching container#scan' do
|
4
|
+
[
|
5
|
+
['hi', %w(hi high highlight histerical)],
|
6
|
+
['hig', %w(high highlight)],
|
7
|
+
].each do |test_params|
|
8
|
+
prefix, expected = test_params
|
9
|
+
|
10
|
+
it "returns an array with the words that match '#{prefix}'" do
|
11
|
+
expect(container.scan prefix).to eq expected
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
shared_examples_for 'a matching container#word' do
|
4
|
+
%w(hello high).each do |word|
|
5
|
+
it 'matches the whole word' do
|
6
|
+
expect(container.word? word).to be true
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
shared_examples_for 'a non-matching container#word' do
|
12
|
+
%w(halt al).each do |word|
|
13
|
+
it 'does not match the whole word' do
|
14
|
+
expect(container.word? word).to be false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
shared_examples_for 'a propagating node' do
|
20
|
+
[
|
21
|
+
[true, 'Rambling::Trie::Nodes::Compressed'],
|
22
|
+
[false, 'Rambling::Trie::Nodes::Raw'],
|
23
|
+
].each do |test_params|
|
24
|
+
compressed_value, instance_double_class = test_params
|
25
|
+
|
26
|
+
context "when root has compressed=#{compressed_value}" do
|
27
|
+
let(:root) do
|
28
|
+
instance_double(
|
29
|
+
instance_double_class,
|
30
|
+
:root,
|
31
|
+
compressed?: compressed_value,
|
32
|
+
word?: nil,
|
33
|
+
partial_word?: nil,
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'calls the root with the word characters' do
|
38
|
+
container.public_send method, 'words'
|
39
|
+
expect(root).to have_received(method).with %w(w o r d s)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
shared_examples_for 'a matching container#words_within' do
|
4
|
+
[
|
5
|
+
['word', %w(word)],
|
6
|
+
['wordxyz', %w(word)],
|
7
|
+
].each do |test_params|
|
8
|
+
phrase, expected = test_params
|
9
|
+
|
10
|
+
it "returns an array with the word found in the phrase '#{phrase}'" do
|
11
|
+
expect(container.words_within phrase).to match_array expected
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
shared_examples_for 'a non-matching container#words_within' do
|
17
|
+
it 'returns an array with all words found in the phrase' do
|
18
|
+
expect(container.words_within 'xyzword otherzxyone')
|
19
|
+
.to match_array %w(word other one)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
shared_examples_for 'a matching container#words_within?' do
|
24
|
+
context 'when phrase does not contain any words' do
|
25
|
+
it 'returns false' do
|
26
|
+
expect(container.words_within? 'xyz').to be false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when phrase contains any word' do
|
31
|
+
['xyz words', 'xyzone word'].each do |phrase|
|
32
|
+
it "returns true for '#{phrase}'" do
|
33
|
+
expect(container.words_within? phrase).to be true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
shared_examples_for 'a non-matching container#words_within?' do
|
40
|
+
it 'returns an array with all words found in the phrase' do
|
41
|
+
expect(container.words_within 'xyzword otherzxyone')
|
42
|
+
.to match_array %w(word other one)
|
43
|
+
end
|
44
|
+
end
|
@@ -4,22 +4,18 @@ shared_examples_for 'a serializable trie' do
|
|
4
4
|
let(:tmp_path) { File.join ::SPEC_ROOT, 'tmp' }
|
5
5
|
let(:filepath) { File.join tmp_path, "trie-root.#{format}" }
|
6
6
|
|
7
|
-
context '
|
8
|
-
before
|
9
|
-
Rambling::Trie.dump trie_to_serialize, filepath
|
10
|
-
end
|
7
|
+
context 'with an uncompressed trie' do
|
8
|
+
before { Rambling::Trie.dump trie_to_serialize, filepath }
|
11
9
|
|
12
10
|
it_behaves_like 'a compressible trie' do
|
13
11
|
let(:trie) { Rambling::Trie.load filepath }
|
14
12
|
end
|
15
13
|
end
|
16
14
|
|
17
|
-
context '
|
15
|
+
context 'with an compressed trie' do
|
18
16
|
let(:trie) { Rambling::Trie.load filepath }
|
19
17
|
|
20
|
-
before
|
21
|
-
Rambling::Trie.dump trie_to_serialize.compress!, filepath
|
22
|
-
end
|
18
|
+
before { Rambling::Trie.dump trie_to_serialize.compress!, filepath }
|
23
19
|
|
24
20
|
it_behaves_like 'a trie data structure'
|
25
21
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
shared_examples_for 'a serializer' do
|
4
|
+
subject(:serializer) { described_class.new }
|
5
|
+
|
4
6
|
let(:trie) { Rambling::Trie.create }
|
5
7
|
let(:tmp_path) { File.join ::SPEC_ROOT, 'tmp' }
|
6
8
|
let(:filepath) { File.join tmp_path, "trie-root.#{format}" }
|
@@ -12,26 +14,47 @@ shared_examples_for 'a serializer' do
|
|
12
14
|
end
|
13
15
|
|
14
16
|
describe '#dump' do
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
[true, false].each do |compress_value|
|
18
|
+
context "with compressed=#{compress_value} trie" do
|
19
|
+
let(:formatted_content) { format_content.call content }
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
before { trie.compress! if compress_value }
|
22
|
+
|
23
|
+
it 'returns the size in bytes of the file dumped' do
|
24
|
+
total_bytes = serializer.dump content, filepath
|
25
|
+
expect(total_bytes).to be_within(20).of formatted_content.size
|
26
|
+
end
|
22
27
|
|
23
|
-
|
24
|
-
|
28
|
+
it 'creates the file with the provided path' do
|
29
|
+
serializer.dump content, filepath
|
30
|
+
expect(File.exist? filepath).to be true
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'converts the contents to the appropriate format' do
|
34
|
+
serializer.dump content, filepath
|
35
|
+
expect(File.size filepath).to be_within(20).of formatted_content.size
|
36
|
+
end
|
37
|
+
end
|
25
38
|
end
|
26
39
|
end
|
27
40
|
|
28
41
|
describe '#load' do
|
29
|
-
|
30
|
-
|
31
|
-
|
42
|
+
[true, false].each do |compress_value|
|
43
|
+
context "with compressed=#{compress_value} trie" do
|
44
|
+
before do
|
45
|
+
trie.compress! if compress_value
|
46
|
+
serializer.dump content, filepath
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'loads the dumped object back into memory' do
|
50
|
+
expect(serializer.load filepath).to eq content
|
51
|
+
end
|
32
52
|
|
33
|
-
|
34
|
-
|
53
|
+
it "loads a compressed=#{compress_value} object" do
|
54
|
+
loaded = serializer.load filepath
|
55
|
+
expect(loaded.compressed?).to be compress_value if :file != format
|
56
|
+
end
|
57
|
+
end
|
35
58
|
end
|
36
59
|
end
|
37
60
|
end
|
@@ -2,25 +2,39 @@
|
|
2
2
|
|
3
3
|
shared_examples_for 'a trie data structure' do
|
4
4
|
it 'contains all the words previously provided' do
|
5
|
-
words.each
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
words.each { |word| expect(trie).to include word }
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'returns true for #word? for all words previously provided' do
|
9
|
+
words.each { |word| expect(trie.word? word).to be true }
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'matches the full word for all words in file' do
|
13
|
+
words.each { |word| expect(trie.match? word).to be true }
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'matches the start of all the words in file' do
|
17
|
+
words.each { |word| expect(trie.match? word[0..-2]).to be true }
|
9
18
|
end
|
10
19
|
|
11
|
-
it '
|
20
|
+
it 'returns true for #partial_word? with full word for all words in file' do
|
21
|
+
words.each { |word| expect(trie.partial_word? word).to be true }
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'returns true for #partial_word? with the start of all words in file' do
|
25
|
+
words.each { |word| expect(trie.partial_word? word[0..-2]).to be true }
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'extracts words within larger strings' do
|
12
29
|
words.each do |word|
|
13
|
-
|
14
|
-
expect(trie.
|
15
|
-
expect(trie.partial_word? word).to be true
|
16
|
-
expect(trie.partial_word? word[0..-2]).to be true
|
30
|
+
phrase = "x#{word}y"
|
31
|
+
expect(trie.words_within phrase).to include word
|
17
32
|
end
|
18
33
|
end
|
19
34
|
|
20
35
|
it 'identifies words within larger strings' do
|
21
36
|
words.each do |word|
|
22
37
|
phrase = "x#{word}y"
|
23
|
-
expect(trie.words_within phrase).to include word
|
24
38
|
expect(trie.words_within? phrase).to be true
|
25
39
|
end
|
26
40
|
end
|