picky 2.0.0.pre2 → 2.0.0.pre3

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.
Files changed (52) hide show
  1. data/lib/picky/application.rb +1 -1
  2. data/lib/picky/cli.rb +2 -2
  3. data/lib/picky/index/base.rb +1 -1
  4. data/lib/picky/internals/generators/similarity/double_metaphone.rb +32 -0
  5. data/lib/picky/internals/generators/similarity/metaphone.rb +32 -0
  6. data/lib/picky/internals/generators/similarity/{double_levenshtone.rb → phonetic.rb} +9 -21
  7. data/lib/picky/internals/generators/similarity/soundex.rb +32 -0
  8. data/lib/picky/internals/index/redis/basic.rb +15 -15
  9. data/lib/picky/internals/index/redis/list_hash.rb +13 -13
  10. data/lib/picky/internals/index/redis/string_hash.rb +11 -9
  11. data/lib/picky/internals/indexers/serial.rb +8 -8
  12. data/lib/picky/internals/indexing/bundle/base.rb +1 -1
  13. data/lib/picky/internals/indexing/bundle/memory.rb +1 -4
  14. data/lib/picky/internals/indexing/category.rb +3 -3
  15. data/lib/picky/internals/query/combinations/base.rb +5 -11
  16. data/lib/picky/internals/query/combinations/redis.rb +44 -24
  17. data/lib/picky/internals/query/indexes.rb +29 -24
  18. data/lib/picky/internals/query/token.rb +12 -12
  19. data/lib/picky/internals/tokenizers/base.rb +1 -1
  20. data/lib/picky/loader.rb +4 -4
  21. data/lib/picky/sources/couch.rb +4 -6
  22. data/lib/picky/sources/delicious.rb +1 -1
  23. data/spec/lib/analyzer_spec.rb +18 -0
  24. data/spec/lib/application_spec.rb +13 -3
  25. data/spec/lib/bundling_spec.rb +21 -0
  26. data/spec/lib/character_substituters/west_european_spec.rb +8 -2
  27. data/spec/lib/cli_spec.rb +45 -17
  28. data/spec/lib/index/redis_spec.rb +15 -0
  29. data/spec/lib/internals/adapters/rack/live_parameters_spec.rb +11 -6
  30. data/spec/lib/internals/frontend_adapters/rack_spec.rb +22 -0
  31. data/spec/lib/internals/generators/similarity/{double_levenshtone_spec.rb → double_metaphone_spec.rb} +1 -7
  32. data/spec/lib/internals/generators/similarity/metaphone_spec.rb +60 -0
  33. data/spec/lib/internals/generators/similarity/phonetic_spec.rb +13 -0
  34. data/spec/lib/internals/generators/similarity/soundex_spec.rb +60 -0
  35. data/spec/lib/internals/generators/similarity_generator_spec.rb +1 -1
  36. data/spec/lib/internals/index/file/basic_spec.rb +15 -5
  37. data/spec/lib/internals/index/redis/list_hash_spec.rb +34 -0
  38. data/spec/lib/internals/index/redis/string_hash_spec.rb +12 -0
  39. data/spec/lib/internals/indexed/bundle/memory_spec.rb +66 -0
  40. data/spec/lib/internals/indexing/bundle/memory_spec.rb +87 -71
  41. data/spec/lib/internals/indexing/bundle/redis_spec.rb +282 -0
  42. data/spec/lib/internals/indexing/bundle/super_base_spec.rb +1 -1
  43. data/spec/lib/internals/indexing/categories_spec.rb +49 -0
  44. data/spec/lib/internals/indexing/category_spec.rb +68 -35
  45. data/spec/lib/query/combinations/base_spec.rb +0 -9
  46. data/spec/lib/query/combinations/memory_spec.rb +0 -9
  47. data/spec/lib/query/combinations/redis_spec.rb +40 -5
  48. data/spec/lib/sources/couch_spec.rb +22 -0
  49. data/spec/lib/sources/csv_spec.rb +7 -0
  50. data/spec/lib/sources/db_spec.rb +7 -1
  51. data/spec/lib/sources/delicious_spec.rb +6 -2
  52. 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, but also
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(indexes.inject([]) do |previous_allocations, index|
33
- # Expand the combinations.
34
- #
35
- possible_combinations = tokens.possible_combinations_in index
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
- # Optimization for ignoring tokens that allocate to nothing and
38
- # can be ignored.
39
- # For example in a special search, where "florian" is not
40
- # mapped to any category.
41
- #
42
- possible_combinations.compact!
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
- # Generate all possible combinations.
45
- #
46
- expanded_combinations = expand_combinations_from possible_combinations
50
+ # Generate all possible combinations.
51
+ #
52
+ expanded_combinations = expand_combinations_from possible_combinations
47
53
 
48
- # If there are none, try the next allocation.
49
- #
50
- next previous_allocations unless expanded_combinations
54
+ # If there are none, try the next allocation.
55
+ #
56
+ return [] unless expanded_combinations
51
57
 
52
- # Add the wrapped possible allocations to the ones we already have.
53
- #
54
- previous_allocations + expanded_combinations.map! do |expanded_combination|
55
- @combinations_type.new(expanded_combination).pack_into_allocation(index.result_identifier) # TODO Do not extract result_identifier. Remove pack_into_allocation.
56
- end
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 type
119
- type.possible_combinations self
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/double_levenshtone'
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.
@@ -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:
@@ -25,7 +25,7 @@ module Sources
25
25
  end
26
26
 
27
27
  def to_s
28
- self.class.name
28
+ "#{self.class.name}(#{@username})"
29
29
  end
30
30
 
31
31
  # Harvests the data to index.
@@ -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::DoubleLevenshtone.new(3) # Up to three similar title word indexed.
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(:each) do
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
- before(:each) do
15
- @cli = Picky::CLI.new
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
- @cli.executor_class_for.should == [Picky::CLI::Help]
51
+ cli.executor_class_for.should == [Picky::CLI::Help]
20
52
  end
21
53
  it 'returns Generator for generate' do
22
- @cli.executor_class_for(:generate).should == [Picky::CLI::Generate, :'{sinatra_client,unicorn_server,empty_unicorn_server}', :"app_directory_name"]
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
- @cli.executor_class_for(:help).should == [Picky::CLI::Help]
57
+ cli.executor_class_for(:help).should == [Picky::CLI::Help]
26
58
  end
27
59
  it 'returns Statistics for stats' do
28
- @cli.executor_class_for(:stats).should == [Picky::CLI::Statistics, :"logfile (e.g. log/search.log)", "port (default: 4567)"]
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
- @cli.executor_class_for(:live).should == [Picky::CLI::Live, "host:port/path (default: localhost:8080/admin)", "port (default: 4568)"]
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
- @cli.executor_class_for(:gagagagagagaga).should == [Picky::CLI::Help]
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
- before(:each) do
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
- before(:each) do
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
- @executor.should_receive(:puts).once.with "Usage\n picky some_name param1 [param2]"
79
+ executor.should_receive(:puts).once.with "Usage\n picky some_name param1 [param2]"
52
80
 
53
- @executor.usage :some_name, [:param1, 'param2']
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
- @executor.params_to_s([:param1, 'param2']).should == 'param1 [param2]'
86
+ executor.params_to_s([:param1, 'param2']).should == 'param1 [param2]'
59
87
  end
60
88
  end
61
89
  end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ describe Index::Redis do
6
+
7
+ let(:some_source) { stub :source, :harvest => nil }
8
+
9
+ describe 'initialize' do
10
+ it 'works' do
11
+ described_class.new :some_name, some_source
12
+ end
13
+ end
14
+
15
+ end
@@ -4,17 +4,22 @@ require 'spec_helper'
4
4
 
5
5
  describe Internals::Adapters::Rack::LiveParameters do
6
6
 
7
- before(:each) do
8
- @live_parameters = stub :live_parameters
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 { @adapter.to_app }.should_not raise_error
12
+ lambda { adapter.to_app }.should_not raise_error
15
13
  end
16
14
  it 'returns the right thing' do
17
- @adapter.to_app.should respond_to(:call)
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::DoubleLevenshtone do
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::DoubleLevenshtone.new).should == { :MR => [:meier, :maier, :mayer, :meyer], :PTR => [:peter] }
18
+ generator.generate(Internals::Generators::Similarity::DoubleMetaphone.new).should == { :MR => [:meier, :maier, :mayer, :meyer], :PTR => [:peter] }
19
19
  end
20
20
  end
21
21