ruby-dictionary 1.1.0 → 1.1.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 +7 -0
- data/.rspec +1 -0
- data/README.md +7 -0
- data/lib/ruby-dictionary/dictionary.rb +8 -0
- data/lib/ruby-dictionary/version.rb +1 -1
- data/lib/ruby-dictionary/word_path.rb +19 -0
- data/spec/ruby-dictionary/dictionary_spec.rb +66 -35
- data/spec/ruby-dictionary/word_path_spec.rb +17 -17
- metadata +18 -27
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 20430da0e54cba0c7228d1213a4f17dc51b35566
|
4
|
+
data.tar.gz: b745c2a145c235e8e53547b5d2edd3daf2b4fcbe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 48cc361c6dcc15ab3183ce263d5d5fdd886655e7ca9eb44cf87d7d9c2395ec013ba3cb173dc2cfc29e71e7d4322190213664fbe79d7d8f5c50b22c7f0f58fde2
|
7
|
+
data.tar.gz: d4a9a1dae9da2b6fc23cd0839610e88d746174ec1a387e6f7bf567e22213e54c0f2a9763a0ca6f5739877cc7d03b45ee18d796137eb2f93c6900455ba7ae9b8d
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/README.md
CHANGED
@@ -53,6 +53,13 @@ the provided string.
|
|
53
53
|
dictionary.starting_with('bee') # => ["bee", "been", "bees"]
|
54
54
|
dictionary.starting_with('foo') # => []
|
55
55
|
|
56
|
+
The `#prefixes` method returns a sorted array of all the words appearing in the
|
57
|
+
beginning of the provided string.
|
58
|
+
|
59
|
+
dictionary.prefixes('abstract') # => ["a", "ab", "abs"]
|
60
|
+
dictionary.prefixes('bend') # => ["be", "bend"]
|
61
|
+
|
62
|
+
|
56
63
|
### Case Sensitivity
|
57
64
|
|
58
65
|
By default, a new `Dictionary` is case-insensitive, meaning "bee", "Bee", and
|
@@ -32,6 +32,14 @@ class Dictionary
|
|
32
32
|
words.sort!
|
33
33
|
end
|
34
34
|
|
35
|
+
def prefixes(string)
|
36
|
+
string = string.to_s.strip
|
37
|
+
string = string.downcase unless case_sensitive?
|
38
|
+
|
39
|
+
@word_path.find_prefixes(string).sort
|
40
|
+
end
|
41
|
+
|
42
|
+
|
35
43
|
def hash
|
36
44
|
self.class.hash ^ @word_path.hash
|
37
45
|
end
|
@@ -39,6 +39,13 @@ class Dictionary
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
def find_prefixes(string)
|
43
|
+
raise ArgumentError, 'must be a string' unless string.kind_of?(String)
|
44
|
+
string = string.downcase unless @case_sensitive
|
45
|
+
_find_prefixes(string.strip)
|
46
|
+
end
|
47
|
+
|
48
|
+
|
42
49
|
def hash
|
43
50
|
self.class.hash ^ @is_leaf.hash ^ @word_paths.hash ^ @case_sensitive.hash
|
44
51
|
end
|
@@ -68,6 +75,18 @@ class Dictionary
|
|
68
75
|
end
|
69
76
|
end
|
70
77
|
|
78
|
+
def _find_prefixes(str)
|
79
|
+
char = str[0]
|
80
|
+
|
81
|
+
word_path = @word_paths[char]
|
82
|
+
return [] unless word_path
|
83
|
+
|
84
|
+
[].tap do |prefixes|
|
85
|
+
prefixes << char if word_path.leaf?
|
86
|
+
prefixes.concat(word_path._find_prefixes(str[1, str.size]).collect { |prefix| "#{char}#{prefix}" })
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
71
90
|
def _append(word)
|
72
91
|
return if word.empty?
|
73
92
|
|
@@ -21,23 +21,23 @@ describe Dictionary do
|
|
21
21
|
describe '#exists?' do
|
22
22
|
describe 'when case-insensitive' do
|
23
23
|
it 'finds existing single-letter words regardless of casing' do
|
24
|
-
subject.exists?('a').
|
25
|
-
subject.exists?('A').
|
24
|
+
expect(subject.exists?('a')).to be_truthy
|
25
|
+
expect(subject.exists?('A')).to be_truthy
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'finds existing multi-letter words regardless of casing' do
|
29
|
-
subject.exists?('ab').
|
30
|
-
subject.exists?('AB').
|
29
|
+
expect(subject.exists?('ab')).to be_truthy
|
30
|
+
expect(subject.exists?('AB')).to be_truthy
|
31
31
|
end
|
32
32
|
|
33
33
|
it "doesn't find non-existing single-letter words regardless of casing" do
|
34
|
-
subject.exists?('e').
|
35
|
-
subject.exists?('E').
|
34
|
+
expect(subject.exists?('e')).to be_falsey
|
35
|
+
expect(subject.exists?('E')).to be_falsey
|
36
36
|
end
|
37
37
|
|
38
38
|
it "doesn't find non-existing multi-letter words regardless of casing" do
|
39
|
-
subject.exists?('eggsactly').
|
40
|
-
subject.exists?('EGGSACTLY').
|
39
|
+
expect(subject.exists?('eggsactly')).to be_falsey
|
40
|
+
expect(subject.exists?('EGGSACTLY')).to be_falsey
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -45,29 +45,29 @@ describe Dictionary do
|
|
45
45
|
let(:case_sensitive) { true }
|
46
46
|
|
47
47
|
it 'finds existing single-letter words of the same casing' do
|
48
|
-
subject.exists?('a').
|
48
|
+
expect(subject.exists?('a')).to be_truthy
|
49
49
|
end
|
50
50
|
|
51
51
|
it 'finds existing multi-letter words of the same casing' do
|
52
|
-
subject.exists?('ab').
|
52
|
+
expect(subject.exists?('ab')).to be_truthy
|
53
53
|
end
|
54
54
|
|
55
55
|
it "doesn't find existing single-letter words of a different casing" do
|
56
|
-
subject.exists?('A').
|
56
|
+
expect(subject.exists?('A')).to be_falsey
|
57
57
|
end
|
58
58
|
|
59
59
|
it "doesn't find existing multi-letter words of a different casing" do
|
60
|
-
subject.exists?('AB').
|
60
|
+
expect(subject.exists?('AB')).to be_falsey
|
61
61
|
end
|
62
62
|
|
63
63
|
it "doesn't find non-existing single-letter words of any casing" do
|
64
|
-
subject.exists?('e').
|
65
|
-
subject.exists?('E').
|
64
|
+
expect(subject.exists?('e')).to be_falsey
|
65
|
+
expect(subject.exists?('E')).to be_falsey
|
66
66
|
end
|
67
67
|
|
68
68
|
it "doesn't find non-existing multi-letter words of any casing" do
|
69
|
-
subject.exists?('eggsactly').
|
70
|
-
subject.exists?('EGGSACTLY').
|
69
|
+
expect(subject.exists?('eggsactly')).to be_falsey
|
70
|
+
expect(subject.exists?('EGGSACTLY')).to be_falsey
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|
@@ -76,25 +76,25 @@ describe Dictionary do
|
|
76
76
|
describe 'when case-insensitive' do
|
77
77
|
it 'finds all words starting with a single letter regardless of casing' do
|
78
78
|
%w(a A).each do |prefix|
|
79
|
-
subject.starting_with(prefix).
|
79
|
+
expect(subject.starting_with(prefix)).to eq %w(a ab abs absolute absolutely)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
83
|
it 'finds all words starting with multiple letters regardless of casing' do
|
84
84
|
%w(abso ABSO).each do |prefix|
|
85
|
-
subject.starting_with(prefix).
|
85
|
+
expect(subject.starting_with(prefix)).to eq %w(absolute absolutely)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
89
|
it 'finds no words starting with unmatched single letter regardless of casing' do
|
90
90
|
%w(e E).each do |prefix|
|
91
|
-
subject.starting_with(prefix).
|
91
|
+
expect(subject.starting_with(prefix)).to be_empty
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
95
|
it 'finds no words starting with unmatched multiple letters regardless of casing' do
|
96
96
|
%w(absolutetastic ABSOLUTETASTIC).each do |prefix|
|
97
|
-
subject.starting_with(prefix).
|
97
|
+
expect(subject.starting_with(prefix)).to be_empty
|
98
98
|
end
|
99
99
|
end
|
100
100
|
end
|
@@ -103,33 +103,64 @@ describe Dictionary do
|
|
103
103
|
let(:case_sensitive) { true }
|
104
104
|
|
105
105
|
it 'finds all words starting with a single letter of the same casing' do
|
106
|
-
subject.starting_with('a').
|
107
|
-
subject.starting_with('A').
|
106
|
+
expect(subject.starting_with('a')).to eq %w(a ab abs absolute absolutely)
|
107
|
+
expect(subject.starting_with('A')).to be_empty
|
108
108
|
end
|
109
109
|
|
110
110
|
it 'finds all words starting with multiple letters of the same casing' do
|
111
|
-
subject.starting_with('abso').
|
112
|
-
subject.starting_with('ABSO').
|
111
|
+
expect(subject.starting_with('abso')).to eq %w(absolute absolutely)
|
112
|
+
expect(subject.starting_with('ABSO')).to be_empty
|
113
113
|
end
|
114
114
|
|
115
115
|
it 'finds no words starting with unmatched single letter of the same casing' do
|
116
|
-
subject.starting_with('e').
|
117
|
-
subject.starting_with('E').
|
116
|
+
expect(subject.starting_with('e')).to be_empty
|
117
|
+
expect(subject.starting_with('E')).to be_empty
|
118
118
|
end
|
119
119
|
|
120
120
|
it 'finds no words starting with unmatched multiple letters of the same casing' do
|
121
|
-
subject.starting_with('absolutetastic').
|
122
|
-
subject.starting_with('ABSOLUTETASTIC').
|
121
|
+
expect(subject.starting_with('absolutetastic')).to be_empty
|
122
|
+
expect(subject.starting_with('ABSOLUTETASTIC')).to be_empty
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
126
126
|
|
127
|
+
describe '#prefixes' do
|
128
|
+
describe "for exceptional input" do
|
129
|
+
it "returns empty string for empty string" do
|
130
|
+
expect(subject.prefixes('')).to be_empty
|
131
|
+
end
|
132
|
+
|
133
|
+
it "finds the prefix of a single letter (the letter itself)" do
|
134
|
+
expect(subject.prefixes('a')).to eq %w(a)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'when case-insensitive' do
|
139
|
+
it 'finds all the prefixes of a string regardless of casing' do
|
140
|
+
%w(abstract Abstract).each do |string|
|
141
|
+
expect(subject.prefixes(string)).to eq %w(a ab abs)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe 'when case-sensitive' do
|
147
|
+
let(:case_sensitive) { true }
|
148
|
+
|
149
|
+
it 'finds all the prefixes of a string, of the same casing' do
|
150
|
+
expect(subject.prefixes('abstract')).to eq %w(a ab abs)
|
151
|
+
expect(subject.prefixes('aBstract')).to eq %w(a)
|
152
|
+
expect(subject.prefixes('Abstract')).to be_empty
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
|
127
158
|
describe '#inspect' do
|
128
|
-
specify { subject.inspect.
|
159
|
+
specify { expect(subject.inspect).to eq '#<Dictionary>' }
|
129
160
|
end
|
130
161
|
|
131
162
|
describe '#to_s' do
|
132
|
-
specify { subject.to_s.
|
163
|
+
specify { expect(subject.to_s).to eq '#<Dictionary>' }
|
133
164
|
end
|
134
165
|
|
135
166
|
describe '.from_file' do
|
@@ -139,15 +170,15 @@ describe Dictionary do
|
|
139
170
|
|
140
171
|
shared_examples 'loaded dictionary' do
|
141
172
|
it 'loads all words' do
|
142
|
-
subject.starting_with('a').size.
|
143
|
-
subject.starting_with('b').size.
|
144
|
-
subject.starting_with('y').size.
|
145
|
-
subject.starting_with('z').size.
|
173
|
+
expect(subject.starting_with('a').size).to eq 5
|
174
|
+
expect(subject.starting_with('b').size).to eq 4
|
175
|
+
expect(subject.starting_with('y').size).to eq 1
|
176
|
+
expect(subject.starting_with('z').size).to eq 3
|
146
177
|
end
|
147
178
|
|
148
179
|
it 'does not load nonexistent words' do
|
149
180
|
('c'..'x').each do |letter|
|
150
|
-
subject.starting_with(letter).
|
181
|
+
expect(subject.starting_with(letter)).to be_empty
|
151
182
|
end
|
152
183
|
end
|
153
184
|
|
@@ -20,12 +20,12 @@ describe Dictionary::WordPath do
|
|
20
20
|
describe '#leaf=' do
|
21
21
|
it 'should set to false' do
|
22
22
|
subject.leaf = false
|
23
|
-
subject.
|
23
|
+
expect(subject).not_to be_leaf
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'should set to true' do
|
27
27
|
subject.leaf = true
|
28
|
-
subject.
|
28
|
+
expect(subject).to be_leaf
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -37,18 +37,18 @@ describe Dictionary::WordPath do
|
|
37
37
|
|
38
38
|
it 'finds existing word paths of matching case-sensitivity' do
|
39
39
|
word_path = subject.find('potat')
|
40
|
-
word_path.
|
41
|
-
word_path.
|
40
|
+
expect(word_path).to be_a Dictionary::WordPath
|
41
|
+
expect(word_path).to eq Dictionary::WordPath.new(case_sensitive).tap { |wp| wp << 'o' }
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'finds existing word paths of unmatching case-sensitivity' do
|
45
45
|
word_path = subject.find('poTAt')
|
46
|
-
word_path.
|
47
|
-
word_path.
|
46
|
+
expect(word_path).to be_a Dictionary::WordPath
|
47
|
+
expect(word_path).to eq Dictionary::WordPath.new(case_sensitive).tap { |wp| wp << 'o' }
|
48
48
|
end
|
49
49
|
|
50
50
|
it 'does not find nonexistent word paths' do
|
51
|
-
subject.find('potable').
|
51
|
+
expect(subject.find('potable')).to be_nil
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -61,16 +61,16 @@ describe Dictionary::WordPath do
|
|
61
61
|
|
62
62
|
it 'finds existing word paths of matching case-sensitivity' do
|
63
63
|
word_path = subject.find('poTAt')
|
64
|
-
word_path.
|
65
|
-
word_path.
|
64
|
+
expect(word_path).to be_a Dictionary::WordPath
|
65
|
+
expect(word_path).to eq Dictionary::WordPath.new(case_sensitive).tap { |wp| wp << 'o' }
|
66
66
|
end
|
67
67
|
|
68
68
|
it 'does not find existing word paths of unmatching case-sensitivity' do
|
69
|
-
subject.find('potat').
|
69
|
+
expect(subject.find('potat')).to be_nil
|
70
70
|
end
|
71
71
|
|
72
72
|
it 'does not find nonexistent word paths' do
|
73
|
-
subject.find('potat').
|
73
|
+
expect(subject.find('potat')).to be_nil
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
@@ -82,8 +82,8 @@ describe Dictionary::WordPath do
|
|
82
82
|
|
83
83
|
describe 'when case-insensitive' do
|
84
84
|
it 'appends case-insensitive word to word path' do
|
85
|
-
subject.find('potato').
|
86
|
-
subject.find('poTAto').
|
85
|
+
expect(subject.find('potato')).to be_a Dictionary::WordPath
|
86
|
+
expect(subject.find('poTAto')).to eq subject.find('potato')
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -91,8 +91,8 @@ describe Dictionary::WordPath do
|
|
91
91
|
let(:case_sensitive) { true }
|
92
92
|
|
93
93
|
it 'appends case-sensitive word to word path' do
|
94
|
-
subject.find('potato').
|
95
|
-
subject.find('poTAto').
|
94
|
+
expect(subject.find('potato')).to be_a Dictionary::WordPath
|
95
|
+
expect(subject.find('poTAto')).to be_nil
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
@@ -110,7 +110,7 @@ describe Dictionary::WordPath do
|
|
110
110
|
describe 'when case-insensitive' do
|
111
111
|
it 'finds all words with the given suffix' do
|
112
112
|
word = subject.find('pot')
|
113
|
-
word.suffixes.
|
113
|
+
expect(word.suffixes).to eq %w(ato able ty)
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
@@ -119,7 +119,7 @@ describe Dictionary::WordPath do
|
|
119
119
|
|
120
120
|
it 'finds all words with the given suffix' do
|
121
121
|
word = subject.find('pot')
|
122
|
-
word.suffixes.
|
122
|
+
expect(word.suffixes).to eq %w(ABle)
|
123
123
|
end
|
124
124
|
end
|
125
125
|
end
|
metadata
CHANGED
@@ -1,58 +1,56 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-dictionary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.1.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Matt Huggins
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-08-14 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
|
-
description:
|
47
|
-
|
41
|
+
description: |-
|
42
|
+
Dictionary class for ruby that allows for checking
|
43
|
+
existence and finding words starting with a given
|
44
|
+
prefix.
|
48
45
|
email:
|
49
46
|
- matt.huggins@gmail.com
|
50
47
|
executables: []
|
51
48
|
extensions: []
|
52
49
|
extra_rdoc_files: []
|
53
50
|
files:
|
54
|
-
- .gitignore
|
55
|
-
- .
|
51
|
+
- ".gitignore"
|
52
|
+
- ".rspec"
|
53
|
+
- ".travis.yml"
|
56
54
|
- Gemfile
|
57
55
|
- LICENSE.txt
|
58
56
|
- README.md
|
@@ -73,33 +71,26 @@ files:
|
|
73
71
|
- tasks/rspec.rake
|
74
72
|
homepage: https://github.com/mhuggins/ruby-dictionary
|
75
73
|
licenses: []
|
74
|
+
metadata: {}
|
76
75
|
post_install_message:
|
77
76
|
rdoc_options: []
|
78
77
|
require_paths:
|
79
78
|
- lib
|
80
79
|
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
80
|
requirements:
|
83
|
-
- -
|
81
|
+
- - ">="
|
84
82
|
- !ruby/object:Gem::Version
|
85
83
|
version: '0'
|
86
|
-
segments:
|
87
|
-
- 0
|
88
|
-
hash: -3725738245159260742
|
89
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
85
|
requirements:
|
92
|
-
- -
|
86
|
+
- - ">="
|
93
87
|
- !ruby/object:Gem::Version
|
94
88
|
version: '0'
|
95
|
-
segments:
|
96
|
-
- 0
|
97
|
-
hash: -3725738245159260742
|
98
89
|
requirements: []
|
99
90
|
rubyforge_project:
|
100
|
-
rubygems_version:
|
91
|
+
rubygems_version: 2.2.2
|
101
92
|
signing_key:
|
102
|
-
specification_version:
|
93
|
+
specification_version: 4
|
103
94
|
summary: Simple dictionary class for checking existence of words
|
104
95
|
test_files:
|
105
96
|
- spec/fixtures/compressed_lined.txt.gz
|