rambling-trie 1.0.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +6 -4
  3. data/Guardfile +3 -1
  4. data/README.md +4 -4
  5. data/Rakefile +4 -0
  6. data/lib/rambling-trie.rb +2 -0
  7. data/lib/rambling/trie.rb +25 -9
  8. data/lib/rambling/trie/comparable.rb +4 -1
  9. data/lib/rambling/trie/compressible.rb +6 -4
  10. data/lib/rambling/trie/compressor.rb +12 -10
  11. data/lib/rambling/trie/configuration.rb +3 -1
  12. data/lib/rambling/trie/configuration/properties.rb +15 -8
  13. data/lib/rambling/trie/configuration/provider_collection.rb +4 -1
  14. data/lib/rambling/trie/container.rb +7 -40
  15. data/lib/rambling/trie/enumerable.rb +2 -0
  16. data/lib/rambling/trie/inspectable.rb +2 -0
  17. data/lib/rambling/trie/invalid_operation.rb +3 -1
  18. data/lib/rambling/trie/nodes.rb +3 -1
  19. data/lib/rambling/trie/nodes/compressed.rb +53 -70
  20. data/lib/rambling/trie/nodes/missing.rb +2 -0
  21. data/lib/rambling/trie/nodes/node.rb +38 -6
  22. data/lib/rambling/trie/nodes/raw.rb +19 -26
  23. data/lib/rambling/trie/readers.rb +3 -1
  24. data/lib/rambling/trie/readers/plain_text.rb +2 -0
  25. data/lib/rambling/trie/serializers.rb +3 -1
  26. data/lib/rambling/trie/serializers/file.rb +2 -0
  27. data/lib/rambling/trie/serializers/marshal.rb +12 -2
  28. data/lib/rambling/trie/serializers/yaml.rb +18 -2
  29. data/lib/rambling/trie/serializers/zip.rb +6 -0
  30. data/lib/rambling/trie/stringifyable.rb +7 -1
  31. data/lib/rambling/trie/version.rb +3 -1
  32. data/rambling-trie.gemspec +21 -10
  33. data/spec/integration/rambling/trie_spec.rb +8 -4
  34. data/spec/lib/rambling/trie/comparable_spec.rb +2 -0
  35. data/spec/lib/rambling/trie/compressor_spec.rb +35 -33
  36. data/spec/lib/rambling/trie/configuration/properties_spec.rb +17 -9
  37. data/spec/lib/rambling/trie/configuration/provider_collection_spec.rb +10 -14
  38. data/spec/lib/rambling/trie/container_spec.rb +28 -53
  39. data/spec/lib/rambling/trie/enumerable_spec.rb +2 -0
  40. data/spec/lib/rambling/trie/inspectable_spec.rb +32 -7
  41. data/spec/lib/rambling/trie/nodes/compressed_spec.rb +2 -0
  42. data/spec/lib/rambling/trie/nodes/node_spec.rb +2 -0
  43. data/spec/lib/rambling/trie/nodes/raw_spec.rb +2 -0
  44. data/spec/lib/rambling/trie/readers/plain_text_spec.rb +3 -1
  45. data/spec/lib/rambling/trie/serializers/file_spec.rb +2 -0
  46. data/spec/lib/rambling/trie/serializers/marshal_spec.rb +2 -0
  47. data/spec/lib/rambling/trie/serializers/yaml_spec.rb +2 -0
  48. data/spec/lib/rambling/trie/serializers/zip_spec.rb +6 -4
  49. data/spec/lib/rambling/trie/stringifyable_spec.rb +7 -3
  50. data/spec/lib/rambling/trie_spec.rb +16 -9
  51. data/spec/spec_helper.rb +10 -7
  52. data/spec/support/config.rb +6 -0
  53. data/spec/support/helpers/add_word.rb +2 -0
  54. data/spec/support/helpers/one_line_heredoc.rb +11 -0
  55. data/spec/support/shared_examples/a_compressible_trie.rb +7 -3
  56. data/spec/support/shared_examples/a_serializable_trie.rb +2 -0
  57. data/spec/support/shared_examples/a_serializer.rb +2 -0
  58. data/spec/support/shared_examples/a_trie_data_structure.rb +2 -0
  59. data/spec/support/shared_examples/a_trie_node.rb +15 -5
  60. data/spec/support/shared_examples/a_trie_node_implementation.rb +10 -6
  61. metadata +17 -15
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  module Nodes
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  module Nodes
@@ -20,7 +22,8 @@ module Rambling
20
22
  attr_reader :letter
21
23
 
22
24
  # Child nodes tree.
23
- # @return [Hash] the children_tree hash, consisting of `:letter => node`.
25
+ # @return [Hash] the children_tree hash, consisting of `:letter =>
26
+ # node`.
24
27
  attr_accessor :children_tree
25
28
 
26
29
  # Parent node.
@@ -77,6 +80,26 @@ module Rambling
77
80
  @letter = letter.to_sym if letter
78
81
  end
79
82
 
83
+ # Checks if a path for a set of characters exists in the trie.
84
+ # @param [Array<String>] chars the characters to look for in the trie.
85
+ # @return [Boolean] `true` if the characters are found, `false`
86
+ # otherwise.
87
+ def partial_word? chars
88
+ return true if chars.empty?
89
+
90
+ partial_word_chars? chars
91
+ end
92
+
93
+ # Checks if a path for set of characters represents a word in the trie.
94
+ # @param [Array<String>] chars the characters to look for in the trie.
95
+ # @return [Boolean] `true` if the characters are found and form a word,
96
+ # `false` otherwise.
97
+ def word? chars = []
98
+ return terminal? if chars.empty?
99
+
100
+ word_chars? chars
101
+ end
102
+
80
103
  # Returns the node that starts with the specified characters.
81
104
  # @param [Array<String>] chars the characters to look for in the trie.
82
105
  # @return [Node] the node that matches the specified characters.
@@ -89,13 +112,14 @@ module Rambling
89
112
 
90
113
  # Returns all words that match a prefix of any length within chars.
91
114
  # @param [String] chars the chars to base the prefix on.
92
- # @return [Enumerator<String>] all the words that match a prefix given by
93
- # chars.
115
+ # @return [Enumerator<String>] all the words that match a prefix given
116
+ # by chars.
94
117
  # @yield [String] each word found.
95
118
  def match_prefix chars
96
119
  return enum_for :match_prefix, chars unless block_given?
97
120
 
98
121
  yield as_word if terminal?
122
+
99
123
  children_match_prefix chars do |word|
100
124
  yield word
101
125
  end
@@ -126,9 +150,9 @@ module Rambling
126
150
  # @param [Symbol] letter the letter to search for in the node.
127
151
  # @return [Boolean] `true` if the letter is present, `false` otherwise
128
152
  # @see https://ruby-doc.org/core-2.5.0/Hash.html#method-i-has_key-3F
129
- # Hash#has_key?
130
- def has_key? letter
131
- children_tree.has_key? letter
153
+ # Hash#key?
154
+ def key? letter
155
+ children_tree.key? letter
132
156
  end
133
157
 
134
158
  # Delete a given letter and its corresponding {Node Node} from
@@ -142,6 +166,14 @@ module Rambling
142
166
  children_tree.delete letter
143
167
  end
144
168
 
169
+ alias_method :has_key?, :key?
170
+
171
+ protected
172
+
173
+ def missing
174
+ Rambling::Trie::Nodes::Missing.new
175
+ end
176
+
145
177
  private
146
178
 
147
179
  attr_accessor :terminal
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  module Nodes
@@ -15,30 +17,6 @@ module Rambling
15
17
  end
16
18
  end
17
19
 
18
- # Checks if a path for a set of characters exists in the trie.
19
- # @param [Array<String>] chars the characters to look for in the trie.
20
- # @return [Boolean] `true` if the characters are found, `false`
21
- # otherwise.
22
- def partial_word? chars = []
23
- return true if chars.empty?
24
-
25
- letter = chars.slice!(0).to_sym
26
- child = children_tree[letter]
27
- !!child && child.partial_word?(chars)
28
- end
29
-
30
- # Checks if a path for set of characters represents a word in the trie.
31
- # @param [Array<String>] chars the characters to look for in the trie.
32
- # @return [Boolean] `true` if the characters are found and form a word,
33
- # `false` otherwise.
34
- def word? chars = []
35
- return terminal? if chars.empty?
36
-
37
- letter = chars.slice!(0).to_sym
38
- child = children_tree[letter]
39
- !!child && child.word?(chars)
40
- end
41
-
42
20
  # Always return `false` for a raw (uncompressed) node.
43
21
  # @return [Boolean] always `false` for a raw (uncompressed) node.
44
22
  def compressed?
@@ -60,11 +38,26 @@ module Rambling
60
38
  node
61
39
  end
62
40
 
63
- def closest_node chars
41
+ def partial_word_chars? chars = []
42
+ letter = chars.slice!(0).to_sym
43
+ child = children_tree[letter]
44
+ return false unless child
45
+
46
+ child.partial_word? chars
47
+ end
48
+
49
+ def word_chars? chars = []
64
50
  letter = chars.slice!(0).to_sym
65
51
  child = children_tree[letter]
52
+ return false unless child
66
53
 
67
- return Rambling::Trie::Nodes::Missing.new unless child
54
+ child.word? chars
55
+ end
56
+
57
+ def closest_node chars
58
+ letter = chars.slice!(0).to_sym
59
+ child = children_tree[letter]
60
+ return missing unless child
68
61
 
69
62
  child.scan chars
70
63
  end
@@ -1,4 +1,6 @@
1
- %w{plain_text}.each do |file|
1
+ # frozen_string_literal: true
2
+
3
+ %w(plain_text).each do |file|
2
4
  require File.join('rambling', 'trie', 'readers', file)
3
5
  end
4
6
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  module Readers
@@ -1,4 +1,6 @@
1
- %w{file marshal yaml zip}.each do |file|
1
+ # frozen_string_literal: true
2
+
3
+ %w(file marshal yaml zip).each do |file|
2
4
  require File.join('rambling', 'trie', 'serializers', file)
3
5
  end
4
6
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  module Serializers
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  module Serializers
@@ -15,16 +17,24 @@ module Rambling
15
17
  # @param [String] filepath the full path of the file to load the
16
18
  # marshaled object from.
17
19
  # @return [Nodes::Node] The deserialized {Nodes::Node Node}.
20
+ # @see https://ruby-doc.org/core-2.5.0/Marshal.html#method-c-load
21
+ # Marshal.load
22
+ # @note Use of
23
+ # {https://ruby-doc.org/core-2.5.0/Marshal.html#method-c-load
24
+ # Marshal.load} is generally discouraged. Only use this with trusted
25
+ # input.
18
26
  def load filepath
19
27
  ::Marshal.load serializer.load filepath
20
28
  end
21
29
 
22
- # Serializes a {Nodes::Node Node} and dumps it as a marshaled object into
23
- # filepath.
30
+ # Serializes a {Nodes::Node Node} and dumps it as a marshaled object
31
+ # into filepath.
24
32
  # @param [Nodes::Node] node the node to serialize
25
33
  # @param [String] filepath the full path of the file to dump the
26
34
  # marshaled object into.
27
35
  # @return [Numeric] number of bytes written to disk.
36
+ # @see https://ruby-doc.org/core-2.5.0/Marshal.html#method-c-dump
37
+ # Marshal.dump
28
38
  def dump node, filepath
29
39
  serializer.dump ::Marshal.dump(node), filepath
30
40
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  module Serializers
@@ -15,16 +17,30 @@ module Rambling
15
17
  # @param [String] filepath the full path of the file to load the
16
18
  # serialized YAML object from.
17
19
  # @return [Nodes::Node] The deserialized {Nodes::Node Node}.
20
+ # @see https://ruby-doc.org/stdlib-2.5.0/libdoc/psych/rdoc/Psych.html#method-c-safe_load
21
+ # Psych.safe_load
18
22
  def load filepath
19
23
  require 'yaml'
20
- ::YAML.load serializer.load filepath
24
+ ::YAML.safe_load(
25
+ serializer.load(filepath),
26
+ [
27
+ Symbol,
28
+ Rambling::Trie::Nodes::Raw,
29
+ Rambling::Trie::Nodes::Compressed,
30
+ ],
31
+ [],
32
+ true,
33
+ )
21
34
  end
22
35
 
23
- # Serializes a {Nodes::Node Node} and dumps it as a YAML object into filepath.
36
+ # Serializes a {Nodes::Node Node} and dumps it as a YAML object into
37
+ # filepath.
24
38
  # @param [Nodes::Node] node the node to serialize
25
39
  # @param [String] filepath the full path of the file to dump the YAML
26
40
  # object into.
27
41
  # @return [Numeric] number of bytes written to disk.
42
+ # @see https://ruby-doc.org/stdlib-2.5.0/libdoc/psych/rdoc/Psych.html#method-c-dump
43
+ # Psych.dump
28
44
  def dump node, filepath
29
45
  require 'yaml'
30
46
  serializer.dump ::YAML.dump(node), filepath
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  module Serializers
@@ -15,6 +17,8 @@ module Rambling
15
17
  # unzipped files.
16
18
  # @param [String] filepath the filepath to load contents from.
17
19
  # @return [String] all contents of the unzipped loaded file.
20
+ # @see https://github.com/rubyzip/rubyzip#reading-a-zip-file Zip
21
+ # reading a file
18
22
  def load filepath
19
23
  require 'zip'
20
24
 
@@ -32,6 +36,8 @@ module Rambling
32
36
  # @param [String] contents the contents to dump.
33
37
  # @param [String] filepath the filepath to dump the contents to.
34
38
  # @return [Numeric] number of bytes written to disk.
39
+ # @see https://github.com/rubyzip/rubyzip#basic-zip-archive-creation
40
+ # Zip archive creation
35
41
  def dump contents, filepath
36
42
  require 'zip'
37
43
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  # Provides the String representation behavior for the trie data structure.
@@ -6,7 +8,11 @@ module Rambling
6
8
  # @return [String] the string representation of the current node.
7
9
  # @raise [InvalidOperation] if node is not terminal or is root.
8
10
  def as_word
9
- raise Rambling::Trie::InvalidOperation, 'Cannot represent branch as a word' if letter && !terminal?
11
+ if letter && !terminal?
12
+ raise Rambling::Trie::InvalidOperation,
13
+ 'Cannot represent branch as a word'
14
+ end
15
+
10
16
  to_s
11
17
  end
12
18
 
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rambling
2
4
  module Trie
3
5
  # Current version of the rambling-trie.
4
- VERSION = '1.0.3'.freeze
6
+ VERSION = '2.0.0'
5
7
  end
6
8
  end
@@ -1,26 +1,37 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
4
  require 'rambling/trie/version'
4
5
 
5
6
  Gem::Specification.new do |gem|
6
7
  gem.authors = ['Edgar Gonzalez', 'Lilibeth De La Cruz']
7
8
  gem.email = ['edggonzalezg@gmail.com', 'lilibethdlc@gmail.com']
8
- gem.description = 'The Rambling Trie is a Ruby implementation of the trie data structure, which includes compression abilities and is designed to be very fast to traverse.'
9
+
10
+ gem.description = <<~DESCRIPTION.gsub(%r{\s+}, ' ')
11
+ The Rambling Trie is a Ruby implementation of the trie data structure, which
12
+ includes compression abilities and is designed to be very fast to traverse.
13
+ DESCRIPTION
14
+
9
15
  gem.summary = 'A Ruby implementation of the trie data structure.'
10
16
  gem.homepage = 'http://github.com/gonzedge/rambling-trie'
11
17
  gem.date = Time.now.strftime '%Y-%m-%d'
12
18
 
13
- gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename f }
14
- gem.files = `git ls-files -- {lib,*file,*.gemspec,LICENSE*,README*}`.split "\n"
15
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split "\n"
16
- gem.require_paths = ['lib']
19
+ executables = `git ls-files -- bin/*`.split "\n"
20
+ files = `git ls-files -- {lib,*file,*.gemspec,LICENSE*,README*}`.split "\n"
21
+ test_files = `git ls-files -- {test,spec,features}/*`.split "\n"
22
+
23
+ gem.executables = executables.map { |f| File.basename f }
24
+ gem.files = files
25
+ gem.test_files = test_files
26
+ gem.require_paths = %w(lib)
17
27
 
18
28
  gem.name = 'rambling-trie'
19
29
  gem.license = 'MIT'
20
30
  gem.version = Rambling::Trie::VERSION
21
31
  gem.platform = Gem::Platform::RUBY
32
+ gem.required_ruby_version = '~> 2.3'
22
33
 
23
- gem.add_development_dependency 'rspec', '~> 3.5'
24
- gem.add_development_dependency 'rake', '~> 12.0'
25
- gem.add_development_dependency 'yard', '~> 0.9.5'
34
+ gem.add_development_dependency 'rake', '~> 12.3'
35
+ gem.add_development_dependency 'rspec', '~> 3.7'
36
+ gem.add_development_dependency 'yard', '~> 0.9.12'
26
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
  require 'zip'
3
5
 
@@ -6,8 +8,8 @@ describe Rambling::Trie do
6
8
 
7
9
  context 'when providing words directly' do
8
10
  it_behaves_like 'a compressible trie' do
9
- let(:words) { %w(a couple of words for our full trie integration test) }
10
11
  let(:trie) { Rambling::Trie.create }
12
+ let(:words) { %w(a couple of words for our full trie integration test) }
11
13
 
12
14
  before do
13
15
  trie.concat words
@@ -17,8 +19,10 @@ describe Rambling::Trie do
17
19
 
18
20
  context 'when provided with words with unicode characters' do
19
21
  it_behaves_like 'a compressible trie' do
20
- let(:words) { %w(poquísimas palabras para nuestra prueba de integración completa 🙃) }
21
22
  let(:trie) { Rambling::Trie.create }
23
+ let(:words) do
24
+ %w(poquísimas palabras para nuestra prueba de integración completa 🙃)
25
+ end
22
26
 
23
27
  before do
24
28
  trie.concat words
@@ -27,8 +31,8 @@ describe Rambling::Trie do
27
31
  end
28
32
 
29
33
  context 'when provided with a filepath' do
30
- let(:words) { File.readlines(filepath).map &:chomp! }
31
34
  let(:trie) { Rambling::Trie.create filepath }
35
+ let(:words) { File.readlines(filepath).map(&:chomp) }
32
36
 
33
37
  context 'with english words' do
34
38
  it_behaves_like 'a compressible trie' do
@@ -45,7 +49,7 @@ describe Rambling::Trie do
45
49
 
46
50
  describe 'dump and load' do
47
51
  let(:words_filepath) { File.join assets_path, 'test_words.en_US.txt' }
48
- let(:words) { File.readlines(words_filepath).map &:chomp }
52
+ let(:words) { File.readlines(words_filepath).map(&:chomp) }
49
53
 
50
54
  context 'when serialized with Ruby marshal format (default)' do
51
55
  it_behaves_like 'a serializable trie' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Rambling::Trie::Comparable do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Rambling::Trie::Compressor do
@@ -10,7 +12,7 @@ describe Rambling::Trie::Compressor do
10
12
  add_words node, %w(a few words hello hell)
11
13
  compressed = compressor.compress node
12
14
 
13
- expect(compressed.children_tree.keys).to eq %i(a few words hell)
15
+ expect(compressed.children_tree.keys).to eq %i(a f w h)
14
16
  end
15
17
 
16
18
  context 'with at least one word' do
@@ -33,10 +35,10 @@ describe Rambling::Trie::Compressor do
33
35
  it 'compresses into a single node without children' do
34
36
  compressed = compressor.compress node
35
37
 
36
- expect(compressed[:all].letter).to eq :all
37
- expect(compressed[:all].children.size).to eq 0
38
- expect(compressed[:all]).to be_terminal
39
- expect(compressed[:all]).to be_compressed
38
+ expect(compressed[:a].letter).to eq :all
39
+ expect(compressed[:a].children.size).to eq 0
40
+ expect(compressed[:a]).to be_terminal
41
+ expect(compressed[:a]).to be_compressed
40
42
  end
41
43
  end
42
44
 
@@ -51,17 +53,17 @@ describe Rambling::Trie::Compressor do
51
53
  expect(compressed[:a].letter).to eq :a
52
54
  expect(compressed[:a].children.size).to eq 2
53
55
 
54
- expect(compressed[:a][:ll].letter).to eq :ll
55
- expect(compressed[:a][:sk].letter).to eq :sk
56
+ expect(compressed[:a][:l].letter).to eq :ll
57
+ expect(compressed[:a][:s].letter).to eq :sk
56
58
 
57
- expect(compressed[:a][:ll].children.size).to eq 0
58
- expect(compressed[:a][:sk].children.size).to eq 0
59
+ expect(compressed[:a][:l].children.size).to eq 0
60
+ expect(compressed[:a][:s].children.size).to eq 0
59
61
 
60
- expect(compressed[:a][:ll]).to be_terminal
61
- expect(compressed[:a][:sk]).to be_terminal
62
+ expect(compressed[:a][:l]).to be_terminal
63
+ expect(compressed[:a][:s]).to be_terminal
62
64
 
63
- expect(compressed[:a][:ll]).to be_compressed
64
- expect(compressed[:a][:sk]).to be_compressed
65
+ expect(compressed[:a][:l]).to be_compressed
66
+ expect(compressed[:a][:s]).to be_compressed
65
67
  end
66
68
  end
67
69
 
@@ -69,38 +71,38 @@ describe Rambling::Trie::Compressor do
69
71
  add_words node, %w(repay rest repaint)
70
72
  compressed = compressor.compress node
71
73
 
72
- expect(compressed[:re].letter).to eq :re
73
- expect(compressed[:re].parent).to eq compressed
74
- expect(compressed[:re].children.size).to eq 2
74
+ expect(compressed[:r].letter).to eq :re
75
+ expect(compressed[:r].parent).to eq compressed
76
+ expect(compressed[:r].children.size).to eq 2
75
77
 
76
- expect(compressed[:re][:pa].letter).to eq :pa
77
- expect(compressed[:re][:pa].parent).to eq compressed[:re]
78
- expect(compressed[:re][:pa].children.size).to eq 2
78
+ expect(compressed[:r][:p].letter).to eq :pa
79
+ expect(compressed[:r][:p].parent).to eq compressed[:r]
80
+ expect(compressed[:r][:p].children.size).to eq 2
79
81
 
80
- expect(compressed[:re][:st].letter).to eq :st
81
- expect(compressed[:re][:st].parent).to eq compressed[:re]
82
- expect(compressed[:re][:st].children.size).to eq 0
82
+ expect(compressed[:r][:s].letter).to eq :st
83
+ expect(compressed[:r][:s].parent).to eq compressed[:r]
84
+ expect(compressed[:r][:s].children.size).to eq 0
83
85
 
84
- expect(compressed[:re][:pa][:y].letter).to eq :y
85
- expect(compressed[:re][:pa][:y].parent).to eq compressed[:re][:pa]
86
- expect(compressed[:re][:pa][:y].children.size).to eq 0
86
+ expect(compressed[:r][:p][:y].letter).to eq :y
87
+ expect(compressed[:r][:p][:y].parent).to eq compressed[:r][:p]
88
+ expect(compressed[:r][:p][:y].children.size).to eq 0
87
89
 
88
- expect(compressed[:re][:pa][:int].letter).to eq :int
89
- expect(compressed[:re][:pa][:int].parent).to eq compressed[:re][:pa]
90
- expect(compressed[:re][:pa][:int].children.size).to eq 0
90
+ expect(compressed[:r][:p][:i].letter).to eq :int
91
+ expect(compressed[:r][:p][:i].parent).to eq compressed[:r][:p]
92
+ expect(compressed[:r][:p][:i].children.size).to eq 0
91
93
  end
92
94
 
93
95
  it 'does not compress terminal nodes' do
94
96
  add_words node, %w(you your yours)
95
97
  compressed = compressor.compress node
96
98
 
97
- expect(compressed[:you].letter).to eq :you
99
+ expect(compressed[:y].letter).to eq :you
98
100
 
99
- expect(compressed[:you][:r].letter).to eq :r
100
- expect(compressed[:you][:r]).to be_compressed
101
+ expect(compressed[:y][:r].letter).to eq :r
102
+ expect(compressed[:y][:r]).to be_compressed
101
103
 
102
- expect(compressed[:you][:r][:s].letter).to eq :s
103
- expect(compressed[:you][:r][:s]).to be_compressed
104
+ expect(compressed[:y][:r][:s].letter).to eq :s
105
+ expect(compressed[:y][:r][:s]).to be_compressed
104
106
  end
105
107
  end
106
108
  end