elasticsearch-model-queryable 0.1.5

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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/CHANGELOG.md +26 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +13 -0
  6. data/README.md +695 -0
  7. data/Rakefile +59 -0
  8. data/elasticsearch-model.gemspec +57 -0
  9. data/examples/activerecord_article.rb +77 -0
  10. data/examples/activerecord_associations.rb +162 -0
  11. data/examples/couchbase_article.rb +66 -0
  12. data/examples/datamapper_article.rb +71 -0
  13. data/examples/mongoid_article.rb +68 -0
  14. data/examples/ohm_article.rb +70 -0
  15. data/examples/riak_article.rb +52 -0
  16. data/gemfiles/3.0.gemfile +12 -0
  17. data/gemfiles/4.0.gemfile +11 -0
  18. data/lib/elasticsearch/model/adapter.rb +145 -0
  19. data/lib/elasticsearch/model/adapters/active_record.rb +104 -0
  20. data/lib/elasticsearch/model/adapters/default.rb +50 -0
  21. data/lib/elasticsearch/model/adapters/mongoid.rb +92 -0
  22. data/lib/elasticsearch/model/callbacks.rb +35 -0
  23. data/lib/elasticsearch/model/client.rb +61 -0
  24. data/lib/elasticsearch/model/ext/active_record.rb +14 -0
  25. data/lib/elasticsearch/model/hash_wrapper.rb +15 -0
  26. data/lib/elasticsearch/model/importing.rb +144 -0
  27. data/lib/elasticsearch/model/indexing.rb +472 -0
  28. data/lib/elasticsearch/model/naming.rb +101 -0
  29. data/lib/elasticsearch/model/proxy.rb +127 -0
  30. data/lib/elasticsearch/model/response/base.rb +44 -0
  31. data/lib/elasticsearch/model/response/pagination.rb +173 -0
  32. data/lib/elasticsearch/model/response/records.rb +69 -0
  33. data/lib/elasticsearch/model/response/result.rb +63 -0
  34. data/lib/elasticsearch/model/response/results.rb +31 -0
  35. data/lib/elasticsearch/model/response.rb +71 -0
  36. data/lib/elasticsearch/model/searching.rb +107 -0
  37. data/lib/elasticsearch/model/serializing.rb +35 -0
  38. data/lib/elasticsearch/model/version.rb +5 -0
  39. data/lib/elasticsearch/model.rb +157 -0
  40. data/test/integration/active_record_associations_parent_child.rb +139 -0
  41. data/test/integration/active_record_associations_test.rb +307 -0
  42. data/test/integration/active_record_basic_test.rb +179 -0
  43. data/test/integration/active_record_custom_serialization_test.rb +62 -0
  44. data/test/integration/active_record_import_test.rb +100 -0
  45. data/test/integration/active_record_namespaced_model_test.rb +49 -0
  46. data/test/integration/active_record_pagination_test.rb +132 -0
  47. data/test/integration/mongoid_basic_test.rb +193 -0
  48. data/test/test_helper.rb +63 -0
  49. data/test/unit/adapter_active_record_test.rb +140 -0
  50. data/test/unit/adapter_default_test.rb +41 -0
  51. data/test/unit/adapter_mongoid_test.rb +102 -0
  52. data/test/unit/adapter_test.rb +69 -0
  53. data/test/unit/callbacks_test.rb +31 -0
  54. data/test/unit/client_test.rb +27 -0
  55. data/test/unit/importing_test.rb +176 -0
  56. data/test/unit/indexing_test.rb +478 -0
  57. data/test/unit/module_test.rb +57 -0
  58. data/test/unit/naming_test.rb +76 -0
  59. data/test/unit/proxy_test.rb +89 -0
  60. data/test/unit/response_base_test.rb +40 -0
  61. data/test/unit/response_pagination_kaminari_test.rb +189 -0
  62. data/test/unit/response_pagination_will_paginate_test.rb +208 -0
  63. data/test/unit/response_records_test.rb +91 -0
  64. data/test/unit/response_result_test.rb +90 -0
  65. data/test/unit/response_results_test.rb +31 -0
  66. data/test/unit/response_test.rb +67 -0
  67. data/test/unit/searching_search_request_test.rb +78 -0
  68. data/test/unit/searching_test.rb +41 -0
  69. data/test/unit/serializing_test.rb +17 -0
  70. metadata +466 -0
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::ModuleTest < Test::Unit::TestCase
4
+ context "The main module" do
5
+
6
+ context "client" do
7
+ should "have a default" do
8
+ client = Elasticsearch::Model.client
9
+ assert_not_nil client
10
+ assert_instance_of Elasticsearch::Transport::Client, client
11
+ end
12
+
13
+ should "be settable" do
14
+ begin
15
+ Elasticsearch::Model.client = "Foobar"
16
+ assert_equal "Foobar", Elasticsearch::Model.client
17
+ ensure
18
+ Elasticsearch::Model.client = nil
19
+ end
20
+ end
21
+ end
22
+
23
+ context "when included in module/class, " do
24
+ class ::DummyIncludingModel; end
25
+ class ::DummyIncludingModelWithSearchMethodDefined
26
+ def self.search(query, options={})
27
+ "SEARCH"
28
+ end
29
+ end
30
+
31
+ should "include and set up the proxy" do
32
+ DummyIncludingModel.__send__ :include, Elasticsearch::Model
33
+
34
+ assert_respond_to DummyIncludingModel, :__elasticsearch__
35
+ assert_respond_to DummyIncludingModel.new, :__elasticsearch__
36
+ end
37
+
38
+ should "delegate important methods to the proxy" do
39
+ DummyIncludingModel.__send__ :include, Elasticsearch::Model
40
+
41
+ assert_respond_to DummyIncludingModel, :search
42
+ assert_respond_to DummyIncludingModel, :mappings
43
+ assert_respond_to DummyIncludingModel, :settings
44
+ assert_respond_to DummyIncludingModel, :index_name
45
+ assert_respond_to DummyIncludingModel, :document_type
46
+ assert_respond_to DummyIncludingModel, :import
47
+ end
48
+
49
+ should "not override existing method" do
50
+ DummyIncludingModelWithSearchMethodDefined.__send__ :include, Elasticsearch::Model
51
+
52
+ assert_equal 'SEARCH', DummyIncludingModelWithSearchMethodDefined.search('foo')
53
+ end
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,76 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::NamingTest < Test::Unit::TestCase
4
+ context "Naming module" do
5
+ class ::DummyNamingModel
6
+ extend ActiveModel::Naming
7
+
8
+ extend Elasticsearch::Model::Naming::ClassMethods
9
+ include Elasticsearch::Model::Naming::InstanceMethods
10
+ end
11
+
12
+ module ::MyNamespace
13
+ class DummyNamingModelInNamespace
14
+ extend ActiveModel::Naming
15
+
16
+ extend Elasticsearch::Model::Naming::ClassMethods
17
+ include Elasticsearch::Model::Naming::InstanceMethods
18
+ end
19
+ end
20
+
21
+ should "return the default index_name" do
22
+ assert_equal 'dummy_naming_models', DummyNamingModel.index_name
23
+ assert_equal 'dummy_naming_models', DummyNamingModel.new.index_name
24
+ end
25
+
26
+ should "return the sanitized default index_name for namespaced model" do
27
+ assert_equal 'my_namespace-dummy_naming_model_in_namespaces', ::MyNamespace::DummyNamingModelInNamespace.index_name
28
+ assert_equal 'my_namespace-dummy_naming_model_in_namespaces', ::MyNamespace::DummyNamingModelInNamespace.new.index_name
29
+ end
30
+
31
+ should "return the default document_type" do
32
+ assert_equal 'dummy_naming_model', DummyNamingModel.document_type
33
+ assert_equal 'dummy_naming_model', DummyNamingModel.new.document_type
34
+ end
35
+
36
+ should "set and return the index_name" do
37
+ DummyNamingModel.index_name 'foobar'
38
+ assert_equal 'foobar', DummyNamingModel.index_name
39
+
40
+ d = DummyNamingModel.new
41
+ d.index_name 'foobar_d'
42
+ assert_equal 'foobar_d', d.index_name
43
+ end
44
+
45
+ should "set the index_name with setter" do
46
+ DummyNamingModel.index_name = 'foobar_index_S'
47
+ assert_equal 'foobar_index_S', DummyNamingModel.index_name
48
+
49
+ d = DummyNamingModel.new
50
+ d.index_name = 'foobar_index_s'
51
+ assert_equal 'foobar_index_s', d.index_name
52
+
53
+ assert_equal 'foobar_index_S', DummyNamingModel.index_name
54
+ end
55
+
56
+ should "set and return the document_type" do
57
+ DummyNamingModel.document_type 'foobar'
58
+ assert_equal 'foobar', DummyNamingModel.document_type
59
+
60
+ d = DummyNamingModel.new
61
+ d.document_type 'foobar_d'
62
+ assert_equal 'foobar_d', d.document_type
63
+ end
64
+
65
+ should "set the document_type with setter" do
66
+ DummyNamingModel.document_type = 'foobar_type_S'
67
+ assert_equal 'foobar_type_S', DummyNamingModel.document_type
68
+
69
+ d = DummyNamingModel.new
70
+ d.document_type = 'foobar_type_s'
71
+ assert_equal 'foobar_type_s', d.document_type
72
+
73
+ assert_equal 'foobar_type_S', DummyNamingModel.document_type
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,89 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::SearchTest < Test::Unit::TestCase
4
+ context "Searching module" do
5
+ class ::DummyProxyModel
6
+ include Elasticsearch::Model::Proxy
7
+
8
+ def self.foo
9
+ 'classy foo'
10
+ end
11
+
12
+ def bar
13
+ 'insta barr'
14
+ end
15
+
16
+ def as_json(options)
17
+ {foo: 'bar'}
18
+ end
19
+ end
20
+
21
+ class ::DummyProxyModelWithCallbacks
22
+ def self.before_save(&block)
23
+ (@callbacks ||= {})[block.hash] = block
24
+ end
25
+
26
+ def changed_attributes; [:foo]; end
27
+
28
+ def changes
29
+ {:foo => ['One', 'Two']}
30
+ end
31
+ end
32
+
33
+ should "setup the class proxy method" do
34
+ assert_respond_to DummyProxyModel, :__elasticsearch__
35
+ end
36
+
37
+ should "setup the instance proxy method" do
38
+ assert_respond_to DummyProxyModel.new, :__elasticsearch__
39
+ end
40
+
41
+ should "register the hook for before_save callback" do
42
+ ::DummyProxyModelWithCallbacks.expects(:before_save).returns(true)
43
+ DummyProxyModelWithCallbacks.__send__ :include, Elasticsearch::Model::Proxy
44
+ end
45
+
46
+ should "set the @__changed_attributes variable before save" do
47
+ instance = ::DummyProxyModelWithCallbacks.new
48
+ instance.__elasticsearch__.expects(:instance_variable_set).with do |name, value|
49
+ assert_equal :@__changed_attributes, name
50
+ assert_equal({foo: 'Two'}, value)
51
+ true
52
+ end
53
+
54
+ ::DummyProxyModelWithCallbacks.__send__ :include, Elasticsearch::Model::Proxy
55
+
56
+ ::DummyProxyModelWithCallbacks.instance_variable_get(:@callbacks).each do |n,b|
57
+ instance.instance_eval(&b)
58
+ end
59
+ end
60
+
61
+ should "delegate methods to the target" do
62
+ assert_respond_to DummyProxyModel.__elasticsearch__, :foo
63
+ assert_respond_to DummyProxyModel.new.__elasticsearch__, :bar
64
+
65
+ assert_raise(NoMethodError) { DummyProxyModel.__elasticsearch__.xoxo }
66
+ assert_raise(NoMethodError) { DummyProxyModel.new.__elasticsearch__.xoxo }
67
+
68
+ assert_equal 'classy foo', DummyProxyModel.__elasticsearch__.foo
69
+ assert_equal 'insta barr', DummyProxyModel.new.__elasticsearch__.bar
70
+ end
71
+
72
+ should "return the proxy class from instance proxy" do
73
+ assert_equal Elasticsearch::Model::Proxy::ClassMethodsProxy, DummyProxyModel.new.__elasticsearch__.class.class
74
+ end
75
+
76
+ should "return the origin class from instance proxy" do
77
+ assert_equal DummyProxyModel, DummyProxyModel.new.__elasticsearch__.klass
78
+ end
79
+
80
+ should "delegate as_json from the proxy to target" do
81
+ assert_equal({foo: 'bar'}, DummyProxyModel.new.__elasticsearch__.as_json)
82
+ end
83
+
84
+ should "have inspect method indicating the proxy" do
85
+ assert_match /PROXY/, DummyProxyModel.__elasticsearch__.inspect
86
+ assert_match /PROXY/, DummyProxyModel.new.__elasticsearch__.inspect
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::BaseTest < Test::Unit::TestCase
4
+ context "Response base module" do
5
+ class OriginClass
6
+ def self.index_name; 'foo'; end
7
+ def self.document_type; 'bar'; end
8
+ end
9
+
10
+ class DummyBaseClass
11
+ include Elasticsearch::Model::Response::Base
12
+ end
13
+
14
+ RESPONSE = { 'hits' => { 'total' => 123, 'max_score' => 456, 'hits' => [] } }
15
+
16
+ setup do
17
+ @search = Elasticsearch::Model::Searching::SearchRequest.new OriginClass, '*'
18
+ @response = Elasticsearch::Model::Response::Response.new OriginClass, @search
19
+ @search.stubs(:execute!).returns(RESPONSE)
20
+ end
21
+
22
+ should "access klass, response, total and max_score" do
23
+ r = DummyBaseClass.new OriginClass, @response
24
+
25
+ assert_equal OriginClass, r.klass
26
+ assert_equal @response, r.response
27
+ assert_equal RESPONSE, r.response.response
28
+ assert_equal 123, r.total
29
+ assert_equal 456, r.max_score
30
+ end
31
+
32
+ should "have abstract methods results and records" do
33
+ r = DummyBaseClass.new OriginClass, @response
34
+
35
+ assert_raise(Elasticsearch::Model::NotImplemented) { |e| r.results }
36
+ assert_raise(Elasticsearch::Model::NotImplemented) { |e| r.records }
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,189 @@
1
+ require 'test_helper'
2
+
3
+ class Elasticsearch::Model::ResponsePaginationKaminariTest < Test::Unit::TestCase
4
+ context "Response pagination" do
5
+ class ModelClass
6
+ include ::Kaminari::ConfigurationMethods
7
+
8
+ def self.index_name; 'foo'; end
9
+ def self.document_type; 'bar'; end
10
+ end
11
+
12
+ RESPONSE = { 'took' => '5', 'timed_out' => false, '_shards' => {'one' => 'OK'},
13
+ 'hits' => { 'total' => 100, 'hits' => (1..100).to_a.map { |i| { _id: i } } } }
14
+
15
+ setup do
16
+ @search = Elasticsearch::Model::Searching::SearchRequest.new ModelClass, '*'
17
+ @response = Elasticsearch::Model::Response::Response.new ModelClass, @search, RESPONSE
18
+ @response.klass.stubs(:client).returns mock('client')
19
+ end
20
+
21
+ should "have pagination methods" do
22
+ assert_respond_to @response, :page
23
+ assert_respond_to @response, :limit_value
24
+ assert_respond_to @response, :offset_value
25
+ assert_respond_to @response, :limit
26
+ assert_respond_to @response, :offset
27
+ assert_respond_to @response, :total_count
28
+ end
29
+
30
+ context "#page method" do
31
+ should "advance the from/size" do
32
+ @response.klass.client
33
+ .expects(:search)
34
+ .with do |definition|
35
+ assert_equal 25, definition[:from]
36
+ assert_equal 25, definition[:size]
37
+ true
38
+ end
39
+ .returns(RESPONSE)
40
+
41
+ assert_nil @response.search.definition[:from]
42
+ assert_nil @response.search.definition[:size]
43
+
44
+ @response.page(2).to_a
45
+ assert_equal 25, @response.search.definition[:from]
46
+ assert_equal 25, @response.search.definition[:size]
47
+ end
48
+
49
+ should "advance the from/size further" do
50
+ @response.klass.client
51
+ .expects(:search)
52
+ .with do |definition|
53
+ assert_equal 75, definition[:from]
54
+ assert_equal 25, definition[:size]
55
+ true
56
+ end
57
+ .returns(RESPONSE)
58
+
59
+ @response.page(4).to_a
60
+ assert_equal 75, @response.search.definition[:from]
61
+ assert_equal 25, @response.search.definition[:size]
62
+ end
63
+ end
64
+
65
+ context "limit/offset readers" do
66
+ should "return the default" do
67
+ assert_equal Kaminari.config.default_per_page, @response.limit_value
68
+ assert_equal 0, @response.offset_value
69
+ end
70
+
71
+ should "return the value from URL parameters" do
72
+ search = Elasticsearch::Model::Searching::SearchRequest.new ModelClass, '*', size: 10, from: 50
73
+ @response = Elasticsearch::Model::Response::Response.new ModelClass, search, RESPONSE
74
+
75
+ assert_equal 10, @response.limit_value
76
+ assert_equal 50, @response.offset_value
77
+ end
78
+
79
+ should "ignore the value from request body" do
80
+ search = Elasticsearch::Model::Searching::SearchRequest.new ModelClass,
81
+ { query: { match_all: {} }, from: 333, size: 999 }
82
+ @response = Elasticsearch::Model::Response::Response.new ModelClass, search, RESPONSE
83
+
84
+ assert_equal Kaminari.config.default_per_page, @response.limit_value
85
+ assert_equal 0, @response.offset_value
86
+ end
87
+ end
88
+
89
+ context "limit setter" do
90
+ setup do
91
+ @response.records
92
+ @response.results
93
+ end
94
+
95
+ should "set the values" do
96
+ @response.limit(35)
97
+ assert_equal 35, @response.search.definition[:size]
98
+ end
99
+
100
+ should "reset the variables" do
101
+ @response.limit(35)
102
+
103
+ assert_nil @response.instance_variable_get(:@response)
104
+ assert_nil @response.instance_variable_get(:@records)
105
+ assert_nil @response.instance_variable_get(:@results)
106
+ end
107
+ end
108
+
109
+ context "with the page() and limit() methods" do
110
+ setup do
111
+ @response.records
112
+ @response.results
113
+ end
114
+
115
+ should "set the values" do
116
+ @response.page(3).limit(35)
117
+ assert_equal 35, @response.search.definition[:size]
118
+ assert_equal 70, @response.search.definition[:from]
119
+ end
120
+
121
+ should "set the values when limit is called first" do
122
+ @response.limit(35).page(3)
123
+ assert_equal 35, @response.search.definition[:size]
124
+ assert_equal 70, @response.search.definition[:from]
125
+ end
126
+
127
+ should "reset the instance variables" do
128
+ @response.page(3).limit(35)
129
+
130
+ assert_nil @response.instance_variable_get(:@response)
131
+ assert_nil @response.instance_variable_get(:@records)
132
+ assert_nil @response.instance_variable_get(:@results)
133
+ end
134
+ end
135
+
136
+ context "offset setter" do
137
+ setup do
138
+ @response.records
139
+ @response.results
140
+ end
141
+
142
+ should "set the values" do
143
+ @response.offset(15)
144
+ assert_equal 15, @response.search.definition[:from]
145
+ end
146
+
147
+ should "reset the variables" do
148
+ @response.offset(35)
149
+
150
+ assert_nil @response.instance_variable_get(:@response)
151
+ assert_nil @response.instance_variable_get(:@records)
152
+ assert_nil @response.instance_variable_get(:@results)
153
+ end
154
+ end
155
+
156
+ context "total" do
157
+ should "return the number of hits" do
158
+ @response.expects(:results).returns(mock('results', total: 100))
159
+ assert_equal 100, @response.total_count
160
+ end
161
+ end
162
+
163
+ context "results" do
164
+ setup do
165
+ @search.stubs(:execute!).returns RESPONSE
166
+ end
167
+
168
+ should "return current page and total count" do
169
+ assert_equal 1, @response.page(1).results.current_page
170
+ assert_equal 100, @response.results.total_count
171
+
172
+ assert_equal 5, @response.page(5).results.current_page
173
+ end
174
+ end
175
+
176
+ context "records" do
177
+ setup do
178
+ @search.stubs(:execute!).returns RESPONSE
179
+ end
180
+
181
+ should "return current page and total count" do
182
+ assert_equal 1, @response.page(1).records.current_page
183
+ assert_equal 100, @response.records.total_count
184
+
185
+ assert_equal 5, @response.page(5).records.current_page
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,208 @@
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
+ :offset,
34
+ :per_page,
35
+ :total_entries,
36
+ :length,
37
+
38
+ # methods defined by WillPaginate::CollectionMethods
39
+ :total_pages,
40
+ :previous_page,
41
+ :next_page,
42
+ :out_of_bounds?,
43
+ ]
44
+ end
45
+
46
+ should "have pagination methods" do
47
+ assert_respond_to @response, :paginate
48
+
49
+ @expected_methods.each do |method|
50
+ assert_respond_to @response, method
51
+ end
52
+ end
53
+
54
+ context "response.results" do
55
+ should "have pagination methods" do
56
+ @expected_methods.each do |method|
57
+ assert_respond_to @response.results, method
58
+ end
59
+ end
60
+ end
61
+
62
+ context "response.records" do
63
+ should "have pagination methods" do
64
+ @expected_methods.each do |method|
65
+ @response.klass.stubs(:find).returns([])
66
+ assert_respond_to @response.records, method
67
+ end
68
+ end
69
+ end
70
+
71
+ context "#offset method" do
72
+ should "calculate offset using current_page and per_page" do
73
+ @response.per_page(3).page(3)
74
+ assert_equal 6, @response.offset
75
+ end
76
+ end
77
+ context "#length method" do
78
+ should "return count of paginated results" do
79
+ @response.per_page(3).page(3)
80
+ assert_equal 3, @response.length
81
+ end
82
+ end
83
+
84
+ context "#paginate method" do
85
+ should "set from/size using defaults" do
86
+ @response.klass.client
87
+ .expects(:search)
88
+ .with do |definition|
89
+ assert_equal 0, definition[:from]
90
+ assert_equal 33, definition[:size]
91
+ true
92
+ end
93
+ .returns(RESPONSE)
94
+
95
+ assert_nil @response.search.definition[:from]
96
+ assert_nil @response.search.definition[:size]
97
+
98
+ @response.paginate(page: nil).to_a
99
+ assert_equal 0, @response.search.definition[:from]
100
+ assert_equal 33, @response.search.definition[:size]
101
+ end
102
+
103
+ should "set from/size using default per_page" do
104
+ @response.klass.client
105
+ .expects(:search)
106
+ .with do |definition|
107
+ assert_equal 33, definition[:from]
108
+ assert_equal 33, definition[:size]
109
+ true
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: 2).to_a
117
+ assert_equal 33, @response.search.definition[:from]
118
+ assert_equal 33, @response.search.definition[:size]
119
+ end
120
+
121
+ should "set from/size using custom page and per_page" do
122
+ @response.klass.client
123
+ .expects(:search)
124
+ .with do |definition|
125
+ assert_equal 18, definition[:from]
126
+ assert_equal 9, definition[:size]
127
+ true
128
+ end
129
+ .returns(RESPONSE)
130
+
131
+ assert_nil @response.search.definition[:from]
132
+ assert_nil @response.search.definition[:size]
133
+
134
+ @response.paginate(page: 3, per_page: 9).to_a
135
+ assert_equal 18, @response.search.definition[:from]
136
+ assert_equal 9, @response.search.definition[:size]
137
+ end
138
+
139
+ should "search for first page if specified page is < 1" do
140
+ @response.klass.client
141
+ .expects(:search)
142
+ .with do |definition|
143
+ assert_equal 0, definition[:from]
144
+ assert_equal 33, definition[:size]
145
+ true
146
+ end
147
+ .returns(RESPONSE)
148
+
149
+ assert_nil @response.search.definition[:from]
150
+ assert_nil @response.search.definition[:size]
151
+
152
+ @response.paginate(page: "-1").to_a
153
+ assert_equal 0, @response.search.definition[:from]
154
+ assert_equal 33, @response.search.definition[:size]
155
+ end
156
+ end
157
+
158
+ context "#page and #per_page shorthand methods" do
159
+ should "set from/size using default per_page" do
160
+ @response.page(5)
161
+ assert_equal 132, @response.search.definition[:from]
162
+ assert_equal 33, @response.search.definition[:size]
163
+ end
164
+
165
+ should "set from/size when calling #page then #per_page" do
166
+ @response.page(5).per_page(3)
167
+ assert_equal 12, @response.search.definition[:from]
168
+ assert_equal 3, @response.search.definition[:size]
169
+ end
170
+
171
+ should "set from/size when calling #per_page then #page" do
172
+ @response.per_page(3).page(5)
173
+ assert_equal 12, @response.search.definition[:from]
174
+ assert_equal 3, @response.search.definition[:size]
175
+ end
176
+ end
177
+
178
+ context "#current_page method" do
179
+ should "return 1 by default" do
180
+ @response.paginate({})
181
+ assert_equal 1, @response.current_page
182
+ end
183
+
184
+ should "return current page number" do
185
+ @response.paginate(page: 3, per_page: 9)
186
+ assert_equal 3, @response.current_page
187
+ end
188
+
189
+ should "return nil if not pagination set" do
190
+ assert_equal nil, @response.current_page
191
+ end
192
+ end
193
+
194
+ context "#per_page method" do
195
+ should "return value set in paginate call" do
196
+ @response.paginate(per_page: 8)
197
+ assert_equal 8, @response.per_page
198
+ end
199
+ end
200
+
201
+ context "#total_entries method" do
202
+ should "return total from response" do
203
+ @response.expects(:results).returns(mock('results', total: 100))
204
+ assert_equal 100, @response.total_entries
205
+ end
206
+ end
207
+ end
208
+ end