picky 2.0.0.pre2 → 2.0.0.pre3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/picky/application.rb +1 -1
- data/lib/picky/cli.rb +2 -2
- data/lib/picky/index/base.rb +1 -1
- data/lib/picky/internals/generators/similarity/double_metaphone.rb +32 -0
- data/lib/picky/internals/generators/similarity/metaphone.rb +32 -0
- data/lib/picky/internals/generators/similarity/{double_levenshtone.rb → phonetic.rb} +9 -21
- data/lib/picky/internals/generators/similarity/soundex.rb +32 -0
- data/lib/picky/internals/index/redis/basic.rb +15 -15
- data/lib/picky/internals/index/redis/list_hash.rb +13 -13
- data/lib/picky/internals/index/redis/string_hash.rb +11 -9
- data/lib/picky/internals/indexers/serial.rb +8 -8
- data/lib/picky/internals/indexing/bundle/base.rb +1 -1
- data/lib/picky/internals/indexing/bundle/memory.rb +1 -4
- data/lib/picky/internals/indexing/category.rb +3 -3
- data/lib/picky/internals/query/combinations/base.rb +5 -11
- data/lib/picky/internals/query/combinations/redis.rb +44 -24
- data/lib/picky/internals/query/indexes.rb +29 -24
- data/lib/picky/internals/query/token.rb +12 -12
- data/lib/picky/internals/tokenizers/base.rb +1 -1
- data/lib/picky/loader.rb +4 -4
- data/lib/picky/sources/couch.rb +4 -6
- data/lib/picky/sources/delicious.rb +1 -1
- data/spec/lib/analyzer_spec.rb +18 -0
- data/spec/lib/application_spec.rb +13 -3
- data/spec/lib/bundling_spec.rb +21 -0
- data/spec/lib/character_substituters/west_european_spec.rb +8 -2
- data/spec/lib/cli_spec.rb +45 -17
- data/spec/lib/index/redis_spec.rb +15 -0
- data/spec/lib/internals/adapters/rack/live_parameters_spec.rb +11 -6
- data/spec/lib/internals/frontend_adapters/rack_spec.rb +22 -0
- data/spec/lib/internals/generators/similarity/{double_levenshtone_spec.rb → double_metaphone_spec.rb} +1 -7
- data/spec/lib/internals/generators/similarity/metaphone_spec.rb +60 -0
- data/spec/lib/internals/generators/similarity/phonetic_spec.rb +13 -0
- data/spec/lib/internals/generators/similarity/soundex_spec.rb +60 -0
- data/spec/lib/internals/generators/similarity_generator_spec.rb +1 -1
- data/spec/lib/internals/index/file/basic_spec.rb +15 -5
- data/spec/lib/internals/index/redis/list_hash_spec.rb +34 -0
- data/spec/lib/internals/index/redis/string_hash_spec.rb +12 -0
- data/spec/lib/internals/indexed/bundle/memory_spec.rb +66 -0
- data/spec/lib/internals/indexing/bundle/memory_spec.rb +87 -71
- data/spec/lib/internals/indexing/bundle/redis_spec.rb +282 -0
- data/spec/lib/internals/indexing/bundle/super_base_spec.rb +1 -1
- data/spec/lib/internals/indexing/categories_spec.rb +49 -0
- data/spec/lib/internals/indexing/category_spec.rb +68 -35
- data/spec/lib/query/combinations/base_spec.rb +0 -9
- data/spec/lib/query/combinations/memory_spec.rb +0 -9
- data/spec/lib/query/combinations/redis_spec.rb +40 -5
- data/spec/lib/sources/couch_spec.rb +22 -0
- data/spec/lib/sources/csv_spec.rb +7 -0
- data/spec/lib/sources/db_spec.rb +7 -1
- data/spec/lib/sources/delicious_spec.rb +6 -2
- metadata +26 -5
@@ -17,8 +17,7 @@ module Internals
|
|
17
17
|
|
18
18
|
# Creates a new Query::Indexes.
|
19
19
|
#
|
20
|
-
# Its job is to generate all possible combinations
|
21
|
-
# checking whether the query indexes are all of the same type.
|
20
|
+
# Its job is to generate all possible combinations.
|
22
21
|
# Note: We cannot mix memory and redis indexes just yet.
|
23
22
|
#
|
24
23
|
def initialize *index_definitions, combinations_type
|
@@ -29,32 +28,38 @@ module Internals
|
|
29
28
|
# Returns a number of possible allocations for the given tokens.
|
30
29
|
#
|
31
30
|
def allocations_for tokens
|
32
|
-
Allocations.new(
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
Allocations.new allocations_ary_for(tokens)
|
32
|
+
end
|
33
|
+
def allocations_ary_for tokens
|
34
|
+
indexes.inject([]) do |allocations, index|
|
35
|
+
allocations + allocation_for(tokens, index)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
def allocation_for tokens, index
|
39
|
+
# Expand the combinations.
|
40
|
+
#
|
41
|
+
possible_combinations = tokens.possible_combinations_in index
|
36
42
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
+
# Optimization for ignoring tokens that allocate to nothing and
|
44
|
+
# can be ignored.
|
45
|
+
# For example in a special search, where "florian" is not
|
46
|
+
# mapped to any category.
|
47
|
+
#
|
48
|
+
possible_combinations.compact!
|
43
49
|
|
44
|
-
|
45
|
-
|
46
|
-
|
50
|
+
# Generate all possible combinations.
|
51
|
+
#
|
52
|
+
expanded_combinations = expand_combinations_from possible_combinations
|
47
53
|
|
48
|
-
|
49
|
-
|
50
|
-
|
54
|
+
# If there are none, try the next allocation.
|
55
|
+
#
|
56
|
+
return [] unless expanded_combinations
|
51
57
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end)
|
58
|
+
# Add the wrapped possible allocations to the ones we already have.
|
59
|
+
#
|
60
|
+
expanded_combinations.map! do |expanded_combination|
|
61
|
+
Allocation.new @combinations_type.new(expanded_combination), index.result_identifier # TODO Do not extract result_identifier.
|
62
|
+
end
|
58
63
|
end
|
59
64
|
|
60
65
|
# This is the core of the search engine.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Internals
|
2
2
|
|
3
3
|
module Query
|
4
|
-
|
4
|
+
|
5
5
|
# This is a query token. Together with other tokens it makes up a query.
|
6
6
|
#
|
7
7
|
# It remembers the original form, and and a normalized form.
|
@@ -95,7 +95,7 @@ module Internals
|
|
95
95
|
def remove_illegals
|
96
96
|
@text.gsub! @@illegals, '' unless @text.blank?
|
97
97
|
end
|
98
|
-
|
98
|
+
|
99
99
|
# Visitor for tokenizer.
|
100
100
|
#
|
101
101
|
# TODO Rewrite!!!
|
@@ -115,10 +115,10 @@ module Internals
|
|
115
115
|
|
116
116
|
# Returns an array of possible combinations.
|
117
117
|
#
|
118
|
-
def possible_combinations_in
|
119
|
-
|
118
|
+
def possible_combinations_in index
|
119
|
+
index.possible_combinations self
|
120
120
|
end
|
121
|
-
|
121
|
+
|
122
122
|
# Returns a token with the next similar text.
|
123
123
|
#
|
124
124
|
# TODO Rewrite this. It is hard to understand. Also spec performance.
|
@@ -168,19 +168,19 @@ module Internals
|
|
168
168
|
def to_solr
|
169
169
|
blank? ? '' : (to_s + @@solr_fuzzy_mapping[@text.size].to_s)
|
170
170
|
end
|
171
|
-
|
171
|
+
|
172
172
|
#
|
173
173
|
#
|
174
174
|
def to_result
|
175
175
|
[@original, @text]
|
176
176
|
end
|
177
|
-
|
177
|
+
|
178
178
|
# Internal identifier.
|
179
179
|
#
|
180
180
|
def identifier
|
181
181
|
"#{similar?? :similarity : :index}:#{@text}"
|
182
182
|
end
|
183
|
-
|
183
|
+
|
184
184
|
# Displays the qualifier text and the text, joined.
|
185
185
|
#
|
186
186
|
# e.g. name:meier
|
@@ -188,9 +188,9 @@ module Internals
|
|
188
188
|
def to_s
|
189
189
|
[@qualifier, @text].compact.join ':'
|
190
190
|
end
|
191
|
-
|
191
|
+
|
192
192
|
private
|
193
|
-
|
193
|
+
|
194
194
|
# Splits text into a qualifier and text.
|
195
195
|
#
|
196
196
|
# Returns [qualifier, text].
|
@@ -205,7 +205,7 @@ module Internals
|
|
205
205
|
end
|
206
206
|
|
207
207
|
end
|
208
|
-
|
208
|
+
|
209
209
|
end
|
210
|
-
|
210
|
+
|
211
211
|
end
|
@@ -20,7 +20,7 @@ Removes chars after split: #{@removes_characters_after_splitting_regexp ? "/#{@r
|
|
20
20
|
Normalizes words: #{@normalizes_words_regexp_replaces ? @normalizes_words_regexp_replaces : '-'}
|
21
21
|
Rejects tokens? #{reject_condition_location ? "Yes, see line #{reject_condition_location} in app/application.rb" : '-'}
|
22
22
|
Substitutes chars? #{@substituter ? "Yes, using #{@substituter}." : '-' }
|
23
|
-
TOKENIZER
|
23
|
+
TOKENIZER
|
24
24
|
end
|
25
25
|
|
26
26
|
# Stopwords.
|
data/lib/picky/loader.rb
CHANGED
@@ -22,9 +22,6 @@ module Loader # :nodoc:all
|
|
22
22
|
load __FILE__
|
23
23
|
end
|
24
24
|
|
25
|
-
def self.require_relative filename
|
26
|
-
require File.join(File.dirname(__FILE__), filename)
|
27
|
-
end
|
28
25
|
def self.load_relative filename_without_rb
|
29
26
|
load File.join(File.dirname(__FILE__), "#{filename_without_rb}.rb")
|
30
27
|
end
|
@@ -136,7 +133,10 @@ module Loader # :nodoc:all
|
|
136
133
|
#
|
137
134
|
load_internals 'generators/similarity/strategy'
|
138
135
|
load_internals 'generators/similarity/none'
|
139
|
-
load_internals 'generators/similarity/
|
136
|
+
load_internals 'generators/similarity/phonetic'
|
137
|
+
load_internals 'generators/similarity/metaphone'
|
138
|
+
load_internals 'generators/similarity/double_metaphone'
|
139
|
+
load_internals 'generators/similarity/soundex'
|
140
140
|
load_internals 'generators/similarity/default'
|
141
141
|
|
142
142
|
# Index generators.
|
data/lib/picky/sources/couch.rb
CHANGED
@@ -26,19 +26,17 @@ module Sources
|
|
26
26
|
check_gem
|
27
27
|
|
28
28
|
Hash === options && options[:url] || raise_no_db_given(category_names)
|
29
|
+
|
29
30
|
@db = RestClient::Resource.new options.delete(:url), options
|
31
|
+
|
32
|
+
key_format = options.delete :key_format
|
33
|
+
@key_format = key_format && key_format.to_sym || :to_sym
|
30
34
|
end
|
31
35
|
|
32
36
|
def to_s
|
33
37
|
self.class.name
|
34
38
|
end
|
35
39
|
|
36
|
-
# Default key format method for couch DB is to_sym.
|
37
|
-
#
|
38
|
-
def key_format
|
39
|
-
:to_sym
|
40
|
-
end
|
41
|
-
|
42
40
|
# Tries to require the rest_client gem.
|
43
41
|
#
|
44
42
|
def check_gem # :nodoc:
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Analyzer do
|
6
|
+
|
7
|
+
let(:analyzer) { described_class.new }
|
8
|
+
|
9
|
+
context 'after initialize' do
|
10
|
+
it 'sets the comments' do
|
11
|
+
analyzer.comments.should == []
|
12
|
+
end
|
13
|
+
it 'sets the analysis' do
|
14
|
+
analyzer.analysis.should == {}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -42,13 +42,15 @@ describe Application do
|
|
42
42
|
books_index = Index::Memory.new :books,
|
43
43
|
Sources::DB.new('SELECT id, title, author, isbn13 as isbn FROM books', :file => 'app/db.yml')
|
44
44
|
books_index.define_category :title,
|
45
|
-
similarity: Similarity::
|
46
|
-
books_index.define_category :author
|
45
|
+
similarity: Similarity::DoubleMetaphone.new(3) # Up to three similar title word indexed.
|
46
|
+
books_index.define_category :author,
|
47
|
+
similarity: Similarity::Soundex.new(2)
|
47
48
|
books_index.define_category :isbn,
|
48
49
|
partial: Partial::None.new # Partially searching on an ISBN makes not much sense.
|
49
50
|
|
50
51
|
geo_index = Index::Memory.new :geo, Sources::CSV.new(:location, :north, :east, file: 'data/ch.csv', col_sep: ',') do
|
51
|
-
category :location
|
52
|
+
category :location,
|
53
|
+
similarity: Similarity::Metaphone.new(4)
|
52
54
|
ranged_category :north1, 1, precision: 3, from: :north
|
53
55
|
ranged_category :east1, 1, precision: 3, from: :east
|
54
56
|
end
|
@@ -77,6 +79,14 @@ describe Application do
|
|
77
79
|
end
|
78
80
|
end
|
79
81
|
|
82
|
+
describe 'check' do
|
83
|
+
it 'does something' do
|
84
|
+
Application.should_receive(:warn).once.with "\nWARNING: No routes defined for application configuration in Class.\n\n"
|
85
|
+
|
86
|
+
Application.check
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
80
90
|
describe 'delegation' do
|
81
91
|
it "should delegate route" do
|
82
92
|
Application.rack_adapter.should_receive(:route).once.with :path => :query
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'bundling' do
|
6
|
+
|
7
|
+
# TODO
|
8
|
+
#
|
9
|
+
# context 'loading bundler fails' do
|
10
|
+
# before(:each) do
|
11
|
+
# Kernel.should_receive(:require).once.with('bundler').and_raise LoadError.new
|
12
|
+
# end
|
13
|
+
# it 'does something' do
|
14
|
+
# Kernel.should_receive(:require).once.with 'rubygems'
|
15
|
+
# Kernel.should_receive(:require).once.with 'bundler'
|
16
|
+
#
|
17
|
+
# load File.expand_path '../../../lib/bundling.rb', __FILE__
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
end
|
@@ -3,8 +3,8 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe CharacterSubstituters do
|
6
|
-
before(:
|
7
|
-
@substituter = CharacterSubstituters::WestEuropean.new
|
6
|
+
before(:all) do
|
7
|
+
@substituter = CharacterSubstituters::WestEuropean.new.tap { |s| s.substitute '' }
|
8
8
|
end
|
9
9
|
|
10
10
|
# A bit of metaprogramming to help with the myriads of its.
|
@@ -33,6 +33,12 @@ describe CharacterSubstituters do
|
|
33
33
|
result.should < 0.00015
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
describe 'to_s' do
|
38
|
+
it 'outputs correctly' do
|
39
|
+
@substituter.to_s.should == 'CharacterSubstituters::WestEuropean'
|
40
|
+
end
|
41
|
+
end
|
36
42
|
|
37
43
|
describe "normal characters" do
|
38
44
|
it_should_not_substitute('abcdefghijklmnopqrstuvwxyz1234567890')
|
data/spec/lib/cli_spec.rb
CHANGED
@@ -10,52 +10,80 @@ require File.expand_path '../../../lib/picky/cli', __FILE__
|
|
10
10
|
#
|
11
11
|
describe Picky::CLI do
|
12
12
|
|
13
|
+
describe '.mapping' do
|
14
|
+
it 'returns the right mapping' do
|
15
|
+
Picky::CLI.mapping.should == {
|
16
|
+
:generate => [Picky::CLI::Generate, :"{sinatra_client,unicorn_server,empty_unicorn_server}", :app_directory_name],
|
17
|
+
:help => [Picky::CLI::Help],
|
18
|
+
:stats => [Picky::CLI::Statistics, :"logfile (e.g. log/search.log)", "port (default: 4567)"],
|
19
|
+
:live => [Picky::CLI::Live, "host:port/path (default: localhost:8080/admin)", "port (default: 4568)"]
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
13
24
|
describe 'instance' do
|
14
|
-
|
15
|
-
|
25
|
+
let(:cli) { described_class.new }
|
26
|
+
describe 'execute' do
|
27
|
+
it 'calls generate correctly' do
|
28
|
+
Kernel.should_receive(:system).once.with 'picky-generate one two three'
|
29
|
+
|
30
|
+
cli.execute 'generate', 'one', 'two', 'three'
|
31
|
+
end
|
32
|
+
it 'calls help correctly' do
|
33
|
+
Kernel.should_receive(:puts).once.with <<-HELP
|
34
|
+
Possible commands:
|
35
|
+
picky generate {sinatra_client,unicorn_server,empty_unicorn_server} app_directory_name
|
36
|
+
picky help
|
37
|
+
picky stats logfile (e.g. log/search.log) [port (default: 4567)]
|
38
|
+
picky live [host:port/path (default: localhost:8080/admin)] [port (default: 4568)]
|
39
|
+
HELP
|
40
|
+
cli.execute 'help'
|
41
|
+
end
|
42
|
+
# it 'calls live and it does not fail' do
|
43
|
+
# cli.execute 'live'
|
44
|
+
# end
|
45
|
+
# it 'calls stats and it does not fail' do
|
46
|
+
# cli.execute 'stats', 'some/log/file.log'
|
47
|
+
# end
|
16
48
|
end
|
17
49
|
describe 'executor_class_for' do
|
18
50
|
it 'returns Help by default' do
|
19
|
-
|
51
|
+
cli.executor_class_for.should == [Picky::CLI::Help]
|
20
52
|
end
|
21
53
|
it 'returns Generator for generate' do
|
22
|
-
|
54
|
+
cli.executor_class_for(:generate).should == [Picky::CLI::Generate, :'{sinatra_client,unicorn_server,empty_unicorn_server}', :"app_directory_name"]
|
23
55
|
end
|
24
56
|
it 'returns Help for help' do
|
25
|
-
|
57
|
+
cli.executor_class_for(:help).should == [Picky::CLI::Help]
|
26
58
|
end
|
27
59
|
it 'returns Statistics for stats' do
|
28
|
-
|
60
|
+
cli.executor_class_for(:stats).should == [Picky::CLI::Statistics, :"logfile (e.g. log/search.log)", "port (default: 4567)"]
|
29
61
|
end
|
30
62
|
it 'returns Live for live' do
|
31
|
-
|
63
|
+
cli.executor_class_for(:live).should == [Picky::CLI::Live, "host:port/path (default: localhost:8080/admin)", "port (default: 4568)"]
|
32
64
|
end
|
33
65
|
it 'returns Help for silly input' do
|
34
|
-
|
66
|
+
cli.executor_class_for(:gagagagagagaga).should == [Picky::CLI::Help]
|
35
67
|
end
|
36
68
|
end
|
37
69
|
end
|
38
70
|
|
39
71
|
describe Picky::CLI::Live do
|
40
|
-
|
41
|
-
@cli = Picky::CLI::Live.new
|
42
|
-
end
|
72
|
+
let(:executor) { described_class.new }
|
43
73
|
end
|
44
74
|
|
45
75
|
describe Picky::CLI::Base do
|
46
|
-
|
47
|
-
@executor = Picky::CLI::Base.new
|
48
|
-
end
|
76
|
+
let(:executor) { described_class.new }
|
49
77
|
describe 'usage' do
|
50
78
|
it 'calls puts with an usage' do
|
51
|
-
|
79
|
+
executor.should_receive(:puts).once.with "Usage\n picky some_name param1 [param2]"
|
52
80
|
|
53
|
-
|
81
|
+
executor.usage :some_name, [:param1, 'param2']
|
54
82
|
end
|
55
83
|
end
|
56
84
|
describe 'params_to_s' do
|
57
85
|
it 'returns the right string' do
|
58
|
-
|
86
|
+
executor.params_to_s([:param1, 'param2']).should == 'param1 [param2]'
|
59
87
|
end
|
60
88
|
end
|
61
89
|
end
|
@@ -4,17 +4,22 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Internals::Adapters::Rack::LiveParameters do
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
@adapter = described_class.new @live_parameters
|
10
|
-
end
|
7
|
+
let(:live_parameters) { stub :live_parameters }
|
8
|
+
let(:adapter) { described_class.new live_parameters }
|
11
9
|
|
12
10
|
describe 'to_app' do
|
13
11
|
it 'works' do
|
14
|
-
lambda {
|
12
|
+
lambda { adapter.to_app }.should_not raise_error
|
15
13
|
end
|
16
14
|
it 'returns the right thing' do
|
17
|
-
|
15
|
+
adapter.to_app.should respond_to(:call)
|
16
|
+
end
|
17
|
+
it 'returned lambda should call parameters on the live parameters' do
|
18
|
+
env = { 'rack.input' => 'some input' }
|
19
|
+
|
20
|
+
live_parameters.should_receive(:parameters).once.with({})
|
21
|
+
|
22
|
+
adapter.to_app.call env
|
18
23
|
end
|
19
24
|
end
|
20
25
|
|
@@ -52,6 +52,11 @@ describe Internals::FrontendAdapters::Rack do
|
|
52
52
|
it 'returns the right answer' do
|
53
53
|
@rack_adapter.empty?.should == false
|
54
54
|
end
|
55
|
+
describe 'to_s' do
|
56
|
+
it 'outputs correctly' do
|
57
|
+
@rack_adapter.to_s.should == "Note: Anchored (✓) regexps are faster, e.g. /\\A.*\\Z/ or /^.*$/.\n\n something => Search()"
|
58
|
+
end
|
59
|
+
end
|
55
60
|
end
|
56
61
|
end
|
57
62
|
|
@@ -136,6 +141,14 @@ describe Internals::FrontendAdapters::Rack do
|
|
136
141
|
end
|
137
142
|
end
|
138
143
|
|
144
|
+
describe 'to_s' do
|
145
|
+
context 'no routes' do
|
146
|
+
it 'outputs correctly' do
|
147
|
+
@rack_adapter.to_s.should == "Note: Anchored (✓) regexps are faster, e.g. /\\A.*\\Z/ or /^.*$/.\n\n"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
139
152
|
context 'stubbed routes' do
|
140
153
|
before(:each) do
|
141
154
|
@routes = stub :routes
|
@@ -216,6 +229,15 @@ describe Internals::FrontendAdapters::Rack do
|
|
216
229
|
end
|
217
230
|
end
|
218
231
|
|
232
|
+
describe 'STATUSES' do
|
233
|
+
it 'is a lambda' do
|
234
|
+
Internals::FrontendAdapters::Rack::STATUSES[200].respond_to?(:call).should == true
|
235
|
+
end
|
236
|
+
it 'is a lambda' do
|
237
|
+
Internals::FrontendAdapters::Rack::STATUSES[404].respond_to?(:call).should == true
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
219
241
|
describe 'root' do
|
220
242
|
it 'should call answer' do
|
221
243
|
@rack_adapter.should_receive(:answer).once.with %r{^/$}, Internals::FrontendAdapters::Rack::STATUSES[200]
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe Internals::Generators::Similarity::
|
5
|
+
describe Internals::Generators::Similarity::DoubleMetaphone do
|
6
6
|
|
7
7
|
before(:each) do
|
8
8
|
@similarity = described_class.new
|
@@ -56,11 +56,5 @@ describe Internals::Generators::Similarity::DoubleLevenshtone do
|
|
56
56
|
index[code].should == [:mair, :maier, :meier, :meira, :mairai]
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
60
|
-
context "alias" do
|
61
|
-
it "works also with Phonetic" do
|
62
|
-
lambda { Internals::Generators::Similarity::Phonetic.new(1) }.should_not raise_error
|
63
|
-
end
|
64
|
-
end
|
65
59
|
|
66
60
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Internals::Generators::Similarity::Metaphone do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@similarity = described_class.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.it_should_encode text, expected
|
12
|
+
it "should encode #{text.inspect} correctly" do
|
13
|
+
@similarity.encoded(text).should == expected
|
14
|
+
end
|
15
|
+
end
|
16
|
+
def self.it_should_generate_from index, expected
|
17
|
+
it "should generate #{expected.inspect} correctly from #{index.inspect}" do
|
18
|
+
@similarity.generate_from(index).should == expected
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it_should_encode :meier, :MR
|
23
|
+
it_should_encode :grossberger, :KRSBRJR
|
24
|
+
it_should_encode :hadelbla, :HTLBL
|
25
|
+
|
26
|
+
it_should_generate_from({}, {})
|
27
|
+
it_should_generate_from({ :maier => nil, :meier => nil }, :MR => [:maier, :meier]) # should be correctly ordered
|
28
|
+
it_should_generate_from({ :maier => nil, :meier => nil, :hallaballa => nil }, :MR => [:maier, :meier], :HLBL => [:hallaballa])
|
29
|
+
it_should_generate_from({ :susan => nil, :susanne => nil, :bruderer => nil }, :SSN => [:susan, :susanne], :BRTRR => [:bruderer])
|
30
|
+
|
31
|
+
describe 'with reduced amount' do
|
32
|
+
before(:each) do
|
33
|
+
@similarity = described_class.new(1)
|
34
|
+
end
|
35
|
+
it_should_generate_from({ :maier => nil, :meier => nil }, :MR => [:maier])
|
36
|
+
it_should_generate_from({ :susan => nil, :susanne => nil, :bruderer => nil }, :SSN => [:susan], :BRTRR => [:bruderer])
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'hashify' do
|
40
|
+
it 'should turn an empty list into an empty hash' do
|
41
|
+
@similarity.send(:hashify, []).should == {}
|
42
|
+
end
|
43
|
+
it 'should turn the list into an unordered similarity' do
|
44
|
+
@similarity.send(:hashify, [:meier, :maier]).should == { :MR => [:meier, :maier] }
|
45
|
+
end
|
46
|
+
it 'should turn the list into a encoded hash' do
|
47
|
+
@similarity.send(:hashify, [:meier, :maier, :peter]).should == { :MR => [:meier, :maier], :PTR => [:peter] }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'integration' do
|
52
|
+
it 'should return the right ordered array' do
|
53
|
+
index = @similarity.generate_from :meier => nil, :maier => nil, :mairai => nil, :mair => nil, :meira => nil
|
54
|
+
code = @similarity.encoded :maier
|
55
|
+
|
56
|
+
index[code].should == [:mair, :maier, :meier, :meira, :mairai]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Internals::Generators::Similarity::Phonetic do
|
6
|
+
|
7
|
+
it 'raises if you try to use Phonetic directly' do
|
8
|
+
expect {
|
9
|
+
described_class.new
|
10
|
+
}.to raise_error("From Picky 2.0 on you need to use the DoubleMetaphone similarity instead of the Phonetic similarity.")
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Internals::Generators::Similarity::Soundex do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@similarity = described_class.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.it_should_encode text, expected
|
12
|
+
it "should encode #{text.inspect} correctly" do
|
13
|
+
@similarity.encoded(text).should == expected
|
14
|
+
end
|
15
|
+
end
|
16
|
+
def self.it_should_generate_from index, expected
|
17
|
+
it "should generate #{expected.inspect} correctly from #{index.inspect}" do
|
18
|
+
@similarity.generate_from(index).should == expected
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it_should_encode :meier, :M600
|
23
|
+
it_should_encode :grossberger, :G621
|
24
|
+
it_should_encode :hadelbla, :H341
|
25
|
+
|
26
|
+
it_should_generate_from({}, {})
|
27
|
+
it_should_generate_from({ :maier => nil, :meier => nil }, :M600 => [:maier, :meier]) # should be correctly ordered
|
28
|
+
it_should_generate_from({ :maier => nil, :meier => nil, :hallaballa => nil }, :M600 => [:maier, :meier], :H414 => [:hallaballa])
|
29
|
+
it_should_generate_from({ :susan => nil, :susanne => nil, :bruderer => nil }, :S250 => [:susan, :susanne], :B636 => [:bruderer])
|
30
|
+
|
31
|
+
describe 'with reduced amount' do
|
32
|
+
before(:each) do
|
33
|
+
@similarity = described_class.new(1)
|
34
|
+
end
|
35
|
+
it_should_generate_from({ :maier => nil, :meier => nil }, :M600 => [:maier])
|
36
|
+
it_should_generate_from({ :susan => nil, :susanne => nil, :bruderer => nil }, :S250 => [:susan], :B636 => [:bruderer])
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'hashify' do
|
40
|
+
it 'should turn an empty list into an empty hash' do
|
41
|
+
@similarity.send(:hashify, []).should == {}
|
42
|
+
end
|
43
|
+
it 'should turn the list into an unordered similarity' do
|
44
|
+
@similarity.send(:hashify, [:meier, :maier]).should == { :M600 => [:meier, :maier] }
|
45
|
+
end
|
46
|
+
it 'should turn the list into a encoded hash' do
|
47
|
+
@similarity.send(:hashify, [:meier, :maier, :peter]).should == { :M600 => [:meier, :maier], :P360 => [:peter] }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'integration' do
|
52
|
+
it 'should return the right ordered array' do
|
53
|
+
index = @similarity.generate_from :meier => nil, :maier => nil, :mairai => nil, :mair => nil, :meira => nil
|
54
|
+
code = @similarity.encoded :maier
|
55
|
+
|
56
|
+
index[code].should == [:mair, :maier, :meier, :meira, :mairai]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -15,7 +15,7 @@ describe Internals::Generators::SimilarityGenerator do
|
|
15
15
|
:meyer => nil,
|
16
16
|
:peter => nil
|
17
17
|
|
18
|
-
generator.generate(Internals::Generators::Similarity::
|
18
|
+
generator.generate(Internals::Generators::Similarity::DoubleMetaphone.new).should == { :MR => [:meier, :maier, :mayer, :meyer], :PTR => [:peter] }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|