api-pagination 4.7.2 → 4.8.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fcd1a8e55bce363ef14c8fca2ff4a06ea1cf325e61fe2eba564d6bcbcb0cbb43
4
- data.tar.gz: 66a8a77cc4e1fa163ce3e644c2828388778efaab24783967c2c9e7986a83ac30
3
+ metadata.gz: 9027303d9da656103e61812aded61149a601a27dbc398d40d44d2952242fbb6d
4
+ data.tar.gz: 5758331c124689a6160d6b787409bb8abfbba83213e201289c227f624afe7db5
5
5
  SHA512:
6
- metadata.gz: 475209b5986a009d9bc52cded5269fec22998e6d94c419635772950ee17ea7a1b0a01818b6791f009fe9da545022522f2ba0303a5fae93d81a364f3bc740cb1e
7
- data.tar.gz: 355d8e7786bf49318941d48ea57ff6fd81fd6cf9b97d9e185fb1302eb20dc4144100f3fce675809d73bffc0341b0f100e37fb3f12a2e6c51ea9b98e4d9db5a03
6
+ metadata.gz: 7ae4651a31cfbe45a02ffc9da7376c30ef5400d30265528de8f39130924fbef327d7158aedfe21fe7c24899c3632a14161bfc4392f8ab69fc167c21d4de608be
7
+ data.tar.gz: 842bb2e7b03046cbacfbfed1dc8ea6c4ebc435f7a91423d98f844dde5a2128573cd21bda81d5813a8e813abfb0154f22e0fc0436033923ddd4af04f96888f0ea
@@ -9,6 +9,8 @@ module ApiPagination
9
9
  options[:per_page] = options[:per_page].to_i
10
10
 
11
11
  case ApiPagination.config.paginator
12
+ when :pagy
13
+ paginate_with_pagy(collection, options)
12
14
  when :kaminari
13
15
  paginate_with_kaminari(collection, options, options[:paginate_array_options] || {})
14
16
  when :will_paginate
@@ -18,7 +20,9 @@ module ApiPagination
18
20
  end
19
21
  end
20
22
 
21
- def pages_from(collection)
23
+ def pages_from(collection, options = {})
24
+ return pagy_pages_from(collection) if collection.is_a?(Pagy)
25
+
22
26
  {}.tap do |pages|
23
27
  unless collection.first_page?
24
28
  pages[:first] = 1
@@ -34,6 +38,7 @@ module ApiPagination
34
38
 
35
39
  def total_from(collection)
36
40
  case ApiPagination.config.paginator
41
+ when :pagy then collection.count.to_s
37
42
  when :kaminari then collection.total_count.to_s
38
43
  when :will_paginate then collection.total_entries.to_s
39
44
  end
@@ -41,6 +46,41 @@ module ApiPagination
41
46
 
42
47
  private
43
48
 
49
+ def paginate_with_pagy(collection, options)
50
+ if Pagy::VARS[:max_per_page] && options[:per_page] > Pagy::VARS[:max_per_page]
51
+ options[:per_page] = Pagy::VARS[:max_per_page]
52
+ elsif options[:per_page] <= 0
53
+ options[:per_page] = Pagy::VARS[:items]
54
+ end
55
+
56
+ pagy = pagy_from(collection, options)
57
+ collection = if collection.respond_to?(:offset) && collection.respond_to?(:limit)
58
+ collection.offset(pagy.offset).limit(pagy.items)
59
+ else
60
+ collection[pagy.offset, pagy.items]
61
+ end
62
+
63
+ return [collection, pagy]
64
+ end
65
+
66
+ def pagy_from(collection, options)
67
+ Pagy.new(count: collection.count, items: options[:per_page], page: options[:page])
68
+ end
69
+
70
+ def pagy_pages_from(pagy)
71
+ {}.tap do |pages|
72
+ unless pagy.page == 1
73
+ pages[:first] = 1
74
+ pages[:prev] = pagy.prev
75
+ end
76
+
77
+ unless pagy.page == pagy.pages
78
+ pages[:last] = pagy.pages
79
+ pages[:next] = pagy.next
80
+ end
81
+ end
82
+ end
83
+
44
84
  def paginate_with_kaminari(collection, options, paginate_array_options = {})
45
85
  if Kaminari.config.max_per_page && options[:per_page] > Kaminari.config.max_per_page
46
86
  options[:per_page] = Kaminari.config.max_per_page
@@ -49,7 +89,7 @@ module ApiPagination
49
89
  end
50
90
 
51
91
  collection = Kaminari.paginate_array(collection, paginate_array_options) if collection.is_a?(Array)
52
- collection.page(options[:page]).per(options[:per_page])
92
+ [collection.page(options[:page]).per(options[:per_page]), nil]
53
93
  end
54
94
 
55
95
  def paginate_with_will_paginate(collection, options)
@@ -57,13 +97,15 @@ module ApiPagination
57
97
  options[:per_page] = default_per_page_for_will_paginate(collection)
58
98
  end
59
99
 
60
- if defined?(Sequel::Dataset) && collection.kind_of?(Sequel::Dataset)
100
+ collection = if defined?(Sequel::Dataset) && collection.kind_of?(Sequel::Dataset)
61
101
  collection.paginate(options[:page], options[:per_page])
62
102
  else
63
103
  supported_options = [:page, :per_page, :total_entries]
64
104
  options = options.dup.keep_if { |k,v| supported_options.include?(k.to_sym) }
65
105
  collection.paginate(options)
66
106
  end
107
+
108
+ [collection, nil]
67
109
  end
68
110
 
69
111
  def get_default_per_page_for_kaminari(collection)
@@ -55,6 +55,8 @@ module ApiPagination
55
55
 
56
56
  def paginator=(paginator)
57
57
  case paginator.to_sym
58
+ when :pagy
59
+ use_pagy
58
60
  when :kaminari
59
61
  use_kaminari
60
62
  when :will_paginate
@@ -67,11 +69,12 @@ module ApiPagination
67
69
  private
68
70
 
69
71
  def set_paginator
70
- if defined?(Kaminari) && defined?(WillPaginate::CollectionMethods)
72
+ conditions = [defined?(Pagy), defined?(Kaminari), defined?(WillPaginate::CollectionMethods)]
73
+ if conditions.compact.size > 1
71
74
  Kernel.warn <<-WARNING
72
- Warning: api-pagination relies on either Kaminari or WillPaginate, but both are
73
- currently active. If possible, you should remove one or the other. If you can't,
74
- you _must_ configure api-pagination on your own. For example:
75
+ Warning: api-pagination relies on Pagy, Kaminari, or WillPaginate, but more than
76
+ one are currently active. If possible, you should remove one or the other. If
77
+ you can't, you _must_ configure api-pagination on your own. For example:
75
78
 
76
79
  ApiPagination.configure do |config|
77
80
  config.paginator = :kaminari
@@ -86,13 +89,19 @@ Kaminari.configure do |config|
86
89
  end
87
90
 
88
91
  WARNING
92
+ elsif defined?(Pagy)
93
+ use_pagy
89
94
  elsif defined?(Kaminari)
90
- return use_kaminari
95
+ use_kaminari
91
96
  elsif defined?(WillPaginate::CollectionMethods)
92
- return use_will_paginate
97
+ use_will_paginate
93
98
  end
94
99
  end
95
100
 
101
+ def use_pagy
102
+ @paginator = :pagy
103
+ end
104
+
96
105
  def use_kaminari
97
106
  require 'kaminari/models/array_extension'
98
107
  @paginator = :kaminari
@@ -4,14 +4,16 @@ if defined?(Grape::API)
4
4
  Grape::API.send(:include, Grape::Pagination)
5
5
  end
6
6
 
7
+ begin; require 'pagy'; rescue LoadError; end
7
8
  begin; require 'kaminari'; rescue LoadError; end
8
9
  begin; require 'will_paginate'; rescue LoadError; end
9
10
 
10
- unless defined?(Kaminari) || defined?(WillPaginate::CollectionMethods)
11
+ unless defined?(Pagy) || defined?(Kaminari) || defined?(WillPaginate::CollectionMethods)
11
12
  Kernel.warn <<-WARNING.gsub(/^\s{4}/, '')
12
- Warning: api-pagination relies on either Kaminari or WillPaginate. Please
13
- install either dependency by adding one of the following to your Gemfile:
13
+ Warning: api-pagination relies on either Pagy, Kaminari, or WillPaginate.
14
+ Please install a paginator by adding one of the following to your Gemfile:
14
15
 
16
+ gem 'pagy'
15
17
  gem 'kaminari'
16
18
  gem 'will_paginate'
17
19
  WARNING
@@ -1,8 +1,8 @@
1
1
  module ApiPagination
2
2
  class Version
3
3
  MAJOR = 4
4
- MINOR = 7
5
- PATCH = 2
4
+ MINOR = 8
5
+ PATCH = 0
6
6
 
7
7
  def self.to_s
8
8
  [MAJOR, MINOR, PATCH].join('.')
@@ -9,11 +9,11 @@ module Grape
9
9
  :page => ApiPagination.config.page_param(params),
10
10
  :per_page => [per_page, route_setting(:max_per_page)].compact.min
11
11
  }
12
- collection = ApiPagination.paginate(collection, options)
12
+ collection, pagy = ApiPagination.paginate(collection, options)
13
13
 
14
14
  links = (header['Link'] || "").split(',').map(&:strip)
15
15
  url = request.url.sub(/\?.*$/, '')
16
- pages = ApiPagination.pages_from(collection)
16
+ pages = ApiPagination.pages_from(pagy || collection, options)
17
17
 
18
18
  pages.each do |k, v|
19
19
  old_params = Rack::Utils.parse_nested_query(request.query_string)
@@ -27,7 +27,7 @@ module Grape
27
27
  include_total = ApiPagination.config.include_total
28
28
 
29
29
  header 'Link', links.join(', ') unless links.empty?
30
- header total_header, ApiPagination.total_from(collection).to_s if include_total
30
+ header total_header, ApiPagination.total_from(pagy || collection).to_s if include_total
31
31
  header per_page_header, options[:per_page].to_s
32
32
  header page_header, options[:page].to_s unless page_header.nil?
33
33
 
@@ -27,11 +27,11 @@ module Rails
27
27
  options[:page] = ApiPagination.config.page_param(params)
28
28
  options[:per_page] ||= ApiPagination.config.per_page_param(params)
29
29
 
30
- collection = ApiPagination.paginate(collection, options)
30
+ collection, pagy = ApiPagination.paginate(collection, options)
31
31
 
32
32
  links = (headers['Link'] || '').split(',').map(&:strip)
33
33
  url = base_url + request.path_info
34
- pages = ApiPagination.pages_from(collection)
34
+ pages = ApiPagination.pages_from(pagy || collection, options)
35
35
 
36
36
  pages.each do |k, v|
37
37
  new_params = request.query_parameters.merge(:page => v)
@@ -46,7 +46,7 @@ module Rails
46
46
  headers['Link'] = links.join(', ') unless links.empty?
47
47
  headers[per_page_header] = options[:per_page].to_s
48
48
  headers[page_header] = options[:page].to_s unless page_header.nil?
49
- headers[total_header] = total_count(collection, options).to_s if include_total
49
+ headers[total_header] = total_count(pagy || collection, options).to_s if include_total
50
50
 
51
51
  return collection
52
52
  end
@@ -62,6 +62,5 @@ module Rails
62
62
  def base_url
63
63
  ApiPagination.config.base_url || request.base_url
64
64
  end
65
-
66
65
  end
67
66
  end
@@ -5,60 +5,48 @@ describe ApiPagination do
5
5
  let(:paginate_array_options) {{ total_count: 1000 }}
6
6
 
7
7
  describe "#paginate" do
8
- context 'Using kaminari' do
9
- before do
10
- ApiPagination.config.paginator = :kaminari
11
- end
12
-
13
- after do
14
- ApiPagination.config.paginator = ENV['PAGINATOR'].to_sym
15
- end
16
-
17
- it 'should accept paginate_array_options option' do
18
- expect(Kaminari).to receive(:paginate_array)
19
- .with(collection, paginate_array_options)
20
- .and_call_original
21
-
22
- ApiPagination.paginate(
23
- collection,
24
- {
25
- per_page: 30,
26
- paginate_array_options: paginate_array_options
27
- }
28
- )
29
- end
8
+ if ENV['PAGINATOR'].to_sym == :kaminari
9
+ context 'Using kaminari' do
10
+ it 'should accept paginate_array_options option' do
11
+ expect(Kaminari).to receive(:paginate_array)
12
+ .with(collection, paginate_array_options)
13
+ .and_call_original
14
+
15
+ ApiPagination.paginate(
16
+ collection,
17
+ {
18
+ per_page: 30,
19
+ paginate_array_options: paginate_array_options
20
+ }
21
+ )
22
+ end
30
23
 
31
- describe '.pages_from' do
32
- subject {described_class.pages_from collection}
24
+ describe '.pages_from' do
25
+ subject { described_class.pages_from(collection) }
33
26
 
34
- context 'on empty collection' do
35
- let(:collection) {ApiPagination.paginate [], page: 1}
27
+ context 'on empty collection' do
28
+ let(:collection) { ApiPagination.paginate([], page: 1).first }
36
29
 
37
- it {is_expected.to be_empty}
30
+ it { is_expected.to be_empty }
31
+ end
38
32
  end
39
33
  end
40
34
  end
41
35
 
42
- context 'Using will_paginate' do
43
- before do
44
- ApiPagination.config.paginator = :will_paginate
45
- end
46
-
47
- after do
48
- ApiPagination.config.paginator = ENV['PAGINATOR'].to_sym
49
- end
50
-
51
- context 'passing in total_entries in options' do
52
- it 'should set total_entries using the passed in value' do
53
- paginated_collection = ApiPagination.paginate(collection, total_entries: 3000)
54
- expect(paginated_collection.total_entries).to eq(3000)
36
+ if ENV['PAGINATOR'].to_sym == :will_paginate
37
+ context 'Using will_paginate' do
38
+ context 'passing in total_entries in options' do
39
+ it 'should set total_entries using the passed in value' do
40
+ paginated_collection = ApiPagination.paginate(collection, total_entries: 3000).first
41
+ expect(paginated_collection.total_entries).to eq(3000)
42
+ end
55
43
  end
56
- end
57
44
 
58
- context 'passing in collection only' do
59
- it 'should set total_entries using the size of the collection ' do
60
- paginated_collection = ApiPagination.paginate(collection)
61
- expect(paginated_collection.total_entries).to eq(100)
45
+ context 'passing in collection only' do
46
+ it 'should set total_entries using the size of the collection ' do
47
+ paginated_collection = ApiPagination.paginate(collection).first
48
+ expect(paginated_collection.total_entries).to eq(100)
49
+ end
62
50
  end
63
51
  end
64
52
  end
@@ -214,8 +214,11 @@ describe NumbersController, :type => :controller do
214
214
  end
215
215
  end
216
216
 
217
- context 'paginate array options' do
218
- shared_examples 'properly set Total header' do
217
+ if ApiPagination.config.paginator.to_sym == :kaminari
218
+ context 'paginate array options' do
219
+ let(:paginate_array_total_count) { 300 }
220
+ let(:total_header) { 300 }
221
+ let(:count) { 50 }
219
222
  let(:params) do
220
223
  {
221
224
  paginate_array_total_count: paginate_array_total_count,
@@ -223,84 +226,57 @@ describe NumbersController, :type => :controller do
223
226
  }
224
227
  end
225
228
 
226
- specify do
229
+ it 'has a properly set Total header' do
227
230
  get :index_with_paginate_array_options, params: params
228
231
 
229
232
  expect(response.header['Total']).to be_kind_of(String)
230
233
  expect(response.header['Total'].to_i).to eq total_header
231
234
  end
232
235
  end
233
-
234
- context 'kaminari' do
235
- around do |example|
236
- paginator = ApiPagination.config.paginator
237
- ApiPagination.config.paginator = :kaminari
238
- example.run
239
- ApiPagination.config.paginator = paginator
240
- end
241
-
242
- it_should_behave_like 'properly set Total header' do
243
- let(:paginate_array_total_count) { 300 }
244
- let(:total_header) { 300 }
245
- let(:count) { 50 }
246
- end
247
- end
248
-
249
- context 'will_paginate' do
250
- around do |example|
251
- paginator = ApiPagination.config.paginator
252
- ApiPagination.config.paginator = :will_paginate
253
- example.run
254
- ApiPagination.config.paginator = paginator
255
- end
256
-
257
- it_should_behave_like 'properly set Total header' do
258
- let(:paginate_array_total_count) { 300 }
259
- let(:total_header) { 50 }
260
- let(:count) { 50 }
261
- end
262
- end
263
236
  end
264
237
 
265
- context 'default per page in model' do
266
- before do
267
- class Fixnum
268
- @default_per_page = 6
269
- @per_page = 6
238
+ if [:will_paginate, :kaminari].include?(ApiPagination.config.paginator.to_sym)
239
+ context 'default per page in model' do
240
+ before do
241
+ class Fixnum
242
+ @default_per_page = 6
243
+ @per_page = 6
270
244
 
271
- class << self
272
- attr_accessor :default_per_page, :per_page
245
+ class << self
246
+ attr_accessor :default_per_page, :per_page
247
+ end
273
248
  end
274
249
  end
275
- end
276
250
 
277
- after do
278
- class Fixnum
279
- @default_per_page = 25
280
- @per_page = 25
251
+ after do
252
+ class Fixnum
253
+ @default_per_page = 25
254
+ @per_page = 25
255
+ end
281
256
  end
282
- end
283
257
 
284
- it 'should use default per page from model' do
285
- get :index_with_no_per_page, params: {count: 100}
258
+ it 'should use default per page from model' do
259
+ get :index_with_no_per_page, params: {count: 100}
286
260
 
287
- expect(response.header['Per-Page']).to eq('6')
288
- end
289
-
290
- it 'should not fail if model does not respond to per page' do
291
- class Fixnum
292
- @default_per_page = nil
293
- @per_page = nil
261
+ expect(response.header['Per-Page']).to eq('6')
294
262
  end
295
263
 
296
- get :index_with_no_per_page, params: {count: 100}
297
-
298
- expect(response.header['Per-Page']).to eq(
299
- case ApiPagination.config.paginator
300
- when :kaminari then Kaminari.config.default_per_page.to_s
301
- when :will_paginate then WillPaginate.per_page.to_s
264
+ it 'should not fail if model does not respond to per page' do
265
+ class Fixnum
266
+ @default_per_page = nil
267
+ @per_page = nil
302
268
  end
303
- )
269
+
270
+ get :index_with_no_per_page, params: {count: 100}
271
+
272
+ expect(response.header['Per-Page']).to eq(
273
+ case ApiPagination.config.paginator
274
+ when :pagy then Pagy::VARS[:items].to_s
275
+ when :kaminari then Kaminari.config.default_per_page.to_s
276
+ when :will_paginate then WillPaginate.per_page.to_s
277
+ end
278
+ )
279
+ end
304
280
  end
305
281
  end
306
282
  end
@@ -23,9 +23,8 @@ if ApiPagination.config.paginator == :will_paginate
23
23
  end
24
24
 
25
25
  it 'returns a Sequel::Dataset' do
26
- collection = ApiPagination.paginate(people)
26
+ collection = ApiPagination.paginate(people).first
27
27
  expect(collection.kind_of?(Sequel::Dataset)).to be_truthy
28
28
  end
29
29
  end
30
30
  end
31
-
@@ -3,14 +3,20 @@ require 'support/numbers_api'
3
3
  require 'api-pagination'
4
4
 
5
5
  if ENV['PAGINATOR'].nil?
6
- warn 'No PAGINATOR set. Defaulting to kaminari. To test against will_paginate, run `PAGINATOR=will_paginate bundle exec rspec`'
7
- ENV['PAGINATOR'] = 'kaminari'
6
+ warn <<-WARNING
7
+ No PAGINATOR set. Defaulting to pagy.
8
+
9
+ To test against kaminari, run `PAGINATOR=kaminari bundle exec rspec`
10
+ To test against will_paginate, run `PAGINATOR=will_paginate bundle exec rspec`
11
+ WARNING
12
+
13
+ ENV['PAGINATOR'] = 'pagy'
8
14
  end
9
15
 
10
16
  require ENV['PAGINATOR']
11
17
  ApiPagination.config.paginator = ENV['PAGINATOR'].to_sym
12
18
 
13
- require 'will_paginate/array'
19
+ require 'will_paginate/array' if ENV['PAGINATOR'].to_sym == :will_paginate
14
20
 
15
21
  RSpec.configure do |config|
16
22
  config.include Rack::Test::Methods
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api-pagination
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.7.2
4
+ version: 4.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Celis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-08 00:00:00.000000000 Z
11
+ date: 2018-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec