geared_pagination 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +38 -0
- data/MIT-LICENSE +20 -0
- data/README.md +40 -0
- data/Rakefile +10 -0
- data/geared_pagination.gemspec +19 -0
- data/lib/geared_pagination.rb +2 -0
- data/lib/geared_pagination/controller.rb +30 -0
- data/lib/geared_pagination/headers.rb +35 -0
- data/lib/geared_pagination/page.rb +43 -0
- data/lib/geared_pagination/portion.rb +23 -0
- data/lib/geared_pagination/railtie.rb +10 -0
- data/lib/geared_pagination/ratios.rb +13 -0
- data/lib/geared_pagination/recordset.rb +35 -0
- data/test/headers_test.rb +47 -0
- data/test/page_test.rb +23 -0
- data/test/portion_test.rb +16 -0
- data/test/ratios_test.rb +27 -0
- data/test/recording_stubs.rb +62 -0
- data/test/recordset_test.rb +35 -0
- data/test/test_helper.rb +5 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 86fef30f9fb2e850e8b305a079d05d39007ec6bd
|
4
|
+
data.tar.gz: 83e91624d0fbd65747604f91628e826f00a131b0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f7e00eb4a7598860c873eb1810ffdba1c8e5a30d625d42b6a7e10f035786e593724b74c8c496089495ada18c992af7b41534041e1b5951f8573932a3d533509e
|
7
|
+
data.tar.gz: c2feb3068a763034a474fca15cd793b3fdeae695cee4c6f0187c4ea2918a76a24f9a124061407922a3b397137119fdc234413153563ba0ed9f3301af9204238e
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
geared_pagination (0.1)
|
5
|
+
activesupport (>= 5.0)
|
6
|
+
addressable (>= 2.5.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (5.1.0.beta1)
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
+
i18n (~> 0.7)
|
14
|
+
minitest (~> 5.1)
|
15
|
+
tzinfo (~> 1.1)
|
16
|
+
addressable (2.5.0)
|
17
|
+
public_suffix (~> 2.0, >= 2.0.2)
|
18
|
+
byebug (9.0.6)
|
19
|
+
concurrent-ruby (1.0.4)
|
20
|
+
i18n (0.8.1)
|
21
|
+
minitest (5.10.1)
|
22
|
+
public_suffix (2.0.5)
|
23
|
+
rake (12.0.0)
|
24
|
+
thread_safe (0.3.5)
|
25
|
+
tzinfo (1.2.2)
|
26
|
+
thread_safe (~> 0.1)
|
27
|
+
|
28
|
+
PLATFORMS
|
29
|
+
ruby
|
30
|
+
|
31
|
+
DEPENDENCIES
|
32
|
+
bundler (~> 1.12)
|
33
|
+
byebug
|
34
|
+
geared_pagination!
|
35
|
+
rake
|
36
|
+
|
37
|
+
BUNDLED WITH
|
38
|
+
1.14.6
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2017 David Heinemeier Hansson, Basecamp
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Geared Pagination
|
2
|
+
|
3
|
+
Most pagination schemes use a fixed page size. Page 1 returns as many elements as page 2. But that's
|
4
|
+
frequently not the most sensible way to page through a large collection when you care about serving the
|
5
|
+
initial request as quickly as possible. This is particularly the case when using the pagination scheme
|
6
|
+
in combination with an infinite scrolling UI.
|
7
|
+
|
8
|
+
Geared Pagination allows you to define different ratios. By default, we will return 15 elements on page 1,
|
9
|
+
30 on page 2, 50 on page 3, and 100 from page 4 and forward. This has proben to be a very sensible set of
|
10
|
+
ratios for much of the Basecamp UIs. But you can of course tweak the ratios, use fewer, or even none at all,
|
11
|
+
if you certain page calls for a fixed-rate scheme.
|
12
|
+
|
13
|
+
On json actions that set a page, we'll also also automatically set Link and X-Total-Count headers for APIs
|
14
|
+
to be able to page through a collection.
|
15
|
+
|
16
|
+
## Example
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
class MessagesController < ApplicationController
|
20
|
+
def index
|
21
|
+
@page = current_page_from Message.order(created_at: :desc)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# app/views/messages/index.html.erb
|
26
|
+
|
27
|
+
Showing page <%= @page.number %> of <%= @page.collection.page_count %> (<%= @page.collection.record_count %> total messages):
|
28
|
+
|
29
|
+
<%= render @page.records %>
|
30
|
+
|
31
|
+
<% if @page.last? %>
|
32
|
+
No more pages!
|
33
|
+
<% else %>
|
34
|
+
<%= link_to "Next page", messages_path(page: @page.next_number) %>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
```
|
38
|
+
|
39
|
+
## License
|
40
|
+
Geared Pagination is released under the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'geared_pagination'
|
3
|
+
s.version = '0.1'
|
4
|
+
s.authors = 'David Heinemeier Hansson'
|
5
|
+
s.email = 'david@basecamp.com'
|
6
|
+
s.summary = 'Paginate Active Record sets at variable speeds'
|
7
|
+
s.homepage = 'https://github.com/basecamp/geared_pagination'
|
8
|
+
s.license = 'MIT'
|
9
|
+
|
10
|
+
s.required_ruby_version = '>= 1.9.3'
|
11
|
+
|
12
|
+
s.add_dependency 'activesupport', '>= 5.0'
|
13
|
+
s.add_dependency 'addressable', '>= 2.5.0'
|
14
|
+
|
15
|
+
s.add_development_dependency 'bundler', '~> 1.12'
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'geared_pagination/recordset'
|
2
|
+
require 'geared_pagination/headers'
|
3
|
+
|
4
|
+
module GearedPagination
|
5
|
+
module Controller
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
after_action :set_paginated_headers
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def set_page_and_extract_portion_from(records, per_page: nil)
|
14
|
+
@page = current_page_from(records, per_page: per_page)
|
15
|
+
@page.records
|
16
|
+
end
|
17
|
+
|
18
|
+
def current_page_from(records, per_page: nil)
|
19
|
+
GearedPagination::Recordset.new(records, per_page: per_page).page(current_page_param)
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_paginated_headers
|
23
|
+
GearedPagination::Headers.new(page: @page, controller: self).apply if @page.is_a?(GearedPagination::Page)
|
24
|
+
end
|
25
|
+
|
26
|
+
def current_page_param
|
27
|
+
params[:page].to_i > 0 ? params[:page].to_i : 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
module GearedPagination
|
4
|
+
class Headers
|
5
|
+
def initialize(page:, controller:)
|
6
|
+
@page, @controller = page, controller
|
7
|
+
end
|
8
|
+
|
9
|
+
def apply
|
10
|
+
@controller.headers.update(headers) if applicable?
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def headers
|
15
|
+
Hash.new.tap do |h|
|
16
|
+
h["X-Total-Count"] = @page.collection.records_count.to_s
|
17
|
+
h["Link"] = next_page_link_header unless @page.last?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def applicable?
|
22
|
+
@controller.request.format&.json?
|
23
|
+
end
|
24
|
+
|
25
|
+
def next_page_link_header
|
26
|
+
link_header(rel: :next, page_number: @page.next_number).to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def link_header(rel:, page_number:)
|
30
|
+
uri = Addressable::URI.parse(@controller.request.url)
|
31
|
+
uri.query_values = (uri.query_values || {}).merge("page" => page_number)
|
32
|
+
%{<#{uri}>; rel="#{rel}"}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'geared_pagination/portion'
|
2
|
+
|
3
|
+
module GearedPagination
|
4
|
+
class Page
|
5
|
+
attr_reader :number, :collection
|
6
|
+
|
7
|
+
def initialize(number, from:)
|
8
|
+
@number, @collection = number, from
|
9
|
+
@portion = GearedPagination::Portion.new(page_number: number, per_page: from.ratios)
|
10
|
+
end
|
11
|
+
|
12
|
+
def records
|
13
|
+
@records ||= @portion.from(collection.records)
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def used?
|
18
|
+
records.load.any?
|
19
|
+
end
|
20
|
+
|
21
|
+
def empty?
|
22
|
+
records.load.none?
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def first?
|
27
|
+
number == 1
|
28
|
+
end
|
29
|
+
|
30
|
+
def only?
|
31
|
+
collection.page_count == 1
|
32
|
+
end
|
33
|
+
|
34
|
+
def last?
|
35
|
+
number == collection.page_count
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
def next_number
|
40
|
+
number + 1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'geared_pagination/ratios'
|
2
|
+
|
3
|
+
module GearedPagination
|
4
|
+
class Portion
|
5
|
+
attr_reader :page_number, :ratios
|
6
|
+
|
7
|
+
def initialize(page_number: 1, per_page: GearedPagination::Ratios.new)
|
8
|
+
@page_number, @ratios = page_number, per_page
|
9
|
+
end
|
10
|
+
|
11
|
+
def from(scope)
|
12
|
+
scope.limit(limit).offset(offset)
|
13
|
+
end
|
14
|
+
|
15
|
+
def limit
|
16
|
+
ratios[page_number]
|
17
|
+
end
|
18
|
+
|
19
|
+
def offset
|
20
|
+
(page_number - 1).times.sum { |index| ratios[index + 1] }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rails/railtie'
|
2
|
+
require 'geared_pagination/controller'
|
3
|
+
|
4
|
+
class GearedPagination::Engine < ::Rails::Engine
|
5
|
+
initializer :webpacker do |app|
|
6
|
+
ActiveSupport.on_load :action_controller do
|
7
|
+
ActionController::Base.send :include, GearedPagination::Controller
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'geared_pagination/ratios'
|
2
|
+
require 'geared_pagination/page'
|
3
|
+
|
4
|
+
module GearedPagination
|
5
|
+
class Recordset
|
6
|
+
attr_reader :records, :ratios
|
7
|
+
|
8
|
+
def initialize(records, per_page: nil)
|
9
|
+
@records = records
|
10
|
+
@ratios = GearedPagination::Ratios.new(per_page)
|
11
|
+
end
|
12
|
+
|
13
|
+
def page(number)
|
14
|
+
GearedPagination::Page.new(number, from: self)
|
15
|
+
end
|
16
|
+
|
17
|
+
def page_count
|
18
|
+
@page_count ||= begin
|
19
|
+
count = 0
|
20
|
+
residual = records_count
|
21
|
+
|
22
|
+
while residual > 0
|
23
|
+
count += 1
|
24
|
+
residual = residual - ratios[count]
|
25
|
+
end
|
26
|
+
|
27
|
+
count
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def records_count
|
32
|
+
@records_count ||= records.unscope(:limit).unscope(:offset).count
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_support/core_ext/string/inquiry'
|
3
|
+
require 'geared_pagination/headers'
|
4
|
+
require 'geared_pagination/recordset'
|
5
|
+
|
6
|
+
class GearedPagination::HeadersTest < ActiveSupport::TestCase
|
7
|
+
Request = Struct.new(:url, :format)
|
8
|
+
Controller = Struct.new(:request, :headers)
|
9
|
+
|
10
|
+
setup do
|
11
|
+
@controller_serving_json = Controller.new(Request.new("http://example.com/collection.json", "json".inquiry), {})
|
12
|
+
@controller_serving_html = Controller.new(Request.new("http://example.com/collection", "html".inquiry), {})
|
13
|
+
|
14
|
+
@single_page_collection = GearedPagination::Recordset.new(Recording.all, per_page: 1000)
|
15
|
+
@many_page_collection = GearedPagination::Recordset.new(Recording.all, per_page: 1)
|
16
|
+
end
|
17
|
+
|
18
|
+
test "total count" do
|
19
|
+
GearedPagination::Headers.new(page: @many_page_collection.page(1), controller: @controller_serving_json).apply
|
20
|
+
assert_equal Recording.all.count.to_s, @controller_serving_json.headers["X-Total-Count"]
|
21
|
+
end
|
22
|
+
|
23
|
+
test "no link for html requests" do
|
24
|
+
GearedPagination::Headers.new(page: @many_page_collection.page(1), controller: @controller_serving_html).apply
|
25
|
+
assert @controller_serving_html.headers["Link"].nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
test "no link for json request with single page" do
|
29
|
+
GearedPagination::Headers.new(page: @many_page_collection.page(1), controller: @controller_serving_html).apply
|
30
|
+
assert @controller_serving_html.headers["Link"].nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
test "links for json request with multiple pages" do
|
34
|
+
GearedPagination::Headers.new(page: @many_page_collection.page(1), controller: @controller_serving_json).apply
|
35
|
+
assert_equal '<http://example.com/collection.json?page=2>; rel="next"',
|
36
|
+
@controller_serving_json.headers["Link"]
|
37
|
+
|
38
|
+
GearedPagination::Headers.new(page: @many_page_collection.page(2), controller: @controller_serving_json).apply
|
39
|
+
assert_equal '<http://example.com/collection.json?page=3>; rel="next"',
|
40
|
+
@controller_serving_json.headers["Link"]
|
41
|
+
end
|
42
|
+
|
43
|
+
test "no link for json request with multiple pages on last page" do
|
44
|
+
GearedPagination::Headers.new(page: @many_page_collection.page(Recording.all.count), controller: @controller_serving_json).apply
|
45
|
+
assert @controller_serving_json.headers["Link"].nil?
|
46
|
+
end
|
47
|
+
end
|
data/test/page_test.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'geared_pagination/recordset'
|
3
|
+
|
4
|
+
class GearedPagination::PageTest < ActiveSupport::TestCase
|
5
|
+
test "first" do
|
6
|
+
assert GearedPagination::Recordset.new(Recording.all).page(1).first?
|
7
|
+
assert_not GearedPagination::Recordset.new(Recording.all).page(2).first?
|
8
|
+
end
|
9
|
+
|
10
|
+
test "only" do
|
11
|
+
assert GearedPagination::Recordset.new(Recording.all, per_page: 1000).page(1).only?
|
12
|
+
assert_not GearedPagination::Recordset.new(Recording.all, per_page: 1).page(1).only?
|
13
|
+
end
|
14
|
+
|
15
|
+
test "last" do
|
16
|
+
assert GearedPagination::Recordset.new(Recording.all, per_page: 1000).page(1).last?
|
17
|
+
assert_not GearedPagination::Recordset.new(Recording.all, per_page: 1).page(1).last?
|
18
|
+
end
|
19
|
+
|
20
|
+
test "next_number" do
|
21
|
+
assert_equal 2, GearedPagination::Recordset.new(Recording.all, per_page: 1000).page(1).next_number
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'active_support/core_ext/array/access'
|
3
|
+
require 'geared_pagination/portion'
|
4
|
+
|
5
|
+
class GearedPagination::PortionTest < ActiveSupport::TestCase
|
6
|
+
test "offset" do
|
7
|
+
assert_equal 0, GearedPagination::Portion.new(page_number: 1).offset
|
8
|
+
assert_equal GearedPagination::Ratios::DEFAULTS.first, GearedPagination::Portion.new(page_number: 2).offset
|
9
|
+
assert_equal GearedPagination::Ratios::DEFAULTS.first + GearedPagination::Ratios::DEFAULTS.second, GearedPagination::Portion.new(page_number: 3).offset
|
10
|
+
end
|
11
|
+
|
12
|
+
test "limit" do
|
13
|
+
assert_equal GearedPagination::Ratios::DEFAULTS.first, GearedPagination::Portion.new(page_number: 1).limit
|
14
|
+
assert_equal GearedPagination::Ratios::DEFAULTS.second, GearedPagination::Portion.new(page_number: 2).limit
|
15
|
+
end
|
16
|
+
end
|
data/test/ratios_test.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'geared_pagination/ratios'
|
3
|
+
|
4
|
+
class GearedPagination::RatiosTest < ActiveSupport::TestCase
|
5
|
+
test "single limit" do
|
6
|
+
limits = GearedPagination::Ratios.new(10)
|
7
|
+
|
8
|
+
assert_equal 10, limits[1]
|
9
|
+
assert_equal 10, limits[2]
|
10
|
+
end
|
11
|
+
|
12
|
+
test "range of limits" do
|
13
|
+
limits = GearedPagination::Ratios.new([ 10, 25, 100 ])
|
14
|
+
|
15
|
+
assert_equal 10, limits[1]
|
16
|
+
assert_equal 25, limits[2]
|
17
|
+
assert_equal 100, limits[3]
|
18
|
+
assert_equal 100, limits[4]
|
19
|
+
end
|
20
|
+
|
21
|
+
test "default limits" do
|
22
|
+
limits = GearedPagination::Ratios.new
|
23
|
+
|
24
|
+
assert_equal GearedPagination::Ratios::DEFAULTS.first, limits[1]
|
25
|
+
assert_equal GearedPagination::Ratios::DEFAULTS.last, limits[99]
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
class Recordings
|
2
|
+
def initialize(recordings)
|
3
|
+
@recordings = recordings
|
4
|
+
@offset = 0
|
5
|
+
@limit = nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def limit(size)
|
9
|
+
@limit = size
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def offset(number)
|
14
|
+
@offset = number
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def unscope(restriction)
|
19
|
+
case restriction
|
20
|
+
when :offset then @offset = 0
|
21
|
+
when :limit then @limit = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def [](index)
|
29
|
+
slice[index]
|
30
|
+
end
|
31
|
+
|
32
|
+
def count
|
33
|
+
slice.size
|
34
|
+
end
|
35
|
+
alias :size :count
|
36
|
+
|
37
|
+
def include?(record)
|
38
|
+
slice.include?(record)
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
private
|
43
|
+
def slice
|
44
|
+
@recordings[@offset..(@limit ? @offset + (@limit - 1) : -1)]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Recording
|
49
|
+
def self.all(count = 120)
|
50
|
+
Recordings.new(count.times.collect { |i| new(i) })
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_reader :number
|
54
|
+
|
55
|
+
def initialize(number)
|
56
|
+
@number = 1
|
57
|
+
end
|
58
|
+
|
59
|
+
def ==(comparison)
|
60
|
+
@number == comparison.number
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'geared_pagination/recordset'
|
3
|
+
|
4
|
+
class GearedPagination::RecordsetTest < ActiveSupport::TestCase
|
5
|
+
test "single limit pagination" do
|
6
|
+
collection = GearedPagination::Recordset.new(Recording.all, per_page: 10)
|
7
|
+
|
8
|
+
assert_equal 10, collection.page(1).records.size
|
9
|
+
assert_equal 10, collection.page(2).records.size
|
10
|
+
end
|
11
|
+
|
12
|
+
test "variable limit pagination" do
|
13
|
+
collection = GearedPagination::Recordset.new(Recording.all, per_page: [ 10, 15, 20 ])
|
14
|
+
|
15
|
+
assert_equal 10, collection.page(1).records.size
|
16
|
+
assert collection.page(1).records.include?(Recording.all[0])
|
17
|
+
|
18
|
+
assert_equal 15, collection.page(2).records.size
|
19
|
+
assert collection.page(2).records.include?(Recording.all[11])
|
20
|
+
|
21
|
+
assert_equal 20, collection.page(3).records.size
|
22
|
+
assert collection.page(3).records.include?(Recording.all[26])
|
23
|
+
|
24
|
+
assert_equal 20, collection.page(4).records.size
|
25
|
+
assert collection.page(4).records.include?(Recording.all[46])
|
26
|
+
end
|
27
|
+
|
28
|
+
test "page count" do
|
29
|
+
assert_equal 7, GearedPagination::Recordset.new(Recording.all, per_page: [ 10, 15, 20 ]).page_count
|
30
|
+
end
|
31
|
+
|
32
|
+
test "records count" do
|
33
|
+
assert_equal Recording.all.count, GearedPagination::Recordset.new(Recording.all, per_page: [ 10, 15, 20 ]).records_count
|
34
|
+
end
|
35
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: geared_pagination
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Heinemeier Hansson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: addressable
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.5.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.5.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.12'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.12'
|
55
|
+
description:
|
56
|
+
email: david@basecamp.com
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- Gemfile
|
62
|
+
- Gemfile.lock
|
63
|
+
- MIT-LICENSE
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- geared_pagination.gemspec
|
67
|
+
- lib/geared_pagination.rb
|
68
|
+
- lib/geared_pagination/controller.rb
|
69
|
+
- lib/geared_pagination/headers.rb
|
70
|
+
- lib/geared_pagination/page.rb
|
71
|
+
- lib/geared_pagination/portion.rb
|
72
|
+
- lib/geared_pagination/railtie.rb
|
73
|
+
- lib/geared_pagination/ratios.rb
|
74
|
+
- lib/geared_pagination/recordset.rb
|
75
|
+
- test/headers_test.rb
|
76
|
+
- test/page_test.rb
|
77
|
+
- test/portion_test.rb
|
78
|
+
- test/ratios_test.rb
|
79
|
+
- test/recording_stubs.rb
|
80
|
+
- test/recordset_test.rb
|
81
|
+
- test/test_helper.rb
|
82
|
+
homepage: https://github.com/basecamp/geared_pagination
|
83
|
+
licenses:
|
84
|
+
- MIT
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 1.9.3
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 2.6.8
|
103
|
+
signing_key:
|
104
|
+
specification_version: 4
|
105
|
+
summary: Paginate Active Record sets at variable speeds
|
106
|
+
test_files:
|
107
|
+
- test/headers_test.rb
|
108
|
+
- test/page_test.rb
|
109
|
+
- test/portion_test.rb
|
110
|
+
- test/ratios_test.rb
|
111
|
+
- test/recording_stubs.rb
|
112
|
+
- test/recordset_test.rb
|
113
|
+
- test/test_helper.rb
|