rambling-trie 2.4.0 → 2.5.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 +3 -0
- data/README.md +16 -10
- data/lib/rambling/trie/compressor.rb +2 -0
- data/lib/rambling/trie/configuration/properties.rb +5 -2
- data/lib/rambling/trie/configuration/provider_collection.rb +2 -2
- data/lib/rambling/trie/container.rb +12 -1
- data/lib/rambling/trie/enumerable.rb +1 -1
- data/lib/rambling/trie/nodes/node.rb +4 -4
- data/lib/rambling/trie/nodes/raw.rb +2 -1
- data/lib/rambling/trie/readers/plain_text.rb +1 -1
- data/lib/rambling/trie/serializers/file.rb +1 -3
- data/lib/rambling/trie/serializers/marshal.rb +3 -3
- data/lib/rambling/trie/serializers/yaml.rb +2 -2
- data/lib/rambling/trie/serializers/zip.rb +2 -0
- data/lib/rambling/trie/version.rb +1 -1
- data/lib/rambling/trie.rb +1 -1
- data/rambling-trie.gemspec +3 -9
- metadata +7 -122
- data/spec/assets/test_words.en_US.txt +0 -23
- data/spec/assets/test_words.es_DO.txt +0 -24
- data/spec/integration/rambling/trie_spec.rb +0 -116
- data/spec/lib/rambling/trie/comparable_spec.rb +0 -87
- data/spec/lib/rambling/trie/compressor_spec.rb +0 -111
- data/spec/lib/rambling/trie/configuration/properties_spec.rb +0 -75
- data/spec/lib/rambling/trie/configuration/provider_collection_spec.rb +0 -177
- data/spec/lib/rambling/trie/container_spec.rb +0 -466
- data/spec/lib/rambling/trie/enumerable_spec.rb +0 -50
- data/spec/lib/rambling/trie/inspectable_spec.rb +0 -62
- data/spec/lib/rambling/trie/nodes/compressed_spec.rb +0 -43
- data/spec/lib/rambling/trie/nodes/node_spec.rb +0 -9
- data/spec/lib/rambling/trie/nodes/raw_spec.rb +0 -184
- data/spec/lib/rambling/trie/readers/plain_text_spec.rb +0 -26
- data/spec/lib/rambling/trie/readers/reader_spec.rb +0 -14
- data/spec/lib/rambling/trie/serializers/file_spec.rb +0 -11
- data/spec/lib/rambling/trie/serializers/marshal_spec.rb +0 -10
- data/spec/lib/rambling/trie/serializers/serializer_spec.rb +0 -21
- data/spec/lib/rambling/trie/serializers/yaml_spec.rb +0 -10
- data/spec/lib/rambling/trie/serializers/zip_spec.rb +0 -36
- data/spec/lib/rambling/trie/stringifyable_spec.rb +0 -89
- data/spec/lib/rambling/trie_spec.rb +0 -244
- data/spec/spec_helper.rb +0 -42
- data/spec/support/config.rb +0 -15
- data/spec/support/helpers/add_word.rb +0 -20
- data/spec/support/helpers/one_line_heredoc.rb +0 -11
- data/spec/support/shared_examples/a_compressible_trie.rb +0 -46
- data/spec/support/shared_examples/a_container_partial_word.rb +0 -17
- data/spec/support/shared_examples/a_container_scan.rb +0 -14
- data/spec/support/shared_examples/a_container_word.rb +0 -43
- data/spec/support/shared_examples/a_container_words_within.rb +0 -44
- data/spec/support/shared_examples/a_serializable_trie.rb +0 -26
- data/spec/support/shared_examples/a_serializer.rb +0 -60
- data/spec/support/shared_examples/a_trie_data_structure.rb +0 -45
- data/spec/support/shared_examples/a_trie_node.rb +0 -135
- data/spec/support/shared_examples/a_trie_node_implementation.rb +0 -149
- data/spec/tmp/.gitkeep +0 -0
data/spec/support/config.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'helpers/add_word'
|
4
|
-
require_relative 'helpers/one_line_heredoc'
|
5
|
-
|
6
|
-
RSpec.configure do |c|
|
7
|
-
c.before do
|
8
|
-
Rambling::Trie.config.reset
|
9
|
-
end
|
10
|
-
|
11
|
-
c.include Support::Helpers::AddWord
|
12
|
-
c.include Support::Helpers::OneLineHeredoc
|
13
|
-
|
14
|
-
RSpec::Matchers.define_negated_matcher :not_change, :change
|
15
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Support
|
4
|
-
module Helpers
|
5
|
-
module AddWord
|
6
|
-
def add_words node, words
|
7
|
-
words.each { |word| add_word node, word }
|
8
|
-
end
|
9
|
-
|
10
|
-
def add_word node, word
|
11
|
-
case node
|
12
|
-
when Rambling::Trie::Container
|
13
|
-
node.add word
|
14
|
-
else
|
15
|
-
node.add word.chars.reverse.map(&:to_sym)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
shared_examples_for 'a compressible trie' do
|
4
|
-
context 'with an uncompressed trie' do
|
5
|
-
it_behaves_like 'a trie data structure'
|
6
|
-
|
7
|
-
it 'does not alter the input' do
|
8
|
-
word = 'string'
|
9
|
-
add_word trie, word
|
10
|
-
|
11
|
-
expect(word).to eq 'string'
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'is marked as not compressed' do
|
15
|
-
expect(trie).not_to be_compressed
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
context 'with an compressed trie' do
|
20
|
-
let!(:original_root) { trie.root }
|
21
|
-
let!(:original_keys) { original_root.children_tree.keys }
|
22
|
-
let!(:original_values) { original_root.children_tree.values }
|
23
|
-
|
24
|
-
before do
|
25
|
-
trie.compress!
|
26
|
-
end
|
27
|
-
|
28
|
-
it_behaves_like 'a trie data structure'
|
29
|
-
|
30
|
-
it 'is marked as compressed' do
|
31
|
-
expect(trie).to be_compressed
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'leaves the original root keys intact' do
|
35
|
-
expect(original_root.children_tree.keys).to eq original_keys
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'leaves the original trie keys intact' do
|
39
|
-
expect(trie.children_tree.keys).to eq original_keys
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'leaves the original trie values intact' do
|
43
|
-
expect(trie.children_tree.values).not_to eq original_values
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,17 +0,0 @@
|
|
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
|
@@ -1,14 +0,0 @@
|
|
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
|
@@ -1,43 +0,0 @@
|
|
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_name, 'words'
|
39
|
-
expect(root).to have_received(method_name).with %w(w o r d s)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,44 +0,0 @@
|
|
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
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
shared_examples_for 'a serializable trie' do
|
4
|
-
let(:tmp_path) { File.join ::SPEC_ROOT, 'tmp' }
|
5
|
-
let(:filepath) { File.join tmp_path, "trie-root.#{file_format}" }
|
6
|
-
|
7
|
-
context 'with an uncompressed trie' do
|
8
|
-
before { Rambling::Trie.dump trie_to_serialize, filepath }
|
9
|
-
|
10
|
-
it_behaves_like 'a compressible trie' do
|
11
|
-
let(:trie) { Rambling::Trie.load filepath }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
context 'with an compressed trie' do
|
16
|
-
let(:trie) { Rambling::Trie.load filepath }
|
17
|
-
|
18
|
-
before { Rambling::Trie.dump trie_to_serialize.compress!, filepath }
|
19
|
-
|
20
|
-
it_behaves_like 'a trie data structure'
|
21
|
-
|
22
|
-
it 'is marked as compressed' do
|
23
|
-
expect(trie).to be_compressed
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
shared_examples_for 'a serializer' do
|
4
|
-
subject(:serializer) { described_class.new }
|
5
|
-
|
6
|
-
let(:trie) { Rambling::Trie.create }
|
7
|
-
let(:tmp_path) { File.join ::SPEC_ROOT, 'tmp' }
|
8
|
-
let(:filepath) { File.join tmp_path, "trie-root.#{file_format}" }
|
9
|
-
let(:content) { trie.root }
|
10
|
-
|
11
|
-
before do
|
12
|
-
trie.concat %w(a few words to validate that load and dump are working)
|
13
|
-
FileUtils.rm_f filepath
|
14
|
-
end
|
15
|
-
|
16
|
-
describe '#dump' do
|
17
|
-
[true, false].each do |compress_value|
|
18
|
-
context "with compressed=#{compress_value} trie" do
|
19
|
-
let(:formatted_content) { format_content.call content }
|
20
|
-
|
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
|
27
|
-
|
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
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe '#load' do
|
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
|
52
|
-
|
53
|
-
it "loads a compressed=#{compress_value} object" do
|
54
|
-
loaded = serializer.load filepath
|
55
|
-
expect(loaded.compressed?).to be compress_value unless :file == file_format
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
shared_examples_for 'a trie data structure' do
|
4
|
-
it 'contains all the words previously provided' do
|
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 }
|
18
|
-
end
|
19
|
-
|
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
|
29
|
-
words.each do |word|
|
30
|
-
phrase = "x#{word}y"
|
31
|
-
expect(trie.words_within phrase).to include word
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'identifies words within larger strings' do
|
36
|
-
words.each do |word|
|
37
|
-
phrase = "x#{word}y"
|
38
|
-
expect(trie.words_within? phrase).to be true
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'allows iterating over all the words' do
|
43
|
-
expect(trie.to_a.sort).to eq words.sort
|
44
|
-
end
|
45
|
-
end
|
@@ -1,135 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
shared_examples_for 'a trie node' do
|
4
|
-
let(:node_class) { node.class }
|
5
|
-
|
6
|
-
describe '.new' do
|
7
|
-
it 'has no letter' do
|
8
|
-
expect(node.letter).to be_nil
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'has no children' do
|
12
|
-
expect(node.children.size).to eq 0
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'is not terminal' do
|
16
|
-
expect(node).not_to be_terminal
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'returns empty string as its word' do
|
20
|
-
expect(node.as_word).to be_empty
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'with a letter and a parent' do
|
24
|
-
let(:parent) { node_class.new }
|
25
|
-
# noinspection RubyArgCount
|
26
|
-
let(:node_with_parent) { node_class.new :a, parent }
|
27
|
-
|
28
|
-
it 'does not have any letter' do
|
29
|
-
expect(node_with_parent.letter).to eq :a
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'has no children' do
|
33
|
-
expect(node_with_parent.children.size).to eq 0
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'is not terminal' do
|
37
|
-
expect(node_with_parent).not_to be_terminal
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe '#root?' do
|
43
|
-
context 'when the node has a parent' do
|
44
|
-
before { node.parent = node }
|
45
|
-
|
46
|
-
it 'returns false' do
|
47
|
-
expect(node).not_to be_root
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'when the node does not have a parent' do
|
52
|
-
before { node.parent = nil }
|
53
|
-
|
54
|
-
it 'returns true' do
|
55
|
-
expect(node).to be_root
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe '#terminal!' do
|
61
|
-
# rubocop:disable RSpec/MultipleExpectations
|
62
|
-
it 'forces the node to be terminal' do
|
63
|
-
expect(node).not_to be_terminal
|
64
|
-
node.terminal!
|
65
|
-
expect(node).to be_terminal
|
66
|
-
end
|
67
|
-
# rubocop:enable RSpec/MultipleExpectations
|
68
|
-
|
69
|
-
it 'returns the node' do
|
70
|
-
expect(node.terminal!).to eq node
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe 'delegates and aliases' do
|
75
|
-
let :children_tree do
|
76
|
-
instance_double(
|
77
|
-
'Hash',
|
78
|
-
:children_tree,
|
79
|
-
:[] => 'value',
|
80
|
-
:[]= => nil,
|
81
|
-
key?: false,
|
82
|
-
delete: true,
|
83
|
-
)
|
84
|
-
end
|
85
|
-
|
86
|
-
before { node.children_tree = children_tree }
|
87
|
-
|
88
|
-
# rubocop:disable RSpec/MultipleExpectations
|
89
|
-
it 'delegates `#[]` to its children tree' do
|
90
|
-
expect(node[:key]).to eq 'value'
|
91
|
-
expect(children_tree).to have_received(:[]).with :key
|
92
|
-
end
|
93
|
-
# rubocop:enable RSpec/MultipleExpectations
|
94
|
-
|
95
|
-
it 'delegates `#[]=` to its children tree' do
|
96
|
-
node[:key] = 'value'
|
97
|
-
expect(children_tree).to have_received(:[]=).with(:key, 'value')
|
98
|
-
end
|
99
|
-
|
100
|
-
# rubocop:disable RSpec/MultipleExpectations
|
101
|
-
it 'delegates `#key?` to its children tree' do
|
102
|
-
allow(children_tree).to receive(:key?)
|
103
|
-
.with(:present_key)
|
104
|
-
.and_return true
|
105
|
-
|
106
|
-
expect(node).to have_key(:present_key)
|
107
|
-
expect(node).not_to have_key(:absent_key)
|
108
|
-
end
|
109
|
-
# rubocop:enable RSpec/MultipleExpectations
|
110
|
-
|
111
|
-
# rubocop:disable RSpec/MultipleExpectations
|
112
|
-
it 'delegates `#delete` to its children tree' do
|
113
|
-
expect(node.delete :key).to be true
|
114
|
-
expect(children_tree).to have_received(:delete).with :key
|
115
|
-
end
|
116
|
-
# rubocop:enable RSpec/MultipleExpectations
|
117
|
-
|
118
|
-
# rubocop:disable RSpec/ExampleLength
|
119
|
-
it 'delegates `#children` to its children tree values' do
|
120
|
-
children = [
|
121
|
-
instance_double('Rambling::Trie::Nodes::Node', :child_one),
|
122
|
-
instance_double('Rambling::Trie::Nodes::Node', :child_two),
|
123
|
-
]
|
124
|
-
allow(children_tree).to receive(:values).and_return children
|
125
|
-
|
126
|
-
expect(node.children).to eq children
|
127
|
-
end
|
128
|
-
# rubocop:enable RSpec/ExampleLength
|
129
|
-
|
130
|
-
it 'aliases `#has_key?` to `#key?`' do
|
131
|
-
node.has_key? :nope
|
132
|
-
expect(children_tree).to have_received(:key?).with :nope
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
@@ -1,149 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
shared_examples_for 'a trie node implementation' do
|
4
|
-
it_behaves_like 'a trie node'
|
5
|
-
|
6
|
-
describe '#partial_word?' do
|
7
|
-
context 'when the chars array is empty' do
|
8
|
-
it 'returns true' do
|
9
|
-
expect(node.partial_word? []).to be true
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
context 'when the chars array is not empty' do
|
14
|
-
context 'when the node has a tree that matches the characters' do
|
15
|
-
before { add_word_to_tree 'abc' }
|
16
|
-
|
17
|
-
[%w(a), %w(a b), %w(a b c)].each do |letters|
|
18
|
-
it "returns true for '#{letters}'" do
|
19
|
-
expect(node.partial_word? letters).to be true
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'when the node has a tree that does not match the characters' do
|
25
|
-
before { add_word_to_tree 'cba' }
|
26
|
-
|
27
|
-
[%w(a), %w(a b), %w(a b c)].each do |letters|
|
28
|
-
it "returns false for '#{letters}'" do
|
29
|
-
expect(node.partial_word? letters).to be false
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
describe '#word?' do
|
37
|
-
context 'when the chars array is empty' do
|
38
|
-
context 'when the node is terminal' do
|
39
|
-
before { node.terminal! }
|
40
|
-
|
41
|
-
it 'returns true' do
|
42
|
-
expect(node.word? []).to be true
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
context 'when the node is not terminal' do
|
47
|
-
it 'returns false' do
|
48
|
-
expect(node.word? []).to be false
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
context 'when the chars array is not empty' do
|
54
|
-
context 'when the node has a tree that matches all the characters' do
|
55
|
-
before { add_word_to_tree 'abc' }
|
56
|
-
|
57
|
-
it 'returns true' do
|
58
|
-
expect(node.word? %w(a b c).map(&:dup)).to be true
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
context 'when the node subtree does not match all the characters' do
|
63
|
-
before { add_word_to_tree 'abc' }
|
64
|
-
|
65
|
-
[%w(a), %w(a b)].each do |letters|
|
66
|
-
it "returns false for '#{letters}'" do
|
67
|
-
expect(node.word? letters.map(&:dup)).to be false
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe '#scan' do
|
75
|
-
context 'when the chars array is empty' do
|
76
|
-
it 'returns itself' do
|
77
|
-
expect(node.scan []).to eq node
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
context 'when the chars array is not empty' do
|
82
|
-
before { add_words_to_tree %w(cba ccab) }
|
83
|
-
|
84
|
-
context 'when the chars are found' do
|
85
|
-
[
|
86
|
-
[%w(c), %w(cba ccab)],
|
87
|
-
[%w(c b), %w(cba)],
|
88
|
-
[%w(c b a), %w(cba)],
|
89
|
-
].each do |test_params|
|
90
|
-
letters, expected = test_params
|
91
|
-
|
92
|
-
it "returns the corresponding children (#{letters} => #{expected})" do
|
93
|
-
expect(node.scan letters).to match_array expected
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
context 'when the chars are not found' do
|
99
|
-
[
|
100
|
-
%w(a),
|
101
|
-
%w(a b),
|
102
|
-
%w(a b c),
|
103
|
-
%w(c a),
|
104
|
-
%w(c c b),
|
105
|
-
%w(c b a d),
|
106
|
-
].each do |letters|
|
107
|
-
it "returns a Nodes::Missing for '#{letters}'" do
|
108
|
-
expect(node.scan letters).to be_a Rambling::Trie::Nodes::Missing
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
describe '#match_prefix' do
|
116
|
-
before do
|
117
|
-
assign_letter :i
|
118
|
-
add_words_to_tree %w(gnite mport mportant mportantly)
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'when the node is terminal' do
|
122
|
-
before { node.terminal! }
|
123
|
-
|
124
|
-
it 'adds itself to the words' do
|
125
|
-
expect(node.match_prefix %w(g n i t e)).to include 'i'
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
context 'when the node is not terminal' do
|
130
|
-
it 'does not add itself to the words' do
|
131
|
-
expect(node.match_prefix %w(g n i t e)).not_to include 'i'
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
context 'when the first few chars match a terminal node' do
|
136
|
-
it 'adds those terminal nodes to the words' do
|
137
|
-
words = node.match_prefix(%w(m p o r t a n t l y)).to_a
|
138
|
-
expect(words).to include 'import', 'important', 'importantly'
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
context 'when the first few chars do not match a terminal node' do
|
143
|
-
it 'does not add any other words found' do
|
144
|
-
words = node.match_prefix(%w(m p m p o r t a n t l y)).to_a
|
145
|
-
expect(words).not_to include 'import', 'important', 'importantly'
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
data/spec/tmp/.gitkeep
DELETED
File without changes
|