api-pagination 2.1.1 → 3.0.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
  SHA1:
3
- metadata.gz: 6f6ccb55a817446accc21e10ff030b9ee40e4af2
4
- data.tar.gz: a562df84550d1521fa5dffcc6459e3ce5ad18038
3
+ metadata.gz: 83a3cdfe943a03cd590d6a3c9e80aa11d7d5e684
4
+ data.tar.gz: df6e1401a570e87fad204d6f249e7e31b09ea159
5
5
  SHA512:
6
- metadata.gz: 10f3c3ed499e25e73ac61845e36f6c8de82c59cba53298a4d25443b68d51a69e5ae747afeff3c8c34562b1752f29f96c49b5e5d74ba51a7b01dda659e3907ca5
7
- data.tar.gz: d30c8b948d7f21b69745d3e00b29e81fe82ef34f7c101a197604823ec2f33c920f2ac70a182250f87a714b139dd4abfbb40282f68d922bc1a76f480d68a40d63
6
+ metadata.gz: 139197be0f405c0e4954250f4ffa56f5bdc02246e49b674d1ecaab262a2c412d8b088ac6eaa54cf00cda4a75e30e74a746c8b3fb122c4ea7dc9954c5ebc67d82
7
+ data.tar.gz: c8e15989e239fa9b3d77f8968b4612c8ce93ca78000c39f1c04063d32b24cb1dbe20664e8b1a4ab677fefdb153c20f184ba6319686e126980440ae4b9a6891f2
@@ -5,15 +5,16 @@ module ApiPagination
5
5
  class << self
6
6
  attr_reader :paginator
7
7
 
8
- def paginate(collection, options = {}, &block)
8
+ def paginate(collection, options = {})
9
9
  options[:page] ||= 1
10
- options[:per_page] ||= 10
10
+ options[:per_page] ||= 25
11
11
 
12
12
  case ApiPagination.paginator
13
13
  when :kaminari
14
- collection.page(options[:page]).per(options[:per_page]).tap(&block)
14
+ collection = Kaminari.paginate_array(collection) if collection.is_a?(Array)
15
+ collection.page(options[:page]).per(options[:per_page])
15
16
  when :will_paginate
16
- collection.paginate(:page => options[:page], :per_page => options[:per_page]).tap(&block)
17
+ collection.paginate(:page => options[:page], :per_page => options[:per_page])
17
18
  end
18
19
  end
19
20
 
@@ -39,5 +40,3 @@ module ApiPagination
39
40
  end
40
41
  end
41
42
  end
42
-
43
- ApiPagination::Hooks.init
@@ -45,3 +45,5 @@ EOC
45
45
  end
46
46
  end
47
47
  end
48
+
49
+ ApiPagination::Hooks.init
@@ -1,8 +1,8 @@
1
1
  module ApiPagination
2
2
  class Version
3
- MAJOR = 2
4
- MINOR = 1
5
- PATCH = 1
3
+ MAJOR = 3
4
+ MINOR = 0
5
+ PATCH = 0
6
6
 
7
7
  def self.to_s
8
8
  [MAJOR, MINOR, PATCH].join('.')
@@ -3,32 +3,36 @@ module Grape
3
3
  def self.included(base)
4
4
  Grape::Endpoint.class_eval do
5
5
  def paginate(collection)
6
- block = Proc.new do |collection|
7
- links = (header['Link'] || "").split(',').map(&:strip)
8
- url = request.url.sub(/\?.*$/, '')
9
- pages = ApiPagination.pages_from(collection)
6
+ options = {
7
+ :page => params[:page],
8
+ :per_page => (settings[:per_page] || params[:per_page])
9
+ }
10
+ collection = ApiPagination.paginate(collection, options)
10
11
 
11
- pages.each do |k, v|
12
- old_params = Rack::Utils.parse_query(request.query_string)
13
- new_params = old_params.merge('page' => v)
14
- links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
15
- end
12
+ links = (header['Link'] || "").split(',').map(&:strip)
13
+ url = request.url.sub(/\?.*$/, '')
14
+ pages = ApiPagination.pages_from(collection)
16
15
 
17
- header 'Link', links.join(', ') unless links.empty?
18
- header 'Total', ApiPagination.total_from(collection)
16
+ pages.each do |k, v|
17
+ old_params = Rack::Utils.parse_query(request.query_string)
18
+ new_params = old_params.merge('page' => v)
19
+ links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
19
20
  end
20
21
 
21
- ApiPagination.paginate(collection, params, &block)
22
+ header 'Link', links.join(', ') unless links.empty?
23
+ header 'Total', ApiPagination.total_from(collection)
24
+
25
+ return collection
22
26
  end
23
27
  end
24
28
 
25
29
  base.class_eval do
26
30
  def self.paginate(options = {})
27
- options.reverse_merge!(:per_page => 10)
31
+ set :per_page, options[:per_page]
28
32
  params do
29
33
  optional :page, :type => Integer, :default => 1,
30
34
  :desc => 'Page of results to fetch.'
31
- optional :per_page, :type => Integer, :default => options[:per_page],
35
+ optional :per_page, :type => Integer,
32
36
  :desc => 'Number of results to return per page.'
33
37
  end
34
38
  end
@@ -2,24 +2,43 @@ module Rails
2
2
  module Pagination
3
3
  protected
4
4
 
5
- def paginate(collection)
6
- collection = instance_variable_get(:"@#{collection}")
5
+ def paginate(options)
6
+ collection = options[:json] || options[:xml]
7
7
 
8
- block = Proc.new do |collection|
9
- links = (headers['Link'] || "").split(',').map(&:strip)
10
- url = request.original_url.sub(/\?.*$/, '')
11
- pages = ApiPagination.pages_from(collection)
8
+ collection = _paginate_collection(collection, options)
9
+ options[:json] = collection if options[:json]
10
+ options[:xml] = collection if options[:xml]
12
11
 
13
- pages.each do |k, v|
14
- new_params = request.query_parameters.merge(:page => v)
15
- links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
16
- end
12
+ render options
13
+ end
17
14
 
18
- headers['Link'] = links.join(', ') unless links.empty?
19
- headers['Total'] = ApiPagination.total_from(collection)
20
- end
15
+ def paginate_with(collection)
16
+ respond_with _paginate_collection(collection)
17
+ end
21
18
 
22
- ApiPagination.paginate(collection, params, &block)
19
+ private
20
+
21
+ def _paginate_collection(collection, options)
22
+ options = {
23
+ :page => params[:page],
24
+ :per_page => (options.delete(:per_page) || params[:per_page])
25
+ }
26
+ collection = ApiPagination.paginate(collection, options)
27
+
28
+ links = (headers['Link'] || "").split(',').map(&:strip)
29
+ url = request.original_url.sub(/\?.*$/, '')
30
+ pages = ApiPagination.pages_from(collection)
31
+
32
+ pages.each do |k, v|
33
+ new_params = request.query_parameters.merge(:page => v)
34
+ links << %(<#{url}?#{new_params.to_param}>; rel="#{k}")
23
35
  end
36
+
37
+ headers['Link'] = links.join(', ') unless links.empty?
38
+ headers['Total'] = ApiPagination.total_from(collection)
39
+
40
+ return collection
41
+ end
24
42
  end
25
43
  end
44
+
data/spec/grape_spec.rb CHANGED
@@ -10,14 +10,19 @@ describe NumbersAPI do
10
10
  let(:total) { last_response.headers['Total'].to_i }
11
11
 
12
12
  context 'without enough items to give more than one page' do
13
- before { get :numbers, :count => 20 }
13
+ before { get :numbers, :count => 10 }
14
14
 
15
15
  it 'should not paginate' do
16
16
  expect(last_response.headers.keys).not_to include('Link')
17
17
  end
18
18
 
19
19
  it 'should give a Total header' do
20
- expect(total).to eq(20)
20
+ expect(total).to eq(10)
21
+ end
22
+
23
+ it 'should list all numbers in the response body' do
24
+ body = '[1,2,3,4,5,6,7,8,9,10]'
25
+ expect(last_response.body).to eq(body)
21
26
  end
22
27
  end
23
28
 
@@ -35,7 +40,7 @@ describe NumbersAPI do
35
40
  end
36
41
 
37
42
  context 'when on the last page' do
38
- before { get :numbers, :count => 100, :page => 4 }
43
+ before { get :numbers, :count => 100, :page => 10 }
39
44
 
40
45
  it_behaves_like 'an endpoint with a last page'
41
46
  end
data/spec/rails_spec.rb CHANGED
@@ -12,13 +12,19 @@ describe NumbersController, :type => :controller do
12
12
  let(:total) { response.headers['Total'].to_i }
13
13
 
14
14
  context 'without enough items to give more than one page' do
15
- before { get :index, :count => 20 }
15
+ before { get :index, :count => 10 }
16
+
16
17
  it 'should not paginate' do
17
18
  expect(response.headers.keys).not_to include('Link')
18
19
  end
19
20
 
20
21
  it 'should give a Total header' do
21
- expect(total).to eq(20)
22
+ expect(total).to eq(10)
23
+ end
24
+
25
+ it 'should list all numbers in the response body' do
26
+ body = '[1,2,3,4,5,6,7,8,9,10]'
27
+ expect(response.body).to eq(body)
22
28
  end
23
29
  end
24
30
 
@@ -36,7 +42,7 @@ describe NumbersController, :type => :controller do
36
42
  end
37
43
 
38
44
  context 'when on the last page' do
39
- before { get :index, :count => 100, :page => 4 }
45
+ before { get :index, :count => 100, :page => 10 }
40
46
 
41
47
  it_behaves_like 'an endpoint with a last page'
42
48
  end
data/spec/spec_helper.rb CHANGED
@@ -1,33 +1,10 @@
1
+ require 'coveralls'
2
+ Coveralls.wear_merged!
3
+
1
4
  require 'support/numbers_controller'
2
5
  require 'support/numbers_api'
3
6
  require 'api-pagination'
4
7
 
5
- # Quacks like Kaminari and will_paginate
6
- PaginatedSet = Struct.new(:current_page, :per_page, :total_count) do
7
- def total_pages
8
- total_count.zero? ? 1 : (total_count.to_f / per_page).ceil
9
- end
10
-
11
- def first_page?() current_page == 1 end
12
- def last_page?() current_page == total_pages end
13
-
14
- def page(page)
15
- current_page = page
16
- self
17
- end
18
-
19
- def per(per)
20
- per_page = per
21
- self
22
- end
23
-
24
- def paginate(options = {})
25
- page(options[:page]).per(options[:per_page])
26
- end
27
-
28
- alias :total_entries :total_count
29
- end
30
-
31
8
  if ENV['PAGINATOR']
32
9
  ApiPagination.instance_variable_set(:@paginator, ENV['PAGINATOR'].to_sym)
33
10
  else
@@ -35,6 +12,12 @@ else
35
12
  ApiPagination.instance_variable_set(:@paginator, :kaminari)
36
13
  end
37
14
 
15
+ if ApiPagination.paginator == :kaminari
16
+ Kaminari::Hooks.init
17
+ elsif ApiPagination.paginator == :will_paginate
18
+ require 'will_paginate/array'
19
+ end
20
+
38
21
  RSpec.configure do |config|
39
22
  config.include Rack::Test::Methods
40
23
  config.include ControllerExampleGroup, :type => :controller
@@ -5,7 +5,7 @@ class NumbersAPI < Grape::API
5
5
  format :json
6
6
 
7
7
  desc 'Return some paginated set of numbers'
8
- paginate :per_page => 25
8
+ paginate :per_page => 10
9
9
  params do
10
10
  requires :count, :type => Integer
11
11
  optional :with_headers, :default => false, :type => Boolean
@@ -18,6 +18,6 @@ class NumbersAPI < Grape::API
18
18
  header 'Link', %(<#{url}?#{query.to_query}>; rel="without")
19
19
  end
20
20
 
21
- paginate PaginatedSet.new(params[:page], params[:per_page], params[:count])
21
+ paginate (1..params[:count]).to_a
22
22
  end
23
23
  end
@@ -45,8 +45,6 @@ end
45
45
  class NumbersController < ActionController::Base
46
46
  include Rails.application.routes.url_helpers
47
47
 
48
- after_filter :only => [:index] { paginate(:numbers) }
49
-
50
48
  def index
51
49
  page = params.fetch(:page, 1).to_i
52
50
  total = params.fetch(:count).to_i
@@ -57,7 +55,6 @@ class NumbersController < ActionController::Base
57
55
  headers['Link'] = %(<#{numbers_url}?#{query.to_param}>; rel="without")
58
56
  end
59
57
 
60
- @numbers = PaginatedSet.new(page, 25, total)
61
- render :json => @numbers
58
+ paginate :json => (1..total).to_a, :per_page => 10
62
59
  end
63
60
  end
@@ -5,7 +5,7 @@ shared_examples 'an endpoint with existing Link headers' do
5
5
 
6
6
  it 'should contain pagination Links' do
7
7
  expect(links).to include('<http://example.org/numbers?count=30&page=2&with_headers=true>; rel="next"')
8
- expect(links).to include('<http://example.org/numbers?count=30&page=2&with_headers=true>; rel="last"')
8
+ expect(links).to include('<http://example.org/numbers?count=30&page=3&with_headers=true>; rel="last"')
9
9
  end
10
10
 
11
11
  it 'should give a Total header' do
@@ -8,7 +8,7 @@ shared_examples 'an endpoint with a first page' do
8
8
  end
9
9
 
10
10
  it 'should give a link with rel "last"' do
11
- expect(links).to include('<http://example.org/numbers?count=100&page=4>; rel="last"')
11
+ expect(links).to include('<http://example.org/numbers?count=100&page=10>; rel="last"')
12
12
  end
13
13
 
14
14
  it 'should give a link with rel "next"' do
@@ -18,4 +18,13 @@ shared_examples 'an endpoint with a first page' do
18
18
  it 'should give a Total header' do
19
19
  expect(total).to eq(100)
20
20
  end
21
+
22
+ it 'should list the first page of numbers in the response body' do
23
+ body = '[1,2,3,4,5,6,7,8,9,10]'
24
+ if defined?(response)
25
+ expect(response.body).to eq(body)
26
+ else
27
+ expect(last_response.body).to eq(body)
28
+ end
29
+ end
21
30
  end
@@ -12,10 +12,20 @@ shared_examples 'an endpoint with a last page' do
12
12
  end
13
13
 
14
14
  it 'should give a link with rel "prev"' do
15
- expect(links).to include('<http://example.org/numbers?count=100&page=3>; rel="prev"')
15
+ expect(links).to include('<http://example.org/numbers?count=100&page=9>; rel="prev"')
16
16
  end
17
17
 
18
18
  it 'should give a Total header' do
19
19
  expect(total).to eq(100)
20
20
  end
21
+
22
+ it 'should list the last page of numbers in the response body' do
23
+ body = '[91,92,93,94,95,96,97,98,99,100]'
24
+
25
+ if defined?(response)
26
+ expect(response.body).to eq(body)
27
+ else
28
+ expect(last_response.body).to eq(body)
29
+ end
30
+ end
21
31
  end
@@ -1,7 +1,7 @@
1
1
  shared_examples 'an endpoint with a middle page' do
2
2
  it 'should give all pagination links' do
3
3
  expect(links).to include('<http://example.org/numbers?count=100&page=1>; rel="first"')
4
- expect(links).to include('<http://example.org/numbers?count=100&page=4>; rel="last"')
4
+ expect(links).to include('<http://example.org/numbers?count=100&page=10>; rel="last"')
5
5
  expect(links).to include('<http://example.org/numbers?count=100&page=3>; rel="next"')
6
6
  expect(links).to include('<http://example.org/numbers?count=100&page=1>; rel="prev"')
7
7
  end
@@ -9,4 +9,14 @@ shared_examples 'an endpoint with a middle page' do
9
9
  it 'should give a Total header' do
10
10
  expect(total).to eq(100)
11
11
  end
12
+
13
+ it 'should list a middle page of numbers in the response body' do
14
+ body = '[11,12,13,14,15,16,17,18,19,20]'
15
+
16
+ if defined?(response)
17
+ expect(response.body).to eq(body)
18
+ else
19
+ expect(last_response.body).to eq(body)
20
+ end
21
+ end
12
22
  end
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: 2.1.1
4
+ version: 3.0.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: 2014-02-13 00:00:00.000000000 Z
11
+ date: 2014-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: railties
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 3.0.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 3.0.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: actionpack
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -52,7 +66,7 @@ dependencies:
52
66
  - - ">="
53
67
  - !ruby/object:Gem::Version
54
68
  version: 3.0.0
55
- description: Link header pagination for Rails APIs
69
+ description: Link header pagination for Rails and Grape APIs
56
70
  email:
57
71
  - me@davidcel.is
58
72
  executables: []
@@ -93,10 +107,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
107
  version: '0'
94
108
  requirements: []
95
109
  rubyforge_project:
96
- rubygems_version: 2.2.0
110
+ rubygems_version: 2.2.2
97
111
  signing_key:
98
112
  specification_version: 4
99
- summary: Link header pagination for Rails APIs. Don't use the request body.
113
+ summary: Link header pagination for Rails and Grape APIs. Don't use the request body.
100
114
  test_files:
101
115
  - spec/grape_spec.rb
102
116
  - spec/rails_spec.rb
@@ -107,3 +121,4 @@ test_files:
107
121
  - spec/support/shared_examples/first_page.rb
108
122
  - spec/support/shared_examples/last_page.rb
109
123
  - spec/support/shared_examples/middle_page.rb
124
+ has_rdoc: