elasticsearch-model 0.1.1 → 0.1.2

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.
@@ -95,6 +95,18 @@ if ENV["MONGODB_AVAILABLE"]
95
95
  end
96
96
  end
97
97
 
98
+ should "preserve the search results order for records" do
99
+ response = MongoidArticle.search('title:code')
100
+
101
+ response.records.each_with_hit do |r, h|
102
+ assert_equal h._id, r.id.to_s
103
+ end
104
+
105
+ response.records.map_with_hit do |r, h|
106
+ assert_equal h._id, r.id.to_s
107
+ end
108
+ end
109
+
98
110
  should "remove document from index on destroy" do
99
111
  article = MongoidArticle.first
100
112
 
@@ -82,13 +82,42 @@ class Elasticsearch::Model::AdapterActiveRecordTest < Test::Unit::TestCase
82
82
  end
83
83
 
84
84
  context "Importing" do
85
+ setup do
86
+ DummyClassForActiveRecord.__send__ :extend, Elasticsearch::Model::Adapter::ActiveRecord::Importing
87
+ end
88
+
89
+ should "raise an exception when passing an invalid scope" do
90
+ assert_raise NoMethodError do
91
+ DummyClassForActiveRecord.__find_in_batches(scope: :not_found_method) do; end
92
+ end
93
+ end
94
+
85
95
  should "implement the __find_in_batches method" do
86
96
  DummyClassForActiveRecord.expects(:find_in_batches).returns([])
87
-
88
- DummyClassForActiveRecord.__send__ :extend, Elasticsearch::Model::Adapter::ActiveRecord::Importing
89
97
  DummyClassForActiveRecord.__find_in_batches do; end
90
98
  end
91
- end
92
99
 
100
+ should "limit the relation to a specific scope" do
101
+ DummyClassForActiveRecord.expects(:find_in_batches).returns([])
102
+ DummyClassForActiveRecord.expects(:published).returns(DummyClassForActiveRecord)
103
+
104
+ DummyClassForActiveRecord.__find_in_batches(scope: :published) do; end
105
+ end
106
+
107
+ context "when transforming models" do
108
+ setup do
109
+ @transform = DummyClassForActiveRecord.__transform
110
+ end
111
+
112
+ should "provide an object that responds to #call" do
113
+ assert_respond_to @transform, :call
114
+ end
115
+
116
+ should "provide default transformation" do
117
+ model = mock("model", id: 1, __elasticsearch__: stub(as_indexed_json: {}))
118
+ assert_equal @transform.call(model), { index: { _id: 1, data: {} } }
119
+ end
120
+ end
121
+ end
93
122
  end
94
123
  end
@@ -19,11 +19,21 @@ class Elasticsearch::Model::AdapterDefaultTest < Test::Unit::TestCase
19
19
  assert_instance_of Module, Elasticsearch::Model::Adapter::Default::Callbacks
20
20
  end
21
21
 
22
- should "have the default Importing implementation" do
23
- DummyClassForDefaultAdapter.__send__ :include, Elasticsearch::Model::Adapter::Default::Importing
22
+ context "concerning abstract methods" do
23
+ setup do
24
+ DummyClassForDefaultAdapter.__send__ :include, Elasticsearch::Model::Adapter::Default::Importing
25
+ end
26
+
27
+ should "have the default Importing implementation" do
28
+ assert_raise Elasticsearch::Model::NotImplemented do
29
+ DummyClassForDefaultAdapter.new.__find_in_batches
30
+ end
31
+ end
24
32
 
25
- assert_raise Elasticsearch::Model::NotImplemented do
26
- DummyClassForDefaultAdapter.new.__find_in_batches
33
+ should "have the default transform implementation" do
34
+ assert_raise Elasticsearch::Model::NotImplemented do
35
+ DummyClassForDefaultAdapter.new.__transform
36
+ end
27
37
  end
28
38
  end
29
39
 
@@ -81,6 +81,21 @@ class Elasticsearch::Model::AdapterMongoidTest < Test::Unit::TestCase
81
81
  DummyClassForMongoid.__send__ :extend, Elasticsearch::Model::Adapter::Mongoid::Importing
82
82
  DummyClassForMongoid.__find_in_batches do; end
83
83
  end
84
+
85
+ context "when transforming models" do
86
+ setup do
87
+ @transform = DummyClassForMongoid.__transform
88
+ end
89
+
90
+ should "provide an object that responds to #call" do
91
+ assert_respond_to @transform, :call
92
+ end
93
+
94
+ should "provide basic transformation" do
95
+ model = mock("model", id: 1, as_indexed_json: {})
96
+ assert_equal @transform.call(model), { index: { _id: "1", data: {} } }
97
+ end
98
+ end
84
99
  end
85
100
 
86
101
  end
@@ -10,6 +10,9 @@ class Elasticsearch::Model::ImportingTest < Test::Unit::TestCase
10
10
  def __find_in_batches(options={}, &block)
11
11
  yield if block_given?
12
12
  end
13
+ def __transform
14
+ lambda {|a|}
15
+ end
13
16
  end
14
17
 
15
18
  def importing_mixin
@@ -41,7 +44,7 @@ class Elasticsearch::Model::ImportingTest < Test::Unit::TestCase
41
44
  DummyImportingModel.expects(:client).returns(client)
42
45
  DummyImportingModel.expects(:index_name).returns('foo')
43
46
  DummyImportingModel.expects(:document_type).returns('foo')
44
-
47
+ DummyImportingModel.stubs(:__batch_to_bulk)
45
48
  assert_equal 0, DummyImportingModel.import
46
49
  end
47
50
 
@@ -58,6 +61,7 @@ class Elasticsearch::Model::ImportingTest < Test::Unit::TestCase
58
61
  DummyImportingModel.stubs(:client).returns(client)
59
62
  DummyImportingModel.stubs(:index_name).returns('foo')
60
63
  DummyImportingModel.stubs(:document_type).returns('foo')
64
+ DummyImportingModel.stubs(:__batch_to_bulk)
61
65
 
62
66
  assert_equal 1, DummyImportingModel.import
63
67
  end
@@ -75,6 +79,7 @@ class Elasticsearch::Model::ImportingTest < Test::Unit::TestCase
75
79
  DummyImportingModel.stubs(:client).returns(client)
76
80
  DummyImportingModel.stubs(:index_name).returns('foo')
77
81
  DummyImportingModel.stubs(:document_type).returns('foo')
82
+ DummyImportingModel.stubs(:__batch_to_bulk)
78
83
 
79
84
  DummyImportingModel.import do |response|
80
85
  assert_equal 2, response['items'].size
@@ -116,8 +121,36 @@ class Elasticsearch::Model::ImportingTest < Test::Unit::TestCase
116
121
  .returns({'items' => [ {'index' => {} }]})
117
122
 
118
123
  DummyImportingModel.stubs(:client).returns(client)
124
+ DummyImportingModel.stubs(:__batch_to_bulk)
119
125
 
120
126
  DummyImportingModel.import index: 'my-new-index', type: 'my-other-type'
121
127
  end
128
+
129
+ should "use the default transform from adapter" do
130
+ client = mock('client', bulk: {'items' => []})
131
+ transform = lambda {|a|}
132
+
133
+ DummyImportingModel.stubs(:client).returns(client)
134
+ DummyImportingModel.expects(:__transform).returns(transform)
135
+ DummyImportingModel.expects(:__batch_to_bulk).with(anything, transform)
136
+
137
+ DummyImportingModel.import index: 'foo', type: 'bar'
138
+ end
139
+
140
+ should "use the transformer from options" do
141
+ client = mock('client', bulk: {'items' => []})
142
+ transform = lambda {|a|}
143
+
144
+ DummyImportingModel.stubs(:client).returns(client)
145
+ DummyImportingModel.expects(:__batch_to_bulk).with(anything, transform)
146
+
147
+ DummyImportingModel.import index: 'foo', type: 'bar', transform: transform
148
+ end
149
+
150
+ should "raise an ArgumentError if transform doesn't respond to the call method" do
151
+ assert_raise ArgumentError do
152
+ DummyImportingModel.import index: 'foo', type: 'bar', transform: "not_callable"
153
+ end
154
+ end
122
155
  end
123
156
  end
@@ -47,6 +47,12 @@ class Elasticsearch::Model::IndexingTest < Test::Unit::TestCase
47
47
  assert_instance_of Elasticsearch::Model::Indexing::Mappings, DummyIndexingModel.mappings
48
48
  end
49
49
 
50
+ should "raise an exception when not passed type" do
51
+ assert_raise ArgumentError do
52
+ Elasticsearch::Model::Indexing::Mappings.new
53
+ end
54
+ end
55
+
50
56
  should "be convertible to hash" do
51
57
  mappings = Elasticsearch::Model::Indexing::Mappings.new :mytype, { foo: 'bar' }
52
58
  assert_equal( { :mytype => { foo: 'bar', :properties => {} } }, mappings.to_hash )
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class Elasticsearch::Model::ResponsePaginationTest < Test::Unit::TestCase
3
+ class Elasticsearch::Model::ResponsePaginationKaminariTest < Test::Unit::TestCase
4
4
  context "Response pagination" do
5
5
  class ModelClass
6
6
  include ::Kaminari::ConfigurationMethods
@@ -0,0 +1,189 @@
1
+ require 'test_helper'
2
+ require 'will_paginate'
3
+ require 'will_paginate/collection'
4
+
5
+ class Elasticsearch::Model::ResponsePaginationWillPaginateTest < Test::Unit::TestCase
6
+ context "Response pagination" do
7
+ class ModelClass
8
+ def self.index_name; 'foo'; end
9
+ def self.document_type; 'bar'; end
10
+
11
+ # WillPaginate adds this method to models (see WillPaginate::PerPage module)
12
+ def self.per_page
13
+ 33
14
+ end
15
+ end
16
+
17
+ # Subsclass Response so we can include WillPaginate module without conflicts with Kaminari.
18
+ class WillPaginateResponse < Elasticsearch::Model::Response::Response
19
+ include Elasticsearch::Model::Response::Pagination::WillPaginate
20
+ end
21
+
22
+ RESPONSE = { 'took' => '5', 'timed_out' => false, '_shards' => {'one' => 'OK'},
23
+ 'hits' => { 'total' => 100, 'hits' => (1..100).to_a.map { |i| { _id: i } } } }
24
+
25
+ setup do
26
+ @search = Elasticsearch::Model::Searching::SearchRequest.new ModelClass, '*'
27
+ @response = WillPaginateResponse.new ModelClass, @search, RESPONSE
28
+ @response.klass.stubs(:client).returns mock('client')
29
+
30
+ @expected_methods = [
31
+ # methods needed by WillPaginate::CollectionMethods
32
+ :current_page,
33
+ :per_page,
34
+ :total_entries,
35
+
36
+ # methods defined by WillPaginate::CollectionMethods
37
+ :total_pages,
38
+ :previous_page,
39
+ :next_page,
40
+ :out_of_bounds?,
41
+ ]
42
+ end
43
+
44
+ should "have pagination methods" do
45
+ assert_respond_to @response, :paginate
46
+
47
+ @expected_methods.each do |method|
48
+ assert_respond_to @response, method
49
+ end
50
+ end
51
+
52
+ context "response.results" do
53
+ should "have pagination methods" do
54
+ @expected_methods.each do |method|
55
+ assert_respond_to @response.results, method
56
+ end
57
+ end
58
+ end
59
+
60
+ context "response.records" do
61
+ should "have pagination methods" do
62
+ @expected_methods.each do |method|
63
+ @response.klass.stubs(:find).returns([])
64
+ assert_respond_to @response.records, method
65
+ end
66
+ end
67
+ end
68
+
69
+ context "#paginate method" do
70
+ should "set from/size using defaults" do
71
+ @response.klass.client
72
+ .expects(:search)
73
+ .with do |definition|
74
+ assert_equal 0, definition[:from]
75
+ assert_equal 33, definition[:size]
76
+ end
77
+ .returns(RESPONSE)
78
+
79
+ assert_nil @response.search.definition[:from]
80
+ assert_nil @response.search.definition[:size]
81
+
82
+ @response.paginate(page: nil).to_a
83
+ assert_equal 0, @response.search.definition[:from]
84
+ assert_equal 33, @response.search.definition[:size]
85
+ end
86
+
87
+ should "set from/size using default per_page" do
88
+ @response.klass.client
89
+ .expects(:search)
90
+ .with do |definition|
91
+ assert_equal 33, definition[:from]
92
+ assert_equal 33, definition[:size]
93
+ end
94
+ .returns(RESPONSE)
95
+
96
+ assert_nil @response.search.definition[:from]
97
+ assert_nil @response.search.definition[:size]
98
+
99
+ @response.paginate(page: 2).to_a
100
+ assert_equal 33, @response.search.definition[:from]
101
+ assert_equal 33, @response.search.definition[:size]
102
+ end
103
+
104
+ should "set from/size using custom page and per_page" do
105
+ @response.klass.client
106
+ .expects(:search)
107
+ .with do |definition|
108
+ assert_equal 18, definition[:from]
109
+ assert_equal 9, definition[:size]
110
+ end
111
+ .returns(RESPONSE)
112
+
113
+ assert_nil @response.search.definition[:from]
114
+ assert_nil @response.search.definition[:size]
115
+
116
+ @response.paginate(page: 3, per_page: 9).to_a
117
+ assert_equal 18, @response.search.definition[:from]
118
+ assert_equal 9, @response.search.definition[:size]
119
+ end
120
+
121
+ should "searches for page 1 if specified page is < 1" do
122
+ @response.klass.client
123
+ .expects(:search)
124
+ .with do |definition|
125
+ assert_equal 0, definition[:from]
126
+ assert_equal 33, definition[:size]
127
+ end
128
+ .returns(RESPONSE)
129
+
130
+ assert_nil @response.search.definition[:from]
131
+ assert_nil @response.search.definition[:size]
132
+
133
+ @response.paginate(page: "-1").to_a
134
+ assert_equal 0, @response.search.definition[:from]
135
+ assert_equal 33, @response.search.definition[:size]
136
+ end
137
+ end
138
+
139
+ context "#page and #per_page shorthand methods" do
140
+ should "set from/size using default per_page" do
141
+ @response.page(5)
142
+ assert_equal 132, @response.search.definition[:from]
143
+ assert_equal 33, @response.search.definition[:size]
144
+ end
145
+
146
+ should "set from/size when calling #page then #per_page" do
147
+ @response.page(5).per_page(3)
148
+ assert_equal 12, @response.search.definition[:from]
149
+ assert_equal 3, @response.search.definition[:size]
150
+ end
151
+
152
+ should "set from/size when calling #per_page then #page" do
153
+ @response.per_page(3).page(5)
154
+ assert_equal 12, @response.search.definition[:from]
155
+ assert_equal 3, @response.search.definition[:size]
156
+ end
157
+ end
158
+
159
+ context "#current_page method" do
160
+ should "return 1 by default" do
161
+ @response.paginate({})
162
+ assert_equal 1, @response.current_page
163
+ end
164
+
165
+ should "return current page number" do
166
+ @response.paginate(page: 3, per_page: 9)
167
+ assert_equal 3, @response.current_page
168
+ end
169
+
170
+ should "return nil if not pagination set" do
171
+ assert_equal nil, @response.current_page
172
+ end
173
+ end
174
+
175
+ context "#per_page method" do
176
+ should "return value set in paginate call" do
177
+ @response.paginate(per_page: 8)
178
+ assert_equal 8, @response.per_page
179
+ end
180
+ end
181
+
182
+ context "#total_entries method" do
183
+ should "return total from response" do
184
+ @response.expects(:results).returns(mock('results', total: 100))
185
+ assert_equal 100, @response.total_entries
186
+ end
187
+ end
188
+ end
189
+ end
@@ -15,6 +15,20 @@ class Elasticsearch::Model::ResultTest < Test::Unit::TestCase
15
15
  assert_raise(NoMethodError) { result.xoxo }
16
16
  end
17
17
 
18
+ should "return _id as #id" do
19
+ result = Elasticsearch::Model::Response::Result.new foo: 'bar', _id: 42, _source: { id: 12 }
20
+
21
+ assert_equal 42, result.id
22
+ assert_equal 12, result._source.id
23
+ end
24
+
25
+ should "return _type as #type" do
26
+ result = Elasticsearch::Model::Response::Result.new foo: 'bar', _type: 'baz', _source: { type: 'BAM' }
27
+
28
+ assert_equal 'baz', result.type
29
+ assert_equal 'BAM', result._source.type
30
+ end
31
+
18
32
  should "delegate method calls to `_source` when available" do
19
33
  result = Elasticsearch::Model::Response::Result.new foo: 'bar', _source: { bar: 'baz' }
20
34
 
@@ -27,12 +41,27 @@ class Elasticsearch::Model::ResultTest < Test::Unit::TestCase
27
41
  assert_equal 'baz', result.bar
28
42
  end
29
43
 
44
+ should "delegate existence method calls to `_source`" do
45
+ result = Elasticsearch::Model::Response::Result.new foo: 'bar', _source: { bar: { bam: 'baz' } }
46
+
47
+ assert_respond_to result._source, :bar?
48
+ assert_respond_to result, :bar?
49
+
50
+ assert_equal true, result._source.bar?
51
+ assert_equal true, result.bar?
52
+ assert_equal false, result.boo?
53
+
54
+ assert_equal true, result.bar.bam?
55
+ assert_equal false, result.bar.boo?
56
+ end
57
+
30
58
  should "delegate methods to @result" do
31
59
  result = Elasticsearch::Model::Response::Result.new foo: 'bar'
32
60
 
33
- assert_equal 'bar', result.foo
34
- assert_equal 'bar', result.fetch('foo')
35
- assert_equal 'moo', result.fetch('NOT_EXIST', 'moo')
61
+ assert_equal 'bar', result.foo
62
+ assert_equal 'bar', result.fetch('foo')
63
+ assert_equal 'moo', result.fetch('NOT_EXIST', 'moo')
64
+ assert_equal ['foo'], result.keys
36
65
 
37
66
  assert_respond_to result, :to_hash
38
67
  assert_equal({'foo' => 'bar'}, result.to_hash)
@@ -40,6 +69,16 @@ class Elasticsearch::Model::ResultTest < Test::Unit::TestCase
40
69
  assert_raise(NoMethodError) { result.does_not_exist }
41
70
  end
42
71
 
72
+ should "delegate existence method calls to @result" do
73
+ result = Elasticsearch::Model::Response::Result.new foo: 'bar', _source: { bar: 'bam' }
74
+ assert_respond_to result, :foo?
75
+
76
+ assert_equal true, result.foo?
77
+ assert_equal false, result.boo?
78
+ assert_equal false, result._source.foo?
79
+ assert_equal false, result._source.boo?
80
+ end
81
+
43
82
  should "delegate as_json to @result even when ActiveSupport changed half of Ruby" do
44
83
  require 'active_support/json/encoding'
45
84
  result = Elasticsearch::Model::Response::Result.new foo: 'bar'
@@ -47,6 +86,5 @@ class Elasticsearch::Model::ResultTest < Test::Unit::TestCase
47
86
  result.instance_variable_get(:@result).expects(:as_json)
48
87
  result.as_json(except: 'foo')
49
88
  end
50
-
51
89
  end
52
90
  end