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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +377 -84
- data/LICENSE.txt +1 -1
- data/README.md +859 -602
- data/lib/searchkick/bulk_reindex_job.rb +13 -9
- data/lib/searchkick/controller_runtime.rb +40 -0
- data/lib/searchkick/hash_wrapper.rb +12 -0
- data/lib/searchkick/index.rb +281 -356
- data/lib/searchkick/index_cache.rb +30 -0
- data/lib/searchkick/index_options.rb +487 -281
- data/lib/searchkick/indexer.rb +15 -8
- data/lib/searchkick/log_subscriber.rb +57 -0
- data/lib/searchkick/middleware.rb +9 -2
- data/lib/searchkick/model.rb +72 -118
- data/lib/searchkick/multi_search.rb +9 -10
- data/lib/searchkick/process_batch_job.rb +12 -15
- data/lib/searchkick/process_queue_job.rb +22 -13
- data/lib/searchkick/query.rb +458 -217
- data/lib/searchkick/railtie.rb +7 -0
- data/lib/searchkick/record_data.rb +128 -0
- data/lib/searchkick/record_indexer.rb +164 -0
- data/lib/searchkick/reindex_queue.rb +51 -9
- data/lib/searchkick/reindex_v2_job.rb +10 -32
- data/lib/searchkick/relation.rb +247 -0
- data/lib/searchkick/relation_indexer.rb +155 -0
- data/lib/searchkick/results.rb +201 -82
- data/lib/searchkick/version.rb +1 -1
- data/lib/searchkick/where.rb +11 -0
- data/lib/searchkick.rb +269 -97
- data/lib/tasks/searchkick.rake +37 -0
- metadata +24 -178
- data/.gitignore +0 -22
- data/.travis.yml +0 -39
- data/Gemfile +0 -16
- data/Rakefile +0 -20
- data/benchmark/Gemfile +0 -23
- data/benchmark/benchmark.rb +0 -97
- data/lib/searchkick/logging.rb +0 -242
- data/lib/searchkick/tasks.rb +0 -33
- data/searchkick.gemspec +0 -28
- data/test/aggs_test.rb +0 -197
- data/test/autocomplete_test.rb +0 -75
- data/test/boost_test.rb +0 -202
- data/test/callbacks_test.rb +0 -59
- data/test/ci/before_install.sh +0 -17
- data/test/errors_test.rb +0 -19
- data/test/gemfiles/activerecord31.gemfile +0 -7
- data/test/gemfiles/activerecord32.gemfile +0 -7
- data/test/gemfiles/activerecord40.gemfile +0 -8
- data/test/gemfiles/activerecord41.gemfile +0 -8
- data/test/gemfiles/activerecord42.gemfile +0 -7
- data/test/gemfiles/activerecord50.gemfile +0 -7
- data/test/gemfiles/apartment.gemfile +0 -8
- data/test/gemfiles/cequel.gemfile +0 -8
- data/test/gemfiles/mongoid2.gemfile +0 -7
- data/test/gemfiles/mongoid3.gemfile +0 -6
- data/test/gemfiles/mongoid4.gemfile +0 -7
- data/test/gemfiles/mongoid5.gemfile +0 -7
- data/test/gemfiles/mongoid6.gemfile +0 -12
- data/test/gemfiles/nobrainer.gemfile +0 -8
- data/test/gemfiles/parallel_tests.gemfile +0 -8
- data/test/geo_shape_test.rb +0 -175
- data/test/highlight_test.rb +0 -78
- data/test/index_test.rb +0 -166
- data/test/inheritance_test.rb +0 -83
- data/test/marshal_test.rb +0 -8
- data/test/match_test.rb +0 -276
- data/test/misspellings_test.rb +0 -56
- data/test/model_test.rb +0 -42
- data/test/multi_search_test.rb +0 -36
- data/test/multi_tenancy_test.rb +0 -22
- data/test/order_test.rb +0 -46
- data/test/pagination_test.rb +0 -70
- data/test/partial_reindex_test.rb +0 -58
- data/test/query_test.rb +0 -35
- data/test/records_test.rb +0 -10
- data/test/reindex_test.rb +0 -64
- data/test/reindex_v2_job_test.rb +0 -32
- data/test/routing_test.rb +0 -23
- data/test/should_index_test.rb +0 -32
- data/test/similar_test.rb +0 -28
- data/test/sql_test.rb +0 -214
- data/test/suggest_test.rb +0 -95
- data/test/support/kaminari.yml +0 -21
- data/test/synonyms_test.rb +0 -67
- data/test/test_helper.rb +0 -567
- data/test/where_test.rb +0 -223
data/test/highlight_test.rb
DELETED
@@ -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 "<b><em>Hello</em></b>", 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
|
data/test/inheritance_test.rb
DELETED
@@ -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
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
|
data/test/misspellings_test.rb
DELETED
@@ -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
|