api-pagination 4.7.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/api-pagination/configuration.rb +23 -7
- data/lib/api-pagination/hooks.rb +28 -27
- data/lib/api-pagination/railtie.rb +19 -0
- data/lib/api-pagination/version.rb +3 -3
- data/lib/api-pagination.rb +63 -14
- data/lib/grape/pagination.rb +4 -4
- data/lib/rails/pagination.rb +13 -7
- data/spec/active_record_spec.rb +50 -0
- data/spec/api-pagination_spec.rb +52 -42
- data/spec/grape_spec.rb +10 -1
- data/spec/rails_spec.rb +56 -51
- data/spec/sequel_spec.rb +1 -2
- data/spec/spec_helper.rb +9 -3
- data/spec/support/active_record/foo.rb +3 -0
- data/spec/support/active_record/schema.rb +5 -0
- data/spec/support/numbers_controller.rb +4 -2
- data/spec/support/shared_examples/first_page.rb +2 -2
- data/spec/support/shared_examples/last_page.rb +2 -2
- metadata +120 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba0df72041cd862671500fd9efe94c7fe8e35975877e0e9bbcd1c0b77860e4a4
|
4
|
+
data.tar.gz: debcf49e29dcda50d93cd31a2e9efec2332541dbe38f6bdaa488b450e5bb7d09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4661d9bfa18456e1c6fcfb837ef4c3acbc9e35dd983299201340dc077056e3f5632c39a8f718b285d66b4e3985aec23da68a56c8c278f0fc850f27626352bb0b
|
7
|
+
data.tar.gz: 688fae38d680fb9f1b133a627172d687c7fa6f56186039a88a5bfe238e396c5310359266580644d7719b981d6f3589ac884f6b6d88688c497c8516cbffd122cd
|
@@ -10,6 +10,8 @@ module ApiPagination
|
|
10
10
|
|
11
11
|
attr_accessor :base_url
|
12
12
|
|
13
|
+
attr_accessor :response_formats
|
14
|
+
|
13
15
|
def configure(&block)
|
14
16
|
yield self
|
15
17
|
end
|
@@ -20,6 +22,7 @@ module ApiPagination
|
|
20
22
|
@page_header = nil
|
21
23
|
@include_total = true
|
22
24
|
@base_url = nil
|
25
|
+
@response_formats = [:json, :xml]
|
23
26
|
end
|
24
27
|
|
25
28
|
['page', 'per_page'].each do |param_name|
|
@@ -50,11 +53,17 @@ module ApiPagination
|
|
50
53
|
end
|
51
54
|
|
52
55
|
def paginator
|
53
|
-
|
56
|
+
if instance_variable_defined? :@paginator
|
57
|
+
@paginator
|
58
|
+
else
|
59
|
+
set_paginator
|
60
|
+
end
|
54
61
|
end
|
55
62
|
|
56
63
|
def paginator=(paginator)
|
57
64
|
case paginator.to_sym
|
65
|
+
when :pagy
|
66
|
+
use_pagy
|
58
67
|
when :kaminari
|
59
68
|
use_kaminari
|
60
69
|
when :will_paginate
|
@@ -67,11 +76,12 @@ module ApiPagination
|
|
67
76
|
private
|
68
77
|
|
69
78
|
def set_paginator
|
70
|
-
|
79
|
+
conditions = [defined?(Pagy), defined?(Kaminari), defined?(WillPaginate::CollectionMethods)]
|
80
|
+
if conditions.compact.size > 1
|
71
81
|
Kernel.warn <<-WARNING
|
72
|
-
Warning: api-pagination relies on
|
73
|
-
currently active. If possible, you should remove one or the other. If
|
74
|
-
you _must_ configure api-pagination on your own. For example:
|
82
|
+
Warning: api-pagination relies on Pagy, Kaminari, or WillPaginate, but more than
|
83
|
+
one are currently active. If possible, you should remove one or the other. If
|
84
|
+
you can't, you _must_ configure api-pagination on your own. For example:
|
75
85
|
|
76
86
|
ApiPagination.configure do |config|
|
77
87
|
config.paginator = :kaminari
|
@@ -86,13 +96,19 @@ Kaminari.configure do |config|
|
|
86
96
|
end
|
87
97
|
|
88
98
|
WARNING
|
99
|
+
elsif defined?(Pagy)
|
100
|
+
use_pagy
|
89
101
|
elsif defined?(Kaminari)
|
90
|
-
|
102
|
+
use_kaminari
|
91
103
|
elsif defined?(WillPaginate::CollectionMethods)
|
92
|
-
|
104
|
+
use_will_paginate
|
93
105
|
end
|
94
106
|
end
|
95
107
|
|
108
|
+
def use_pagy
|
109
|
+
@paginator = :pagy
|
110
|
+
end
|
111
|
+
|
96
112
|
def use_kaminari
|
97
113
|
require 'kaminari/models/array_extension'
|
98
114
|
@paginator = :kaminari
|
data/lib/api-pagination/hooks.rb
CHANGED
@@ -1,42 +1,43 @@
|
|
1
|
-
begin; require 'rails'; rescue LoadError; end
|
2
|
-
begin; require 'rails-api'; rescue LoadError; end
|
3
|
-
|
4
|
-
if defined?(Rails)
|
5
|
-
module ApiPagination
|
6
|
-
module Hooks
|
7
|
-
def self.rails_parent_controller
|
8
|
-
if Gem::Version.new(Rails.version) >= Gem::Version.new('5') || defined?(ActionController::API)
|
9
|
-
ActionController::API
|
10
|
-
else
|
11
|
-
ActionController::Base
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
require 'rails/pagination'
|
18
|
-
|
19
|
-
ActiveSupport.on_load(:action_controller) do
|
20
|
-
ApiPagination::Hooks.rails_parent_controller.send(:include, Rails::Pagination)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
1
|
begin; require 'grape'; rescue LoadError; end
|
25
2
|
if defined?(Grape::API)
|
26
3
|
require 'grape/pagination'
|
27
|
-
|
4
|
+
|
5
|
+
klass = if Grape::VERSION >= '1.2.0' || defined?(Grape::API::Instance)
|
6
|
+
Grape::API::Instance
|
7
|
+
else
|
8
|
+
Grape::API
|
9
|
+
end
|
10
|
+
|
11
|
+
klass.send(:include, Grape::Pagination)
|
28
12
|
end
|
29
13
|
|
14
|
+
begin; require 'pagy'; rescue LoadError; end
|
30
15
|
begin; require 'kaminari'; rescue LoadError; end
|
31
16
|
begin; require 'will_paginate'; rescue LoadError; end
|
32
17
|
|
33
|
-
unless defined?(Kaminari) || defined?(WillPaginate::CollectionMethods)
|
18
|
+
unless defined?(Pagy) || defined?(Kaminari) || defined?(WillPaginate::CollectionMethods)
|
34
19
|
Kernel.warn <<-WARNING.gsub(/^\s{4}/, '')
|
35
|
-
Warning: api-pagination relies on either Kaminari or WillPaginate.
|
36
|
-
install
|
20
|
+
Warning: api-pagination relies on either Pagy, Kaminari, or WillPaginate.
|
21
|
+
Please install a paginator by adding one of the following to your Gemfile:
|
37
22
|
|
23
|
+
gem 'pagy'
|
38
24
|
gem 'kaminari'
|
39
25
|
gem 'will_paginate'
|
40
26
|
WARNING
|
41
27
|
end
|
42
28
|
|
29
|
+
if defined?(Rails)
|
30
|
+
module ApiPagination
|
31
|
+
module Hooks
|
32
|
+
def self.rails_parent_controller
|
33
|
+
if Rails::VERSION::MAJOR >= 5 || defined?(ActionController::API)
|
34
|
+
ActionController::API
|
35
|
+
else
|
36
|
+
ActionController::Base
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
require 'api-pagination/railtie'
|
43
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rails/railtie'
|
2
|
+
|
3
|
+
module ApiPagination
|
4
|
+
class Railtie < ::Rails::Railtie
|
5
|
+
initializer :api_pagination do
|
6
|
+
ActiveSupport.on_load(:action_controller) do
|
7
|
+
require 'rails/pagination'
|
8
|
+
|
9
|
+
klass = if Rails::VERSION::MAJOR >= 5 || defined?(ActionController::API)
|
10
|
+
ActionController::API
|
11
|
+
else
|
12
|
+
ActionController::Base
|
13
|
+
end
|
14
|
+
|
15
|
+
klass.send(:include, Rails::Pagination)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/api-pagination.rb
CHANGED
@@ -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 ApiPagination.config.paginator == :pagy && collection.is_a?(Pagy)
|
25
|
+
|
22
26
|
{}.tap do |pages|
|
23
27
|
unless collection.first_page?
|
24
28
|
pages[:first] = 1
|
@@ -26,7 +30,7 @@ module ApiPagination
|
|
26
30
|
end
|
27
31
|
|
28
32
|
unless collection.last_page? || (ApiPagination.config.paginator == :kaminari && collection.out_of_range?)
|
29
|
-
pages[:last] = collection.total_pages
|
33
|
+
pages[:last] = collection.total_pages if ApiPagination.config.include_total
|
30
34
|
pages[:next] = collection.current_page + 1
|
31
35
|
end
|
32
36
|
end
|
@@ -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,47 @@ module ApiPagination
|
|
41
46
|
|
42
47
|
private
|
43
48
|
|
49
|
+
def paginate_with_pagy(collection, options)
|
50
|
+
if Pagy::DEFAULT[:max_per_page] && options[:per_page] > Pagy::DEFAULT[:max_per_page]
|
51
|
+
options[:per_page] = Pagy::DEFAULT[:max_per_page]
|
52
|
+
elsif options[:per_page] <= 0
|
53
|
+
options[:per_page] = Pagy::DEFAULT[: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
|
+
if options[:count]
|
68
|
+
count = options[:count]
|
69
|
+
else
|
70
|
+
count = collection.is_a?(Array) ? collection.count : collection.count(:all)
|
71
|
+
end
|
72
|
+
|
73
|
+
Pagy.new(count: count, items: options[:per_page], page: options[:page])
|
74
|
+
end
|
75
|
+
|
76
|
+
def pagy_pages_from(pagy)
|
77
|
+
{}.tap do |pages|
|
78
|
+
unless pagy.page == 1
|
79
|
+
pages[:first] = 1
|
80
|
+
pages[:prev] = pagy.prev
|
81
|
+
end
|
82
|
+
|
83
|
+
unless pagy.page == pagy.pages
|
84
|
+
pages[:last] = pagy.pages if ApiPagination.config.include_total
|
85
|
+
pages[:next] = pagy.next
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
44
90
|
def paginate_with_kaminari(collection, options, paginate_array_options = {})
|
45
91
|
if Kaminari.config.max_per_page && options[:per_page] > Kaminari.config.max_per_page
|
46
92
|
options[:per_page] = Kaminari.config.max_per_page
|
@@ -48,8 +94,10 @@ module ApiPagination
|
|
48
94
|
options[:per_page] = get_default_per_page_for_kaminari(collection)
|
49
95
|
end
|
50
96
|
|
51
|
-
collection = Kaminari.paginate_array(collection, paginate_array_options) if collection.is_a?(Array)
|
52
|
-
collection.page(options[:page]).per(options[:per_page])
|
97
|
+
collection = Kaminari.paginate_array(collection, **paginate_array_options) if collection.is_a?(Array)
|
98
|
+
collection = collection.page(options[:page]).per(options[:per_page])
|
99
|
+
collection.without_count if !collection.is_a?(Array) && !ApiPagination.config.include_total
|
100
|
+
[collection, nil]
|
53
101
|
end
|
54
102
|
|
55
103
|
def paginate_with_will_paginate(collection, options)
|
@@ -57,35 +105,36 @@ module ApiPagination
|
|
57
105
|
options[:per_page] = default_per_page_for_will_paginate(collection)
|
58
106
|
end
|
59
107
|
|
60
|
-
if defined?(Sequel::Dataset) && collection.kind_of?(Sequel::Dataset)
|
108
|
+
collection = if defined?(Sequel::Dataset) && collection.kind_of?(Sequel::Dataset)
|
61
109
|
collection.paginate(options[:page], options[:per_page])
|
62
110
|
else
|
63
111
|
supported_options = [:page, :per_page, :total_entries]
|
64
112
|
options = options.dup.keep_if { |k,v| supported_options.include?(k.to_sym) }
|
65
113
|
collection.paginate(options)
|
66
114
|
end
|
115
|
+
|
116
|
+
[collection, nil]
|
67
117
|
end
|
68
118
|
|
69
119
|
def get_default_per_page_for_kaminari(collection)
|
70
120
|
default = Kaminari.config.default_per_page
|
71
|
-
|
72
|
-
rescue
|
73
|
-
default
|
121
|
+
extract_per_page_from_model(collection, :default_per_page) || default
|
74
122
|
end
|
75
123
|
|
76
124
|
def default_per_page_for_will_paginate(collection)
|
77
125
|
default = WillPaginate.per_page
|
78
|
-
|
79
|
-
rescue
|
80
|
-
default
|
126
|
+
extract_per_page_from_model(collection, :per_page) || default
|
81
127
|
end
|
82
128
|
|
83
|
-
def
|
84
|
-
if collection.respond_to?(:
|
85
|
-
collection.
|
129
|
+
def extract_per_page_from_model(collection, accessor)
|
130
|
+
klass = if collection.respond_to?(:klass)
|
131
|
+
collection.klass
|
86
132
|
else
|
87
133
|
collection.first.class
|
88
134
|
end
|
135
|
+
|
136
|
+
return unless klass.respond_to?(accessor)
|
137
|
+
klass.send(accessor)
|
89
138
|
end
|
90
139
|
end
|
91
140
|
end
|
data/lib/grape/pagination.rb
CHANGED
@@ -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
|
|
@@ -46,7 +46,7 @@ module Grape
|
|
46
46
|
params do
|
47
47
|
optional :page, :type => Integer, :default => 1,
|
48
48
|
:desc => 'Page of results to fetch.'
|
49
|
-
optional :per_page, :type => Integer,
|
49
|
+
optional :per_page, :type => Integer, :default => options[:per_page],
|
50
50
|
:desc => 'Number of results to return per page.',
|
51
51
|
:values => per_page_values
|
52
52
|
end
|
data/lib/rails/pagination.rb
CHANGED
@@ -8,11 +8,12 @@ module Rails
|
|
8
8
|
|
9
9
|
return _paginate_collection(collection, options) if collection
|
10
10
|
|
11
|
-
|
11
|
+
response_format = _discover_format(options)
|
12
|
+
|
13
|
+
collection = options[response_format]
|
12
14
|
collection = _paginate_collection(collection, options)
|
13
15
|
|
14
|
-
options[
|
15
|
-
options[:xml] = collection if options[:xml]
|
16
|
+
options[response_format] = collection if options[response_format]
|
16
17
|
|
17
18
|
render options
|
18
19
|
end
|
@@ -23,15 +24,21 @@ module Rails
|
|
23
24
|
|
24
25
|
private
|
25
26
|
|
27
|
+
def _discover_format(options)
|
28
|
+
for response_format in ApiPagination.config.response_formats
|
29
|
+
return response_format if options.key?(response_format)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
26
33
|
def _paginate_collection(collection, options={})
|
27
34
|
options[:page] = ApiPagination.config.page_param(params)
|
28
35
|
options[:per_page] ||= ApiPagination.config.per_page_param(params)
|
29
36
|
|
30
|
-
collection = ApiPagination.paginate(collection, options)
|
37
|
+
collection, pagy = ApiPagination.paginate(collection, options)
|
31
38
|
|
32
39
|
links = (headers['Link'] || '').split(',').map(&:strip)
|
33
40
|
url = base_url + request.path_info
|
34
|
-
pages = ApiPagination.pages_from(collection)
|
41
|
+
pages = ApiPagination.pages_from(pagy || collection, options)
|
35
42
|
|
36
43
|
pages.each do |k, v|
|
37
44
|
new_params = request.query_parameters.merge(:page => v)
|
@@ -46,7 +53,7 @@ module Rails
|
|
46
53
|
headers['Link'] = links.join(', ') unless links.empty?
|
47
54
|
headers[per_page_header] = options[:per_page].to_s
|
48
55
|
headers[page_header] = options[:page].to_s unless page_header.nil?
|
49
|
-
headers[total_header] = total_count(collection, options).to_s if include_total
|
56
|
+
headers[total_header] = total_count(pagy || collection, options).to_s if include_total
|
50
57
|
|
51
58
|
return collection
|
52
59
|
end
|
@@ -62,6 +69,5 @@ module Rails
|
|
62
69
|
def base_url
|
63
70
|
ApiPagination.config.base_url || request.base_url
|
64
71
|
end
|
65
|
-
|
66
72
|
end
|
67
73
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/active_record/foo'
|
3
|
+
require 'nulldb_rspec'
|
4
|
+
|
5
|
+
ActiveRecord::Base.establish_connection(
|
6
|
+
adapter: :nulldb,
|
7
|
+
schema: 'spec/support/active_record/schema.rb'
|
8
|
+
)
|
9
|
+
|
10
|
+
NullDB.configure { |ndb| def ndb.project_root; Dir.pwd; end; }
|
11
|
+
|
12
|
+
shared_examples 'produces_correct_sql' do
|
13
|
+
it 'produces correct sql for first page' do
|
14
|
+
allow(collection).to receive(:count).and_return(collection_size)
|
15
|
+
paginated_sql, _ = ApiPagination.paginate(collection, per_page: per_page)
|
16
|
+
expect(paginated_sql.to_sql).to eql(Foo.limit(per_page).offset(0).to_sql)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'ActiveRecord Support' do
|
21
|
+
let(:collection) { Foo.all }
|
22
|
+
let(:collection_size) { 50 }
|
23
|
+
let(:per_page) { 5 }
|
24
|
+
|
25
|
+
if ApiPagination.config.paginator == :will_paginate
|
26
|
+
require 'will_paginate/active_record'
|
27
|
+
end
|
28
|
+
|
29
|
+
context "pagination with #{ApiPagination.config.paginator}" do
|
30
|
+
include_examples 'produces_correct_sql'
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
if ApiPagination.config.paginator != :pagy
|
35
|
+
context 'reflections' do
|
36
|
+
it 'invokes the correct methods to determine type' do
|
37
|
+
expect(collection).to receive(:klass).at_least(:once)
|
38
|
+
.and_call_original
|
39
|
+
ApiPagination.paginate(collection)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'does not fail if table name is not snake cased class name' do
|
43
|
+
allow(collection).to receive(:table_name).and_return(SecureRandom.uuid)
|
44
|
+
expect { ApiPagination.paginate(collection) }.to_not raise_error
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
data/spec/api-pagination_spec.rb
CHANGED
@@ -2,63 +2,73 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ApiPagination do
|
4
4
|
let(:collection) {(1..100).to_a}
|
5
|
+
let(:active_record_relation) {double("ActiveRecord_Relation").as_null_object}
|
5
6
|
let(:paginate_array_options) {{ total_count: 1000 }}
|
6
7
|
|
7
8
|
describe "#paginate" do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
if ENV['PAGINATOR'].to_sym == :kaminari
|
10
|
+
context 'Using kaminari' do
|
11
|
+
describe '.paginate' do
|
12
|
+
it 'should accept paginate_array_options option' do
|
13
|
+
expect(Kaminari).to receive(:paginate_array)
|
14
|
+
.with(collection, **paginate_array_options)
|
15
|
+
.and_call_original
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
ApiPagination.paginate(
|
18
|
+
collection,
|
19
|
+
{
|
20
|
+
per_page: 30,
|
21
|
+
paginate_array_options: paginate_array_options
|
22
|
+
}
|
23
|
+
)
|
24
|
+
end
|
16
25
|
|
17
|
-
|
18
|
-
|
19
|
-
.with(collection, paginate_array_options)
|
20
|
-
.and_call_original
|
26
|
+
context 'configured not to include the total' do
|
27
|
+
before { ApiPagination.config.include_total = false }
|
21
28
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
context 'and paginating an array' do
|
30
|
+
it 'should not call without_count on the collection' do
|
31
|
+
expect(collection).to_not receive :without_count
|
32
|
+
ApiPagination.paginate(collection)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
context 'and paginating an active record relation' do
|
36
|
+
it 'should call without_count on the relation' do
|
37
|
+
expect(active_record_relation).to receive :without_count
|
38
|
+
ApiPagination.paginate(active_record_relation)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
after { ApiPagination.config.include_total = true }
|
43
|
+
end
|
44
|
+
end
|
30
45
|
|
31
|
-
|
32
|
-
|
46
|
+
describe '.pages_from' do
|
47
|
+
subject { described_class.pages_from(collection) }
|
33
48
|
|
34
|
-
|
35
|
-
|
49
|
+
context 'on empty collection' do
|
50
|
+
let(:collection) { ApiPagination.paginate([], page: 1).first }
|
36
51
|
|
37
|
-
|
52
|
+
it { is_expected.to be_empty }
|
53
|
+
end
|
38
54
|
end
|
39
55
|
end
|
40
56
|
end
|
41
57
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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)
|
58
|
+
if ENV['PAGINATOR'].to_sym == :will_paginate
|
59
|
+
context 'Using will_paginate' do
|
60
|
+
context 'passing in total_entries in options' do
|
61
|
+
it 'should set total_entries using the passed in value' do
|
62
|
+
paginated_collection = ApiPagination.paginate(collection, total_entries: 3000).first
|
63
|
+
expect(paginated_collection.total_entries).to eq(3000)
|
64
|
+
end
|
55
65
|
end
|
56
|
-
end
|
57
66
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
67
|
+
context 'passing in collection only' do
|
68
|
+
it 'should set total_entries using the size of the collection ' do
|
69
|
+
paginated_collection = ApiPagination.paginate(collection).first
|
70
|
+
expect(paginated_collection.total_entries).to eq(100)
|
71
|
+
end
|
62
72
|
end
|
63
73
|
end
|
64
74
|
end
|
data/spec/grape_spec.rb
CHANGED
@@ -5,8 +5,11 @@ require 'support/shared_examples/middle_page'
|
|
5
5
|
require 'support/shared_examples/last_page'
|
6
6
|
|
7
7
|
describe NumbersAPI do
|
8
|
+
it { is_expected.to be_kind_of(Grape::Pagination) }
|
9
|
+
|
8
10
|
describe 'GET #index' do
|
9
|
-
let(:
|
11
|
+
let(:link) { last_response.headers['Link'] }
|
12
|
+
let(:links) { link.split(', ') }
|
10
13
|
let(:total) { last_response.headers['Total'].to_i }
|
11
14
|
let(:per_page) { last_response.headers['Per-Page'].to_i }
|
12
15
|
|
@@ -139,6 +142,12 @@ describe NumbersAPI do
|
|
139
142
|
expect(last_response.header['Total']).to be_nil
|
140
143
|
end
|
141
144
|
|
145
|
+
it 'should not include a link with rel "last"' do
|
146
|
+
get '/numbers', count: 100
|
147
|
+
|
148
|
+
expect(link).to_not include('rel="last"')
|
149
|
+
end
|
150
|
+
|
142
151
|
after { ApiPagination.config.include_total = true }
|
143
152
|
end
|
144
153
|
|
data/spec/rails_spec.rb
CHANGED
@@ -8,7 +8,8 @@ describe NumbersController, :type => :controller do
|
|
8
8
|
before { request.host = 'example.org' }
|
9
9
|
|
10
10
|
describe 'GET #index' do
|
11
|
-
let(:
|
11
|
+
let(:link) { response.headers['Link'] }
|
12
|
+
let(:links) { link.split(', ') }
|
12
13
|
let(:total) { response.headers['Total'].to_i }
|
13
14
|
let(:per_page) { response.headers['Per-Page'].to_i }
|
14
15
|
|
@@ -134,6 +135,12 @@ describe NumbersController, :type => :controller do
|
|
134
135
|
expect(response.header['Total']).to be_nil
|
135
136
|
end
|
136
137
|
|
138
|
+
it 'should not include a link with rel "last"' do
|
139
|
+
get :index, params: { count: 100 }
|
140
|
+
|
141
|
+
expect(link).to_not include('rel="last"')
|
142
|
+
end
|
143
|
+
|
137
144
|
after { ApiPagination.config.include_total = true }
|
138
145
|
end
|
139
146
|
|
@@ -214,8 +221,11 @@ describe NumbersController, :type => :controller do
|
|
214
221
|
end
|
215
222
|
end
|
216
223
|
|
217
|
-
|
218
|
-
|
224
|
+
if ApiPagination.config.paginator.to_sym == :kaminari
|
225
|
+
context 'paginate array options' do
|
226
|
+
let(:paginate_array_total_count) { 300 }
|
227
|
+
let(:total_header) { 300 }
|
228
|
+
let(:count) { 50 }
|
219
229
|
let(:params) do
|
220
230
|
{
|
221
231
|
paginate_array_total_count: paginate_array_total_count,
|
@@ -223,80 +233,75 @@ describe NumbersController, :type => :controller do
|
|
223
233
|
}
|
224
234
|
end
|
225
235
|
|
226
|
-
|
236
|
+
it 'has a properly set Total header' do
|
227
237
|
get :index_with_paginate_array_options, params: params
|
228
238
|
|
229
239
|
expect(response.header['Total']).to be_kind_of(String)
|
230
240
|
expect(response.header['Total'].to_i).to eq total_header
|
231
241
|
end
|
232
242
|
end
|
243
|
+
end
|
233
244
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
end
|
245
|
+
if [:will_paginate, :kaminari].include?(ApiPagination.config.paginator.to_sym)
|
246
|
+
context 'default per page in model' do
|
247
|
+
before do
|
248
|
+
class Fixnum
|
249
|
+
@default_per_page = 6
|
250
|
+
@per_page = 6
|
241
251
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
252
|
+
class << self
|
253
|
+
attr_accessor :default_per_page, :per_page
|
254
|
+
end
|
255
|
+
end
|
246
256
|
end
|
247
|
-
end
|
248
257
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
ApiPagination.config.paginator = paginator
|
258
|
+
after do
|
259
|
+
class Fixnum
|
260
|
+
@default_per_page = 25
|
261
|
+
@per_page = 25
|
262
|
+
end
|
255
263
|
end
|
256
264
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
265
|
+
after :all do
|
266
|
+
class Fixnum
|
267
|
+
class << self
|
268
|
+
undef_method :default_per_page, :per_page
|
269
|
+
end
|
270
|
+
end
|
261
271
|
end
|
262
|
-
end
|
263
|
-
end
|
264
272
|
|
265
|
-
|
266
|
-
|
267
|
-
class Fixnum
|
268
|
-
@default_per_page = 6
|
269
|
-
@per_page = 6
|
273
|
+
it 'should use default per page from model' do
|
274
|
+
get :index_with_no_per_page, params: {count: 100}
|
270
275
|
|
271
|
-
|
272
|
-
attr_accessor :default_per_page, :per_page
|
273
|
-
end
|
276
|
+
expect(response.header['Per-Page']).to eq('6')
|
274
277
|
end
|
275
|
-
end
|
276
278
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
end
|
279
|
+
it 'should not fail if the model yields nil for per page' do
|
280
|
+
class Fixnum
|
281
|
+
@default_per_page = nil
|
282
|
+
@per_page = nil
|
283
|
+
end
|
283
284
|
|
284
|
-
|
285
|
-
get :index_with_no_per_page, params: {count: 100}
|
285
|
+
get :index_with_no_per_page, params: {count: 100}
|
286
286
|
|
287
|
-
|
287
|
+
expect(response.header['Per-Page']).to eq(
|
288
|
+
case ApiPagination.config.paginator
|
289
|
+
when :pagy then Pagy::DEFAULT[:items].to_s
|
290
|
+
when :kaminari then Kaminari.config.default_per_page.to_s
|
291
|
+
when :will_paginate then WillPaginate.per_page.to_s
|
292
|
+
end
|
293
|
+
)
|
294
|
+
end
|
288
295
|
end
|
296
|
+
end
|
289
297
|
|
298
|
+
context 'default per page in objects without paginator defaults' do
|
290
299
|
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
|
294
|
-
end
|
295
|
-
|
296
300
|
get :index_with_no_per_page, params: {count: 100}
|
297
301
|
|
298
302
|
expect(response.header['Per-Page']).to eq(
|
299
303
|
case ApiPagination.config.paginator
|
304
|
+
when :pagy then Pagy::DEFAULT[:items].to_s
|
300
305
|
when :kaminari then Kaminari.config.default_per_page.to_s
|
301
306
|
when :will_paginate then WillPaginate.per_page.to_s
|
302
307
|
end
|
data/spec/sequel_spec.rb
CHANGED
@@ -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
|
-
|
data/spec/spec_helper.rb
CHANGED
@@ -3,14 +3,20 @@ require 'support/numbers_api'
|
|
3
3
|
require 'api-pagination'
|
4
4
|
|
5
5
|
if ENV['PAGINATOR'].nil?
|
6
|
-
warn
|
7
|
-
|
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
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'action_controller'
|
1
|
+
require 'action_controller/railtie'
|
2
2
|
require 'api-pagination/hooks'
|
3
3
|
require 'ostruct'
|
4
4
|
|
@@ -59,7 +59,7 @@ class NumbersSerializer
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
class NumbersController <
|
62
|
+
class NumbersController < ActionController::API
|
63
63
|
include Rails.application.routes.url_helpers
|
64
64
|
|
65
65
|
def index
|
@@ -99,3 +99,5 @@ class NumbersController < ApiPagination::Hooks.rails_parent_controller
|
|
99
99
|
render json: NumbersSerializer.new(numbers)
|
100
100
|
end
|
101
101
|
end
|
102
|
+
|
103
|
+
ApiPagination::Railtie.initializers.each(&:run)
|
@@ -1,10 +1,10 @@
|
|
1
1
|
shared_examples 'an endpoint with a first page' do
|
2
2
|
it 'should not give a link with rel "first"' do
|
3
|
-
expect(
|
3
|
+
expect(link).not_to include('rel="first"')
|
4
4
|
end
|
5
5
|
|
6
6
|
it 'should not give a link with rel "prev"' do
|
7
|
-
expect(
|
7
|
+
expect(link).not_to include('rel="prev"')
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'should give a link with rel "last"' do
|
@@ -1,10 +1,10 @@
|
|
1
1
|
shared_examples 'an endpoint with a last page' do
|
2
2
|
it 'should not give a link with rel "last"' do
|
3
|
-
expect(
|
3
|
+
expect(link).not_to include('rel="last"')
|
4
4
|
end
|
5
5
|
|
6
6
|
it 'should not give a link with rel "next"' do
|
7
|
-
expect(
|
7
|
+
expect(link).not_to include('rel="next"')
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'should give a link with rel "first"' do
|
metadata
CHANGED
@@ -1,85 +1,171 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api-pagination
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Celis
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: kaminari
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1.2'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.2.1
|
20
23
|
type: :development
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - "~>"
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
29
|
+
version: '1.2'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.2.1
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
34
|
+
name: pagy
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '5.1'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 5.1.2
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '5.1'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 5.1.2
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: will_paginate
|
29
55
|
requirement: !ruby/object:Gem::Requirement
|
30
56
|
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '3.3'
|
31
60
|
- - ">="
|
32
61
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
62
|
+
version: 3.3.1
|
34
63
|
type: :development
|
35
64
|
prerelease: false
|
36
65
|
version_requirements: !ruby/object:Gem::Requirement
|
37
66
|
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.3'
|
38
70
|
- - ">="
|
39
71
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
72
|
+
version: 3.3.1
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: rspec
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '3.10'
|
80
|
+
type: :development
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '3.10'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: grape
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.6'
|
94
|
+
type: :development
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - "~>"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '1.6'
|
41
101
|
- !ruby/object:Gem::Dependency
|
42
102
|
name: railties
|
43
103
|
requirement: !ruby/object:Gem::Requirement
|
44
104
|
requirements:
|
105
|
+
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '6.1'
|
45
108
|
- - ">="
|
46
109
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
110
|
+
version: 6.1.4.1
|
48
111
|
type: :development
|
49
112
|
prerelease: false
|
50
113
|
version_requirements: !ruby/object:Gem::Requirement
|
51
114
|
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '6.1'
|
52
118
|
- - ">="
|
53
119
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
120
|
+
version: 6.1.4.1
|
55
121
|
- !ruby/object:Gem::Dependency
|
56
122
|
name: actionpack
|
57
123
|
requirement: !ruby/object:Gem::Requirement
|
58
124
|
requirements:
|
125
|
+
- - "~>"
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '6.1'
|
59
128
|
- - ">="
|
60
129
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
130
|
+
version: 6.1.4.1
|
62
131
|
type: :development
|
63
132
|
prerelease: false
|
64
133
|
version_requirements: !ruby/object:Gem::Requirement
|
65
134
|
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '6.1'
|
66
138
|
- - ">="
|
67
139
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
140
|
+
version: 6.1.4.1
|
69
141
|
- !ruby/object:Gem::Dependency
|
70
142
|
name: sequel
|
71
143
|
requirement: !ruby/object:Gem::Requirement
|
72
144
|
requirements:
|
73
|
-
- - "
|
145
|
+
- - "~>"
|
74
146
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
147
|
+
version: '5.49'
|
76
148
|
type: :development
|
77
149
|
prerelease: false
|
78
150
|
version_requirements: !ruby/object:Gem::Requirement
|
79
151
|
requirements:
|
80
|
-
- - "
|
152
|
+
- - "~>"
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '5.49'
|
155
|
+
- !ruby/object:Gem::Dependency
|
156
|
+
name: activerecord-nulldb-adapter
|
157
|
+
requirement: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - "~>"
|
81
160
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
161
|
+
version: 0.7.0
|
162
|
+
type: :development
|
163
|
+
prerelease: false
|
164
|
+
version_requirements: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - "~>"
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: 0.7.0
|
83
169
|
description: Link header pagination for Rails and Grape APIs
|
84
170
|
email:
|
85
171
|
- me@davidcel.is
|
@@ -90,14 +176,18 @@ files:
|
|
90
176
|
- lib/api-pagination.rb
|
91
177
|
- lib/api-pagination/configuration.rb
|
92
178
|
- lib/api-pagination/hooks.rb
|
179
|
+
- lib/api-pagination/railtie.rb
|
93
180
|
- lib/api-pagination/version.rb
|
94
181
|
- lib/grape/pagination.rb
|
95
182
|
- lib/rails/pagination.rb
|
183
|
+
- spec/active_record_spec.rb
|
96
184
|
- spec/api-pagination_spec.rb
|
97
185
|
- spec/grape_spec.rb
|
98
186
|
- spec/rails_spec.rb
|
99
187
|
- spec/sequel_spec.rb
|
100
188
|
- spec/spec_helper.rb
|
189
|
+
- spec/support/active_record/foo.rb
|
190
|
+
- spec/support/active_record/schema.rb
|
101
191
|
- spec/support/numbers_api.rb
|
102
192
|
- spec/support/numbers_controller.rb
|
103
193
|
- spec/support/shared_examples/existing_headers.rb
|
@@ -108,35 +198,37 @@ homepage: https://github.com/davidcelis/api-pagination
|
|
108
198
|
licenses:
|
109
199
|
- MIT
|
110
200
|
metadata: {}
|
111
|
-
post_install_message:
|
201
|
+
post_install_message:
|
112
202
|
rdoc_options: []
|
113
203
|
require_paths:
|
114
204
|
- lib
|
115
205
|
required_ruby_version: !ruby/object:Gem::Requirement
|
116
206
|
requirements:
|
117
|
-
- - "
|
207
|
+
- - ">"
|
118
208
|
- !ruby/object:Gem::Version
|
119
|
-
version: '
|
209
|
+
version: '2.7'
|
120
210
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
211
|
requirements:
|
122
212
|
- - ">="
|
123
213
|
- !ruby/object:Gem::Version
|
124
214
|
version: '0'
|
125
215
|
requirements: []
|
126
|
-
|
127
|
-
|
128
|
-
signing_key:
|
216
|
+
rubygems_version: 3.2.22
|
217
|
+
signing_key:
|
129
218
|
specification_version: 4
|
130
219
|
summary: Link header pagination for Rails and Grape APIs. Don't use the request body.
|
131
220
|
test_files:
|
132
|
-
- spec/
|
221
|
+
- spec/active_record_spec.rb
|
133
222
|
- spec/api-pagination_spec.rb
|
223
|
+
- spec/grape_spec.rb
|
224
|
+
- spec/rails_spec.rb
|
134
225
|
- spec/sequel_spec.rb
|
226
|
+
- spec/spec_helper.rb
|
227
|
+
- spec/support/active_record/foo.rb
|
228
|
+
- spec/support/active_record/schema.rb
|
135
229
|
- spec/support/numbers_api.rb
|
136
230
|
- spec/support/numbers_controller.rb
|
231
|
+
- spec/support/shared_examples/existing_headers.rb
|
137
232
|
- spec/support/shared_examples/first_page.rb
|
138
|
-
- spec/support/shared_examples/middle_page.rb
|
139
233
|
- spec/support/shared_examples/last_page.rb
|
140
|
-
- spec/support/shared_examples/
|
141
|
-
- spec/grape_spec.rb
|
142
|
-
- spec/rails_spec.rb
|
234
|
+
- spec/support/shared_examples/middle_page.rb
|