searchkick 2.3.2 → 5.2.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.
Files changed (87) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +377 -84
  3. data/LICENSE.txt +1 -1
  4. data/README.md +859 -602
  5. data/lib/searchkick/bulk_reindex_job.rb +13 -9
  6. data/lib/searchkick/controller_runtime.rb +40 -0
  7. data/lib/searchkick/hash_wrapper.rb +12 -0
  8. data/lib/searchkick/index.rb +281 -356
  9. data/lib/searchkick/index_cache.rb +30 -0
  10. data/lib/searchkick/index_options.rb +487 -281
  11. data/lib/searchkick/indexer.rb +15 -8
  12. data/lib/searchkick/log_subscriber.rb +57 -0
  13. data/lib/searchkick/middleware.rb +9 -2
  14. data/lib/searchkick/model.rb +72 -118
  15. data/lib/searchkick/multi_search.rb +9 -10
  16. data/lib/searchkick/process_batch_job.rb +12 -15
  17. data/lib/searchkick/process_queue_job.rb +22 -13
  18. data/lib/searchkick/query.rb +458 -217
  19. data/lib/searchkick/railtie.rb +7 -0
  20. data/lib/searchkick/record_data.rb +128 -0
  21. data/lib/searchkick/record_indexer.rb +164 -0
  22. data/lib/searchkick/reindex_queue.rb +51 -9
  23. data/lib/searchkick/reindex_v2_job.rb +10 -32
  24. data/lib/searchkick/relation.rb +247 -0
  25. data/lib/searchkick/relation_indexer.rb +155 -0
  26. data/lib/searchkick/results.rb +201 -82
  27. data/lib/searchkick/version.rb +1 -1
  28. data/lib/searchkick/where.rb +11 -0
  29. data/lib/searchkick.rb +269 -97
  30. data/lib/tasks/searchkick.rake +37 -0
  31. metadata +24 -178
  32. data/.gitignore +0 -22
  33. data/.travis.yml +0 -39
  34. data/Gemfile +0 -16
  35. data/Rakefile +0 -20
  36. data/benchmark/Gemfile +0 -23
  37. data/benchmark/benchmark.rb +0 -97
  38. data/lib/searchkick/logging.rb +0 -242
  39. data/lib/searchkick/tasks.rb +0 -33
  40. data/searchkick.gemspec +0 -28
  41. data/test/aggs_test.rb +0 -197
  42. data/test/autocomplete_test.rb +0 -75
  43. data/test/boost_test.rb +0 -202
  44. data/test/callbacks_test.rb +0 -59
  45. data/test/ci/before_install.sh +0 -17
  46. data/test/errors_test.rb +0 -19
  47. data/test/gemfiles/activerecord31.gemfile +0 -7
  48. data/test/gemfiles/activerecord32.gemfile +0 -7
  49. data/test/gemfiles/activerecord40.gemfile +0 -8
  50. data/test/gemfiles/activerecord41.gemfile +0 -8
  51. data/test/gemfiles/activerecord42.gemfile +0 -7
  52. data/test/gemfiles/activerecord50.gemfile +0 -7
  53. data/test/gemfiles/apartment.gemfile +0 -8
  54. data/test/gemfiles/cequel.gemfile +0 -8
  55. data/test/gemfiles/mongoid2.gemfile +0 -7
  56. data/test/gemfiles/mongoid3.gemfile +0 -6
  57. data/test/gemfiles/mongoid4.gemfile +0 -7
  58. data/test/gemfiles/mongoid5.gemfile +0 -7
  59. data/test/gemfiles/mongoid6.gemfile +0 -12
  60. data/test/gemfiles/nobrainer.gemfile +0 -8
  61. data/test/gemfiles/parallel_tests.gemfile +0 -8
  62. data/test/geo_shape_test.rb +0 -175
  63. data/test/highlight_test.rb +0 -78
  64. data/test/index_test.rb +0 -166
  65. data/test/inheritance_test.rb +0 -83
  66. data/test/marshal_test.rb +0 -8
  67. data/test/match_test.rb +0 -276
  68. data/test/misspellings_test.rb +0 -56
  69. data/test/model_test.rb +0 -42
  70. data/test/multi_search_test.rb +0 -36
  71. data/test/multi_tenancy_test.rb +0 -22
  72. data/test/order_test.rb +0 -46
  73. data/test/pagination_test.rb +0 -70
  74. data/test/partial_reindex_test.rb +0 -58
  75. data/test/query_test.rb +0 -35
  76. data/test/records_test.rb +0 -10
  77. data/test/reindex_test.rb +0 -64
  78. data/test/reindex_v2_job_test.rb +0 -32
  79. data/test/routing_test.rb +0 -23
  80. data/test/should_index_test.rb +0 -32
  81. data/test/similar_test.rb +0 -28
  82. data/test/sql_test.rb +0 -214
  83. data/test/suggest_test.rb +0 -95
  84. data/test/support/kaminari.yml +0 -21
  85. data/test/synonyms_test.rb +0 -67
  86. data/test/test_helper.rb +0 -567
  87. data/test/where_test.rb +0 -223
@@ -1,78 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class HighlightTest < Minitest::Test
4
- def test_basic
5
- store_names ["Two Door Cinema Club"]
6
- assert_equal "Two Door <em>Cinema</em> Club", Product.search("cinema", fields: [:name], highlight: true).first.search_highlights[:name]
7
- end
8
-
9
- def test_tag
10
- store_names ["Two Door Cinema Club"]
11
- assert_equal "Two Door <strong>Cinema</strong> Club", Product.search("cinema", fields: [:name], highlight: {tag: "<strong>"}).first.search_highlights[:name]
12
- end
13
-
14
- def test_tag_class
15
- store_names ["Two Door Cinema Club"]
16
- assert_equal "Two Door <strong class='classy'>Cinema</strong> Club", Product.search("cinema", fields: [:name], highlight: {tag: "<strong class='classy'>"}).first.search_highlights[:name]
17
- end
18
-
19
- def test_multiple_fields
20
- store [{name: "Two Door Cinema Club", color: "Cinema Orange"}]
21
- highlights = Product.search("cinema", fields: [:name, :color], highlight: true).first.search_highlights
22
- assert_equal "Two Door <em>Cinema</em> Club", highlights[:name]
23
- assert_equal "<em>Cinema</em> Orange", highlights[:color]
24
- end
25
-
26
- def test_fields
27
- store [{name: "Two Door Cinema Club", color: "Cinema Orange"}]
28
- highlights = Product.search("cinema", fields: [:name, :color], highlight: {fields: [:name]}).first.search_highlights
29
- assert_equal "Two Door <em>Cinema</em> Club", highlights[:name]
30
- assert_nil highlights[:color]
31
- end
32
-
33
- def test_field_options
34
- store_names ["Two Door Cinema Club are a Northern Irish indie rock band"]
35
- fragment_size = ENV["MATCH"] == "word_start" ? 26 : 21
36
- assert_equal "Two Door <em>Cinema</em> Club are", Product.search("cinema", fields: [:name], highlight: {fields: {name: {fragment_size: fragment_size}}}).first.search_highlights[:name]
37
- end
38
-
39
- def test_multiple_words
40
- store_names ["Hello World Hello"]
41
- assert_equal "<em>Hello</em> World <em>Hello</em>", Product.search("hello", fields: [:name], highlight: true).first.search_highlights[:name]
42
- end
43
-
44
- def test_encoder
45
- store_names ["<b>Hello</b>"]
46
- assert_equal "&lt;b&gt;<em>Hello</em>&lt;&#x2F;b&gt;", Product.search("hello", fields: [:name], highlight: {encoder: "html"}, misspellings: false).first.search_highlights[:name]
47
- end
48
-
49
- def test_word_middle
50
- store_names ["Two Door Cinema Club"]
51
- assert_equal "Two Door <em>Cinema</em> Club", Product.search("ine", fields: [:name], match: :word_middle, highlight: true).first.search_highlights[:name]
52
- end
53
-
54
- def test_body
55
- skip if ENV["MATCH"] == "word_start"
56
- store_names ["Two Door Cinema Club"]
57
- body = {
58
- query: {
59
- match: {
60
- "name.analyzed" => "cinema"
61
- }
62
- },
63
- highlight: {
64
- pre_tags: ["<strong>"],
65
- post_tags: ["</strong>"],
66
- fields: {
67
- "name.analyzed" => {}
68
- }
69
- }
70
- }
71
- assert_equal "Two Door <strong>Cinema</strong> Club", Product.search(body: body).first.search_highlights[:"name.analyzed"]
72
- end
73
-
74
- def test_legacy
75
- store_names ["Two Door Cinema Club"]
76
- assert_equal "Two Door <em>Cinema</em> Club", Product.search("cinema", fields: [:name], highlight: true).with_details.first[1][:highlight][:name]
77
- end
78
- end
data/test/index_test.rb DELETED
@@ -1,166 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class IndexTest < Minitest::Test
4
- def setup
5
- super
6
- Region.destroy_all
7
- end
8
-
9
- def test_clean_indices
10
- suffix = Searchkick.index_suffix ? "_#{Searchkick.index_suffix}" : ""
11
- old_index = Searchkick::Index.new("products_test#{suffix}_20130801000000000")
12
- different_index = Searchkick::Index.new("items_test#{suffix}_20130801000000000")
13
-
14
- old_index.delete if old_index.exists?
15
- different_index.delete if different_index.exists?
16
-
17
- # create indexes
18
- old_index.create
19
- different_index.create
20
-
21
- Product.searchkick_index.clean_indices
22
-
23
- assert Product.searchkick_index.exists?
24
- assert different_index.exists?
25
- assert !old_index.exists?
26
- end
27
-
28
- def test_clean_indices_old_format
29
- suffix = Searchkick.index_suffix ? "_#{Searchkick.index_suffix}" : ""
30
- old_index = Searchkick::Index.new("products_test#{suffix}_20130801000000")
31
- old_index.create
32
-
33
- Product.searchkick_index.clean_indices
34
-
35
- assert !old_index.exists?
36
- end
37
-
38
- def test_retain
39
- Product.reindex
40
- assert_equal 1, Product.searchkick_index.all_indices.size
41
- Product.reindex(retain: true)
42
- assert_equal 2, Product.searchkick_index.all_indices.size
43
- end
44
-
45
- def test_total_docs
46
- store_names ["Product A"]
47
- assert_equal 1, Product.searchkick_index.total_docs
48
- end
49
-
50
- def test_mapping
51
- store_names ["Dollar Tree"], Store
52
- assert_equal [], Store.search(body: {query: {match: {name: "dollar"}}}).map(&:name)
53
- assert_equal ["Dollar Tree"], Store.search(body: {query: {match: {name: "Dollar Tree"}}}).map(&:name)
54
- end
55
-
56
- def test_body
57
- store_names ["Dollar Tree"], Store
58
- assert_equal [], Store.search(body: {query: {match: {name: "dollar"}}}).map(&:name)
59
- assert_equal ["Dollar Tree"], Store.search(body: {query: {match: {name: "Dollar Tree"}}}, load: false).map(&:name)
60
- end
61
-
62
- def test_body_warning
63
- assert_output(nil, "The body option replaces the entire body, so the following options are ignored: where\n") { Store.search(body: {query: {match: {name: "dollar"}}}, where: {id: 1}) }
64
- end
65
-
66
- def test_block
67
- store_names ["Dollar Tree"]
68
- products =
69
- Product.search "boom" do |body|
70
- body[:query] = {match_all: {}}
71
- end
72
- assert_equal ["Dollar Tree"], products.map(&:name)
73
- end
74
-
75
- def test_tokens
76
- assert_equal ["dollar", "dollartre", "tree"], Product.searchkick_index.tokens("Dollar Tree", analyzer: "searchkick_index")
77
- end
78
-
79
- def test_tokens_analyzer
80
- assert_equal ["dollar", "tree"], Product.searchkick_index.tokens("Dollar Tree", analyzer: "searchkick_search2")
81
- end
82
-
83
- def test_record_not_found
84
- store_names ["Product A", "Product B"]
85
- Product.where(name: "Product A").delete_all
86
- assert_search "product", ["Product B"]
87
- ensure
88
- Product.reindex
89
- end
90
-
91
- def test_bad_mapping
92
- Product.searchkick_index.delete
93
- store_names ["Product A"]
94
- assert_raises(Searchkick::InvalidQueryError) { Product.search "test" }
95
- ensure
96
- Product.reindex
97
- end
98
-
99
- def test_remove_blank_id
100
- store_names ["Product A"]
101
- Product.searchkick_index.remove(Product.new)
102
- assert_search "product", ["Product A"]
103
- ensure
104
- Product.reindex
105
- end
106
-
107
- def test_missing_index
108
- assert_raises(Searchkick::MissingIndexError) { Product.search("test", index_name: "not_found") }
109
- end
110
-
111
- def test_unsupported_version
112
- raises_exception = ->(_) { raise Elasticsearch::Transport::Transport::Error, "[500] No query registered for [multi_match]" }
113
- Searchkick.client.stub :search, raises_exception do
114
- assert_raises(Searchkick::UnsupportedVersionError) { Product.search("test") }
115
- end
116
- end
117
-
118
- def test_invalid_body
119
- assert_raises(Searchkick::InvalidQueryError) { Product.search(body: {boom: true}) }
120
- end
121
-
122
- def test_transaction
123
- skip unless defined?(ActiveRecord)
124
- Product.transaction do
125
- store_names ["Product A"]
126
- raise ActiveRecord::Rollback
127
- end
128
- assert_search "*", []
129
- end
130
-
131
- def test_filterable
132
- # skip for 5.0 since it throws
133
- # Cannot search on field [alt_description] since it is not indexed.
134
- skip unless elasticsearch_below50?
135
- store [{name: "Product A", alt_description: "Hello"}]
136
- assert_search "*", [], where: {alt_description: "Hello"}
137
- end
138
-
139
- def test_filterable_non_string
140
- store [{name: "Product A", store_id: 1}]
141
- assert_search "*", ["Product A"], where: {store_id: 1}
142
- end
143
-
144
- def test_large_value
145
- skip if nobrainer?
146
- large_value = 1000.times.map { "hello" }.join(" ")
147
- store [{name: "Product A", text: large_value}], Region
148
- assert_search "product", ["Product A"], {}, Region
149
- assert_search "hello", ["Product A"], {fields: [:name, :text]}, Region
150
-
151
- # needs fields for ES 6
152
- if elasticsearch_below60?
153
- assert_search "hello", ["Product A"], {}, Region
154
- end
155
- end
156
-
157
- def test_very_large_value
158
- skip if nobrainer? || elasticsearch_below22?
159
- large_value = 10000.times.map { "hello" }.join(" ")
160
- store [{name: "Product A", text: large_value}], Region
161
- assert_search "product", ["Product A"], {}, Region
162
- assert_search "hello", ["Product A"], {fields: [:name, :text]}, Region
163
- # values that exceed ignore_above are not included in _all field :(
164
- # assert_search "hello", ["Product A"], {}, Region
165
- end
166
- end
@@ -1,83 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class InheritanceTest < Minitest::Test
4
- def setup
5
- skip if defined?(Cequel)
6
- super
7
- end
8
-
9
- def test_child_reindex
10
- store_names ["Max"], Cat
11
- assert Dog.reindex
12
- Animal.searchkick_index.refresh
13
- assert_equal 1, Animal.search("*").size
14
- end
15
-
16
- def test_child_index_name
17
- assert_equal "animals-#{Date.today.year}", Dog.searchkick_index.name
18
- end
19
-
20
- def test_child_search
21
- store_names ["Bear"], Dog
22
- store_names ["Bear"], Cat
23
- assert_equal 1, Dog.search("bear").size
24
- end
25
-
26
- def test_parent_search
27
- store_names ["Bear"], Dog
28
- store_names ["Bear"], Cat
29
- assert_equal 2, Animal.search("bear").size
30
- end
31
-
32
- def test_force_one_type
33
- store_names ["Green Bear"], Dog
34
- store_names ["Blue Bear"], Cat
35
- assert_equal ["Blue Bear"], Animal.search("bear", type: [Cat]).map(&:name)
36
- end
37
-
38
- def test_force_multiple_types
39
- store_names ["Green Bear"], Dog
40
- store_names ["Blue Bear"], Cat
41
- store_names ["Red Bear"], Animal
42
- assert_equal ["Green Bear", "Blue Bear"], Animal.search("bear", type: [Dog, Cat]).map(&:name)
43
- end
44
-
45
- def test_child_autocomplete
46
- store_names ["Max"], Cat
47
- store_names ["Mark"], Dog
48
- assert_equal ["Max"], Cat.search("ma", fields: [:name], match: :text_start).map(&:name)
49
- end
50
-
51
- def test_parent_autocomplete
52
- store_names ["Max"], Cat
53
- store_names ["Bear"], Dog
54
- assert_equal ["Bear"], Animal.search("bea", fields: [:name], match: :text_start).map(&:name).sort
55
- end
56
-
57
- # def test_child_suggest
58
- # store_names ["Shark"], Cat
59
- # store_names ["Sharp"], Dog
60
- # assert_equal ["shark"], Cat.search("shar", fields: [:name], suggest: true).suggestions
61
- # end
62
-
63
- def test_parent_suggest
64
- store_names ["Shark"], Cat
65
- store_names ["Tiger"], Dog
66
- assert_equal ["tiger"], Animal.search("tige", fields: [:name], suggest: true).suggestions.sort
67
- end
68
-
69
- def test_reindex
70
- store_names ["Bear A"], Cat
71
- store_names ["Bear B"], Dog
72
- Animal.reindex
73
- assert_equal 1, Dog.search("bear").size
74
- end
75
-
76
- # TODO move somewhere better
77
-
78
- def test_multiple_indices
79
- store_names ["Product A"]
80
- store_names ["Product B"], Animal
81
- assert_search "product", ["Product A", "Product B"], index_name: [Product.searchkick_index.name, Animal.searchkick_index.name], conversions: false
82
- end
83
- end
data/test/marshal_test.rb DELETED
@@ -1,8 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class MarshalTest < Minitest::Test
4
- def test_marshal
5
- store_names ["Product A"]
6
- assert Marshal.dump(Product.search("*", load: {dumpable: true}).results)
7
- end
8
- end
data/test/match_test.rb DELETED
@@ -1,276 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class MatchTest < Minitest::Test
4
- # exact
5
-
6
- def test_match
7
- store_names ["Whole Milk", "Fat Free Milk", "Milk"]
8
- assert_search "milk", ["Milk", "Whole Milk", "Fat Free Milk"]
9
- end
10
-
11
- def test_case
12
- store_names ["Whole Milk", "Fat Free Milk", "Milk"]
13
- assert_search "MILK", ["Milk", "Whole Milk", "Fat Free Milk"]
14
- end
15
-
16
- def test_cheese_space_in_index
17
- store_names ["Pepper Jack Cheese Skewers"]
18
- assert_search "pepperjack cheese skewers", ["Pepper Jack Cheese Skewers"]
19
- end
20
-
21
- # def test_cheese_space_in_query
22
- # store_names ["Pepperjack Cheese Skewers"]
23
- # assert_search "pepper jack cheese skewers", ["Pepperjack Cheese Skewers"]
24
- # end
25
-
26
- def test_middle_token
27
- store_names ["Dish Washer Amazing Organic Soap"]
28
- assert_search "dish soap", ["Dish Washer Amazing Organic Soap"]
29
- end
30
-
31
- def test_middle_token_wine
32
- store_names ["Beringer Wine Founders Estate Chardonnay"]
33
- assert_search "beringer chardonnay", ["Beringer Wine Founders Estate Chardonnay"]
34
- end
35
-
36
- def test_percent
37
- # Note: "2% Milk" doesn't get matched in ES below 5.1.1
38
- # This could be a bug since it has an edit distance of 1
39
- store_names ["1% Milk", "Whole Milk"]
40
- assert_search "1%", ["1% Milk"]
41
- end
42
-
43
- # ascii
44
-
45
- def test_jalapenos
46
- store_names ["Jalapeño"]
47
- assert_search "jalapeno", ["Jalapeño"]
48
- end
49
-
50
- def test_swedish
51
- store_names ["ÅÄÖ"]
52
- assert_search "aao", ["ÅÄÖ"]
53
- end
54
-
55
- # stemming
56
-
57
- def test_stemming
58
- store_names ["Whole Milk", "Fat Free Milk", "Milk"]
59
- assert_search "milks", ["Milk", "Whole Milk", "Fat Free Milk"]
60
- end
61
-
62
- # fuzzy
63
-
64
- def test_misspelling_sriracha
65
- store_names ["Sriracha"]
66
- assert_search "siracha", ["Sriracha"]
67
- end
68
-
69
- def test_misspelling_multiple
70
- store_names ["Greek Yogurt", "Green Onions"]
71
- assert_search "greed", ["Greek Yogurt", "Green Onions"]
72
- end
73
-
74
- def test_short_word
75
- store_names ["Finn"]
76
- assert_search "fin", ["Finn"]
77
- end
78
-
79
- def test_edit_distance_two
80
- store_names ["Bingo"]
81
- assert_search "bin", []
82
- assert_search "bingooo", []
83
- assert_search "mango", []
84
- end
85
-
86
- def test_edit_distance_one
87
- store_names ["Bingo"]
88
- assert_search "bing", ["Bingo"]
89
- assert_search "bingoo", ["Bingo"]
90
- assert_search "ringo", ["Bingo"]
91
- end
92
-
93
- def test_edit_distance_long_word
94
- store_names ["thisisareallylongword"]
95
- assert_search "thisisareallylongwor", ["thisisareallylongword"] # missing letter
96
- assert_search "thisisareelylongword", [] # edit distance = 2
97
- end
98
-
99
- def test_misspelling_tabasco
100
- store_names ["Tabasco"]
101
- assert_search "tobasco", ["Tabasco"]
102
- end
103
-
104
- def test_misspelling_zucchini
105
- store_names ["Zucchini"]
106
- assert_search "zuchini", ["Zucchini"]
107
- end
108
-
109
- def test_misspelling_ziploc
110
- store_names ["Ziploc"]
111
- assert_search "zip lock", ["Ziploc"]
112
- end
113
-
114
- def test_misspelling_zucchini_transposition
115
- store_names ["zucchini"]
116
- assert_search "zuccihni", ["zucchini"]
117
- assert_search "zuccihni", [], misspellings: {transpositions: false}
118
- end
119
-
120
- def test_misspelling_lasagna
121
- store_names ["lasagna"]
122
- assert_search "lasanga", ["lasagna"], misspellings: {transpositions: true}
123
- assert_search "lasgana", ["lasagna"], misspellings: {transpositions: true}
124
- assert_search "lasaang", [], misspellings: {transpositions: true} # triple transposition, shouldn't work
125
- assert_search "lsagana", [], misspellings: {transpositions: true} # triple transposition, shouldn't work
126
- end
127
-
128
- def test_misspelling_lasagna_pasta
129
- store_names ["lasagna pasta"]
130
- assert_search "lasanga", ["lasagna pasta"], misspellings: {transpositions: true}
131
- assert_search "lasanga pasta", ["lasagna pasta"], misspellings: {transpositions: true}
132
- assert_search "lasanga pasat", ["lasagna pasta"], misspellings: {transpositions: true} # both words misspelled with a transposition should still work
133
- end
134
-
135
- def test_misspellings_word_start
136
- store_names ["Sriracha"]
137
- assert_search "siracha", ["Sriracha"], fields: [{name: :word_start}]
138
- end
139
-
140
- # spaces
141
-
142
- def test_spaces_in_field
143
- store_names ["Red Bull"]
144
- assert_search "redbull", ["Red Bull"]
145
- end
146
-
147
- def test_spaces_in_query
148
- store_names ["Dishwasher"]
149
- assert_search "dish washer", ["Dishwasher"]
150
- end
151
-
152
- def test_spaces_three_words
153
- store_names ["Dish Washer Soap", "Dish Washer"]
154
- assert_search "dish washer soap", ["Dish Washer Soap"]
155
- end
156
-
157
- def test_spaces_stemming
158
- store_names ["Almond Milk"]
159
- assert_search "almondmilks", ["Almond Milk"]
160
- end
161
-
162
- # butter
163
-
164
- def test_exclude_butter
165
- store_names ["Butter Tub", "Peanut Butter Tub"]
166
- assert_search "butter", ["Butter Tub"], exclude: ["peanut butter"]
167
- end
168
-
169
- def test_exclude_butter_word_start
170
- store_names ["Butter Tub", "Peanut Butter Tub"]
171
- assert_search "butter", ["Butter Tub"], exclude: ["peanut butter"], match: :word_start
172
- end
173
-
174
- def test_exclude_butter_exact
175
- store_names ["Butter Tub", "Peanut Butter Tub"]
176
- assert_search "butter", [], exclude: ["peanut butter"], match: :exact
177
- end
178
-
179
- def test_exclude_same_exact
180
- store_names ["Butter Tub", "Peanut Butter Tub"]
181
- assert_search "Butter Tub", [], exclude: ["Butter Tub"], match: :exact
182
- end
183
-
184
- def test_exclude_egg_word_start
185
- store_names ["eggs", "eggplant"]
186
- assert_search "egg", ["eggs"], exclude: ["eggplant"], match: :word_start
187
- end
188
-
189
- def test_exclude_string
190
- store_names ["Butter Tub", "Peanut Butter Tub"]
191
- assert_search "butter", ["Butter Tub"], exclude: "peanut butter"
192
- end
193
-
194
- # other
195
-
196
- def test_all
197
- store_names ["Product A", "Product B"]
198
- assert_search "*", ["Product A", "Product B"]
199
- end
200
-
201
- def test_no_arguments
202
- store_names []
203
- assert_equal [], Product.search.to_a
204
- end
205
-
206
- def test_no_term
207
- store_names ["Product A"]
208
- assert_equal ["Product A"], Product.search(where: {name: "Product A"}).map(&:name)
209
- end
210
-
211
- def test_to_be_or_not_to_be
212
- store_names ["to be or not to be"]
213
- assert_search "to be", ["to be or not to be"]
214
- end
215
-
216
- def test_apostrophe
217
- store_names ["Ben and Jerry's"]
218
- assert_search "ben and jerrys", ["Ben and Jerry's"]
219
- end
220
-
221
- def test_apostrophe_search
222
- store_names ["Ben and Jerrys"]
223
- assert_search "ben and jerry's", ["Ben and Jerrys"]
224
- end
225
-
226
- def test_ampersand_index
227
- store_names ["Ben & Jerry's"]
228
- assert_search "ben and jerrys", ["Ben & Jerry's"]
229
- end
230
-
231
- def test_ampersand_search
232
- store_names ["Ben and Jerry's"]
233
- assert_search "ben & jerrys", ["Ben and Jerry's"]
234
- end
235
-
236
- def test_phrase
237
- store_names ["Fresh Honey", "Honey Fresh"]
238
- assert_search "fresh honey", ["Fresh Honey"], match: :phrase
239
- end
240
-
241
- def test_phrase_order
242
- store_names ["Wheat Bread", "Whole Wheat Bread"]
243
- assert_order "wheat bread", ["Wheat Bread", "Whole Wheat Bread"], match: :phrase
244
- end
245
-
246
- def test_dynamic_fields
247
- store_names ["Red Bull"], Speaker
248
- assert_search "redbull", ["Red Bull"], {fields: [:name]}, Speaker
249
- end
250
-
251
- def test_unsearchable
252
- store [
253
- {name: "Unsearchable", description: "Almond"}
254
- ]
255
- assert_search "almond", []
256
- end
257
-
258
- def test_unsearchable_where
259
- store [
260
- {name: "Unsearchable", description: "Almond"}
261
- ]
262
- assert_search "*", ["Unsearchable"], where: {description: "Almond"}
263
- end
264
-
265
- def test_emoji
266
- skip unless defined?(EmojiParser)
267
- store_names ["Banana"]
268
- assert_search "🍌", ["Banana"], emoji: true
269
- end
270
-
271
- def test_emoji_multiple
272
- skip unless defined?(EmojiParser)
273
- store_names ["Ice Cream Cake"]
274
- assert_search "🍨🍰", ["Ice Cream Cake"], emoji: true
275
- end
276
- end
@@ -1,56 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- class MisspellingsTest < Minitest::Test
4
- def test_misspellings
5
- store_names ["abc", "abd", "aee"]
6
- assert_search "abc", ["abc"], misspellings: false
7
- end
8
-
9
- def test_misspellings_distance
10
- store_names ["abbb", "aabb"]
11
- assert_search "aaaa", ["aabb"], misspellings: {distance: 2}
12
- end
13
-
14
- def test_misspellings_prefix_length
15
- store_names ["ap", "api", "apt", "any", "nap", "ah", "ahi"]
16
- assert_search "ap", ["ap"], misspellings: {prefix_length: 2}
17
- assert_search "api", ["ap", "api", "apt"], misspellings: {prefix_length: 2}
18
- end
19
-
20
- def test_misspellings_prefix_length_operator
21
- store_names ["ap", "api", "apt", "any", "nap", "ah", "aha"]
22
- assert_search "ap ah", ["ap", "ah"], operator: "or", misspellings: {prefix_length: 2}
23
- assert_search "api ahi", ["ap", "api", "apt", "ah", "aha"], operator: "or", misspellings: {prefix_length: 2}
24
- end
25
-
26
- def test_misspellings_fields_operator
27
- store [
28
- {name: "red", color: "red"},
29
- {name: "blue", color: "blue"},
30
- {name: "cyan", color: "blue green"},
31
- {name: "magenta", color: "red blue"},
32
- {name: "green", color: "green"}
33
- ]
34
- assert_search "red blue", ["red", "blue", "cyan", "magenta"], operator: "or", fields: ["color"], misspellings: false
35
- end
36
-
37
- def test_misspellings_below_unmet
38
- store_names ["abc", "abd", "aee"]
39
- assert_search "abc", ["abc", "abd"], misspellings: {below: 2}
40
- end
41
-
42
- def test_misspellings_below_unmet_result
43
- store_names ["abc", "abd", "aee"]
44
- assert Product.search("abc", misspellings: {below: 2}).misspellings?
45
- end
46
-
47
- def test_misspellings_below_met
48
- store_names ["abc", "abd", "aee"]
49
- assert_search "abc", ["abc"], misspellings: {below: 1}
50
- end
51
-
52
- def test_misspellings_below_met_result
53
- store_names ["abc", "abd", "aee"]
54
- assert !Product.search("abc", misspellings: {below: 1}).misspellings?
55
- end
56
- end