paginator 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ == 1.0.0 / 2006-10-23
2
+
3
+ * Initial release
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/paginator
6
+ lib/paginator.rb
7
+ test/test_paginator.rb
@@ -0,0 +1,80 @@
1
+ paginator
2
+ by Bruce Williams
3
+ http://codefluency.com
4
+
5
+ == DESCRIPTION:
6
+
7
+ Paginator is a simple pagination class that provides a generic interface suitable
8
+ for use in any Ruby program.
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ Paginator doesn't make any assumptions as to how data is retrieved; you just
13
+ have to provide it with the total number of objects and a way to pull a specific
14
+ set of objects based on the offset and number of objects per page.
15
+
16
+ == SYNOPSIS:
17
+
18
+ === In a Rails Application
19
+
20
+ # In your controller
21
+ PER_PAGE = 20
22
+ @pager = Paginator.new(Foo.count, PER_PAGE) do |offset, per_page|
23
+ Foo.find(:all, :limit => per_page, :offset => offset)
24
+ end
25
+ @page = @pager.page(params[:page])
26
+
27
+ # In your view
28
+ <% @page.items.each do |foo| %>
29
+ <%# Show something for each item %>
30
+ <% end %>
31
+ <%= @page.number %>
32
+ <%= link_to("Prev", foos_url(:page => @page.prev.number)) if @page.prev? %>
33
+ <%= link_to("Next", foos_url(:page => @page.next.number)) if @page.next? %>
34
+
35
+ === Anything else
36
+
37
+ bunch_o_data = (1..60).to_a
38
+ PER_PAGE = 10
39
+ pager = Paginator.new(bunch_o_data.size, PER_PAGE) do |offset, per_page|
40
+ bunch_o_data[offset,per_page]
41
+ end
42
+ pager.each do |page|
43
+ puts "Page ##{page.number}"
44
+ page.each do |item|
45
+ puts item
46
+ end
47
+ end
48
+
49
+ == REQUIREMENTS:
50
+
51
+ None.
52
+
53
+ == INSTALL:
54
+
55
+ No special instructions.
56
+
57
+ == LICENSE:
58
+
59
+ (The MIT License)
60
+
61
+ Copyright (c) 2006 Bruce Williams (http://codefluency.com)
62
+
63
+ Permission is hereby granted, free of charge, to any person obtaining
64
+ a copy of this software and associated documentation files (the
65
+ 'Software'), to deal in the Software without restriction, including
66
+ without limitation the rights to use, copy, modify, merge, publish,
67
+ distribute, sublicense, and/or sell copies of the Software, and to
68
+ permit persons to whom the Software is furnished to do so, subject to
69
+ the following conditions:
70
+
71
+ The above copyright notice and this permission notice shall be
72
+ included in all copies or substantial portions of the Software.
73
+
74
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
75
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
76
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
77
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
78
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
79
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
80
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/paginator.rb'
6
+
7
+ Hoe.new('paginator', Paginator::VERSION) do |p|
8
+ p.rubyforge_name = 'paginator'
9
+ p.summary = 'A generic paginator object for use in any Ruby program'
10
+ p.description =<<EOD
11
+ Paginator doesn't make any assumptions as to how data is retrieved; you just
12
+ have to provide it with the total number of objects and a way to pull a specific
13
+ set of objects based on the offset and number of objects per page.
14
+ EOD
15
+ p.url = "http://paginator.rubyforge.org"
16
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
17
+ end
18
+
19
+ # vim: syntax=Ruby
File without changes
@@ -0,0 +1,107 @@
1
+ require 'forwardable'
2
+
3
+ class Paginator
4
+
5
+ VERSION = '1.0.0'
6
+
7
+ class ArgumentError < ::ArgumentError; end
8
+ class MissingCountError < ArgumentError; end
9
+ class MissingSelectError < ArgumentError; end
10
+
11
+ attr_reader :per_page
12
+
13
+ # Instantiate a new Paginator object
14
+ #
15
+ # Provide:
16
+ # * A total count of the number of objects to paginate
17
+ # * The number of objects in each page
18
+ # * A block that returns the array of items
19
+ # * The block is passed the item offset
20
+ # (and the number of items to show per page, for
21
+ # convenience)
22
+ def initialize(count, per_page, &select)
23
+ @count, @per_page = count, per_page
24
+ unless select
25
+ raise MissingSelectError, "Must provide block to select data for each page"
26
+ end
27
+ @select = select
28
+ end
29
+
30
+ # Total number of pages
31
+ def number_of_pages
32
+ (@count / @per_page) + (@count % @per_page > 0 ? 1 : 0)
33
+ end
34
+
35
+ # First page object
36
+ def first
37
+ page 1
38
+ end
39
+
40
+ # Last page object
41
+ def last
42
+ page number_of_pages
43
+ end
44
+
45
+ # Iterate through pages
46
+ def each
47
+ 1.upto(number_of_pages) do |number|
48
+ yield page(number)
49
+ end
50
+ end
51
+
52
+ # Retrieve page object by number
53
+ def page(number)
54
+ Page.new(self, number, lambda{ @select.call((number - 1) * @per_page, @per_page) })
55
+ end
56
+
57
+ # Page object
58
+ #
59
+ # Retrieves items for a page and provides metadata about the position
60
+ # of the page in the paginator
61
+ class Page
62
+
63
+ extend Forwardable
64
+ def_delegator :@pager, :first, :first
65
+ def_delegator :@pager, :last, :last
66
+ def_delegator :items, :each
67
+
68
+ attr_reader :number, :pager
69
+
70
+ def initialize(pager, number, select) #:nodoc:
71
+ @pager, @number = pager, number
72
+ @select = select
73
+ end
74
+
75
+ # Retrieve the items for this page
76
+ # * Caches
77
+ def items
78
+ @items ||= @select.call
79
+ end
80
+
81
+ # Checks to see if there's a page before this one
82
+ def prev?
83
+ @number > 1
84
+ end
85
+
86
+ # Get previous page (if possible)
87
+ def prev
88
+ @pager.page(@number - 1) if prev?
89
+ end
90
+
91
+ # Checks to see if there's a page after this one
92
+ def next?
93
+ @number < @pager.number_of_pages
94
+ end
95
+
96
+ # Get next page (if possible)
97
+ def next
98
+ @pager.page(@number + 1) if next?
99
+ end
100
+
101
+ def ==(other) #:nodoc:
102
+ @pager == other.pager && self.number == other.number
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,76 @@
1
+ require 'test/unit'
2
+ require 'paginator'
3
+
4
+ class PaginatorTest < Test::Unit::TestCase
5
+
6
+ PER_PAGE = 10
7
+
8
+ def setup
9
+ @data = (0..43).to_a
10
+ @pager = Paginator.new(@data.size, PER_PAGE) do |offset,per_page|
11
+ @data[offset,per_page]
12
+ end
13
+ end
14
+
15
+ def test_initializing_paginator_raises_exception
16
+ assert_raises(Paginator::MissingSelectError) do
17
+ @pager = Paginator.new(@data.size, PER_PAGE)
18
+ end
19
+ end
20
+
21
+ def test_can_get_last_page_from_page_object
22
+ assert_equal @pager.last, @pager.page(2).last
23
+ end
24
+
25
+ def test_can_get_first_page_from_page_object
26
+ assert_equal @pager.first, @pager.page(2).first
27
+ end
28
+
29
+ def test_does_not_exceed_per_page
30
+ @pager.each do |page|
31
+ assert page.items.size <= PER_PAGE
32
+ end
33
+ end
34
+
35
+ def test_only_last_page_has_less_items
36
+ @pager.each do |page|
37
+ if page != @pager.last
38
+ assert page.items.size <= PER_PAGE
39
+ else
40
+ assert page.items.size < PER_PAGE
41
+ end
42
+ end
43
+ end
44
+
45
+ def test_returns_correct_first_page
46
+ assert_equal @pager.page(1).number, @pager.first.number
47
+ end
48
+
49
+ def test_returns_correct_last_page
50
+ assert_equal @pager.page(5).number, @pager.last.number
51
+ end
52
+
53
+ def test_last_page_has_no_next_page
54
+ assert !@pager.last.next?
55
+ assert !@pager.last.next
56
+ end
57
+
58
+ def test_first_page_has_no_prev_page
59
+ assert !@pager.first.prev?
60
+ assert !@pager.first.prev
61
+ end
62
+
63
+ def test_each
64
+ @pager.each do |page|
65
+ assert page
66
+ page.each do |item|
67
+ assert item
68
+ end
69
+ end
70
+ end
71
+
72
+ def test_number_of_pages
73
+ assert_equal 5, @pager.number_of_pages
74
+ end
75
+
76
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: paginator
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2006-10-23 00:00:00 -06:00
8
+ summary: A generic paginator object for use in any Ruby program
9
+ require_paths:
10
+ - lib
11
+ - test
12
+ email: ryand-ruby@zenspider.com
13
+ homepage: http://paginator.rubyforge.org
14
+ rubyforge_project: paginator
15
+ description: Paginator doesn't make any assumptions as to how data is retrieved; you just have to provide it with the total number of objects and a way to pull a specific set of objects based on the offset and number of objects per page.
16
+ autorequire:
17
+ default_executable:
18
+ bindir: bin
19
+ has_rdoc: true
20
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
21
+ requirements:
22
+ - - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ authors:
30
+ - Ryan Davis
31
+ files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - Rakefile
36
+ - bin/paginator
37
+ - lib/paginator.rb
38
+ - test/test_paginator.rb
39
+ test_files: []
40
+
41
+ rdoc_options: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ executables:
46
+ - paginator
47
+ extensions: []
48
+
49
+ requirements: []
50
+
51
+ dependencies:
52
+ - !ruby/object:Gem::Dependency
53
+ name: hoe
54
+ version_requirement:
55
+ version_requirements: !ruby/object:Gem::Version::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 1.1.2
60
+ version: