rambling-trie 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +16 -10
  4. data/lib/rambling/trie/compressor.rb +2 -0
  5. data/lib/rambling/trie/configuration/properties.rb +5 -2
  6. data/lib/rambling/trie/configuration/provider_collection.rb +2 -2
  7. data/lib/rambling/trie/container.rb +12 -1
  8. data/lib/rambling/trie/enumerable.rb +1 -1
  9. data/lib/rambling/trie/nodes/node.rb +4 -4
  10. data/lib/rambling/trie/nodes/raw.rb +2 -1
  11. data/lib/rambling/trie/readers/plain_text.rb +1 -1
  12. data/lib/rambling/trie/serializers/file.rb +1 -3
  13. data/lib/rambling/trie/serializers/marshal.rb +3 -3
  14. data/lib/rambling/trie/serializers/yaml.rb +2 -2
  15. data/lib/rambling/trie/serializers/zip.rb +2 -0
  16. data/lib/rambling/trie/version.rb +1 -1
  17. data/lib/rambling/trie.rb +1 -1
  18. data/rambling-trie.gemspec +3 -9
  19. metadata +7 -122
  20. data/spec/assets/test_words.en_US.txt +0 -23
  21. data/spec/assets/test_words.es_DO.txt +0 -24
  22. data/spec/integration/rambling/trie_spec.rb +0 -116
  23. data/spec/lib/rambling/trie/comparable_spec.rb +0 -87
  24. data/spec/lib/rambling/trie/compressor_spec.rb +0 -111
  25. data/spec/lib/rambling/trie/configuration/properties_spec.rb +0 -75
  26. data/spec/lib/rambling/trie/configuration/provider_collection_spec.rb +0 -177
  27. data/spec/lib/rambling/trie/container_spec.rb +0 -466
  28. data/spec/lib/rambling/trie/enumerable_spec.rb +0 -50
  29. data/spec/lib/rambling/trie/inspectable_spec.rb +0 -62
  30. data/spec/lib/rambling/trie/nodes/compressed_spec.rb +0 -43
  31. data/spec/lib/rambling/trie/nodes/node_spec.rb +0 -9
  32. data/spec/lib/rambling/trie/nodes/raw_spec.rb +0 -184
  33. data/spec/lib/rambling/trie/readers/plain_text_spec.rb +0 -26
  34. data/spec/lib/rambling/trie/readers/reader_spec.rb +0 -14
  35. data/spec/lib/rambling/trie/serializers/file_spec.rb +0 -11
  36. data/spec/lib/rambling/trie/serializers/marshal_spec.rb +0 -10
  37. data/spec/lib/rambling/trie/serializers/serializer_spec.rb +0 -21
  38. data/spec/lib/rambling/trie/serializers/yaml_spec.rb +0 -10
  39. data/spec/lib/rambling/trie/serializers/zip_spec.rb +0 -36
  40. data/spec/lib/rambling/trie/stringifyable_spec.rb +0 -89
  41. data/spec/lib/rambling/trie_spec.rb +0 -244
  42. data/spec/spec_helper.rb +0 -42
  43. data/spec/support/config.rb +0 -15
  44. data/spec/support/helpers/add_word.rb +0 -20
  45. data/spec/support/helpers/one_line_heredoc.rb +0 -11
  46. data/spec/support/shared_examples/a_compressible_trie.rb +0 -46
  47. data/spec/support/shared_examples/a_container_partial_word.rb +0 -17
  48. data/spec/support/shared_examples/a_container_scan.rb +0 -14
  49. data/spec/support/shared_examples/a_container_word.rb +0 -43
  50. data/spec/support/shared_examples/a_container_words_within.rb +0 -44
  51. data/spec/support/shared_examples/a_serializable_trie.rb +0 -26
  52. data/spec/support/shared_examples/a_serializer.rb +0 -60
  53. data/spec/support/shared_examples/a_trie_data_structure.rb +0 -45
  54. data/spec/support/shared_examples/a_trie_node.rb +0 -135
  55. data/spec/support/shared_examples/a_trie_node_implementation.rb +0 -149
  56. data/spec/tmp/.gitkeep +0 -0
@@ -1,116 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'zip'
5
-
6
- describe Rambling::Trie do
7
- let(:assets_path) { File.join ::SPEC_ROOT, 'assets' }
8
-
9
- describe '::VERSION' do
10
- let(:root_path) { File.join ::SPEC_ROOT, '..' }
11
- let(:readme_path) { File.join root_path, 'README.md' }
12
- let(:readme) { File.read readme_path }
13
- let(:changelog_path) { File.join root_path, 'CHANGELOG.md' }
14
- let(:changelog) { File.read changelog_path }
15
-
16
- let(:changelog_versions) do
17
- matches = []
18
- changelog.scan %r{^## (\d+\.\d+\.\d+)} do |match|
19
- matches << match[0]
20
- end
21
- matches
22
- end
23
-
24
- it 'matches with the version in the README badge' do
25
- match = %r{\?version=(?<version>.*)$}.match readme
26
- expect(match['version']).to eq Rambling::Trie::VERSION
27
- end
28
-
29
- it 'is the version before the one at the top of the CHANGELOG' do
30
- changelog_version = Gem::Version.new changelog_versions.first
31
- lib_version = Gem::Version.new "#{Rambling::Trie::VERSION}.0"
32
- expect(changelog_version).to eq lib_version.bump
33
- end
34
-
35
- it 'is included in the CHANGELOG diffs' do
36
- changelog_versions.shift
37
- expect(changelog_versions.first).to eq Rambling::Trie::VERSION
38
- end
39
- end
40
-
41
- context 'when providing words directly' do
42
- it_behaves_like 'a compressible trie' do
43
- let(:trie) { described_class.create }
44
- let(:words) { %w(a couple of words for our full trie integration test) }
45
-
46
- before { trie.concat words }
47
- end
48
- end
49
-
50
- context 'when provided with words with unicode characters' do
51
- it_behaves_like 'a compressible trie' do
52
- let(:trie) { described_class.create }
53
- let :words do
54
- %w(poquísimas palabras para nuestra prueba de integración completa 🙃)
55
- end
56
-
57
- before { trie.concat words }
58
- end
59
- end
60
-
61
- context 'when provided with a filepath' do
62
- let(:trie) { described_class.create filepath }
63
- let(:words) { File.readlines(filepath).map(&:chomp) }
64
-
65
- context 'with english words' do
66
- it_behaves_like 'a compressible trie' do
67
- let(:filepath) { File.join assets_path, 'test_words.en_US.txt' }
68
- end
69
- end
70
-
71
- context 'with unicode characters' do
72
- it_behaves_like 'a compressible trie' do
73
- let(:filepath) { File.join assets_path, 'test_words.es_DO.txt' }
74
- end
75
- end
76
- end
77
-
78
- describe 'dump and load' do
79
- let(:words_filepath) { File.join assets_path, 'test_words.en_US.txt' }
80
- let(:words) { File.readlines(words_filepath).map(&:chomp) }
81
-
82
- context 'when serialized with Ruby marshal format (default)' do
83
- it_behaves_like 'a serializable trie' do
84
- let(:trie_to_serialize) { described_class.create words_filepath }
85
- let(:file_format) { :marshal }
86
- end
87
- end
88
-
89
- context 'when serialized with YAML' do
90
- it_behaves_like 'a serializable trie' do
91
- let(:trie_to_serialize) { described_class.create words_filepath }
92
- let(:file_format) { :yml }
93
- end
94
- end
95
-
96
- context 'when serialized with zipped Ruby marshal format' do
97
- let!(:original_on_exists_proc) { ::Zip.on_exists_proc }
98
- let!(:original_continue_on_exists_proc) { ::Zip.continue_on_exists_proc }
99
-
100
- before do
101
- ::Zip.on_exists_proc = true
102
- ::Zip.continue_on_exists_proc = true
103
- end
104
-
105
- after do
106
- ::Zip.on_exists_proc = original_on_exists_proc
107
- ::Zip.continue_on_exists_proc = original_continue_on_exists_proc
108
- end
109
-
110
- it_behaves_like 'a serializable trie' do
111
- let(:trie_to_serialize) { described_class.create words_filepath }
112
- let(:file_format) { 'marshal.zip' }
113
- end
114
- end
115
- end
116
- end
@@ -1,87 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Rambling::Trie::Comparable do
6
- describe '#==' do
7
- let(:node_one) { Rambling::Trie::Nodes::Raw.new }
8
- let(:node_two) { Rambling::Trie::Nodes::Raw.new }
9
-
10
- context 'when the nodes do not have the same letter' do
11
- before do
12
- node_one.letter = :a
13
- node_two.letter = :b
14
- end
15
-
16
- it 'returns false' do
17
- expect(node_one).not_to eq node_two
18
- end
19
- end
20
-
21
- context 'when nodes have same letter, not terminal and no children' do
22
- before do
23
- node_one.letter = :a
24
- node_two.letter = :a
25
- end
26
-
27
- it 'returns true' do
28
- expect(node_one).to eq node_two
29
- end
30
- end
31
-
32
- context 'when the nodes have the same letter and are terminal' do
33
- before do
34
- node_one.letter = :a
35
- node_one.terminal!
36
-
37
- node_two.letter = :a
38
- node_two.terminal!
39
- end
40
-
41
- it 'returns true' do
42
- expect(node_one).to eq node_two
43
- end
44
- end
45
-
46
- context 'when the nodes have the same letter but are not both terminal' do
47
- before do
48
- node_one.letter = :a
49
- node_one.terminal!
50
-
51
- node_two.letter = :a
52
- end
53
-
54
- it 'returns false' do
55
- expect(node_one).not_to eq node_two
56
- end
57
- end
58
-
59
- context 'when the nodes have the same letter and the same children' do
60
- before do
61
- node_one.letter = :t
62
- add_words node_one, %w(hese hree hings)
63
-
64
- node_two.letter = :t
65
- add_words node_two, %w(hese hree hings)
66
- end
67
-
68
- it 'returns true' do
69
- expect(node_one).to eq node_two
70
- end
71
- end
72
-
73
- context 'when the nodes have the same letter but different children' do
74
- before do
75
- node_one.letter = :t
76
- add_words node_one, %w(hese wo)
77
-
78
- node_two.letter = :t
79
- add_words node_two, %w(hese hree hings)
80
- end
81
-
82
- it 'returns false' do
83
- expect(node_one).not_to eq node_two
84
- end
85
- end
86
- end
87
- end
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Rambling::Trie::Compressor do
6
- let(:compressor) { described_class.new }
7
-
8
- describe '#compress' do
9
- let(:node) { Rambling::Trie::Nodes::Raw.new }
10
-
11
- it 'compresses the node' do
12
- add_words node, %w(a few words hello hell)
13
- compressed = compressor.compress node
14
-
15
- expect(compressed.children_tree.keys).to eq %i(a f w h)
16
- end
17
-
18
- context 'with at least one word' do
19
- before { add_words node, %w(all the words) }
20
-
21
- it 'keeps the node letter nil' do
22
- compressed = compressor.compress node
23
-
24
- expect(compressed.letter).to be_nil
25
- end
26
- end
27
-
28
- context 'with a single word' do
29
- before { add_word node, 'all' }
30
-
31
- # rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
32
- it 'compresses into a single node without children' do
33
- compressed = compressor.compress node
34
- compressed_node_a = compressed[:a]
35
-
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
40
- end
41
- # rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
42
- end
43
-
44
- context 'with two words' do
45
- before { add_words node, %w(all ask) }
46
-
47
- # rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
48
- it 'compresses into corresponding three nodes' do
49
- compressed = compressor.compress node
50
-
51
- expect(compressed[:a].letter).to eq :a
52
- expect(compressed[:a].children.size).to eq 2
53
-
54
- expect(compressed[:a][:l].letter).to eq :ll
55
- expect(compressed[:a][:s].letter).to eq :sk
56
-
57
- expect(compressed[:a][:l].children.size).to eq 0
58
- expect(compressed[:a][:s].children.size).to eq 0
59
-
60
- expect(compressed[:a][:l]).to be_terminal
61
- expect(compressed[:a][:s]).to be_terminal
62
-
63
- expect(compressed[:a][:l]).to be_compressed
64
- expect(compressed[:a][:s]).to be_compressed
65
- end
66
- # rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
67
- end
68
-
69
- # rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
70
- it 'reassigns the parent nodes correctly' do
71
- add_words node, %w(repay rest repaint)
72
- compressed = compressor.compress node
73
-
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
77
-
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
81
-
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
85
-
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
89
-
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
93
- end
94
- # rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
95
-
96
- # rubocop:disable RSpec/ExampleLength, RSpec/MultipleExpectations
97
- it 'does not compress terminal nodes' do
98
- add_words node, %w(you your yours)
99
- compressed = compressor.compress node
100
-
101
- expect(compressed[:y].letter).to eq :you
102
-
103
- expect(compressed[:y][:r].letter).to eq :r
104
- expect(compressed[:y][:r]).to be_compressed
105
-
106
- expect(compressed[:y][:r][:s].letter).to eq :s
107
- expect(compressed[:y][:r][:s]).to be_compressed
108
- end
109
- # rubocop:enable RSpec/ExampleLength, RSpec/MultipleExpectations
110
- end
111
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Rambling::Trie::Configuration::Properties do
6
- let(:properties) { described_class.new }
7
-
8
- describe '.new' do
9
- it 'configures the serializer formats' do
10
- serializers = properties.serializers
11
- expect(serializers.formats).to match_array %i(marshal yaml yml zip)
12
- end
13
-
14
- # rubocop:disable RSpec/ExampleLength
15
- it 'configures the serializer providers' do
16
- serializers = properties.serializers
17
- expect(serializers.providers.to_a).to match_array [
18
- [:marshal, Rambling::Trie::Serializers::Marshal],
19
- [:yaml, Rambling::Trie::Serializers::Yaml],
20
- [:yml, Rambling::Trie::Serializers::Yaml],
21
- [:zip, Rambling::Trie::Serializers::Zip],
22
- ]
23
- end
24
- # rubocop:enable RSpec/ExampleLength
25
-
26
- it 'configures the reader formats' do
27
- readers = properties.readers
28
- expect(readers.formats).to match_array %i(txt)
29
- end
30
-
31
- it 'configures the reader providers' do
32
- readers = properties.readers
33
- expect(readers.providers.to_a).to match_array [
34
- [:txt, Rambling::Trie::Readers::PlainText],
35
- ]
36
- end
37
-
38
- it 'configures the compressor' do
39
- compressor = properties.compressor
40
- expect(compressor).to be_instance_of Rambling::Trie::Compressor
41
- end
42
-
43
- it 'configures the root_builder' do
44
- root = properties.root_builder.call
45
- expect(root).to be_instance_of Rambling::Trie::Nodes::Raw
46
- end
47
- end
48
-
49
- describe '#reset' do
50
- before do
51
- properties.serializers.add :test, 'test'
52
- properties.readers.add :test, 'test'
53
- end
54
-
55
- # rubocop:disable RSpec/MultipleExpectations
56
- it 'resets the serializers to initial values' do
57
- expect(properties.serializers.formats).to include :test
58
-
59
- properties.reset
60
-
61
- expect(properties.serializers.formats).not_to include :test
62
- end
63
- # rubocop:enable RSpec/MultipleExpectations
64
-
65
- # rubocop:disable RSpec/MultipleExpectations
66
- it 'resets the readers to initial values' do
67
- expect(properties.readers.formats).to include :test
68
-
69
- properties.reset
70
-
71
- expect(properties.readers.formats).not_to include :test
72
- end
73
- # rubocop:enable RSpec/MultipleExpectations
74
- end
75
- end
@@ -1,177 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe Rambling::Trie::Configuration::ProviderCollection do
6
- let(:configured_default) { nil }
7
- let :configured_providers do
8
- { one: first_provider, two: second_provider }
9
- end
10
-
11
- let :first_provider do
12
- instance_double 'Rambling::Trie::Serializers::Marshal', :first_provider
13
- end
14
- let :second_provider do
15
- instance_double 'Rambling::Trie::Serializers::Marshal', :second_provider
16
- end
17
-
18
- let :provider_collection do
19
- described_class.new(
20
- :provider,
21
- configured_providers,
22
- configured_default,
23
- )
24
- end
25
-
26
- describe '.new' do
27
- it 'has a name' do
28
- expect(provider_collection.name).to eq :provider
29
- end
30
-
31
- it 'has the given providers' do
32
- expect(provider_collection.providers)
33
- .to eq one: first_provider, two: second_provider
34
- end
35
-
36
- it 'has a default provider' do
37
- expect(provider_collection.default).to eq first_provider
38
- end
39
-
40
- context 'when a default is provided' do
41
- let(:configured_default) { second_provider }
42
-
43
- it 'has that as the default provider' do
44
- expect(provider_collection.default).to eq second_provider
45
- end
46
- end
47
- end
48
-
49
- describe 'aliases and delegates' do
50
- let(:providers) { provider_collection.providers }
51
-
52
- before do
53
- allow(providers).to receive_messages(
54
- :[] => 'value',
55
- keys: %i(a b),
56
- )
57
- end
58
-
59
- # rubocop:disable RSpec/MultipleExpectations
60
- it 'delegates `#[]` to providers' do
61
- expect(provider_collection[:key]).to eq 'value'
62
- expect(providers).to have_received(:[]).with :key
63
- end
64
- # rubocop:enable RSpec/MultipleExpectations
65
-
66
- # rubocop:disable RSpec/MultipleExpectations
67
- it 'aliases `#formats` to `providers#keys`' do
68
- expect(provider_collection.formats).to eq %i(a b)
69
- expect(providers).to have_received :keys
70
- end
71
- # rubocop:enable RSpec/MultipleExpectations
72
- end
73
-
74
- describe '#add' do
75
- let :provider do
76
- instance_double 'Rambling::Trie::Serializers::Marshal', :provider
77
- end
78
-
79
- before do
80
- provider_collection.add :three, provider
81
- end
82
-
83
- it 'adds a new provider' do
84
- expect(provider_collection.providers[:three]).to eq provider
85
- end
86
- end
87
-
88
- describe '#default=' do
89
- let :other_provider do
90
- instance_double 'Rambling::Trie::Serializers::Marshal', :other_provider
91
- end
92
-
93
- context 'when the given value is in the providers list' do
94
- it 'changes the default provider' do
95
- provider_collection.default = second_provider
96
- expect(provider_collection.default).to eq second_provider
97
- end
98
- end
99
-
100
- context 'when the given value is not in the providers list' do
101
- it 'raises an error and keeps the default provider' do
102
- expect { provider_collection.default = other_provider }
103
- .to raise_error(ArgumentError)
104
- .and(not_change { provider_collection.default })
105
- end
106
-
107
- it 'raises an ArgumentError' do
108
- expect { provider_collection.default = other_provider }
109
- .to raise_error ArgumentError
110
- end
111
- end
112
-
113
- context 'when the providers list is empty' do
114
- let(:configured_providers) { {} }
115
-
116
- it 'accepts nil' do
117
- provider_collection.default = nil
118
- expect(provider_collection.default).to be_nil
119
- end
120
-
121
- # rubocop:disable RSpec/MultipleExpectations
122
- it 'raises an ArgumentError for any other provider' do
123
- expect do
124
- provider_collection.default = other_provider
125
- end.to raise_error ArgumentError
126
- expect(provider_collection.default).to be_nil
127
- end
128
- # rubocop:enable RSpec/MultipleExpectations
129
- end
130
- end
131
-
132
- describe '#resolve' do
133
- context 'when the file extension is one of the providers' do
134
- [
135
- ['hola.one', :first_provider],
136
- ['hola.two', :second_provider],
137
- ].each do |test_params|
138
- filepath, provider = test_params
139
-
140
- it 'returns the corresponding provider' do
141
- provider_instance = public_send provider
142
- expect(provider_collection.resolve filepath).to eq provider_instance
143
- end
144
- end
145
- end
146
-
147
- context 'when the file extension is not one of the providers' do
148
- %w(hola.unknown hola).each do |filepath|
149
- it 'returns the default provider' do
150
- expect(provider_collection.resolve filepath).to eq first_provider
151
- end
152
- end
153
- end
154
- end
155
-
156
- describe '#reset' do
157
- let(:configured_default) { second_provider }
158
- let :provider do
159
- instance_double 'Rambling::Trie::Serializers::Marshal', :provider
160
- end
161
-
162
- before do
163
- provider_collection.add :three, provider
164
- provider_collection.default = provider
165
- end
166
-
167
- it 'resets to back to the initially configured values (:three => nil)' do
168
- provider_collection.reset
169
- expect(provider_collection[:three]).to be_nil
170
- end
171
-
172
- it 'resets to back to the initially configured default' do
173
- provider_collection.reset
174
- expect(provider_collection.default).to eq second_provider
175
- end
176
- end
177
- end