paginate-responder 2.1.0 → 2.2.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +12 -0
  3. data/.github/workflows/maintenance-cache-wipe.yml +13 -0
  4. data/.github/workflows/maintenance-workflow-cleanup.yml +17 -0
  5. data/.github/workflows/release.yml +38 -0
  6. data/.github/workflows/test.yml +70 -0
  7. data/.markdownlint.yml +12 -0
  8. data/.rubocop.yml +12 -0
  9. data/Appraisals +16 -21
  10. data/CHANGELOG.md +74 -26
  11. data/Gemfile +19 -2
  12. data/README.md +20 -38
  13. data/Rakefile +2 -0
  14. data/gemfiles/rails_6.1.gemfile +21 -0
  15. data/gemfiles/rails_7.0.gemfile +21 -0
  16. data/gemfiles/rails_7.1.gemfile +21 -0
  17. data/gemfiles/rails_7.2.gemfile +21 -0
  18. data/gemfiles/rails_8.0.gemfile +21 -0
  19. data/lib/paginate-responder/base.rb +12 -6
  20. data/lib/paginate-responder/kaminari_adapter.rb +7 -6
  21. data/lib/paginate-responder/pagy_adapter.rb +6 -5
  22. data/lib/paginate-responder/version.rb +4 -2
  23. data/lib/paginate-responder/will_paginate_adapter.rb +5 -5
  24. data/lib/paginate-responder.rb +2 -0
  25. data/lib/responders/paginate_responder.rb +4 -2
  26. data/paginate-responder.gemspec +18 -25
  27. data/renovate.json5 +4 -0
  28. data/spec/{paginate_responder_spec.rb → responders/paginate_responder_spec.rb} +41 -46
  29. data/spec/spec_helper.rb +8 -8
  30. data/spec/support/{10-application.rb → application.rb} +22 -33
  31. data/spec/support/{05-setup-and-teardown-adapter.rb → setup_and_teardown_adapter.rb} +4 -2
  32. metadata +25 -207
  33. data/.travis.yml +0 -58
  34. data/gemfiles/rails_4_2.gemfile +0 -8
  35. data/gemfiles/rails_5_0.gemfile +0 -8
  36. data/gemfiles/rails_5_1.gemfile +0 -8
  37. data/gemfiles/rails_5_2.gemfile +0 -8
  38. data/gemfiles/rails_head.gemfile +0 -8
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PaginateResponder
2
4
  #
3
5
  # Pagination adapter for kaminari.
@@ -17,7 +19,8 @@ module PaginateResponder
17
19
 
18
20
  def total_pages
19
21
  return resource.total_pages if resource.respond_to? :total_pages
20
- return resource.num_pages if resource.respond_to? :num_pages
22
+
23
+ resource.num_pages if resource.respond_to? :num_pages
21
24
  end
22
25
 
23
26
  def total_count
@@ -25,13 +28,11 @@ module PaginateResponder
25
28
  end
26
29
 
27
30
  class << self
28
- def suitable?(resource, responder)
29
- resource.respond_to?(:page) and not resource.respond_to?(:paginate)
31
+ def suitable?(resource, _responder)
32
+ resource.respond_to?(:page) && !resource.respond_to?(:paginate)
30
33
  end
31
34
  end
32
35
  end
33
36
 
34
- if defined?(:Kaminari)
35
- ::Responders::PaginateResponder.register KaminariAdapter
36
- end
37
+ ::Responders::PaginateResponder.register(KaminariAdapter)
37
38
  end
@@ -1,10 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PaginateResponder
2
4
  #
3
5
  # Pagination adapter for pagy.
4
6
  #
5
7
  class PagyAdapter < Base
6
8
  def paginate
7
- self.pagy, self.pagy_resource = controller.send(self.class.pagy_method(resource), resource, page: page, items: per_page)
9
+ self.pagy, self.pagy_resource = controller.send(self.class.pagy_method(resource), resource, page: page,
10
+ items: per_page,)
8
11
  pagy_resource
9
12
  end
10
13
 
@@ -36,7 +39,7 @@ module PaginateResponder
36
39
  end
37
40
 
38
41
  def pagy_method(resource)
39
- %i[limit offset].all? { |model_method| resource.respond_to?(model_method) } ? :pagy : :pagy_array
42
+ %i[limit offset].all? {|model_method| resource.respond_to?(model_method) } ? :pagy : :pagy_array
40
43
  end
41
44
  end
42
45
 
@@ -45,7 +48,5 @@ module PaginateResponder
45
48
  attr_accessor :pagy, :pagy_resource
46
49
  end
47
50
 
48
- if defined?(:Pagy)
49
- ::Responders::PaginateResponder.register PagyAdapter
50
- end
51
+ ::Responders::PaginateResponder.register(PagyAdapter)
51
52
  end
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PaginateResponder
2
4
  module VERSION
3
5
  MAJOR = 2
4
- MINOR = 1
6
+ MINOR = 2
5
7
  PATCH = 0
6
8
  STAGE = nil
7
9
 
8
10
  def self.to_s
9
- [MAJOR, MINOR, PATCH, STAGE].reject(&:nil?).join '.'
11
+ [MAJOR, MINOR, PATCH, STAGE].compact.join '.'
10
12
  end
11
13
  end
12
14
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module PaginateResponder
2
4
  #
3
5
  # Pagination adapter for will_paginate.
@@ -24,13 +26,11 @@ module PaginateResponder
24
26
  end
25
27
 
26
28
  class << self
27
- def suitable?(resource, responder)
28
- resource.respond_to? :paginate
29
+ def suitable?(resource, _responder)
30
+ resource.respond_to?(:paginate)
29
31
  end
30
32
  end
31
33
  end
32
34
 
33
- if defined?(:WillPaginate)
34
- ::Responders::PaginateResponder.register WillPaginateAdapter
35
- end
35
+ ::Responders::PaginateResponder.register(WillPaginateAdapter)
36
36
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rack-link_headers'
2
4
 
3
5
  module Responders
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Responders
2
4
  module PaginateResponder
3
5
  def respond
@@ -19,7 +21,7 @@ module Responders
19
21
  end
20
22
 
21
23
  def adapters
22
- @adpaters ||= ::Set.new
24
+ @adapters ||= ::Set.new
23
25
  end
24
26
 
25
27
  def init(responder)
@@ -28,7 +30,7 @@ module Responders
28
30
  end
29
31
 
30
32
  adapter = find(responder)
31
- adapter.new(responder) if adapter
33
+ adapter&.new(responder)
32
34
  end
33
35
 
34
36
  def find(responder)
@@ -1,37 +1,30 @@
1
- # -*- encoding: utf-8 -*-
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+ lib = File.expand_path('lib', __dir__)
3
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
6
  require 'paginate-responder/version'
5
7
 
6
8
  Gem::Specification.new do |gem|
7
- gem.name = "paginate-responder"
9
+ gem.name = 'paginate-responder'
8
10
  gem.version = PaginateResponder::VERSION
9
11
  gem.authors = ['Jan Graichen']
10
- gem.email = ['jg@altimos.de']
11
- gem.description = %q{A Rails pagination responder with link header support.}
12
- gem.summary = %q{A Rails pagination responder with link header support.}
13
- gem.homepage = "https://github.com/jgraichen/paginate-responder"
12
+ gem.email = ['jgraichen@altimos.de']
13
+ gem.description = 'A Rails pagination responder with link header support.'
14
+ gem.summary = 'A Rails pagination responder with link header support.'
15
+ gem.homepage = 'https://github.com/jgraichen/paginate-responder'
14
16
  gem.license = 'MIT'
15
17
 
16
- gem.files = `git ls-files`.split($/)
17
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.metadata = {
19
+ 'rubygems_mfa_required' => 'true',
20
+ }
21
+
22
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
23
+ gem.executables = gem.files.grep(%r{^bin/}).map {|f| File.basename(f) }
19
24
  gem.require_paths = ['lib']
20
25
 
21
- gem.add_dependency 'rack-link_headers', '>= 2.2'
26
+ gem.required_ruby_version = '>= 2.7.0'
22
27
 
23
- gem.add_development_dependency 'actionpack', '>= 3.2.0'
24
- gem.add_development_dependency 'activerecord', '>= 3.2.0'
25
- gem.add_development_dependency 'appraisal'
26
- gem.add_development_dependency 'kaminari'
27
- gem.add_development_dependency 'pagy'
28
- gem.add_development_dependency 'pry'
29
- gem.add_development_dependency 'pry-byebug'
30
- gem.add_development_dependency 'rake'
31
- gem.add_development_dependency 'responders'
32
- gem.add_development_dependency 'rspec'
33
- gem.add_development_dependency 'rspec-rails'
34
- gem.add_development_dependency 'sqlite3', '~> 1.3.6'
35
- gem.add_development_dependency 'will_paginate'
36
- gem.add_development_dependency 'test-unit'
28
+ gem.add_dependency 'rack-link_headers', '>= 2.2'
29
+ gem.add_dependency 'responders'
37
30
  end
data/renovate.json5 ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ $schema: "https://docs.renovatebot.com/renovate-schema.json",
3
+ extends: ["local>jgraichen/renovate-config"],
4
+ }
@@ -1,36 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
- RSpec.describe Responders::PaginateResponder, type: :controller do
4
- case $gem
5
- when 'will_paginate',
6
- 'pagy'
7
- let(:array_resource) do
8
- ('AA'..'zz').to_a
9
- end
10
- when 'kaminari'
11
- let(:array_resource) do
12
- Kaminari.paginate_array ('AA'..'zz').to_a
13
- end
5
+ RSpec.describe Responders::PaginateResponder do
6
+ subject(:json) do
7
+ action.call
8
+ JSON.parse(response.body)
14
9
  end
15
10
 
16
- before do
17
- if ActiveRecord::VERSION::MAJOR >= 4
18
- self.resource = ArModel.all
19
- else
20
- self.resource = ArModel.scoped
21
- end
22
- end
11
+ let(:resource) { ArModel.all }
23
12
 
24
13
  let(:method) { :get }
25
- let(:response) { action.call; @response }
26
- let(:json) { JSON.parse response.body }
27
14
  let(:params) { {format: :json} }
28
-
29
- if ActionPack::VERSION::MAJOR >= 5
30
- let(:action) { -> { send(method, :index, params: params) } }
31
- else
32
- let(:action) { -> { send(method, :index, params) } }
33
- end
15
+ let(:action) { -> { send(method, :index, params: params) } }
34
16
 
35
17
  context 'with AR resource' do
36
18
  it { expect(json).to eq (1..50).to_a }
@@ -71,7 +53,14 @@ RSpec.describe Responders::PaginateResponder, type: :controller do
71
53
  end
72
54
 
73
55
  context 'with array resource' do
74
- before { @controller.resource = array_resource }
56
+ let(:resource) do
57
+ case GEM
58
+ when 'will_paginate', 'pagy'
59
+ ('AA'..'zz').to_a
60
+ when 'kaminari'
61
+ Kaminari.paginate_array ('AA'..'zz').to_a
62
+ end
63
+ end
75
64
 
76
65
  it { expect(json).to eq ('AA'..'zz').to_a[0..49] }
77
66
 
@@ -95,15 +84,18 @@ RSpec.describe Responders::PaginateResponder, type: :controller do
95
84
  end
96
85
 
97
86
  context 'with AR association' do
98
- before { @controller.resource = ArModel.find(1).ar_assoc_models }
87
+ let(:resource) { ArModel.find(1).ar_assoc_models }
99
88
 
100
89
  it { expect(json).to eq (1..5).to_a }
101
90
  end
102
91
 
103
92
  describe 'links' do
104
- subject { response.links.map{|l| [l[:params][:rel], l[:url]]}.to_h }
93
+ subject(:links) do
94
+ action.call
95
+ response.links.to_h {|l| [l[:params][:rel], l[:url]] }
96
+ end
105
97
 
106
- it { expect(subject.size).to eq 3 }
98
+ it { expect(links.size).to eq 3 }
107
99
  it { is_expected.to include 'first' => 'http://test.host/index.json?page=1' }
108
100
  it { is_expected.to include 'next' => 'http://test.host/index.json?page=2' }
109
101
  it { is_expected.to include 'last' => 'http://test.host/index.json?page=14' }
@@ -111,7 +103,7 @@ RSpec.describe Responders::PaginateResponder, type: :controller do
111
103
  context '?page' do
112
104
  let(:params) { super().merge page: 2 }
113
105
 
114
- it { expect(subject.size).to eq 4 }
106
+ it { expect(links.size).to eq 4 }
115
107
  it { is_expected.to include 'first' => 'http://test.host/index.json?page=1' }
116
108
  it { is_expected.to include 'prev' => 'http://test.host/index.json?page=1' }
117
109
  it { is_expected.to include 'next' => 'http://test.host/index.json?page=3' }
@@ -121,7 +113,7 @@ RSpec.describe Responders::PaginateResponder, type: :controller do
121
113
  context '?page=5' do
122
114
  let(:params) { super().merge page: 5 }
123
115
 
124
- it { expect(subject.size).to eq 4 }
116
+ it { expect(links.size).to eq 4 }
125
117
  it { is_expected.to include 'first' => 'http://test.host/index.json?page=1' }
126
118
  it { is_expected.to include 'prev' => 'http://test.host/index.json?page=4' }
127
119
  it { is_expected.to include 'next' => 'http://test.host/index.json?page=6' }
@@ -131,7 +123,7 @@ RSpec.describe Responders::PaginateResponder, type: :controller do
131
123
  context '?page last' do
132
124
  let(:params) { super().merge page: 14 }
133
125
 
134
- it { expect(subject.size).to eq 3 }
126
+ it { expect(links.size).to eq 3 }
135
127
  it { is_expected.to include 'first' => 'http://test.host/index.json?page=1' }
136
128
  it { is_expected.to include 'prev' => 'http://test.host/index.json?page=13' }
137
129
  it { is_expected.to include 'last' => 'http://test.host/index.json?page=14' }
@@ -140,7 +132,7 @@ RSpec.describe Responders::PaginateResponder, type: :controller do
140
132
  context '?page before last' do
141
133
  let(:params) { super().merge page: 13 }
142
134
 
143
- it { expect(subject.size).to eq 4 }
135
+ it { expect(links.size).to eq 4 }
144
136
  it { is_expected.to include 'first' => 'http://test.host/index.json?page=1' }
145
137
  it { is_expected.to include 'prev' => 'http://test.host/index.json?page=12' }
146
138
  it { is_expected.to include 'next' => 'http://test.host/index.json?page=14' }
@@ -150,7 +142,7 @@ RSpec.describe Responders::PaginateResponder, type: :controller do
150
142
  context '?per_page' do
151
143
  let(:params) { super().merge page: 1, per_page: 10 }
152
144
 
153
- it { expect(subject.size).to eq 3 }
145
+ it { expect(links.size).to eq 3 }
154
146
  it { is_expected.to include 'first' => 'http://test.host/index.json?page=1&per_page=10' }
155
147
  it { is_expected.to include 'next' => 'http://test.host/index.json?page=2&per_page=10' }
156
148
  it { is_expected.to include 'last' => 'http://test.host/index.json?page=68&per_page=10' }
@@ -159,7 +151,7 @@ RSpec.describe Responders::PaginateResponder, type: :controller do
159
151
  context '?per_page above max per page limit' do
160
152
  let(:params) { super().merge page: 1, per_page: 100 }
161
153
 
162
- it { expect(subject.size).to eq 3 }
154
+ it { expect(links.size).to eq 3 }
163
155
  it { is_expected.to include 'first' => 'http://test.host/index.json?page=1&per_page=50' }
164
156
  it { is_expected.to include 'next' => 'http://test.host/index.json?page=2&per_page=50' }
165
157
  it { is_expected.to include 'last' => 'http://test.host/index.json?page=14&per_page=50' }
@@ -168,7 +160,7 @@ RSpec.describe Responders::PaginateResponder, type: :controller do
168
160
  context 'when method is HEAD' do
169
161
  let(:method) { :head }
170
162
 
171
- it { expect(subject.size).to eq 3 }
163
+ it { expect(links.size).to eq 3 }
172
164
  it { is_expected.to include 'first' => 'http://test.host/index.json?page=1' }
173
165
  it { is_expected.to include 'next' => 'http://test.host/index.json?page=2' }
174
166
  it { is_expected.to include 'last' => 'http://test.host/index.json?page=14' }
@@ -176,20 +168,23 @@ RSpec.describe Responders::PaginateResponder, type: :controller do
176
168
  end
177
169
 
178
170
  describe 'headers' do
179
- subject { response.headers.to_h }
171
+ subject do
172
+ action.call
173
+ response.headers.to_h.transform_keys(&:downcase)
174
+ end
180
175
 
181
- it { is_expected.to include 'X-Total-Pages' => '14' }
182
- it { is_expected.to include 'X-Total-Count' => '676' }
183
- it { is_expected.to include 'X-Per-Page' => '50' }
184
- it { is_expected.to include 'X-Current-Page' => '1' }
176
+ it { is_expected.to include 'x-total-pages' => '14' }
177
+ it { is_expected.to include 'x-total-count' => '676' }
178
+ it { is_expected.to include 'x-per-page' => '50' }
179
+ it { is_expected.to include 'x-current-page' => '1' }
185
180
 
186
181
  context 'when method is HEAD' do
187
182
  let(:method) { :head }
188
183
 
189
- it { is_expected.to include 'X-Total-Pages' => '14' }
190
- it { is_expected.to include 'X-Total-Count' => '676' }
191
- it { is_expected.to include 'X-Per-Page' => '50' }
192
- it { is_expected.to include 'X-Current-Page' => '1' }
184
+ it { is_expected.to include 'x-total-pages' => '14' }
185
+ it { is_expected.to include 'x-total-count' => '676' }
186
+ it { is_expected.to include 'x-per-page' => '50' }
187
+ it { is_expected.to include 'x-current-page' => '1' }
193
188
  end
194
189
  end
195
190
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems'
2
4
  require 'bundler/setup'
3
5
 
6
+ # Workaround for older Rails versions not explicitly requiring logger
7
+ require 'logger'
8
+
4
9
  # Configure Rails
5
10
  ENV['RAILS_ENV'] = 'test'
6
11
 
@@ -12,18 +17,13 @@ require 'active_record'
12
17
  require 'rspec'
13
18
 
14
19
  require 'responders'
15
-
16
20
  require 'paginate-responder'
17
21
 
18
- require 'pry'
19
- require 'pry-byebug'
20
-
21
- Dir[File.expand_path('spec/support/**/*.rb')].each {|f| require f }
22
+ Dir[File.expand_path('spec/support/**/*.rb')].sort.each {|f| require f }
22
23
 
23
- $gem = ENV['GEM'].to_s
24
- $gem = 'will_paginate' if $gem.empty?
24
+ GEM = ENV.fetch('GEM', 'will_paginate')
25
25
 
26
- case $gem
26
+ case GEM
27
27
  when 'will_paginate'
28
28
  require 'will_paginate/array'
29
29
  require 'will_paginate/active_record'
@@ -1,35 +1,28 @@
1
-
2
- $routes = ActionDispatch::Routing::RouteSet.new
3
- $routes.draw do
4
- get '/index' => 'test#index'
5
- end
6
-
7
- class ActiveSupport::TestCase
8
- setup do
9
- @routes = $routes
10
- end
11
- end
1
+ # frozen_string_literal: true
12
2
 
13
3
  class ArModel < ActiveRecord::Base
14
4
  has_many :ar_assoc_models
15
- def as_json(opts = {})
5
+
6
+ def as_json(_opts = {})
16
7
  id
17
8
  end
18
9
  end
19
10
 
20
11
  class ArAssocModel < ActiveRecord::Base
21
- def as_json(opts = {})
12
+ def as_json(_opts = {})
22
13
  id
23
14
  end
24
15
  end
25
16
 
26
17
  ActiveRecord::Base.establish_connection(
27
18
  adapter: 'sqlite3',
28
- database: ':memory:'
19
+ database: ':memory:',
29
20
  )
21
+
30
22
  ActiveRecord::Base.connection.execute <<SQL
31
23
  CREATE TABLE ar_models (id INTEGER PRIMARY KEY AUTOINCREMENT);
32
24
  SQL
25
+
33
26
  ActiveRecord::Base.connection.execute <<SQL
34
27
  CREATE TABLE ar_assoc_models (
35
28
  id INTEGER PRIMARY KEY AUTOINCREMENT, ar_model_id INTEGER
@@ -48,35 +41,31 @@ class TestResponder < ActionController::Responder
48
41
  include Responders::PaginateResponder
49
42
  end
50
43
 
51
- class TestController < ActionController::Base
52
- include $routes.url_helpers
44
+ ROUTES = ActionDispatch::Routing::RouteSet.new
45
+ ROUTES.draw do
46
+ get '/index' => 'test#index'
47
+ end
53
48
 
54
- attr_accessor :resource
49
+ class TestController < ActionController::Base
50
+ include ROUTES.url_helpers
55
51
 
56
52
  self.responder = TestResponder
57
53
 
58
54
  respond_to :json
59
55
 
60
- def index
61
- respond_with resource
56
+ def initialize(&block)
57
+ super
58
+ @cb = block
62
59
  end
63
- end
64
-
65
- module TestSpecConfiguration
66
- extend ActiveSupport::Concern
67
60
 
68
- included do
69
- before do
70
- @routes = $routes
71
- @controller = TestController.new
72
- end
73
-
74
- def resource=(resource)
75
- @controller.resource = resource
76
- end
61
+ def index
62
+ respond_with @cb.call
77
63
  end
78
64
  end
79
65
 
80
66
  RSpec.configure do |config|
81
- config.include TestSpecConfiguration
67
+ config.before do
68
+ @routes = ROUTES
69
+ @controller = TestController.new { resource }
70
+ end
82
71
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SetupAndTeardownAdapter
2
4
  extend ActiveSupport::Concern
3
5
 
@@ -6,7 +8,7 @@ module SetupAndTeardownAdapter
6
8
  # hooks.
7
9
  def setup(*methods, &block)
8
10
  methods.each do |method|
9
- if method.to_s =~ /^setup_(with_controller|fixtures|controller_request_and_response)$/
11
+ if /^setup_(with_controller|fixtures|controller_request_and_response)$/.match?(method.to_s)
10
12
  prepend_before { __send__ method }
11
13
  else
12
14
  before { __send__ method }
@@ -20,7 +22,7 @@ module SetupAndTeardownAdapter
20
22
  # Wraps `teardown` calls from within Rails' testing framework in
21
23
  # `after` hooks.
22
24
  def teardown(*methods, &block)
23
- methods.each { |method| after { __send__ method } }
25
+ methods.each {|method| after { __send__ method } }
24
26
  after(&block) if block
25
27
  end
26
28
  end