Skip to content

Commit

Permalink
better handling of blank core variables
Browse files Browse the repository at this point in the history
  • Loading branch information
ddnexus committed May 21, 2018
1 parent 7504fe4 commit e480d04
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 12 deletions.
3 changes: 2 additions & 1 deletion docs/api/pagy.md
Expand Up @@ -73,7 +73,8 @@ These are the core-variables (i.e. instance variables that define the pagination
| `:outset` | the initial offset of the collection to paginate: pass it only if the collection was pre-offset(ted) | `0` |
| `:size` | the size of the page links to show: array of initial pages, before current page, after current page, final pages. _(see also 





[Control the page links](../how-to.md#control-the-page-links))_ | `[1,4,4,1]` |

Pagy validates the core variables passed and raises an `ArgumentError` exception if any value is wrong. It also raises a specific `Pagy::OutOfRangeError` if the `:page` is out of range, so you can rescue from it and do whatever you think fits.
__Notice__: Pagy replaces the blank values of scalar core variables (so excluding `:size`) with their default values. It also applies `to_i` on the values expected to be integers, so you can use values from request `params` without problems. For example: `pagy(some_scope, items: params[:items])` will work without any additional cleanup.



### Non-core Variables
Expand Down
12 changes: 5 additions & 7 deletions lib/pagy.rb
Expand Up @@ -13,21 +13,19 @@ class OutOfRangeError < StandardError; end
def self.root; Pathname.new(__FILE__).dirname end

# default core vars
VARS = { items:20, outset:0, size:[1,4,4,1] }
VARS = { page:1, items:20, outset:0, size:[1,4,4,1] }

# default I18n vars
zero_one = [:zero, :one] ; I18N = { file: Pagy.root.join('locales', 'pagy.yml').to_s, plurals: -> (c) {(zero_one[c] || :other).to_s.freeze} }


attr_reader :count, :page, :items, :vars, :pages, :last, :offset, :from, :to, :prev, :next

# merge and validate the options, do some simple aritmetic and set the instance variables
def initialize(vars)
@vars = VARS.merge(vars) # default vars + instance vars
@vars[:page] = (@vars[:page]||1).to_i # set page to 1 if nil
@vars = VARS.merge(vars.delete_if{|k,v| v.nil? or v == '' }) # default vars + cleaned instance vars
{ count:0, items:1, outset:0, page:1 }.each do |k,min| # validate core variables
@vars[k] >= min rescue nil || raise(ArgumentError, "expected :#{k} >= #{min}; got #{@vars[k].inspect}")
instance_variable_set(:"@#{k}", @vars.delete(k)) # set instance variables
(@vars[k] && @vars[k].to_i >= min) or raise(ArgumentError, "expected :#{k} >= #{min}; got #{@vars[k].inspect}")
instance_variable_set(:"@#{k}", @vars.delete(k).to_i) # set instance variables
end
@pages = @last = [(@count.to_f / @items).ceil, 1].max # cardinal and ordinal meanings
(1..@last).cover?(@page) || raise(OutOfRangeError, "expected :page in 1..#{@last}; got #{@page.inspect}")
Expand All @@ -41,7 +39,7 @@ def initialize(vars)

# return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
def series(size=@vars[:size])
(0..3).each{|i| size[i]>=0 rescue nil || raise(ArgumentError, "expected 4 items in :size >= 0; got #{size.inspect}")}
(0..3).each{|i| (size[i]>=0 rescue nil) or raise(ArgumentError, "expected 4 items >= 0 in :size; got #{size.inspect}")}
series = []
[*0..size[0], *@page-size[1]..@page+size[2], *@last-size[3]+1..@last+1].sort!.each_cons(2) do |a, b|
if a<0 || a==b || a>@last # skip out of range and duplicates
Expand Down
13 changes: 9 additions & 4 deletions test/api_test.rb
Expand Up @@ -13,12 +13,17 @@ def test_version_number
def test_initialization
assert_instance_of Pagy, @pagy
assert_instance_of Pagy, Pagy.new(count: 100)
assert_instance_of Pagy, Pagy.new(count: '100')
assert_instance_of Pagy, Pagy.new(count: 100, page: '2')
assert_instance_of Pagy, Pagy.new(count: 100, page: '')
assert_instance_of Pagy, Pagy.new(count: 100, items: '10')
assert_raises(ArgumentError) { Pagy.new({}) }
assert_raises(ArgumentError) { Pagy.new(count: 100, page: 0) }
assert_raises(ArgumentError) { Pagy.new(count: 100, page: 2, items: 0) }
assert_raises(ArgumentError) { Pagy.new(count: 100, page: 2, size: [1,2,3]).series }
assert_raises(ArgumentError) { Pagy.new(count: 100, page: 2, size: [1,2,3,'4']).series }
assert_raises(Pagy::OutOfRangeError) { Pagy.new(count: 100, page: '11') }
assert_raises(Pagy::OutOfRangeError) { Pagy.new(count: 100, page: 0) }
assert_raises(Pagy::OutOfRangeError) { Pagy.new(count: 100, page: 12 ) }
assert_raises(ArgumentError) { Pagy.new(page: 2) }
assert_raises(ArgumentError) { Pagy.new(count: '100', page: 1) }
assert_raises(ArgumentError) { Pagy.new(count: 100, page: 2, items: '10' ) }
end

def test_respond_to_accessors
Expand Down

0 comments on commit e480d04

Please sign in to comment.