Commit 39b9f96d1896d0c3acceca65f64697a05a63ef08

Authored by Andrew Kane
1 parent 5e591bff

Added tests

.gitignore
... ... @@ -15,3 +15,4 @@ spec/reports
15 15 test/tmp
16 16 test/version_tmp
17 17 tmp
  18 +*.log
... ...
Rakefile
1 1 require "bundler/gem_tasks"
  2 +require "rake/testtask"
  3 +
  4 +task :default => :test
  5 +Rake::TestTask.new do |t|
  6 + t.libs << "test"
  7 + t.pattern = "test/**/*_test.rb"
  8 +end
... ...
searchkick.gemspec
... ... @@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
22 22  
23 23 spec.add_development_dependency "bundler", "~> 1.3"
24 24 spec.add_development_dependency "rake"
  25 + spec.add_development_dependency "minitest"
25 26 end
... ...
test/searchkick_test.rb 0 → 100644
... ... @@ -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
... ...
test/test_helper.rb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +require "bundler/setup"
  2 +Bundler.require(:default)
  3 +require "minitest/autorun"
  4 +require "minitest/pride"
  5 +
  6 +File.delete("elasticsearch.log") if File.exists?("elasticsearch.log")
  7 +Tire.configure { logger "elasticsearch.log", :level => "debug" }
... ...