Commit 39b9f96d1896d0c3acceca65f64697a05a63ef08
1 parent
5e591bff
Exists in
master
and in
21 other branches
Added tests
Showing
5 changed files
with
254 additions
and
0 deletions
Show diff stats
.gitignore
Rakefile
searchkick.gemspec
... | ... | @@ -0,0 +1,238 @@ |
1 | +require "test_helper" | |
2 | + | |
3 | +class TestSearchkick < Minitest::Unit::TestCase | |
4 | + | |
5 | + def setup | |
6 | + $index = Tire::Index.new("products") | |
7 | + $index.delete | |
8 | + index_options = { | |
9 | + settings: { | |
10 | + number_of_shards: 1, | |
11 | + analysis: { | |
12 | + analyzer: { | |
13 | + searchkick_keyword: { | |
14 | + type: "custom", | |
15 | + tokenizer: "keyword", | |
16 | + filter: ["lowercase", "snowball"] | |
17 | + }, | |
18 | + searchkick: { | |
19 | + type: "custom", | |
20 | + tokenizer: "standard", | |
21 | + # synonym should come last, after stemming and shingle | |
22 | + # shingle must come before snowball | |
23 | + filter: ["standard", "lowercase", "asciifolding", "stop", "searchkick_shingle", "snowball", "searchkick_synonym"] | |
24 | + } | |
25 | + }, | |
26 | + filter: { | |
27 | + searchkick_shingle: { | |
28 | + type: "shingle", | |
29 | + token_separator: "" | |
30 | + }, | |
31 | + searchkick_synonym: { | |
32 | + type: "synonym", | |
33 | + ignore_case: true, | |
34 | + synonyms: [ | |
35 | + "clorox => bleach", | |
36 | + "saran wrap => plastic wrap", | |
37 | + "scallion => green onion", | |
38 | + "qtip => cotton swab" | |
39 | + ] | |
40 | + } | |
41 | + } | |
42 | + } | |
43 | + }, | |
44 | + mappings: { | |
45 | + document: { | |
46 | + properties: { | |
47 | + name: { | |
48 | + type: "string", | |
49 | + analyzer: "searchkick" | |
50 | + }, | |
51 | + conversions: { | |
52 | + type: "nested", | |
53 | + properties: { | |
54 | + query: { | |
55 | + type: "string", | |
56 | + analyzer: "searchkick_keyword" | |
57 | + }, | |
58 | + count: { | |
59 | + type: "integer" | |
60 | + } | |
61 | + } | |
62 | + } | |
63 | + } | |
64 | + } | |
65 | + } | |
66 | + } | |
67 | + $index.create index_options | |
68 | + end | |
69 | + | |
70 | + # exact | |
71 | + | |
72 | + def test_match | |
73 | + store_names ["Whole Milk", "Fat Free Milk", "Milk"] | |
74 | + assert_search "milk", ["Milk", "Whole Milk", "Fat Free Milk"] | |
75 | + end | |
76 | + | |
77 | + def test_case | |
78 | + store_names ["Whole Milk", "Fat Free Milk", "Milk"] | |
79 | + assert_search "MILK", ["Milk", "Whole Milk", "Fat Free Milk"] | |
80 | + end | |
81 | + | |
82 | + # ascii | |
83 | + | |
84 | + def test_jalapenos | |
85 | + store_names ["Jalapeño"] | |
86 | + assert_search "jalapeno", ["Jalapeño"] | |
87 | + end | |
88 | + | |
89 | + # stemming | |
90 | + | |
91 | + def test_stemming | |
92 | + store_names ["Whole Milk", "Fat Free Milk", "Milk"] | |
93 | + assert_search "milks", ["Milk", "Whole Milk", "Fat Free Milk"] | |
94 | + end | |
95 | + | |
96 | + # fuzzy | |
97 | + | |
98 | + def test_fuzzy | |
99 | + store_names ["Sliced Beets", "Beef"] | |
100 | + assert_search "beets", ["Sliced Beets", "Beef"] | |
101 | + end | |
102 | + | |
103 | + # conversions | |
104 | + | |
105 | + def test_conversions | |
106 | + store [ | |
107 | + {name: "Tomato Sauce", conversions: [{query: "tomato sauce", count: 100}, {query: "tomato", count: 2}]}, | |
108 | + {name: "Tomato Paste", conversions: []}, | |
109 | + {name: "Tomatoes", conversions: [{query: "tomato", count: 100}, {query: "tomato sauce", count: 2}]} | |
110 | + ] | |
111 | + assert_search "tomato sauce", ["Tomato Sauce", "Tomatoes"] #, "Tomato Paste"] | |
112 | + assert_search "tomato", ["Tomatoes", "Tomato Sauce", "Tomato Paste"] | |
113 | + assert_search "tomato paste", ["Tomato Paste"] #, "Tomatoes", "Tomato Sauce"] | |
114 | + end | |
115 | + | |
116 | + def test_conversions_stemmed | |
117 | + store [ | |
118 | + {name: "Tomato A", conversions: [{query: "tomato", count: 1}, {query: "tomatos", count: 1}, {query: "Tomatoes", count: 3}]}, | |
119 | + {name: "Tomato B", conversions: [{query: "tomato", count: 4}]} | |
120 | + ] | |
121 | + assert_search "tomato", ["Tomato A", "Tomato B"] | |
122 | + end | |
123 | + | |
124 | + # spaces | |
125 | + | |
126 | + def test_spaces_in_field | |
127 | + store_names ["Red Bull"] | |
128 | + assert_search "redbull", ["Red Bull"] | |
129 | + end | |
130 | + | |
131 | + def test_spaces_in_query | |
132 | + store_names ["Dishwasher Soap"] | |
133 | + assert_search "dish washer", ["Dishwasher Soap"] | |
134 | + end | |
135 | + | |
136 | + def test_spaces_three_words | |
137 | + store_names ["Dish Washer Soap", "Dish Washer"] | |
138 | + assert_search "dish washer soap", ["Dish Washer Soap"] | |
139 | + end | |
140 | + | |
141 | + def test_spaces_stemming | |
142 | + store_names ["Almond Milk"] | |
143 | + assert_search "almondmilks", ["Almond Milk"] | |
144 | + end | |
145 | + | |
146 | + # keywords | |
147 | + | |
148 | + def test_keywords | |
149 | + store_names ["Clorox Bleach", "Kroger Bleach", "Saran Wrap", "Kroger Plastic Wrap"] | |
150 | + assert_search "clorox", ["Clorox Bleach", "Kroger Bleach"] | |
151 | + assert_search "saran wrap", ["Saran Wrap", "Kroger Plastic Wrap"] | |
152 | + end | |
153 | + | |
154 | + def test_keywords_qtips | |
155 | + store_names ["Q Tips", "Kroger Cotton Swabs"] | |
156 | + assert_search "q tips", ["Q Tips", "Kroger Cotton Swabs"] | |
157 | + end | |
158 | + | |
159 | + def test_keywords_exact | |
160 | + store_names ["Green Onions", "Yellow Onions"] | |
161 | + assert_search "scallion", ["Green Onions"] | |
162 | + end | |
163 | + | |
164 | + def test_keywords_stemmed | |
165 | + store_names ["Green Onions", "Yellow Onions"] | |
166 | + assert_search "scallions", ["Green Onions"] | |
167 | + end | |
168 | + | |
169 | + # global boost | |
170 | + | |
171 | + def test_boost | |
172 | + store [ | |
173 | + {name: "Organic Tomato A", _boost: 10}, | |
174 | + {name: "Tomato B"} | |
175 | + ] | |
176 | + assert_search "tomato", ["Organic Tomato A", "Tomato B"] | |
177 | + end | |
178 | + | |
179 | + def test_boost_zero | |
180 | + store [ | |
181 | + {name: "Zero Boost", _boost: 0} | |
182 | + ] | |
183 | + assert_search "zero", ["Zero Boost"] | |
184 | + end | |
185 | + | |
186 | + # default to 1 | |
187 | + def test_boost_null | |
188 | + store [ | |
189 | + {name: "Zero Boost A", _boost: 1.1}, | |
190 | + {name: "Zero Boost B"}, | |
191 | + {name: "Zero Boost C", _boost: 0.9}, | |
192 | + ] | |
193 | + assert_search "zero", ["Zero Boost A", "Zero Boost B", "Zero Boost C"] | |
194 | + end | |
195 | + | |
196 | + protected | |
197 | + | |
198 | + def store(documents) | |
199 | + documents.each do |document| | |
200 | + $index.store document | |
201 | + end | |
202 | + $index.refresh | |
203 | + end | |
204 | + | |
205 | + def store_names(names) | |
206 | + store names.map{|name| {name: name} } | |
207 | + end | |
208 | + | |
209 | + def assert_search(term, expected) | |
210 | + fields = ["name"] | |
211 | + search = | |
212 | + Tire.search "products", type: "document" do | |
213 | + query do | |
214 | + boolean do | |
215 | + should do | |
216 | + match fields, term, boost: 10 | |
217 | + end | |
218 | + should do | |
219 | + match fields, term, use_dis_max: false, fuzziness: 0.6, max_expansions: 4, prefix_length: 2 | |
220 | + end | |
221 | + should do | |
222 | + nested path: "conversions", score_mode: "total" do | |
223 | + query do | |
224 | + custom_score script: "log(doc['count'].value)" do | |
225 | + match "query", term | |
226 | + end | |
227 | + end | |
228 | + end | |
229 | + end | |
230 | + end | |
231 | + end | |
232 | + explain true | |
233 | + end | |
234 | + | |
235 | + assert_equal expected, search.results.map(&:name) | |
236 | + end | |
237 | + | |
238 | +end | ... | ... |