elastic_searchable 1.5 → 1.6

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.
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'yaml'
4
+ require 'byebug'
5
+
6
+ begin
7
+ Bundler.setup
8
+ rescue Bundler::BundlerError => e
9
+ $stderr.puts e.message
10
+ $stderr.puts "Run `bundle install` to install missing gems"
11
+ exit e.status_code
12
+ end
13
+ require 'rspec/matchers'
14
+
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
17
+
18
+ require 'elastic_searchable'
19
+ require 'prefactory'
20
+
21
+ SINGLE_NODE_CLUSTER_CONFIG = {
22
+ 'number_of_replicas' => 0,
23
+ 'number_of_shards' => 1
24
+ }
25
+
26
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
27
+
28
+ RSpec.configure do |config|
29
+ config.include Prefactory
30
+ end
@@ -0,0 +1,6 @@
1
+ class Blog < ActiveRecord::Base
2
+ elastic_searchable :if => proc {|b| b.should_index? }, :index_options => SINGLE_NODE_CLUSTER_CONFIG
3
+ def should_index?
4
+ false
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ class Book < ActiveRecord::Base
2
+ elastic_searchable
3
+ after_percolate :on_percolated
4
+ def on_percolated
5
+ @percolated = percolations
6
+ end
7
+ def percolated
8
+ @percolated
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ sqlite:
2
+ adapter: sqlite3
3
+ database: spec/elastic_searchable.sqlite3
@@ -0,0 +1,4 @@
1
+ class Friend < ActiveRecord::Base
2
+ belongs_to :book
3
+ elastic_searchable :json => {:include => {:book => {:only => :title}}, :only => :name}, :index_options => SINGLE_NODE_CLUSTER_CONFIG
4
+ end
@@ -0,0 +1,6 @@
1
+ class MaxPageSizeClass < ActiveRecord::Base
2
+ elastic_searchable :index_options => SINGLE_NODE_CLUSTER_CONFIG
3
+ def self.max_per_page
4
+ 1
5
+ end
6
+ end
@@ -0,0 +1,26 @@
1
+ class Post < ActiveRecord::Base
2
+ Post.class_eval do
3
+ elastic_searchable :index_options => SINGLE_NODE_CLUSTER_CONFIG
4
+ after_index :indexed
5
+ after_index :indexed_on_create, :on => :create
6
+ after_index :indexed_on_update, :on => :update
7
+ def indexed
8
+ @indexed = true
9
+ end
10
+ def indexed?
11
+ @indexed
12
+ end
13
+ def indexed_on_create
14
+ @indexed_on_create = true
15
+ end
16
+ def indexed_on_create?
17
+ @indexed_on_create
18
+ end
19
+ def indexed_on_update
20
+ @indexed_on_update = true
21
+ end
22
+ def indexed_on_update?
23
+ @indexed_on_update
24
+ end
25
+ end
26
+ end
File without changes
@@ -0,0 +1,8 @@
1
+ class User < ActiveRecord::Base
2
+ elastic_searchable :index_options => {
3
+ 'number_of_replicas' => 0,
4
+ 'number_of_shards' => 1,
5
+ "analysis.analyzer.default.tokenizer" => 'standard',
6
+ "analysis.analyzer.default.filter" => ["standard", "lowercase", 'porterStem']},
7
+ :mapping => {:properties => {:name => {:type => 'string', :index => 'not_analyzed'}}}
8
+ end
metadata CHANGED
@@ -1,158 +1,153 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastic_searchable
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.5'
5
- prerelease:
4
+ version: '1.6'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ryan Sonnek
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-08-05 00:00:00.000000000 Z
11
+ date: 2014-09-09 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activerecord
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: 3.0.5
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: 3.0.5
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: httparty
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: 0.6.0
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: 0.6.0
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: backgrounded
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
47
  version: 0.7.0
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ~>
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
54
  version: 0.7.0
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: multi_json
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - ">="
68
60
  - !ruby/object:Gem::Version
69
61
  version: 1.0.0
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - ">="
76
67
  - !ruby/object:Gem::Version
77
68
  version: 1.0.0
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rake
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - '='
73
+ - - ">="
84
74
  - !ruby/object:Gem::Version
85
- version: 0.9.2.2
75
+ version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - '='
80
+ - - ">="
92
81
  - !ruby/object:Gem::Version
93
- version: 0.9.2.2
82
+ version: '0'
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: sqlite3
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
- - - ! '>='
87
+ - - ">="
100
88
  - !ruby/object:Gem::Version
101
89
  version: '0'
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
- - - ! '>='
94
+ - - ">="
108
95
  - !ruby/object:Gem::Version
109
96
  version: '0'
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: pry
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
- - - '='
101
+ - - ">="
116
102
  - !ruby/object:Gem::Version
117
- version: 0.9.6.2
103
+ version: '0'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
- - - '='
108
+ - - ">="
124
109
  - !ruby/object:Gem::Version
125
- version: 0.9.6.2
110
+ version: '0'
126
111
  - !ruby/object:Gem::Dependency
127
- name: shoulda
112
+ name: rspec
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
- - - '='
115
+ - - ">="
132
116
  - !ruby/object:Gem::Version
133
- version: 2.11.3
117
+ version: '0'
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
- - - '='
122
+ - - ">="
140
123
  - !ruby/object:Gem::Version
141
- version: 2.11.3
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: byebug
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
142
139
  - !ruby/object:Gem::Dependency
143
- name: mocha
140
+ name: prefactory
144
141
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
142
  requirements:
147
- - - ! '>='
143
+ - - ">="
148
144
  - !ruby/object:Gem::Version
149
145
  version: '0'
150
146
  type: :development
151
147
  prerelease: false
152
148
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
149
  requirements:
155
- - - ! '>='
150
+ - - ">="
156
151
  - !ruby/object:Gem::Version
157
152
  version: '0'
158
153
  description: integrate the elastic search engine with rails
@@ -162,9 +157,10 @@ executables: []
162
157
  extensions: []
163
158
  extra_rdoc_files: []
164
159
  files:
165
- - .document
166
- - .gitignore
167
- - .rvmrc
160
+ - ".document"
161
+ - ".gitignore"
162
+ - ".rvmrc"
163
+ - ".travis.yml"
168
164
  - CONTRIBUTORS.txt
169
165
  - Gemfile
170
166
  - LICENSE.txt
@@ -180,36 +176,47 @@ files:
180
176
  - lib/elastic_searchable/paginator.rb
181
177
  - lib/elastic_searchable/queries.rb
182
178
  - lib/elastic_searchable/version.rb
183
- - test/database.yml
184
- - test/helper.rb
185
- - test/setup_database.rb
186
- - test/test_elastic_searchable.rb
179
+ - spec/elastic_searchable_spec.rb
180
+ - spec/spec_helper.rb
181
+ - spec/support/blog.rb
182
+ - spec/support/book.rb
183
+ - spec/support/database.yml
184
+ - spec/support/friend.rb
185
+ - spec/support/max_page_size_class.rb
186
+ - spec/support/post.rb
187
+ - spec/support/setup_database.rb
188
+ - spec/support/user.rb
187
189
  homepage: http://github.com/socialcast/elastic_searchable
188
190
  licenses: []
191
+ metadata: {}
189
192
  post_install_message:
190
193
  rdoc_options: []
191
194
  require_paths:
192
195
  - lib
193
196
  required_ruby_version: !ruby/object:Gem::Requirement
194
- none: false
195
197
  requirements:
196
- - - ! '>='
198
+ - - ">="
197
199
  - !ruby/object:Gem::Version
198
200
  version: '0'
199
201
  required_rubygems_version: !ruby/object:Gem::Requirement
200
- none: false
201
202
  requirements:
202
- - - ! '>='
203
+ - - ">="
203
204
  - !ruby/object:Gem::Version
204
205
  version: '0'
205
206
  requirements: []
206
207
  rubyforge_project: elastic_searchable
207
- rubygems_version: 1.8.24
208
+ rubygems_version: 2.2.2
208
209
  signing_key:
209
- specification_version: 3
210
+ specification_version: 4
210
211
  summary: elastic search for activerecord
211
212
  test_files:
212
- - test/database.yml
213
- - test/helper.rb
214
- - test/setup_database.rb
215
- - test/test_elastic_searchable.rb
213
+ - spec/elastic_searchable_spec.rb
214
+ - spec/spec_helper.rb
215
+ - spec/support/blog.rb
216
+ - spec/support/book.rb
217
+ - spec/support/database.yml
218
+ - spec/support/friend.rb
219
+ - spec/support/max_page_size_class.rb
220
+ - spec/support/post.rb
221
+ - spec/support/setup_database.rb
222
+ - spec/support/user.rb
data/test/database.yml DELETED
@@ -1,3 +0,0 @@
1
- sqlite:
2
- adapter: sqlite3
3
- database: test/elastic_searchable.sqlite3
data/test/helper.rb DELETED
@@ -1,37 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler'
3
- begin
4
- Bundler.setup(:default, :development)
5
- rescue Bundler::BundlerError => e
6
- $stderr.puts e.message
7
- $stderr.puts "Run `bundle install` to install missing gems"
8
- exit e.status_code
9
- end
10
- require 'test/unit'
11
- require 'shoulda'
12
- require 'mocha/setup'
13
- require 'pry'
14
-
15
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
- $LOAD_PATH.unshift(File.dirname(__FILE__))
17
- require 'elastic_searchable'
18
- require 'setup_database'
19
-
20
- class DeprecationLogger < Logger
21
- def format_message(severity, timestamp, progname, msg)
22
- "#{severity} #{msg}\n"
23
- end
24
- end
25
-
26
- DEPRECATION_LOGGER = DeprecationLogger.new(File.join(File.dirname(__FILE__), "/deprecations.log"))
27
- ActiveSupport::Deprecation.debug = false
28
- ActiveSupport::Deprecation::DEFAULT_BEHAVIORS[:deprecation_log] = lambda { |message, callstack|
29
- DEPRECATION_LOGGER.warn(message)
30
- }
31
- ActiveSupport::Deprecation.behavior = :deprecation_log
32
-
33
- class Test::Unit::TestCase
34
- def delete_index
35
- ElasticSearchable.delete '/elastic_searchable' rescue nil
36
- end
37
- end
@@ -1,626 +0,0 @@
1
- require File.join(File.dirname(__FILE__), 'helper')
2
-
3
- class TestElasticSearchable < Test::Unit::TestCase
4
- def setup
5
- delete_index
6
- end
7
- # ElasticSearchable.debug_output
8
- SINGLE_NODE_CLUSTER_CONFIG = {'number_of_replicas' => 0, 'number_of_shards' => 1}
9
-
10
- context 'non elastic activerecord class' do
11
- class Parent < ActiveRecord::Base
12
- end
13
- setup do
14
- @clazz = Parent
15
- end
16
- should 'not respond to elastic_options' do
17
- assert !@clazz.respond_to?(:elastic_options)
18
- end
19
- end
20
- context 'instance of non-elastic_searchable activerecord class' do
21
- class Parent < ActiveRecord::Base
22
- end
23
- setup do
24
- @instance = Parent.new
25
- end
26
- should 'not respond to percolations' do
27
- assert !@instance.respond_to?(:percolations)
28
- end
29
- end
30
-
31
- class Post < ActiveRecord::Base
32
- elastic_searchable :index_options => SINGLE_NODE_CLUSTER_CONFIG
33
- after_index :indexed
34
- after_index :indexed_on_create, :on => :create
35
- after_index :indexed_on_update, :on => :update
36
- def indexed
37
- @indexed = true
38
- end
39
- def indexed?
40
- @indexed
41
- end
42
- def indexed_on_create
43
- @indexed_on_create = true
44
- end
45
- def indexed_on_create?
46
- @indexed_on_create
47
- end
48
- def indexed_on_update
49
- @indexed_on_update = true
50
- end
51
- def indexed_on_update?
52
- @indexed_on_update
53
- end
54
- end
55
- context 'activerecord class with default elastic_searchable config' do
56
- setup do
57
- @clazz = Post
58
- end
59
- should 'respond to :search' do
60
- assert @clazz.respond_to?(:search)
61
- end
62
- should 'define elastic_options' do
63
- assert @clazz.elastic_options
64
- end
65
- should 'respond to :percolations' do
66
- assert @clazz.new.respond_to?(:percolations)
67
- assert_equal [], @clazz.new.percolations
68
- end
69
- end
70
-
71
- context 'Model.request with invalid url' do
72
- should 'raise error' do
73
- assert_raises ElasticSearchable::ElasticError do
74
- ElasticSearchable.request :get, '/elastic_searchable/foobar/notfound'
75
- end
76
- end
77
- end
78
-
79
- context 'Model.create_index' do
80
- setup do
81
- Post.create_index
82
- Post.refresh_index
83
- @status = ElasticSearchable.request :get, '/elastic_searchable/_status'
84
- end
85
- should 'have created index' do
86
- assert @status['ok']
87
- end
88
- end
89
-
90
- context 'Model.create' do
91
- setup do
92
- @post = Post.create :title => 'foo', :body => "bar"
93
- end
94
- should 'have fired after_index callback' do
95
- assert @post.indexed?
96
- end
97
- should 'have fired after_index_on_create callback' do
98
- assert @post.indexed_on_create?
99
- end
100
- should 'not have fired after_index_on_update callback' do
101
- assert !@post.indexed_on_update?
102
- end
103
- end
104
-
105
- context 'Model.update' do
106
- setup do
107
- Post.create :title => 'foo', :body => 'bar'
108
- @post = Post.last
109
- @post.title = 'baz'
110
- @post.save
111
- end
112
- should 'have fired after_index callback' do
113
- assert @post.indexed?
114
- end
115
- should 'not have fired after_index_on_create callback' do
116
- assert !@post.indexed_on_create?
117
- end
118
- should 'have fired after_index_on_update callback' do
119
- assert @post.indexed_on_update?
120
- end
121
- end
122
-
123
- context 'Model.create within ElasticSearchable.offline block' do
124
- setup do
125
- ElasticSearchable.offline do
126
- @post = Post.create :title => 'foo', :body => "bar"
127
- end
128
- end
129
- should 'not have fired after_index callback' do
130
- assert !@post.indexed?
131
- end
132
- should 'not have fired after_index_on_create callback' do
133
- assert !@post.indexed_on_create?
134
- end
135
- should 'not have fired after_index_on_update callback' do
136
- assert !@post.indexed_on_update?
137
- end
138
- end
139
-
140
- context 'with empty index when multiple database records' do
141
- setup do
142
- Post.delete_all
143
- Post.create_index
144
- @first_post = Post.create :title => 'foo', :body => "first bar"
145
- @second_post = Post.create :title => 'foo', :body => "second bar"
146
- Post.delete_index
147
- Post.create_index
148
- end
149
- should 'not raise error if error occurs reindexing model' do
150
- ElasticSearchable.expects(:request).raises(ElasticSearchable::ElasticError.new('faux error'))
151
- assert_nothing_raised do
152
- Post.reindex
153
- end
154
- end
155
- should 'not raise error if destroying one instance' do
156
- Logger.any_instance.expects(:warn)
157
- assert_nothing_raised do
158
- @first_post.destroy
159
- end
160
- end
161
- context 'Model.reindex' do
162
- setup do
163
- Post.reindex :per_page => 1, :scope => Post.order('body desc')
164
- Post.refresh_index
165
- end
166
- should 'have reindexed both records' do
167
- assert_nothing_raised do
168
- ElasticSearchable.request :get, "/elastic_searchable/posts/#{@first_post.id}"
169
- ElasticSearchable.request :get, "/elastic_searchable/posts/#{@second_post.id}"
170
- end
171
- end
172
- end
173
- end
174
-
175
- context 'with index containing multiple results' do
176
- setup do
177
- Post.create_index
178
- @first_post = Post.create :title => 'foo', :body => "first bar"
179
- @second_post = Post.create :title => 'foo', :body => "second bar"
180
- Post.refresh_index
181
- end
182
-
183
- context 'searching on a term that returns one result' do
184
- setup do
185
- @results = Post.search 'first'
186
- end
187
- should 'find created object' do
188
- assert_contains @results, @first_post
189
- end
190
- should 'be paginated' do
191
- assert_equal 1, @results.current_page
192
- assert_equal Post.per_page, @results.per_page
193
- assert_nil @results.previous_page
194
- assert_nil @results.next_page
195
- end
196
- should 'have populated hit' do
197
- assert_equal @results.first.hit['_id'], @first_post.id.to_s
198
- end
199
- end
200
- context 'searching on a term that returns multiple results' do
201
- setup do
202
- @results = Post.search 'foo'
203
- end
204
- should 'have populated hit on each record with the correct hit json' do
205
- assert_equal @results.first.hit['_id'], @first_post.id.to_s
206
- assert_equal @results.last.hit['_id'], @second_post.id.to_s
207
- end
208
- end
209
-
210
- context 'searching for results using a query Hash' do
211
- setup do
212
- @results = Post.search({
213
- :filtered => {
214
- :query => {
215
- :term => {:title => 'foo'},
216
- },
217
- :filter => {
218
- :or => [
219
- {:term => {:body => 'second'}},
220
- {:term => {:body => 'third'}}
221
- ]
222
- }
223
- }
224
- })
225
- end
226
- should 'find only the object which ' do
227
- assert_does_not_contain @results, @first_post
228
- assert_contains @results, @second_post
229
- end
230
- end
231
-
232
- context 'when per_page is a string' do
233
- setup do
234
- @results = Post.search 'foo', :per_page => 1.to_s, :sort => 'id'
235
- end
236
- should 'find first object' do
237
- assert_contains @results, @first_post
238
- end
239
- end
240
-
241
- context 'searching for second page using will_paginate params' do
242
- setup do
243
- @results = Post.search 'foo', :page => 2, :per_page => 1, :sort => 'id'
244
- end
245
- should 'not find objects from first page' do
246
- assert_does_not_contain @results, @first_post
247
- end
248
- should 'find second object' do
249
- assert_contains @results, @second_post
250
- end
251
- should 'be paginated' do
252
- assert_equal 2, @results.current_page
253
- assert_equal 1, @results.per_page
254
- assert_equal 1, @results.previous_page
255
- assert_nil @results.next_page
256
- end
257
- end
258
-
259
- context 'sorting search results' do
260
- setup do
261
- @results = Post.search 'foo', :sort => 'id:desc'
262
- end
263
- should 'sort results correctly' do
264
- assert_equal @second_post, @results.first
265
- assert_equal @first_post, @results.last
266
- end
267
- end
268
-
269
- context 'advanced sort options' do
270
- setup do
271
- @results = Post.search 'foo', :sort => [{:id => 'desc'}]
272
- end
273
- should 'sort results correctly' do
274
- assert_equal @second_post, @results.first
275
- assert_equal @first_post, @results.last
276
- end
277
- end
278
-
279
- context 'destroying one object' do
280
- setup do
281
- @first_post.destroy
282
- Post.refresh_index
283
- end
284
- should 'be removed from the index' do
285
- @request = ElasticSearchable.get "/elastic_searchable/posts/#{@first_post.id}"
286
- assert @request.response.is_a?(Net::HTTPNotFound), @request.inspect
287
- end
288
- end
289
- end
290
-
291
- context 'deleting a record without updating the index' do
292
-
293
- context 'backfilling partial result pages' do
294
- setup do
295
- @posts = (1..8).map do |i|
296
- Post.create :title => 'foo', :body => "#{i} bar"
297
- end
298
- Post.refresh_index
299
-
300
- @removed_posts = []
301
- @posts.each_with_index do |post, i|
302
- if i % 2 == 1
303
- @removed_posts << post
304
- post.delete
305
- Post.expects(:delete_id_from_index_backgrounded).with(post.id)
306
- end
307
- end
308
-
309
- assert_nothing_raised do
310
- @results = Post.search 'foo', :size => 4, :sort => 'id:desc'
311
- end
312
- end
313
- # should 'not raise an exception' do end
314
- # should 'trigger deletion of bad index records' do end
315
- should 'backfill the first page with results from other pages' do
316
- assert_equal((@posts - @removed_posts).reverse, @results)
317
- end
318
- should 'adjust total hit count to exclude invalid results encountered from repaging' do
319
- assert_equal 4, @results.total_entries
320
- end
321
- end
322
-
323
- end
324
-
325
- class Blog < ActiveRecord::Base
326
- elastic_searchable :if => proc {|b| b.should_index? }, :index_options => SINGLE_NODE_CLUSTER_CONFIG
327
- def should_index?
328
- false
329
- end
330
- end
331
- context 'activerecord class with optional :if=>proc configuration' do
332
- context 'when creating new instance' do
333
- setup do
334
- Blog.any_instance.expects(:reindex).never
335
- @blog = Blog.create! :title => 'foo'
336
- end
337
- should 'not index record' do end #see expectations
338
- should 'not be found in elasticsearch' do
339
- @request = ElasticSearchable.get "/elastic_searchable/blogs/#{@blog.id}"
340
- assert @request.response.is_a?(Net::HTTPNotFound), @request.inspect
341
- end
342
- end
343
- end
344
-
345
- class User < ActiveRecord::Base
346
- elastic_searchable :index_options => {
347
- 'number_of_replicas' => 0,
348
- 'number_of_shards' => 1,
349
- "analysis.analyzer.default.tokenizer" => 'standard',
350
- "analysis.analyzer.default.filter" => ["standard", "lowercase", 'porterStem']},
351
- :mapping => {:properties => {:name => {:type => 'string', :index => 'not_analyzed'}}}
352
- end
353
- context 'activerecord class with :index_options and :mapping' do
354
- context 'creating index' do
355
- setup do
356
- User.create_index
357
- end
358
- should 'have used custom index_options' do
359
- @status = ElasticSearchable.request :get, '/elastic_searchable/_settings'
360
- @status['elastic_searchable']['settings'].delete('index.version.created')
361
- expected = {
362
- "index.number_of_replicas" => "0",
363
- "index.number_of_shards" => "1",
364
- "index.analysis.analyzer.default.tokenizer" => "standard",
365
- "index.analysis.analyzer.default.filter.0" => "standard",
366
- "index.analysis.analyzer.default.filter.1" => "lowercase",
367
- "index.analysis.analyzer.default.filter.2" => "porterStem"
368
- }
369
- assert_equal expected, @status['elastic_searchable']['settings'], @status.inspect
370
- end
371
- should 'have set mapping' do
372
- @status = ElasticSearchable.request :get, '/elastic_searchable/users/_mapping'
373
- expected = {
374
- "name"=> {"type"=>"string", "index"=>"not_analyzed"}
375
- }
376
- assert_equal expected, @status['users']['properties'], @status.inspect
377
- end
378
- end
379
- end
380
-
381
- class Friend < ActiveRecord::Base
382
- belongs_to :book
383
- elastic_searchable :json => {:include => {:book => {:only => :title}}, :only => :name}, :index_options => SINGLE_NODE_CLUSTER_CONFIG
384
- end
385
- context 'activerecord class with optional :json config' do
386
- context 'creating index' do
387
- setup do
388
- Friend.create_index
389
- @book = Book.create! :isbn => '123abc', :title => 'another world'
390
- @friend = Friend.new :name => 'bob', :favorite_color => 'red'
391
- @friend.book = @book
392
- @friend.save!
393
- Friend.refresh_index
394
- end
395
- should 'index json with configuration' do
396
- @response = ElasticSearchable.request :get, "/elastic_searchable/friends/#{@friend.id}"
397
- # should not index:
398
- # friend.favorite_color
399
- # book.isbn
400
- expected = {
401
- "name" => 'bob',
402
- 'book' => {'title' => 'another world'}
403
- }
404
- assert_equal expected, @response['_source'], @response.inspect
405
- end
406
- end
407
- end
408
-
409
- context 'updating ElasticSearchable.default_index' do
410
- setup do
411
- ElasticSearchable.default_index = 'my_new_index'
412
- end
413
- teardown do
414
- ElasticSearchable.default_index = ElasticSearchable::DEFAULT_INDEX
415
- end
416
- should 'change default index' do
417
- assert_equal 'my_new_index', ElasticSearchable.default_index
418
- end
419
- end
420
-
421
- class Book < ActiveRecord::Base
422
- elastic_searchable
423
- after_percolate :on_percolated
424
- def on_percolated
425
- @percolated = percolations
426
- end
427
- def percolated
428
- @percolated
429
- end
430
- end
431
- context 'Book class with after_percolate callback' do
432
- context 'with created index' do
433
- setup do
434
- Book.create_index
435
- end
436
- context "when index has configured percolation" do
437
- setup do
438
- ElasticSearchable.request :put, '/_percolator/elastic_searchable/myfilter', :json_body => {:query => {:query_string => {:query => 'foo' }}}
439
- ElasticSearchable.request :post, '/_percolator/_refresh'
440
- end
441
- context 'creating an object that does not match the percolation' do
442
- setup do
443
- Book.any_instance.expects(:on_percolated).never
444
- @book = Book.create! :title => 'bar'
445
- end
446
- should 'not percolate the record' do end #see expectations
447
- end
448
- context 'creating an object that matches the percolation' do
449
- setup do
450
- @book = Book.create :title => "foo"
451
- end
452
- should 'return percolated matches in the callback' do
453
- assert_equal ['myfilter'], @book.percolated
454
- end
455
- end
456
- context 'percolating a non-persisted object' do
457
- setup do
458
- @matches = Book.new(:title => 'foo').percolate
459
- end
460
- should 'return percolated matches' do
461
- assert_equal ['myfilter'], @matches
462
- end
463
- end
464
- context "with multiple percolators" do
465
- setup do
466
- ElasticSearchable.request :put, '/_percolator/elastic_searchable/greenfilter', :json_body => { :color => 'green', :query => {:query_string => {:query => 'foo' }}}
467
- ElasticSearchable.request :put, '/_percolator/elastic_searchable/bluefilter', :json_body => { :color => 'blue', :query => {:query_string => {:query => 'foo' }}}
468
- ElasticSearchable.request :post, '/_percolator/_refresh'
469
- end
470
- context 'percolating a non-persisted object with no limitation' do
471
- setup do
472
- @matches = Book.new(:title => 'foo').percolate
473
- end
474
- should 'return all percolated matches' do
475
- assert_equal ['bluefilter','greenfilter','myfilter'], @matches.sort
476
- end
477
- end
478
- context 'percolating a non-persisted object with limitations' do
479
- setup do
480
- @matches = Book.new(:title => 'foo').percolate( { :term => { :color => 'green' }} )
481
- end
482
- should 'return limited percolated matches' do
483
- assert_equal ['greenfilter'], @matches
484
- end
485
- end
486
- end
487
- end
488
- end
489
- end
490
-
491
- class MaxPageSizeClass < ActiveRecord::Base
492
- elastic_searchable :index_options => SINGLE_NODE_CLUSTER_CONFIG
493
- def self.max_per_page
494
- 1
495
- end
496
- end
497
- context 'with 2 MaxPageSizeClass instances' do
498
- setup do
499
- MaxPageSizeClass.create_index
500
- @first = MaxPageSizeClass.create! :name => 'foo one'
501
- @second = MaxPageSizeClass.create! :name => 'foo two'
502
- MaxPageSizeClass.refresh_index
503
- end
504
- context 'MaxPageSizeClass.search with default options and WillPaginate' do
505
- setup do
506
- ElasticSearchable::Paginator.handler = ElasticSearchable::Pagination::WillPaginate
507
- @results = MaxPageSizeClass.search 'foo'
508
- end
509
- should 'have one per page' do
510
- assert_equal 1, @results.per_page
511
- end
512
- should 'return one instance' do
513
- assert_equal 1, @results.length
514
- end
515
- should 'have second page' do
516
- assert_equal 2, @results.total_entries
517
- end
518
- end
519
-
520
- context 'MaxPageSizeClass.search with default options and Kaminari' do
521
- setup do
522
- ElasticSearchable::Paginator.handler = ElasticSearchable::Pagination::Kaminari
523
- @results = MaxPageSizeClass.search 'foo'
524
- end
525
- should 'have one per page' do
526
- assert_equal 1, @results.per_page
527
- end
528
- should 'return one instance' do
529
- assert_equal 1, @results.length
530
- end
531
- should 'have second page' do
532
- assert_equal 2, @results.total_entries
533
- end
534
- should 'have a total of 2 pages' do
535
- assert_equal 2, @results.num_pages
536
- end
537
- end
538
-
539
- context "escape_query" do
540
- should "escape exclamation marks" do
541
- queryString = '!'
542
- result = ElasticSearchable.escape_query(queryString)
543
- assert_equal '\!', result
544
- end
545
-
546
- should "escape ^" do
547
- queryString = '^'
548
- result = ElasticSearchable.escape_query(queryString)
549
- assert_equal '\^', result
550
- end
551
-
552
- should "escape +" do
553
- queryString = '+'
554
- result = ElasticSearchable.escape_query(queryString)
555
- assert_equal '\+', result
556
- end
557
-
558
- should "escape -" do
559
- queryString = '-'
560
- result = ElasticSearchable.escape_query(queryString)
561
- assert_equal '\-', result
562
- end
563
-
564
- should "escape (" do
565
- queryString = '('
566
- result = ElasticSearchable.escape_query(queryString)
567
- assert_equal '\(', result
568
- end
569
-
570
- should "escape )" do
571
- queryString = ')'
572
- result = ElasticSearchable.escape_query(queryString)
573
- assert_equal '\)', result
574
- end
575
-
576
- should "escape {" do
577
- queryString = '}'
578
- result = ElasticSearchable.escape_query(queryString)
579
- assert_equal '\}', result
580
- end
581
-
582
- should "escape [" do
583
- queryString = '['
584
- result = ElasticSearchable.escape_query(queryString)
585
- assert_equal '\[', result
586
- end
587
-
588
- should "escape ]" do
589
- queryString = ']'
590
- result = ElasticSearchable.escape_query(queryString)
591
- assert_equal '\]', result
592
- end
593
-
594
- should 'escape "' do
595
- queryString = '"'
596
- result = ElasticSearchable.escape_query(queryString)
597
- assert_equal '\"', result
598
- end
599
-
600
- should "escape ~" do
601
- queryString = '~'
602
- result = ElasticSearchable.escape_query(queryString)
603
- assert_equal '\~', result
604
- end
605
-
606
- should "escape *" do
607
- queryString = '*'
608
- result = ElasticSearchable.escape_query(queryString)
609
- assert_equal '\*', result
610
- end
611
-
612
- should "escape :" do
613
- queryString = ':'
614
- result = ElasticSearchable.escape_query(queryString)
615
- assert_equal '\:', result
616
- end
617
-
618
- should "escape ?" do
619
- queryString = '?'
620
- result = ElasticSearchable.escape_query(queryString)
621
- assert_equal '\?', result
622
- end
623
- end
624
- end
625
- end
626
-