forked from mislav/will_paginate
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
represent the concept of page number with the PageNumber class
It handles validation of numbers and calculating the offset value.
- Loading branch information
Showing
8 changed files
with
145 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
require 'delegate' | ||
require 'forwardable' | ||
|
||
module WillPaginate | ||
# a module that page number exceptions are tagged with | ||
module InvalidPage; end | ||
|
||
# integer representing a page number | ||
class PageNumber < DelegateClass(Integer) | ||
# a value larger than this is not supported in SQL queries | ||
BIGINT = 9223372036854775807 | ||
|
||
extend Forwardable | ||
|
||
def initialize(value, name) | ||
value = Integer(value) | ||
if 'offset' == name ? (value < 0 or value > BIGINT) : value < 1 | ||
raise RangeError, "invalid #{name}: #{value.inspect}" | ||
end | ||
@name = name | ||
super(value) | ||
rescue ArgumentError, TypeError, RangeError => error | ||
error.extend InvalidPage | ||
raise error | ||
end | ||
|
||
alias_method :to_i, :__getobj__ | ||
|
||
def inspect | ||
"#{@name} #{to_i}" | ||
end | ||
|
||
def to_offset(per_page) | ||
PageNumber.new((to_i - 1) * per_page.to_i, 'offset') | ||
end | ||
|
||
def kind_of?(klass) | ||
super || to_i.kind_of?(klass) | ||
end | ||
alias is_a? kind_of? | ||
end | ||
|
||
# Ultrahax: makes `Fixnum === current_page` checks pass | ||
Numeric.extend Module.new { | ||
def ===(obj) | ||
obj.instance_of? PageNumber or super | ||
end | ||
} | ||
|
||
# An idemptotent coercion method | ||
def self.PageNumber(value, name = 'page') | ||
case value | ||
when PageNumber then value | ||
else PageNumber.new(value, name) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
require 'spec_helper' | ||
require 'will_paginate/page_number' | ||
|
||
describe WillPaginate::PageNumber do | ||
describe "valid" do | ||
subject { described_class.new('12', 'page') } | ||
|
||
it { should eq(12) } | ||
its(:inspect) { should eq('page 12') } | ||
it { should be_a(WillPaginate::PageNumber) } | ||
it { should be_instance_of(WillPaginate::PageNumber) } | ||
it { should be_a(Numeric) } | ||
it { should be_a(Fixnum) } | ||
it { should_not be_instance_of(Fixnum) } | ||
|
||
it "passes the PageNumber=== type check" do |variable| | ||
(WillPaginate::PageNumber === subject).should be | ||
end | ||
|
||
it "passes the Numeric=== type check" do |variable| | ||
(Numeric === subject).should be | ||
(Fixnum === subject).should be | ||
end | ||
end | ||
|
||
describe "invalid" do | ||
def create(value, name = 'page') | ||
described_class.new(value, name) | ||
end | ||
|
||
it "errors out on non-int values" do | ||
lambda { create(nil) }.should raise_error(WillPaginate::InvalidPage) | ||
lambda { create('') }.should raise_error(WillPaginate::InvalidPage) | ||
lambda { create('Schnitzel') }.should raise_error(WillPaginate::InvalidPage) | ||
end | ||
|
||
it "errors out on zero or less" do | ||
lambda { create(0) }.should raise_error(WillPaginate::InvalidPage) | ||
lambda { create(-1) }.should raise_error(WillPaginate::InvalidPage) | ||
end | ||
|
||
it "doesn't error out on zero for 'offset'" do | ||
lambda { create(0, 'offset') }.should_not raise_error | ||
lambda { create(-1, 'offset') }.should raise_error(WillPaginate::InvalidPage) | ||
end | ||
end | ||
|
||
describe "coercion method" do | ||
it "defaults to 'page' name" do | ||
num = WillPaginate::PageNumber(12) | ||
num.inspect.should eq('page 12') | ||
end | ||
|
||
it "accepts a custom name" do | ||
num = WillPaginate::PageNumber(12, 'monkeys') | ||
num.inspect.should eq('monkeys 12') | ||
end | ||
|
||
it "doesn't affect PageNumber instances" do | ||
num = WillPaginate::PageNumber(12) | ||
num2 = WillPaginate::PageNumber(num) | ||
num2.object_id.should eq(num.object_id) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters