rambling-trie 2.2.1 → 2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +5 -1
- data/LICENSE +1 -1
- data/README.md +37 -21
- 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 +17 -15
- data/lib/rambling/trie/container.rb +18 -20
- data/lib/rambling/trie/enumerable.rb +4 -1
- data/lib/rambling/trie/nodes/compressed.rb +3 -3
- data/lib/rambling/trie/nodes/node.rb +18 -18
- 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 +6 -5
- data/lib/rambling/trie/serializers/serializer.rb +27 -0
- data/lib/rambling/trie/serializers/yaml.rb +7 -7
- 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 +12 -10
- data/rambling-trie.gemspec +8 -4
- 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 +14 -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 +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 +26 -10
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rambling
|
4
|
+
module Trie
|
5
|
+
module Readers
|
6
|
+
# Base class for all readers.
|
7
|
+
class Reader
|
8
|
+
# Yields each word read from given file.
|
9
|
+
# @abstract Subclass and override {#each_word} to fit to a particular
|
10
|
+
# file format.
|
11
|
+
# @param [String] filepath the full path of the file to load the words
|
12
|
+
# from.
|
13
|
+
# @yield [String] Each line read from the file.
|
14
|
+
# @return [self]
|
15
|
+
def each_word filepath
|
16
|
+
raise NotImplementedError
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -4,7 +4,7 @@ module Rambling
|
|
4
4
|
module Trie
|
5
5
|
module Serializers
|
6
6
|
# Basic file serializer. Dumps/loads string contents from files.
|
7
|
-
class File
|
7
|
+
class File < Serializer
|
8
8
|
# Loads contents from a specified filepath.
|
9
9
|
# @param [String] filepath the filepath to load contents from.
|
10
10
|
# @return [String] all contents of the file.
|
@@ -3,13 +3,14 @@
|
|
3
3
|
module Rambling
|
4
4
|
module Trie
|
5
5
|
module Serializers
|
6
|
-
# Serializer for Ruby marshal format (
|
7
|
-
class Marshal
|
6
|
+
# Serializer for Ruby marshal format (+.marshal+) files.
|
7
|
+
class Marshal < Serializer
|
8
8
|
# Creates a new Marshal serializer.
|
9
9
|
# @param [Serializer] serializer the serializer responsible to write to
|
10
10
|
# and read from disk.
|
11
11
|
def initialize serializer = nil
|
12
12
|
@serializer = serializer || Rambling::Trie::Serializers::File.new
|
13
|
+
super()
|
13
14
|
end
|
14
15
|
|
15
16
|
# Loads marshaled object from contents in filepath and deserializes it
|
@@ -17,10 +18,10 @@ module Rambling
|
|
17
18
|
# @param [String] filepath the full path of the file to load the
|
18
19
|
# marshaled object from.
|
19
20
|
# @return [Nodes::Node] The deserialized {Nodes::Node Node}.
|
20
|
-
# @see https://ruby-doc.org/core-2.
|
21
|
+
# @see https://ruby-doc.org/core-2.7.0/Marshal.html#method-c-load
|
21
22
|
# Marshal.load
|
22
23
|
# @note Use of
|
23
|
-
# {https://ruby-doc.org/core-2.
|
24
|
+
# {https://ruby-doc.org/core-2.7.0/Marshal.html#method-c-load
|
24
25
|
# Marshal.load} is generally discouraged. Only use this with trusted
|
25
26
|
# input.
|
26
27
|
def load filepath
|
@@ -33,7 +34,7 @@ module Rambling
|
|
33
34
|
# @param [String] filepath the full path of the file to dump the
|
34
35
|
# marshaled object into.
|
35
36
|
# @return [Numeric] number of bytes written to disk.
|
36
|
-
# @see https://ruby-doc.org/core-2.
|
37
|
+
# @see https://ruby-doc.org/core-2.7.0/Marshal.html#method-c-dump
|
37
38
|
# Marshal.dump
|
38
39
|
def dump node, filepath
|
39
40
|
serializer.dump ::Marshal.dump(node), filepath
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rambling
|
4
|
+
module Trie
|
5
|
+
module Serializers
|
6
|
+
# Base class for all serializers.
|
7
|
+
class Serializer
|
8
|
+
# Loads contents from a specified filepath.
|
9
|
+
# @abstract Subclass and override {#load} to parse the desired format.
|
10
|
+
# @param [String] filepath the filepath to load contents from.
|
11
|
+
# @return [TContents] parsed contents from given file.
|
12
|
+
def load filepath
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
# Dumps contents into a specified filepath.
|
17
|
+
# @abstract Subclass and override {#dump} to output the desired format.
|
18
|
+
# @param [TContents] contents the contents to dump into given file.
|
19
|
+
# @param [String] filepath the filepath to dump the contents to.
|
20
|
+
# @return [Numeric] number of bytes written to disk.
|
21
|
+
def dump contents, filepath
|
22
|
+
raise NotImplementedError
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -3,13 +3,14 @@
|
|
3
3
|
module Rambling
|
4
4
|
module Trie
|
5
5
|
module Serializers
|
6
|
-
# Serializer for Ruby yaml format (
|
7
|
-
class Yaml
|
6
|
+
# Serializer for Ruby yaml format (+.yaml+, or +.yml+) files.
|
7
|
+
class Yaml < Serializer
|
8
8
|
# Creates a new Yaml serializer.
|
9
9
|
# @param [Serializer] serializer the serializer responsible to write to
|
10
10
|
# and read from disk.
|
11
11
|
def initialize serializer = nil
|
12
12
|
@serializer = serializer || Rambling::Trie::Serializers::File.new
|
13
|
+
super()
|
13
14
|
end
|
14
15
|
|
15
16
|
# Loads serialized object from YAML file in filepath and deserializes
|
@@ -17,19 +18,18 @@ module Rambling
|
|
17
18
|
# @param [String] filepath the full path of the file to load the
|
18
19
|
# serialized YAML object from.
|
19
20
|
# @return [Nodes::Node] The deserialized {Nodes::Node Node}.
|
20
|
-
# @see https://ruby-doc.org/stdlib-2.
|
21
|
+
# @see https://ruby-doc.org/stdlib-2.7.0/libdoc/psych/rdoc/Psych.html#method-c-safe_load
|
21
22
|
# Psych.safe_load
|
22
23
|
def load filepath
|
23
24
|
require 'yaml'
|
24
25
|
::YAML.safe_load(
|
25
26
|
serializer.load(filepath),
|
26
|
-
[
|
27
|
+
permitted_classes: [
|
27
28
|
Symbol,
|
28
29
|
Rambling::Trie::Nodes::Raw,
|
29
30
|
Rambling::Trie::Nodes::Compressed,
|
30
31
|
],
|
31
|
-
|
32
|
-
true,
|
32
|
+
aliases: true,
|
33
33
|
)
|
34
34
|
end
|
35
35
|
|
@@ -39,7 +39,7 @@ module Rambling
|
|
39
39
|
# @param [String] filepath the full path of the file to dump the YAML
|
40
40
|
# object into.
|
41
41
|
# @return [Numeric] number of bytes written to disk.
|
42
|
-
# @see https://ruby-doc.org/stdlib-2.
|
42
|
+
# @see https://ruby-doc.org/stdlib-2.7.0/libdoc/psych/rdoc/Psych.html#method-c-dump
|
43
43
|
# Psych.dump
|
44
44
|
def dump node, filepath
|
45
45
|
require 'yaml'
|
@@ -3,20 +3,22 @@
|
|
3
3
|
module Rambling
|
4
4
|
module Trie
|
5
5
|
module Serializers
|
6
|
-
# Zip file serializer. Dumps/loads contents from zip files.
|
7
|
-
# detects if zip file contains
|
8
|
-
|
6
|
+
# Zip file serializer. Dumps/loads contents from +.zip+ files.
|
7
|
+
# Automatically detects if zip file contains a +.marshal+ or +.yml+ file,
|
8
|
+
# or any other registered +:format => serializer+ combo.
|
9
|
+
class Zip < Serializer
|
9
10
|
# Creates a new Zip serializer.
|
10
11
|
# @param [Configuration::Properties] properties the configuration
|
11
12
|
# properties set up so far.
|
12
13
|
def initialize properties
|
13
14
|
@properties = properties
|
15
|
+
super()
|
14
16
|
end
|
15
17
|
|
16
18
|
# Unzip contents from specified filepath and load in contents from
|
17
19
|
# unzipped files.
|
18
20
|
# @param [String] filepath the filepath to load contents from.
|
19
|
-
# @return [
|
21
|
+
# @return [TContents] all contents of the unzipped loaded file.
|
20
22
|
# @see https://github.com/rubyzip/rubyzip#reading-a-zip-file Zip
|
21
23
|
# reading a file
|
22
24
|
def load filepath
|
@@ -35,7 +37,7 @@ module Rambling
|
|
35
37
|
# Dumps contents and zips into a specified filepath.
|
36
38
|
# @param [String] contents the contents to dump.
|
37
39
|
# @param [String] filepath the filepath to dump the contents to.
|
38
|
-
# @return [
|
40
|
+
# @return [TContents] number of bytes written to disk.
|
39
41
|
# @see https://github.com/rubyzip/rubyzip#basic-zip-archive-creation
|
40
42
|
# Zip archive creation
|
41
43
|
def dump contents, filepath
|
@@ -50,6 +52,8 @@ module Rambling
|
|
50
52
|
|
51
53
|
zip.add filename, entry_path
|
52
54
|
end
|
55
|
+
|
56
|
+
::File.size filepath
|
53
57
|
end
|
54
58
|
|
55
59
|
private
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Rambling
|
4
4
|
module Trie
|
5
|
-
# Provides the String representation behavior for the trie data structure.
|
5
|
+
# Provides the +String+ representation behavior for the trie data structure.
|
6
6
|
module Stringifyable
|
7
7
|
# String representation of the current node, if it is a terminal node.
|
8
8
|
# @return [String] the string representation of the current node.
|
data/lib/rambling/trie.rb
CHANGED
@@ -10,12 +10,12 @@ end
|
|
10
10
|
|
11
11
|
# General namespace for all Rambling gems.
|
12
12
|
module Rambling
|
13
|
-
# Entry point for rambling-trie API.
|
13
|
+
# Entry point for +rambling-trie+ API.
|
14
14
|
module Trie
|
15
15
|
class << self
|
16
|
-
# Creates a new Rambling::Trie
|
16
|
+
# Creates a new +Rambling::Trie+. Entry point for the +rambling-trie+ API.
|
17
17
|
# @param [String, nil] filepath the file to load the words from.
|
18
|
-
# @param [Reader, nil] reader the file parser to get each word.
|
18
|
+
# @param [Readers::Reader, nil] reader the file parser to get each word.
|
19
19
|
# @return [Container] the trie just created.
|
20
20
|
# @yield [Container] the trie just created.
|
21
21
|
# @see Rambling::Trie::Readers Readers.
|
@@ -36,7 +36,7 @@ module Rambling
|
|
36
36
|
|
37
37
|
# Loads an existing trie from disk into memory. By default, it will
|
38
38
|
# deduce the correct way to deserialize based on the file extension.
|
39
|
-
# Available formats are
|
39
|
+
# Available formats are +yml+, +marshal+, and +zip+ versions of all the
|
40
40
|
# previous formats. You can also define your own.
|
41
41
|
# @param [String] filepath the file to load the words from.
|
42
42
|
# @param [Serializer, nil] serializer the object responsible of loading
|
@@ -45,8 +45,8 @@ module Rambling
|
|
45
45
|
# @yield [Container] the trie just loaded.
|
46
46
|
# @see Rambling::Trie::Serializers Serializers.
|
47
47
|
# @note Use of
|
48
|
-
# {https://ruby-doc.org/core-2.
|
49
|
-
# Marshal.load} is generally discouraged. Only use the
|
48
|
+
# {https://ruby-doc.org/core-2.7.0/Marshal.html#method-c-load
|
49
|
+
# Marshal.load} is generally discouraged. Only use the +.marshal+
|
50
50
|
# format with trusted input.
|
51
51
|
def load filepath, serializer = nil
|
52
52
|
serializer ||= serializers.resolve filepath
|
@@ -58,19 +58,21 @@ module Rambling
|
|
58
58
|
|
59
59
|
# Dumps an existing trie from memory into disk. By default, it will
|
60
60
|
# deduce the correct way to serialize based on the file extension.
|
61
|
-
# Available formats are
|
61
|
+
# Available formats are +yml+, +marshal+, and +zip+ versions of all the
|
62
62
|
# previous formats. You can also define your own.
|
63
63
|
# @param [Container] trie the trie to dump into disk.
|
64
64
|
# @param [String] filepath the file to dump to serialized trie into.
|
65
|
-
# @param [Serializer, nil] serializer the object responsible
|
65
|
+
# @param [Serializers::Serializer, nil] serializer the object responsible
|
66
|
+
# for trie serialization.
|
67
|
+
# @return [void]
|
66
68
|
# serializing and dumping the trie into disk.
|
67
|
-
# @see
|
69
|
+
# @see Serializers Serializers.
|
68
70
|
def dump trie, filepath, serializer = nil
|
69
71
|
serializer ||= serializers.resolve filepath
|
70
72
|
serializer.dump trie.root, filepath
|
71
73
|
end
|
72
74
|
|
73
|
-
# Provides configuration properties for the Rambling::Trie gem.
|
75
|
+
# Provides configuration properties for the +Rambling::Trie+ gem.
|
74
76
|
# @return [Configuration::Properties] the configured properties of the
|
75
77
|
# gem.
|
76
78
|
# @yield [Configuration::Properties] the configured properties of the
|
data/rambling-trie.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
$LOAD_PATH.push File.expand_path('
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
4
4
|
require 'rambling/trie/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |gem|
|
@@ -15,6 +15,10 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.summary = 'A Ruby implementation of the trie data structure.'
|
16
16
|
gem.homepage = 'http://github.com/gonzedge/rambling-trie'
|
17
17
|
gem.date = Time.now.strftime '%Y-%m-%d'
|
18
|
+
gem.metadata = {
|
19
|
+
'changelog_uri' => 'https://github.com/gonzedge/rambling-trie/blob/master/CHANGELOG.md',
|
20
|
+
'documentation_uri' => 'https://www.rubydoc.info/gems/rambling-trie',
|
21
|
+
}
|
18
22
|
|
19
23
|
executables = `git ls-files -- bin/*`.split "\n"
|
20
24
|
files = `git ls-files -- {lib,*file,*.gemspec,LICENSE*,README*}`.split "\n"
|
@@ -29,9 +33,9 @@ Gem::Specification.new do |gem|
|
|
29
33
|
gem.license = 'MIT'
|
30
34
|
gem.version = Rambling::Trie::VERSION
|
31
35
|
gem.platform = Gem::Platform::RUBY
|
32
|
-
gem.required_ruby_version = '>= 2.
|
36
|
+
gem.required_ruby_version = '>= 2.7', '< 4'
|
33
37
|
|
34
38
|
gem.add_development_dependency 'rake', '~> 13.0'
|
35
|
-
gem.add_development_dependency 'rspec', '~> 3.
|
36
|
-
gem.add_development_dependency 'yard', '~> 0.9.
|
39
|
+
gem.add_development_dependency 'rspec', '~> 3.12'
|
40
|
+
gem.add_development_dependency 'yard', '~> 0.9.28'
|
37
41
|
end
|
@@ -8,30 +8,26 @@ describe Rambling::Trie do
|
|
8
8
|
|
9
9
|
context 'when providing words directly' do
|
10
10
|
it_behaves_like 'a compressible trie' do
|
11
|
-
let(:trie) {
|
11
|
+
let(:trie) { described_class.create }
|
12
12
|
let(:words) { %w(a couple of words for our full trie integration test) }
|
13
13
|
|
14
|
-
before
|
15
|
-
trie.concat words
|
16
|
-
end
|
14
|
+
before { trie.concat words }
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
20
18
|
context 'when provided with words with unicode characters' do
|
21
19
|
it_behaves_like 'a compressible trie' do
|
22
|
-
let(:trie) {
|
20
|
+
let(:trie) { described_class.create }
|
23
21
|
let(:words) do
|
24
22
|
%w(poquísimas palabras para nuestra prueba de integración completa 🙃)
|
25
23
|
end
|
26
24
|
|
27
|
-
before
|
28
|
-
trie.concat words
|
29
|
-
end
|
25
|
+
before { trie.concat words }
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
33
29
|
context 'when provided with a filepath' do
|
34
|
-
let(:trie) {
|
30
|
+
let(:trie) { described_class.create filepath }
|
35
31
|
let(:words) { File.readlines(filepath).map(&:chomp) }
|
36
32
|
|
37
33
|
context 'with english words' do
|
@@ -53,33 +49,34 @@ describe Rambling::Trie do
|
|
53
49
|
|
54
50
|
context 'when serialized with Ruby marshal format (default)' do
|
55
51
|
it_behaves_like 'a serializable trie' do
|
56
|
-
let(:trie_to_serialize) {
|
52
|
+
let(:trie_to_serialize) { described_class.create words_filepath }
|
57
53
|
let(:format) { :marshal }
|
58
54
|
end
|
59
55
|
end
|
60
56
|
|
61
57
|
context 'when serialized with YAML' do
|
62
58
|
it_behaves_like 'a serializable trie' do
|
63
|
-
let(:trie_to_serialize) {
|
59
|
+
let(:trie_to_serialize) { described_class.create words_filepath }
|
64
60
|
let(:format) { :yml }
|
65
61
|
end
|
66
62
|
end
|
67
63
|
|
68
64
|
context 'when serialized with zipped Ruby marshal format' do
|
65
|
+
let!(:original_on_exists_proc) { ::Zip.on_exists_proc }
|
66
|
+
let!(:original_continue_on_exists_proc) { ::Zip.continue_on_exists_proc }
|
67
|
+
|
69
68
|
before do
|
70
|
-
@original_on_exists_proc = ::Zip.on_exists_proc
|
71
|
-
@original_continue_on_exists_proc = ::Zip.continue_on_exists_proc
|
72
69
|
::Zip.on_exists_proc = true
|
73
70
|
::Zip.continue_on_exists_proc = true
|
74
71
|
end
|
75
72
|
|
76
73
|
after do
|
77
|
-
::Zip.on_exists_proc =
|
78
|
-
::Zip.continue_on_exists_proc =
|
74
|
+
::Zip.on_exists_proc = original_on_exists_proc
|
75
|
+
::Zip.continue_on_exists_proc = original_continue_on_exists_proc
|
79
76
|
end
|
80
77
|
|
81
78
|
it_behaves_like 'a serializable trie' do
|
82
|
-
let(:trie_to_serialize) {
|
79
|
+
let(:trie_to_serialize) { described_class.create words_filepath }
|
83
80
|
let(:format) { 'marshal.zip' }
|
84
81
|
end
|
85
82
|
end
|
@@ -4,93 +4,83 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Rambling::Trie::Comparable do
|
6
6
|
describe '#==' do
|
7
|
-
let(:
|
8
|
-
let(:
|
7
|
+
let(:node_one) { Rambling::Trie::Nodes::Raw.new }
|
8
|
+
let(:node_two) { Rambling::Trie::Nodes::Raw.new }
|
9
9
|
|
10
10
|
context 'when the nodes do not have the same letter' do
|
11
11
|
before do
|
12
|
-
|
13
|
-
|
12
|
+
node_one.letter = :a
|
13
|
+
node_two.letter = :b
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'returns false' do
|
17
|
-
expect(
|
17
|
+
expect(node_one).not_to eq node_two
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
context 'when
|
21
|
+
context 'when nodes have same letter, not terminal and no children' do
|
22
22
|
before do
|
23
|
-
|
24
|
-
|
23
|
+
node_one.letter = :a
|
24
|
+
node_two.letter = :a
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'returns true' do
|
28
|
-
expect(
|
28
|
+
expect(node_one).to eq node_two
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
context 'when the nodes have the same letter and are terminal' do
|
33
33
|
before do
|
34
|
-
|
35
|
-
|
34
|
+
node_one.letter = :a
|
35
|
+
node_one.terminal!
|
36
36
|
|
37
|
-
|
38
|
-
|
37
|
+
node_two.letter = :a
|
38
|
+
node_two.terminal!
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'returns true' do
|
42
|
-
expect(
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
context 'when the nodes have the same letter and are not terminal' do
|
47
|
-
before do
|
48
|
-
node_1.letter = :a
|
49
|
-
node_2.letter = :a
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'returns true' do
|
53
|
-
expect(node_1).to eq node_2
|
42
|
+
expect(node_one).to eq node_two
|
54
43
|
end
|
55
44
|
end
|
56
45
|
|
57
46
|
context 'when the nodes have the same letter but are not both terminal' do
|
58
47
|
before do
|
59
|
-
|
60
|
-
|
48
|
+
node_one.letter = :a
|
49
|
+
node_one.terminal!
|
61
50
|
|
62
|
-
|
51
|
+
node_two.letter = :a
|
63
52
|
end
|
53
|
+
|
64
54
|
it 'returns false' do
|
65
|
-
expect(
|
55
|
+
expect(node_one).not_to eq node_two
|
66
56
|
end
|
67
57
|
end
|
68
58
|
|
69
59
|
context 'when the nodes have the same letter and the same children' do
|
70
60
|
before do
|
71
|
-
|
72
|
-
add_words
|
61
|
+
node_one.letter = :t
|
62
|
+
add_words node_one, %w(hese hree hings)
|
73
63
|
|
74
|
-
|
75
|
-
add_words
|
64
|
+
node_two.letter = :t
|
65
|
+
add_words node_two, %w(hese hree hings)
|
76
66
|
end
|
77
67
|
|
78
68
|
it 'returns true' do
|
79
|
-
expect(
|
69
|
+
expect(node_one).to eq node_two
|
80
70
|
end
|
81
71
|
end
|
82
72
|
|
83
73
|
context 'when the nodes have the same letter but different children' do
|
84
74
|
before do
|
85
|
-
|
86
|
-
add_words
|
75
|
+
node_one.letter = :t
|
76
|
+
add_words node_one, %w(hese wo)
|
87
77
|
|
88
|
-
|
89
|
-
add_words
|
78
|
+
node_two.letter = :t
|
79
|
+
add_words node_two, %w(hese hree hings)
|
90
80
|
end
|
91
81
|
|
92
82
|
it 'returns false' do
|
93
|
-
expect(
|
83
|
+
expect(node_one).not_to eq node_two
|
94
84
|
end
|
95
85
|
end
|
96
86
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Rambling::Trie::Compressor do
|
6
|
-
let(:compressor) {
|
6
|
+
let(:compressor) { described_class.new }
|
7
7
|
|
8
8
|
describe '#compress' do
|
9
9
|
let(:node) { Rambling::Trie::Nodes::Raw.new }
|
@@ -16,9 +16,7 @@ describe Rambling::Trie::Compressor do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
context 'with at least one word' do
|
19
|
-
before
|
20
|
-
add_words node, %w(all the words)
|
21
|
-
end
|
19
|
+
before { add_words node, %w(all the words) }
|
22
20
|
|
23
21
|
it 'keeps the node letter nil' do
|
24
22
|
compressed = compressor.compress node
|
@@ -28,25 +26,25 @@ describe Rambling::Trie::Compressor do
|
|
28
26
|
end
|
29
27
|
|
30
28
|
context 'with a single word' do
|
31
|
-
before
|
32
|
-
add_word node, 'all'
|
33
|
-
end
|
29
|
+
before { add_word node, 'all' }
|
34
30
|
|
31
|
+
# rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
|
35
32
|
it 'compresses into a single node without children' do
|
36
33
|
compressed = compressor.compress node
|
34
|
+
compressed_node_a = compressed[:a]
|
37
35
|
|
38
|
-
expect(
|
39
|
-
expect(
|
40
|
-
expect(
|
41
|
-
expect(
|
36
|
+
expect(compressed_node_a.letter).to eq :all
|
37
|
+
expect(compressed_node_a.children.size).to eq 0
|
38
|
+
expect(compressed_node_a).to be_terminal
|
39
|
+
expect(compressed_node_a).to be_compressed
|
42
40
|
end
|
41
|
+
# rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
|
43
42
|
end
|
44
43
|
|
45
44
|
context 'with two words' do
|
46
|
-
before
|
47
|
-
add_words node, %w(all ask)
|
48
|
-
end
|
45
|
+
before { add_words node, %w(all ask) }
|
49
46
|
|
47
|
+
# rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
|
50
48
|
it 'compresses into corresponding three nodes' do
|
51
49
|
compressed = compressor.compress node
|
52
50
|
|
@@ -65,8 +63,10 @@ describe Rambling::Trie::Compressor do
|
|
65
63
|
expect(compressed[:a][:l]).to be_compressed
|
66
64
|
expect(compressed[:a][:s]).to be_compressed
|
67
65
|
end
|
66
|
+
# rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
|
68
67
|
end
|
69
68
|
|
69
|
+
# rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
|
70
70
|
it 'reassigns the parent nodes correctly' do
|
71
71
|
add_words node, %w(repay rest repaint)
|
72
72
|
compressed = compressor.compress node
|
@@ -91,7 +91,9 @@ describe Rambling::Trie::Compressor do
|
|
91
91
|
expect(compressed[:r][:p][:i].parent).to eq compressed[:r][:p]
|
92
92
|
expect(compressed[:r][:p][:i].children.size).to eq 0
|
93
93
|
end
|
94
|
+
# rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
|
94
95
|
|
96
|
+
# rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
|
95
97
|
it 'does not compress terminal nodes' do
|
96
98
|
add_words node, %w(you your yours)
|
97
99
|
compressed = compressor.compress node
|
@@ -104,5 +106,6 @@ describe Rambling::Trie::Compressor do
|
|
104
106
|
expect(compressed[:y][:r][:s].letter).to eq :s
|
105
107
|
expect(compressed[:y][:r][:s]).to be_compressed
|
106
108
|
end
|
109
|
+
# rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
|
107
110
|
end
|
108
111
|
end
|