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.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/CHANGELOG.md +26 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +695 -0
- data/Rakefile +59 -0
- data/elasticsearch-model.gemspec +57 -0
- data/examples/activerecord_article.rb +77 -0
- data/examples/activerecord_associations.rb +162 -0
- data/examples/couchbase_article.rb +66 -0
- data/examples/datamapper_article.rb +71 -0
- data/examples/mongoid_article.rb +68 -0
- data/examples/ohm_article.rb +70 -0
- data/examples/riak_article.rb +52 -0
- data/gemfiles/3.0.gemfile +12 -0
- data/gemfiles/4.0.gemfile +11 -0
- data/lib/elasticsearch/model/adapter.rb +145 -0
- data/lib/elasticsearch/model/adapters/active_record.rb +104 -0
- data/lib/elasticsearch/model/adapters/default.rb +50 -0
- data/lib/elasticsearch/model/adapters/mongoid.rb +92 -0
- data/lib/elasticsearch/model/callbacks.rb +35 -0
- data/lib/elasticsearch/model/client.rb +61 -0
- data/lib/elasticsearch/model/ext/active_record.rb +14 -0
- data/lib/elasticsearch/model/hash_wrapper.rb +15 -0
- data/lib/elasticsearch/model/importing.rb +144 -0
- data/lib/elasticsearch/model/indexing.rb +472 -0
- data/lib/elasticsearch/model/naming.rb +101 -0
- data/lib/elasticsearch/model/proxy.rb +127 -0
- data/lib/elasticsearch/model/response/base.rb +44 -0
- data/lib/elasticsearch/model/response/pagination.rb +173 -0
- data/lib/elasticsearch/model/response/records.rb +69 -0
- data/lib/elasticsearch/model/response/result.rb +63 -0
- data/lib/elasticsearch/model/response/results.rb +31 -0
- data/lib/elasticsearch/model/response.rb +71 -0
- data/lib/elasticsearch/model/searching.rb +107 -0
- data/lib/elasticsearch/model/serializing.rb +35 -0
- data/lib/elasticsearch/model/version.rb +5 -0
- data/lib/elasticsearch/model.rb +157 -0
- data/test/integration/active_record_associations_parent_child.rb +139 -0
- data/test/integration/active_record_associations_test.rb +307 -0
- data/test/integration/active_record_basic_test.rb +179 -0
- data/test/integration/active_record_custom_serialization_test.rb +62 -0
- data/test/integration/active_record_import_test.rb +100 -0
- data/test/integration/active_record_namespaced_model_test.rb +49 -0
- data/test/integration/active_record_pagination_test.rb +132 -0
- data/test/integration/mongoid_basic_test.rb +193 -0
- data/test/test_helper.rb +63 -0
- data/test/unit/adapter_active_record_test.rb +140 -0
- data/test/unit/adapter_default_test.rb +41 -0
- data/test/unit/adapter_mongoid_test.rb +102 -0
- data/test/unit/adapter_test.rb +69 -0
- data/test/unit/callbacks_test.rb +31 -0
- data/test/unit/client_test.rb +27 -0
- data/test/unit/importing_test.rb +176 -0
- data/test/unit/indexing_test.rb +478 -0
- data/test/unit/module_test.rb +57 -0
- data/test/unit/naming_test.rb +76 -0
- data/test/unit/proxy_test.rb +89 -0
- data/test/unit/response_base_test.rb +40 -0
- data/test/unit/response_pagination_kaminari_test.rb +189 -0
- data/test/unit/response_pagination_will_paginate_test.rb +208 -0
- data/test/unit/response_records_test.rb +91 -0
- data/test/unit/response_result_test.rb +90 -0
- data/test/unit/response_results_test.rb +31 -0
- data/test/unit/response_test.rb +67 -0
- data/test/unit/searching_search_request_test.rb +78 -0
- data/test/unit/searching_test.rb +41 -0
- data/test/unit/serializing_test.rb +17 -0
- metadata +466 -0
@@ -0,0 +1,179 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
puts "ActiveRecord #{ActiveRecord::VERSION::STRING}", '-'*80
|
5
|
+
|
6
|
+
module Elasticsearch
|
7
|
+
module Model
|
8
|
+
class ActiveRecordBasicIntegrationTest < Elasticsearch::Test::IntegrationTestCase
|
9
|
+
context "ActiveRecord basic integration" do
|
10
|
+
setup do
|
11
|
+
ActiveRecord::Schema.define(:version => 1) do
|
12
|
+
create_table :articles do |t|
|
13
|
+
t.string :title
|
14
|
+
t.datetime :created_at, :default => 'NOW()'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ::Article < ActiveRecord::Base
|
19
|
+
include Elasticsearch::Model
|
20
|
+
include Elasticsearch::Model::Callbacks
|
21
|
+
|
22
|
+
settings index: { number_of_shards: 1, number_of_replicas: 0 } do
|
23
|
+
mapping do
|
24
|
+
indexes :title, type: 'string', analyzer: 'snowball'
|
25
|
+
indexes :created_at, type: 'date'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Article.delete_all
|
31
|
+
Article.__elasticsearch__.create_index! force: true
|
32
|
+
|
33
|
+
::Article.create! title: 'Test'
|
34
|
+
::Article.create! title: 'Testing Coding'
|
35
|
+
::Article.create! title: 'Coding'
|
36
|
+
|
37
|
+
Article.__elasticsearch__.refresh_index!
|
38
|
+
end
|
39
|
+
|
40
|
+
should "index and find a document" do
|
41
|
+
response = Article.search('title:test')
|
42
|
+
|
43
|
+
assert response.any?, "Response should not be empty: #{response.to_a.inspect}"
|
44
|
+
|
45
|
+
assert_equal 2, response.results.size
|
46
|
+
assert_equal 2, response.records.size
|
47
|
+
|
48
|
+
assert_instance_of Elasticsearch::Model::Response::Result, response.results.first
|
49
|
+
assert_instance_of Article, response.records.first
|
50
|
+
|
51
|
+
assert_equal 'Test', response.results.first.title
|
52
|
+
assert_equal 'Test', response.records.first.title
|
53
|
+
end
|
54
|
+
|
55
|
+
should "provide access to result" do
|
56
|
+
response = Article.search query: { match: { title: 'test' } }, highlight: { fields: { title: {} } }
|
57
|
+
|
58
|
+
assert_equal 'Test', response.results.first.title
|
59
|
+
|
60
|
+
assert_equal true, response.results.first.title?
|
61
|
+
assert_equal false, response.results.first.boo?
|
62
|
+
|
63
|
+
assert_equal true, response.results.first.highlight?
|
64
|
+
assert_equal true, response.results.first.highlight.title?
|
65
|
+
assert_equal false, response.results.first.highlight.boo?
|
66
|
+
end
|
67
|
+
|
68
|
+
should "iterate over results" do
|
69
|
+
response = Article.search('title:test')
|
70
|
+
|
71
|
+
assert_equal ['1', '2'], response.results.map(&:_id)
|
72
|
+
assert_equal [1, 2], response.records.map(&:id)
|
73
|
+
end
|
74
|
+
|
75
|
+
should "return _id and _type as #id and #type" do
|
76
|
+
response = Article.search('title:test')
|
77
|
+
|
78
|
+
assert_equal '1', response.results.first.id
|
79
|
+
assert_equal 'article', response.results.first.type
|
80
|
+
end
|
81
|
+
|
82
|
+
should "access results from records" do
|
83
|
+
response = Article.search('title:test')
|
84
|
+
|
85
|
+
response.records.each_with_hit do |r, h|
|
86
|
+
assert_not_nil h._score
|
87
|
+
assert_not_nil h._source.title
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
should "preserve the search results order for records" do
|
92
|
+
response = Article.search('title:code')
|
93
|
+
|
94
|
+
response.records.each_with_hit do |r, h|
|
95
|
+
assert_equal h._id, r.id.to_s
|
96
|
+
end
|
97
|
+
|
98
|
+
response.records.map_with_hit do |r, h|
|
99
|
+
assert_equal h._id, r.id.to_s
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
should "remove document from index on destroy" do
|
104
|
+
article = Article.first
|
105
|
+
|
106
|
+
article.destroy
|
107
|
+
assert_equal 2, Article.count
|
108
|
+
|
109
|
+
Article.__elasticsearch__.refresh_index!
|
110
|
+
|
111
|
+
response = Article.search 'title:test'
|
112
|
+
|
113
|
+
assert_equal 1, response.results.size
|
114
|
+
assert_equal 1, response.records.size
|
115
|
+
end
|
116
|
+
|
117
|
+
should "index updates to the document" do
|
118
|
+
article = Article.first
|
119
|
+
|
120
|
+
article.title = 'Writing'
|
121
|
+
article.save
|
122
|
+
|
123
|
+
Article.__elasticsearch__.refresh_index!
|
124
|
+
|
125
|
+
response = Article.search 'title:write'
|
126
|
+
|
127
|
+
assert_equal 1, response.results.size
|
128
|
+
assert_equal 1, response.records.size
|
129
|
+
end
|
130
|
+
|
131
|
+
should "return results for a DSL search" do
|
132
|
+
response = Article.search query: { match: { title: { query: 'test' } } }
|
133
|
+
|
134
|
+
assert_equal 2, response.results.size
|
135
|
+
assert_equal 2, response.records.size
|
136
|
+
end
|
137
|
+
|
138
|
+
should "return a paged collection" do
|
139
|
+
response = Article.search query: { match: { title: { query: 'test' } } },
|
140
|
+
size: 2,
|
141
|
+
from: 1
|
142
|
+
|
143
|
+
assert_equal 1, response.results.size
|
144
|
+
assert_equal 1, response.records.size
|
145
|
+
|
146
|
+
assert_equal 'Testing Coding', response.results.first.title
|
147
|
+
assert_equal 'Testing Coding', response.records.first.title
|
148
|
+
end
|
149
|
+
|
150
|
+
should "allow chaining SQL commands on response.records" do
|
151
|
+
response = Article.search query: { match: { title: { query: 'test' } } }
|
152
|
+
|
153
|
+
assert_equal 2, response.records.size
|
154
|
+
assert_equal 1, response.records.where(title: 'Test').size
|
155
|
+
assert_equal 'Test', response.records.where(title: 'Test').first.title
|
156
|
+
end
|
157
|
+
|
158
|
+
should "allow ordering response.records in SQL" do
|
159
|
+
response = Article.search query: { match: { title: { query: 'test' } } }
|
160
|
+
|
161
|
+
if defined?(::ActiveRecord) && ::ActiveRecord::VERSION::MAJOR >= 4
|
162
|
+
assert_equal 'Testing Coding', response.records.order(title: :desc).first.title
|
163
|
+
else
|
164
|
+
assert_equal 'Testing Coding', response.records.order('title DESC').first.title
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
should "allow dot access to response" do
|
169
|
+
response = Article.search query: { match: { title: { query: 'test' } } },
|
170
|
+
aggregations: { dates: { date_histogram: { field: 'created_at', interval: 'hour' } } }
|
171
|
+
|
172
|
+
response.response.respond_to?(:aggregations)
|
173
|
+
assert_equal 2, response.response.aggregations.dates.buckets.first.doc_count
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module Elasticsearch
|
5
|
+
module Model
|
6
|
+
class ActiveRecordCustomSerializationTest < Elasticsearch::Test::IntegrationTestCase
|
7
|
+
context "ActiveRecord model with custom JSON serialization" do
|
8
|
+
setup do
|
9
|
+
class ::ArticleWithCustomSerialization < ActiveRecord::Base
|
10
|
+
include Elasticsearch::Model
|
11
|
+
include Elasticsearch::Model::Callbacks
|
12
|
+
|
13
|
+
mapping do
|
14
|
+
indexes :title
|
15
|
+
end
|
16
|
+
|
17
|
+
def as_indexed_json(options={})
|
18
|
+
# as_json(options.merge root: false).slice('title')
|
19
|
+
{ title: self.title }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
ActiveRecord::Schema.define(:version => 1) do
|
24
|
+
create_table ArticleWithCustomSerialization.table_name do |t|
|
25
|
+
t.string :title
|
26
|
+
t.string :status
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
ArticleWithCustomSerialization.delete_all
|
31
|
+
ArticleWithCustomSerialization.__elasticsearch__.create_index! force: true
|
32
|
+
end
|
33
|
+
|
34
|
+
should "index only the title attribute when creating" do
|
35
|
+
ArticleWithCustomSerialization.create! title: 'Test', status: 'green'
|
36
|
+
|
37
|
+
a = ArticleWithCustomSerialization.__elasticsearch__.client.get \
|
38
|
+
index: 'article_with_custom_serializations',
|
39
|
+
type: 'article_with_custom_serialization',
|
40
|
+
id: '1'
|
41
|
+
|
42
|
+
assert_equal( { 'title' => 'Test' }, a['_source'] )
|
43
|
+
end
|
44
|
+
|
45
|
+
should "index only the title attribute when updating" do
|
46
|
+
ArticleWithCustomSerialization.create! title: 'Test', status: 'green'
|
47
|
+
|
48
|
+
article = ArticleWithCustomSerialization.first
|
49
|
+
article.update_attributes title: 'UPDATED', status: 'red'
|
50
|
+
|
51
|
+
a = ArticleWithCustomSerialization.__elasticsearch__.client.get \
|
52
|
+
index: 'article_with_custom_serializations',
|
53
|
+
type: 'article_with_custom_serialization',
|
54
|
+
id: '1'
|
55
|
+
|
56
|
+
assert_equal( { 'title' => 'UPDATED' }, a['_source'] )
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module Elasticsearch
|
5
|
+
module Model
|
6
|
+
class ActiveRecordImportIntegrationTest < Elasticsearch::Test::IntegrationTestCase
|
7
|
+
context "ActiveRecord importing" do
|
8
|
+
setup do
|
9
|
+
ActiveRecord::Schema.define(:version => 1) do
|
10
|
+
create_table :import_articles do |t|
|
11
|
+
t.string :title
|
12
|
+
t.integer :views
|
13
|
+
t.string :numeric # For the sake of invalid data sent to Elasticsearch
|
14
|
+
t.datetime :created_at, :default => 'NOW()'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ::ImportArticle < ActiveRecord::Base
|
19
|
+
include Elasticsearch::Model
|
20
|
+
|
21
|
+
scope :popular, -> { where('views >= 50') }
|
22
|
+
|
23
|
+
mapping do
|
24
|
+
indexes :title, type: 'string'
|
25
|
+
indexes :views, type: 'integer'
|
26
|
+
indexes :numeric, type: 'integer'
|
27
|
+
indexes :created_at, type: 'date'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
ImportArticle.delete_all
|
32
|
+
ImportArticle.__elasticsearch__.create_index! force: true
|
33
|
+
ImportArticle.__elasticsearch__.client.cluster.health wait_for_status: 'yellow'
|
34
|
+
|
35
|
+
100.times { |i| ImportArticle.create! title: "Test #{i}", views: i }
|
36
|
+
end
|
37
|
+
|
38
|
+
should "import all the documents" do
|
39
|
+
assert_equal 100, ImportArticle.count
|
40
|
+
|
41
|
+
ImportArticle.__elasticsearch__.refresh_index!
|
42
|
+
assert_equal 0, ImportArticle.search('*').results.total
|
43
|
+
|
44
|
+
batches = 0
|
45
|
+
errors = ImportArticle.import(batch_size: 10) do |response|
|
46
|
+
batches += 1
|
47
|
+
end
|
48
|
+
|
49
|
+
assert_equal 0, errors
|
50
|
+
assert_equal 10, batches
|
51
|
+
|
52
|
+
ImportArticle.__elasticsearch__.refresh_index!
|
53
|
+
assert_equal 100, ImportArticle.search('*').results.total
|
54
|
+
end
|
55
|
+
|
56
|
+
should "import only documents from a specific scope" do
|
57
|
+
assert_equal 100, ImportArticle.count
|
58
|
+
|
59
|
+
assert_equal 0, ImportArticle.import(scope: 'popular')
|
60
|
+
|
61
|
+
ImportArticle.__elasticsearch__.refresh_index!
|
62
|
+
assert_equal 50, ImportArticle.search('*').results.total
|
63
|
+
end
|
64
|
+
|
65
|
+
should "report and not store/index invalid documents" do
|
66
|
+
ImportArticle.create! title: "Test INVALID", numeric: "INVALID"
|
67
|
+
|
68
|
+
assert_equal 101, ImportArticle.count
|
69
|
+
|
70
|
+
ImportArticle.__elasticsearch__.refresh_index!
|
71
|
+
assert_equal 0, ImportArticle.search('*').results.total
|
72
|
+
|
73
|
+
batches = 0
|
74
|
+
errors = ImportArticle.__elasticsearch__.import(batch_size: 10) do |response|
|
75
|
+
batches += 1
|
76
|
+
end
|
77
|
+
|
78
|
+
assert_equal 1, errors
|
79
|
+
assert_equal 11, batches
|
80
|
+
|
81
|
+
ImportArticle.__elasticsearch__.refresh_index!
|
82
|
+
assert_equal 100, ImportArticle.search('*').results.total
|
83
|
+
end
|
84
|
+
|
85
|
+
should "transform documents with the option" do
|
86
|
+
assert_equal 100, ImportArticle.count
|
87
|
+
|
88
|
+
assert_equal 0, ImportArticle.import( transform: ->(a) {{ index: { data: { name: a.title, foo: 'BAR' } }}} )
|
89
|
+
|
90
|
+
ImportArticle.__elasticsearch__.refresh_index!
|
91
|
+
assert_contains ImportArticle.search('*').results.first._source.keys, 'name'
|
92
|
+
assert_contains ImportArticle.search('*').results.first._source.keys, 'foo'
|
93
|
+
assert_equal 100, ImportArticle.search('test').results.total
|
94
|
+
assert_equal 100, ImportArticle.search('bar').results.total
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module Elasticsearch
|
5
|
+
module Model
|
6
|
+
class ActiveRecordNamespacedModelIntegrationTest < Elasticsearch::Test::IntegrationTestCase
|
7
|
+
context "Namespaced ActiveRecord model integration" do
|
8
|
+
setup do
|
9
|
+
ActiveRecord::Schema.define(:version => 1) do
|
10
|
+
create_table :articles do |t|
|
11
|
+
t.string :title
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ::MyNamespace
|
16
|
+
class Article < ActiveRecord::Base
|
17
|
+
include Elasticsearch::Model
|
18
|
+
include Elasticsearch::Model::Callbacks
|
19
|
+
|
20
|
+
mapping { indexes :title }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
MyNamespace::Article.delete_all
|
25
|
+
MyNamespace::Article.__elasticsearch__.create_index! force: true
|
26
|
+
|
27
|
+
MyNamespace::Article.create! title: 'Test'
|
28
|
+
|
29
|
+
MyNamespace::Article.__elasticsearch__.refresh_index!
|
30
|
+
end
|
31
|
+
|
32
|
+
should "have proper index name and document type" do
|
33
|
+
assert_equal "my_namespace-articles", MyNamespace::Article.index_name
|
34
|
+
assert_equal "article", MyNamespace::Article.document_type
|
35
|
+
end
|
36
|
+
|
37
|
+
should "save document into index on save and find it" do
|
38
|
+
response = MyNamespace::Article.search 'title:test'
|
39
|
+
|
40
|
+
assert response.any?, "No results returned: #{response.inspect}"
|
41
|
+
assert_equal 1, response.size
|
42
|
+
|
43
|
+
assert_equal 'Test', response.results.first.title
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module Elasticsearch
|
5
|
+
module Model
|
6
|
+
class ActiveRecordPaginationTest < Elasticsearch::Test::IntegrationTestCase
|
7
|
+
context "ActiveRecord pagination" do
|
8
|
+
setup do
|
9
|
+
class ::ArticleForPagination < ActiveRecord::Base
|
10
|
+
include Elasticsearch::Model
|
11
|
+
|
12
|
+
scope :published, -> { where(published: true) }
|
13
|
+
|
14
|
+
settings index: { number_of_shards: 1, number_of_replicas: 0 } do
|
15
|
+
mapping do
|
16
|
+
indexes :title, type: 'string', analyzer: 'snowball'
|
17
|
+
indexes :created_at, type: 'date'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
ActiveRecord::Schema.define(:version => 1) do
|
23
|
+
create_table ::ArticleForPagination.table_name do |t|
|
24
|
+
t.string :title
|
25
|
+
t.datetime :created_at, :default => 'NOW()'
|
26
|
+
t.boolean :published
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Kaminari::Hooks.init
|
31
|
+
|
32
|
+
ArticleForPagination.delete_all
|
33
|
+
ArticleForPagination.__elasticsearch__.create_index! force: true
|
34
|
+
|
35
|
+
68.times do |i|
|
36
|
+
::ArticleForPagination.create! title: "Test #{i}", published: (i % 2 == 0)
|
37
|
+
end
|
38
|
+
|
39
|
+
ArticleForPagination.import
|
40
|
+
ArticleForPagination.__elasticsearch__.refresh_index!
|
41
|
+
end
|
42
|
+
|
43
|
+
should "be on the first page by default" do
|
44
|
+
records = ArticleForPagination.search('title:test').page(1).records
|
45
|
+
|
46
|
+
assert_equal 25, records.size
|
47
|
+
assert_equal 1, records.current_page
|
48
|
+
assert_equal nil, records.prev_page
|
49
|
+
assert_equal 2, records.next_page
|
50
|
+
assert_equal 3, records.total_pages
|
51
|
+
|
52
|
+
assert records.first_page?, "Should be the first page"
|
53
|
+
assert ! records.last_page?, "Should NOT be the last page"
|
54
|
+
assert ! records.out_of_range?, "Should NOT be out of range"
|
55
|
+
end
|
56
|
+
|
57
|
+
should "load next page" do
|
58
|
+
records = ArticleForPagination.search('title:test').page(2).records
|
59
|
+
|
60
|
+
assert_equal 25, records.size
|
61
|
+
assert_equal 2, records.current_page
|
62
|
+
assert_equal 1, records.prev_page
|
63
|
+
assert_equal 3, records.next_page
|
64
|
+
assert_equal 3, records.total_pages
|
65
|
+
|
66
|
+
assert ! records.first_page?, "Should NOT be the first page"
|
67
|
+
assert ! records.last_page?, "Should NOT be the last page"
|
68
|
+
assert ! records.out_of_range?, "Should NOT be out of range"
|
69
|
+
end
|
70
|
+
|
71
|
+
should "load last page" do
|
72
|
+
records = ArticleForPagination.search('title:test').page(3).records
|
73
|
+
|
74
|
+
assert_equal 18, records.size
|
75
|
+
assert_equal 3, records.current_page
|
76
|
+
assert_equal 2, records.prev_page
|
77
|
+
assert_equal nil, records.next_page
|
78
|
+
assert_equal 3, records.total_pages
|
79
|
+
|
80
|
+
assert ! records.first_page?, "Should NOT be the first page"
|
81
|
+
assert records.last_page?, "Should be the last page"
|
82
|
+
assert ! records.out_of_range?, "Should NOT be out of range"
|
83
|
+
end
|
84
|
+
|
85
|
+
should "not load invalid page" do
|
86
|
+
records = ArticleForPagination.search('title:test').page(6).records
|
87
|
+
|
88
|
+
assert_equal 0, records.size
|
89
|
+
assert_equal 6, records.current_page
|
90
|
+
assert_equal 5, records.prev_page
|
91
|
+
assert_equal nil, records.next_page
|
92
|
+
assert_equal 3, records.total_pages
|
93
|
+
|
94
|
+
assert ! records.first_page?, "Should NOT be the first page"
|
95
|
+
assert records.last_page?, "Should be the last page"
|
96
|
+
assert records.out_of_range?, "Should be out of range"
|
97
|
+
end
|
98
|
+
|
99
|
+
should "be combined with scopes" do
|
100
|
+
records = ArticleForPagination.search('title:test').page(2).records.published
|
101
|
+
assert records.all? { |r| r.published? }
|
102
|
+
assert_equal 12, records.size
|
103
|
+
end
|
104
|
+
|
105
|
+
should "set the limit per request" do
|
106
|
+
records = ArticleForPagination.search('title:test').limit(50).page(2).records
|
107
|
+
|
108
|
+
assert_equal 18, records.size
|
109
|
+
assert_equal 2, records.current_page
|
110
|
+
assert_equal 1, records.prev_page
|
111
|
+
assert_equal nil, records.next_page
|
112
|
+
assert_equal 2, records.total_pages
|
113
|
+
|
114
|
+
assert records.last_page?, "Should be the last page"
|
115
|
+
end
|
116
|
+
|
117
|
+
context "with specific model settings" do
|
118
|
+
teardown do
|
119
|
+
ArticleForPagination.instance_variable_set(:@_default_per_page, nil)
|
120
|
+
end
|
121
|
+
|
122
|
+
should "respect paginates_per" do
|
123
|
+
ArticleForPagination.paginates_per 50
|
124
|
+
|
125
|
+
assert_equal 50, ArticleForPagination.search('*').page(1).records.size
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|