peiji-san 0.1.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.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright © 2009 Fingertips, Eloy Duran <eloy.de.enige@gmail.com>
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.rdoc ADDED
@@ -0,0 +1,22 @@
1
+ = Peiji-San
2
+
3
+ Peiji-San uses named scopes to create a thin pagination layer.
4
+
5
+ Model:
6
+
7
+ class Member < ActiveRecord::Base
8
+ extend PeijiSan
9
+ self.entries_per_page = 32
10
+ end
11
+
12
+ Controller:
13
+
14
+ @collection = Member.active.page(2)
15
+
16
+ View:
17
+
18
+ <% if @collection.page_count > 1 %>
19
+ <% pages_to_link_to(@collection).each do |page %>
20
+ <%= page.is_a?(String) ? page : link_to_page(page, @collection) %>
21
+ <% end %>
22
+ <% end %>
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |s|
7
+ s.name = "peiji-san"
8
+ s.homepage = "http://github.com/Fingertips/peiji-san"
9
+ s.email = "eloy.de.enige@gmail.com"
10
+ s.authors = ["Eloy Duran"]
11
+ s.summary = s.description = "PeijiSan is a Rails plugin which uses named scopes to create a thin pagination layer."
12
+ s.files = FileList['**/**'] # tmp until we've patched Jeweler to be able to easily add files to defaults
13
+ end
14
+ rescue LoadError
15
+ end
16
+
17
+ begin
18
+ require 'jewelry_portfolio/tasks'
19
+ JewelryPortfolio::Tasks.new do |p|
20
+ p.account = 'Fingertips'
21
+ end
22
+ rescue LoadError
23
+ end
24
+
25
+ require 'rake/rdoctask'
26
+ Rake::RDocTask.new do |rdoc|
27
+ rdoc.rdoc_dir = 'rdoc'
28
+ rdoc.title = 'PeijiSan'
29
+ rdoc.options << '--line-numbers' << '--inline-source' << '--charset=utf-8'
30
+ rdoc.rdoc_files.include('README*', 'LICENSE')
31
+ rdoc.rdoc_files.include('lib/**/*.rb')
32
+ end
33
+
34
+ require 'rake/testtask'
35
+ Rake::TestTask.new(:test) do |test|
36
+ test.libs << 'lib' << 'test'
37
+ test.pattern = 'test/**/*_test.rb'
38
+ test.verbose = false
39
+ end
40
+
41
+ task :default => :test
data/TODO ADDED
@@ -0,0 +1,2 @@
1
+ * Merge Scope and Array methods
2
+ * Make it possible to use this pattern: http://www.percona.com/ppc2009/PPC2009_mysql_pagination.pdf
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 1
4
+ :patch: 1
@@ -0,0 +1,103 @@
1
+ module PeijiSan
2
+ # Include this module into your view helper module, for instance
3
+ # ApplicationController, for super paginating cow powers.
4
+ #
5
+ # Optionally define the peiji_san_options method in your helper to override
6
+ # the default options.
7
+ #
8
+ # Example:
9
+ #
10
+ # @collection = Member.active.page(2)
11
+ #
12
+ # <% pages_to_link_to(@collection).each do |page %>
13
+ # <%= page.is_a?(String) ? page : link_to_page(page, @collection) %>
14
+ # <% end %>
15
+ module ViewHelper
16
+ # The default options for link_to_page and pages_to_link_to.
17
+ DEFAULT_PEIJI_SAN_OPTIONS = {
18
+ # For link_to_page
19
+ :page_parameter => :page,
20
+ :anchor => :explore,
21
+ :current_class => :current,
22
+ # For pages_to_link_to
23
+ :max_visible => 11,
24
+ :separator => '…'
25
+ }
26
+
27
+ # Override this method in your helper to override default values:
28
+ #
29
+ # def peiji_san_options
30
+ # { :max_visible => 7 }
31
+ # end
32
+ def peiji_san_options
33
+ end
34
+
35
+ # Creates a link using +link_to+ for a page in a pagination collection. If
36
+ # the specified page is the current page then its class will be `current'.
37
+ #
38
+ # Options:
39
+ # [:page_parameter]
40
+ # The name of the GET parameter used to indicate the page to display.
41
+ # Defaults to <tt>:page</tt>.
42
+ # [:current_class]
43
+ # The CSS class name used when a page is the current page in a pagination
44
+ # collection. Defaults to <tt>:current</tt>.
45
+ def link_to_page(page, paginated_set, options = {}, html_options = {})
46
+ page_parameter = peiji_san_option(:page_parameter, options)
47
+ url_options = (page == 1 ? controller.params.except(page_parameter) : controller.params.merge(page_parameter => page))
48
+ url_options[:anchor] = peiji_san_option(:anchor, options)
49
+ html_options[:class] = peiji_san_option(:current_class, options) if paginated_set.current_page?(page)
50
+ link_to page, url_for(url_options), html_options
51
+ end
52
+
53
+ # Returns an array of pages to link to. This array includes the separator, so
54
+ # make sure to keep this in mind when iterating over the array and creating
55
+ # links.
56
+ #
57
+ # For consistency’s sake, it is adviced to use an odd number for
58
+ # <tt>:max_visible</tt>.
59
+ #
60
+ # Options:
61
+ # [:max_visible]
62
+ # The maximum amount of elements in the array, this includes the
63
+ # separator(s). Defaults to 11.
64
+ # [:separator]
65
+ # The separator string used to indicate a range between the first or last
66
+ # page and the ones surrounding the current page.
67
+ #
68
+ # Example:
69
+ #
70
+ # collection = Model.all.page(40)
71
+ # collection.page_count # => 80
72
+ #
73
+ # pages_to_link_to(collection) # => [1, '…', 37, 38, 39, 40, 41, 42, 43, '…', 80]
74
+ def pages_to_link_to(paginated_set, options = {})
75
+ current, last = paginated_set.current_page, paginated_set.page_count
76
+ max = peiji_san_option(:max_visible, options)
77
+ separator = peiji_san_option(:separator, options)
78
+
79
+ if last <= max
80
+ (1..last).to_a
81
+ elsif current <= ((max / 2) + 1)
82
+ (1..(max - 2)).to_a + [separator, last]
83
+ elsif current >= (last - (max / 2))
84
+ [1, separator, *((last - (max - 3))..last)]
85
+ else
86
+ offset = (max - 4) / 2
87
+ [1, separator] + ((current - offset)..(current + offset)).to_a + [separator, last]
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def peiji_san_option(key, options)
94
+ if value = options[key]
95
+ value
96
+ elsif (user_options = peiji_san_options) && user_options[key]
97
+ user_options[key]
98
+ else
99
+ DEFAULT_PEIJI_SAN_OPTIONS[key]
100
+ end
101
+ end
102
+ end
103
+ end
data/lib/peiji_san.rb ADDED
@@ -0,0 +1,124 @@
1
+ # Peiji-San uses named scopes to create a thin pagination layer.
2
+ #
3
+ # Example:
4
+ #
5
+ # class Member < ActiveRecord::Base
6
+ # extend PeijiSan
7
+ # self.entries_per_page = 32
8
+ # end
9
+ #
10
+ # Now you can start scoping your queries by `page':
11
+ #
12
+ # Member.active.page(2)
13
+ #
14
+ # Which will return 32 records with an offset of 32, as that's the second page.
15
+ #
16
+ # See PeijiSan::PageScope and PeijiSan::ViewHelper for more info.
17
+ module PeijiSan
18
+ class PageScope < ActiveRecord::NamedScope::Scope
19
+ attr_reader :current_page
20
+
21
+ def initialize(proxy_scope, options)
22
+ @current_page = (options[:page].blank? ? 1 : options[:page]).to_i
23
+ @entries_per_page = options[:entries_per_page]
24
+ super(proxy_scope, :offset => ((@current_page - 1) * @entries_per_page), :limit => @entries_per_page)
25
+ end
26
+
27
+ # Returns whether or not the given page is the current page.
28
+ def current_page?(page)
29
+ @current_page == page
30
+ end
31
+
32
+ # Returns whether or not there is a next page for the current scope.
33
+ def has_next_page?
34
+ @current_page < page_count
35
+ end
36
+
37
+ # Returns whether or not there is a previous page for the current scope.
38
+ def has_previous_page?
39
+ @current_page != 1
40
+ end
41
+
42
+ # Returns the next page number if there is a next page, returns +nil+
43
+ # otherwise.
44
+ def next_page
45
+ @current_page + 1 if has_next_page?
46
+ end
47
+
48
+ # Returns the previous page number if there is a previous page, returns
49
+ # +nil+ otherwise.
50
+ def previous_page
51
+ @current_page - 1 if has_previous_page?
52
+ end
53
+
54
+ # Returns the row count for all the rows that would match the current
55
+ # scope, so not only on the current page.
56
+ def count
57
+ @proxy_scope.count
58
+ end
59
+
60
+ # Returns the number of pages for the current scope.
61
+ def page_count
62
+ (count.to_f / @entries_per_page).ceil
63
+ end
64
+ end
65
+
66
+ # Sets the number of entries you want per page.
67
+ #
68
+ # class Member < ActiveRecord::Base
69
+ # extend PeijiSan
70
+ # entries_per_page 32
71
+ # end
72
+ def entries_per_page=(entries)
73
+ @entries_per_page = entries
74
+ end
75
+
76
+ # Returns the number of entries you want per page.
77
+ #
78
+ # class Member < ActiveRecord::Base
79
+ # extend PeijiSan
80
+ # entries_per_page 32
81
+ # end
82
+ # Member.entries_per_page #=> 32
83
+ def entries_per_page
84
+ @entries_per_page
85
+ end
86
+
87
+ # Set the current scope to a given page number.
88
+ #
89
+ # Consider:
90
+ #
91
+ # class Member < ActiveRecord::Base
92
+ # extend PeijiSan
93
+ # entries_per_page 32
94
+ # end
95
+ #
96
+ # This adds <tt>{ :limit => 32, :offset => 0 }</tt> to the scope:
97
+ #
98
+ # Member.page(1)
99
+ #
100
+ # This adds <tt>{ :limit => 32, :offset => 31 }</tt> to the scope:
101
+ #
102
+ # Member.page(2)
103
+ #
104
+ # You can optionally override the entries_per_page setting by sepcifying a
105
+ # second argument:
106
+ #
107
+ # Member.page(2, 5) # Page 2, 5 entries
108
+ def page(page, entries_per_page = nil)
109
+ scopes[:page].call(self, page, entries_per_page)
110
+ end
111
+
112
+ # Defines the page named_scope when it extends a model class.
113
+ #
114
+ # Member.respond_to? :page # => false
115
+ #
116
+ # class Member < ActiveRecord::Base
117
+ # extend PeijiSan
118
+ # end
119
+ #
120
+ # Member.respond_to? :page # => true
121
+ def self.extended(klass)
122
+ klass.scopes[:page] = lambda { |parent_scope, *args| PageScope.new(parent_scope, :page => args[0], :entries_per_page => args[1] || klass.entries_per_page) }
123
+ end
124
+ end
data/peiji-san.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{peiji-san}
5
+ s.version = "0.1.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Eloy Duran"]
9
+ s.date = %q{2009-03-09}
10
+ s.description = %q{PeijiSan is a Rails plugin which uses named scopes to create a thin pagination layer.}
11
+ s.email = %q{eloy.de.enige@gmail.com}
12
+ s.extra_rdoc_files = ["README.rdoc", "LICENSE"]
13
+ s.files = ["lib", "lib/peiji_san", "lib/peiji_san/view_helper.rb", "lib/peiji_san.rb", "LICENSE", "peiji-san.gemspec", "rails", "rails/init.rb", "Rakefile", "README.rdoc", "test", "test/peiji_san_test.rb", "test/test_helper.rb", "test/view_helper_test.rb", "VERSION.yml"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/Fingertips/peiji-san}
16
+ s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
17
+ s.require_paths = ["lib"]
18
+ s.rubygems_version = %q{1.3.1}
19
+ s.summary = %q{PeijiSan is a Rails plugin which uses named scopes to create a thin pagination layer.}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 2
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'peiji_san'
2
+ require 'peiji_san/view_helper'
@@ -0,0 +1,109 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe "PeijiSan mixin" do
4
+ it "should define an #entries_per_page= class method with which the max amount of entries per page is specified" do
5
+ Member.should.respond_to :entries_per_page=
6
+ Member.instance_variable_get(:@entries_per_page).should.be 10
7
+ end
8
+
9
+ it "should define an #entries_per_page reader method" do
10
+ Member.entries_per_page.should == 10
11
+ end
12
+
13
+ it "should have defined a #page class method and added it to the class's scopes" do
14
+ Member.should.respond_to :page
15
+ end
16
+ end
17
+
18
+ describe "PeijiSan::PageScope" do
19
+ before do
20
+ PeijiSanTest::Initializer.setup_database
21
+ 199.times { |i| Member.create(:name => "KRS #{i}") }
22
+ end
23
+
24
+ after do
25
+ PeijiSanTest::Initializer.teardown_database
26
+ end
27
+
28
+ it "should have defined a named_scope called :page which returns the entries belonging to the page number given" do
29
+ page_1 = Member.page(1)
30
+ page_1.class.should.be PeijiSan::PageScope
31
+ page_1.length.should.be 10
32
+ page_1.should == Member.find(:all, :offset => 0, :limit => 10)
33
+ end
34
+
35
+ it "should return the correct count of pages for the current scope" do
36
+ Member.all_like_krs_1.page(1).page_count.should.be 11
37
+ end
38
+
39
+ it "should know the current page number" do
40
+ Member.page(2).current_page.should.be 2
41
+ Member.page(4).current_page.should.be 4
42
+ end
43
+
44
+ it "should know if there's a next page" do
45
+ Member.page(1).should.have_next_page
46
+ Member.page(20).should.not.have_next_page
47
+ Member.all_like_krs_1.but_ending_with_9.page(1).should.not.have_next_page
48
+ end
49
+
50
+ it "should return the next page" do
51
+ Member.page(1).next_page.should.be 2
52
+ Member.page(20).next_page.should.be nil
53
+ end
54
+
55
+ it "should know if there's a previous page" do
56
+ Member.page(1).should.not.have_previous_page
57
+ Member.page(20).should.have_previous_page
58
+ end
59
+
60
+ it "should return the previous page" do
61
+ Member.page(1).previous_page.should.be nil
62
+ Member.page(20).previous_page.should.be 19
63
+ end
64
+
65
+ it "should return if a given page number is the current page" do
66
+ assert Member.page(1).current_page?(1)
67
+ assert !Member.page(1).current_page?(2)
68
+ end
69
+
70
+ it "should default to page 1 if no valid page argument was given" do
71
+ Member.page(nil).current_page.should.be 1
72
+ Member.page('').current_page.should.be 1
73
+ end
74
+
75
+ it "should cast the page argument to an integer" do
76
+ Member.page('2').current_page.should.be 2
77
+ end
78
+
79
+ it "should take an optional second argument which overrides the entries_per_page setting" do
80
+ Member.all_like_krs_1.page(1, 20).page_count.should.be 6
81
+ end
82
+
83
+ it "should return the count of all the entries across all pages for the current scope" do
84
+ Member.all_like_krs_1.page(1).count.should.be 110
85
+ Member.all_like_krs_1.page(2).count.should.be 110
86
+ Member.all_like_krs_1.but_ending_with_9.page(1).count.should.be 10
87
+ end
88
+
89
+ it "should still work when chained with other regular named scopes" do
90
+ Member.all_like_krs_1.page(1).page_count.should.be 11
91
+ Member.all_like_krs_1.but_ending_with_9.page(2).page_count.should.be 1
92
+
93
+ Member.all_like_krs_1.page(2).should == Member.find(:all, :conditions => "name LIKE 'KRS 1%'", :offset => 10, :limit => 10)
94
+ Member.all_like_krs_1.but_ending_with_9.page(1).should == Member.find(:all, :conditions => "name LIKE 'KRS 1%' AND name LIKE '%9'", :offset => 0, :limit => 10)
95
+ end
96
+
97
+ it "should still work when chained through an association proxy" do
98
+ member = Member.first
99
+ 16.times { member.works.create(:status => 'uploaded') }
100
+ 5.times { member.works.create(:status => 'new') }
101
+
102
+ page = member.reload.works.uploaded.page(1)
103
+ page.length.should.be 5
104
+ page.page_count.should.be 4
105
+ member.works.uploaded.page(4).length.should.be 1
106
+
107
+ member.works.page(1).page_count.should.be 5
108
+ end
109
+ end
@@ -0,0 +1,95 @@
1
+ module PeijiSanTest
2
+ module Initializer
3
+ VENDOR_RAILS = File.expand_path('../../../../rails', __FILE__)
4
+ OTHER_RAILS = File.expand_path('../../../rails', __FILE__)
5
+ PLUGIN_ROOT = File.expand_path('../../', __FILE__)
6
+
7
+ def self.rails_directory
8
+ if File.exist?(File.join(VENDOR_RAILS, 'railties'))
9
+ VENDOR_RAILS
10
+ elsif File.exist?(File.join(OTHER_RAILS, 'railties'))
11
+ OTHER_RAILS
12
+ end
13
+ end
14
+
15
+ def self.load_dependencies
16
+ if rails_directory
17
+ $:.unshift(File.join(rails_directory, 'activesupport', 'lib'))
18
+ $:.unshift(File.join(rails_directory, 'activerecord', 'lib'))
19
+ $:.unshift(File.join(rails_directory, 'actionpack', 'lib'))
20
+ else
21
+ require 'rubygems' rescue LoadError
22
+ end
23
+
24
+ require 'active_support'
25
+ require 'active_record'
26
+ require 'action_view'
27
+
28
+ require 'rubygems' rescue LoadError
29
+
30
+ require 'test/spec'
31
+ require 'mocha'
32
+
33
+ require File.join(PLUGIN_ROOT, 'rails', 'init')
34
+ end
35
+
36
+ def self.configure_database
37
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
38
+ ActiveRecord::Migration.verbose = false
39
+ end
40
+
41
+ def self.setup_database
42
+ ActiveRecord::Schema.define(:version => 1) do
43
+ create_table :members do |t|
44
+ t.column :name, :string
45
+ t.column :created_at, :datetime
46
+ t.column :updated_at, :datetime
47
+ end
48
+
49
+ create_table :works do |t|
50
+ t.column :member_id, :integer
51
+ t.column :status, :string
52
+ end
53
+ end
54
+ end
55
+
56
+ def self.teardown_database
57
+ ActiveRecord::Base.connection.tables.each do |table|
58
+ ActiveRecord::Base.connection.drop_table(table)
59
+ end
60
+ end
61
+
62
+ def self.start
63
+ load_dependencies
64
+ configure_database
65
+ end
66
+ end
67
+ end
68
+
69
+ PeijiSanTest::Initializer.start
70
+
71
+ class PeijiSan::PageScope
72
+ instance_methods.each { |method| alias_method method.sub(/^has_/, 'have_'), method if method =~ /^has_/ }
73
+
74
+ # The delegation of all methods in NamedScope breaks #should.
75
+ def should
76
+ Test::Spec::Should.new(self)
77
+ end
78
+ end
79
+
80
+ class Member < ActiveRecord::Base
81
+ extend PeijiSan
82
+ self.entries_per_page = 10
83
+
84
+ named_scope :all_like_krs_1, :conditions => "name LIKE 'KRS 1%'"
85
+ named_scope :but_ending_with_9, :conditions => "name LIKE '%9'"
86
+
87
+ has_many :works
88
+ end
89
+
90
+ class Work < ActiveRecord::Base
91
+ extend PeijiSan
92
+ self.entries_per_page = 5
93
+
94
+ named_scope :uploaded, :conditions => { :status => 'uploaded' }
95
+ end
@@ -0,0 +1,168 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class TestController
4
+ def params
5
+ @params ||= {}
6
+ end
7
+
8
+ def url_for(options)
9
+ url = "/collections"
10
+ url += "?page=#{options[:page]}" if options[:page]
11
+ url += "?pagina=#{options[:pagina]}" if options[:pagina]
12
+ url += "&starts_with=#{options[:starts_with]}" if options[:starts_with]
13
+ url += "##{options[:anchor]}" if options[:anchor]
14
+ url
15
+ end
16
+ end
17
+
18
+ module PeijiSanHelperTestHelper
19
+ def self.included(klass)
20
+ klass.class_eval do
21
+ include ActionView::Helpers
22
+
23
+ attr_reader :controller
24
+ attr_reader :collection
25
+
26
+ before do
27
+ @controller = TestController.new
28
+
29
+ @collection = stub('Artists paginated collection')
30
+ collection.stubs(:current_page?).with(1).returns(false)
31
+ collection.stubs(:current_page?).with(2).returns(false)
32
+ collection.stubs(:page_count).returns(125)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "PeijiSan::ViewHelper::link_to_page" do
39
+ include PeijiSanHelperTestHelper
40
+ include PeijiSan::ViewHelper
41
+
42
+ it "should return a link for a given page number" do
43
+ link_to_page(2, collection).should == '<a href="/collections?page=2#explore">2</a>'
44
+ end
45
+
46
+ it "should return a link for a given page number with the specified page parameter" do
47
+ link_to_page(2, collection, :page_parameter => 'pagina').should == '<a href="/collections?pagina=2#explore">2</a>'
48
+ end
49
+
50
+ it "should return a link for a given page number with the specified anchor" do
51
+ link_to_page(2, collection, :anchor => 'dude_so_many_pages').should == '<a href="/collections?page=2#dude_so_many_pages">2</a>'
52
+ end
53
+
54
+ it "should return a link for a given page number and include the original params" do
55
+ controller.params[:starts_with] = 'h'
56
+ link_to_page(2, collection).should == '<a href="/collections?page=2&amp;starts_with=h#explore">2</a>'
57
+ end
58
+
59
+ it "should return a link which does not include the page GET variable if it's page number 1" do
60
+ controller.params[:page] = 34
61
+ link_to_page(1, collection).should.not.match /page=\d+/
62
+ end
63
+
64
+ it "should return a link with the class current if it's for the currently selected page" do
65
+ collection.stubs(:current_page?).with(2).returns(true)
66
+ link_to_page(2, collection).should == '<a href="/collections?page=2#explore" class="current">2</a>'
67
+ end
68
+
69
+ it "should return a link with the class current if it's for the currently selected page" do
70
+ collection.stubs(:current_page?).with(2).returns(true)
71
+ link_to_page(2, collection, :current_class => 'looking_at').should == '<a href="/collections?page=2#explore" class="looking_at">2</a>'
72
+ end
73
+ end
74
+
75
+ describe "PeijiSan::ViewHelper::pages_to_link_to" do
76
+ include PeijiSanHelperTestHelper
77
+ include PeijiSan::ViewHelper
78
+
79
+ it "should return a list of page numbers that should be included in the pagination list" do
80
+ collection.stubs(:current_page).returns(83)
81
+ pages_to_link_to(collection).should == [1, '…', 80, 81, 82, 83, 84, 85, 86, '…', 125]
82
+ end
83
+
84
+ it "should return a list of page links with an ellips between page 1 and the next if the current page is at the end of the list" do
85
+ collection.stubs(:current_page).returns(119)
86
+ pages_to_link_to(collection).should == [1, '…', 116, 117, 118, 119, 120, 121, 122, '…', 125]
87
+
88
+ 120.upto(124) do |page|
89
+ collection.stubs(:current_page).returns(page)
90
+ pages_to_link_to(collection).should == [1, '…', 117, 118, 119, 120, 121, 122, 123, 124, 125]
91
+ end
92
+ end
93
+
94
+ it "should return a list of page links with an ellips between the last page and the previous one if the current page is at the beginning of the list" do
95
+ 1.upto(6) do |page|
96
+ collection.stubs(:current_page).returns(page)
97
+ pages_to_link_to(collection).should == [1, 2, 3, 4, 5, 6, 7, 8, 9, '…', 125]
98
+ end
99
+
100
+ collection.stubs(:current_page).returns(7)
101
+ pages_to_link_to(collection).should == [1, '…', 4, 5, 6, 7, 8, 9, 10, '…', 125]
102
+ end
103
+
104
+ it "should not show an ellips but all pages if there are only 10 pages, this is the threshold for when an ellips starts to be necessary" do
105
+ collection.stubs(:page_count).returns(10)
106
+ collection.stubs(:current_page).returns(5)
107
+ pages_to_link_to(collection).should == (1..10).to_a
108
+ end
109
+
110
+ it "should not return more page links if there aren't that many pages" do
111
+ 1.upto(9) do |page|
112
+ collection.stubs(:page_count).returns(page)
113
+ collection.stubs(:current_page).returns(page)
114
+ pages_to_link_to(collection).should == (1..page).to_a
115
+ end
116
+ end
117
+
118
+ it "should return a list of page numbers that should be included in the pagination list with the specified number of :max_visible" do
119
+ collection.stubs(:current_page).returns(83)
120
+ pages_to_link_to(collection, :max_visible => 5).should == [1, '…', 83, '…', 125]
121
+ pages_to_link_to(collection, :max_visible => 15).should == [1, '…', 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, '…', 125]
122
+
123
+ collection.stubs(:current_page).returns(3)
124
+ pages_to_link_to(collection, :max_visible => 5).should == [1, 2, 3, '…', 125]
125
+ pages_to_link_to(collection, :max_visible => 15).should == (1..13).to_a + ['…', 125]
126
+ end
127
+
128
+ it "should return a list of page numbers with the specified separator instead of the default ellips" do
129
+ collection.stubs(:current_page).returns(83)
130
+ pages_to_link_to(collection, :separator => '...').should == [1, '...', 80, 81, 82, 83, 84, 85, 86, '...', 125]
131
+ end
132
+ end
133
+
134
+ module ApplicationHelperWithDefaults
135
+ include PeijiSan::ViewHelper
136
+
137
+ def peiji_san_options
138
+ { :page_parameter => 'pagina', :anchor => 'dude_so_many_pages', :max_visible => 5, :separator => '...' }
139
+ end
140
+ end
141
+
142
+ describe "ApplicationHelper, when overriding defaults" do
143
+ include PeijiSanHelperTestHelper
144
+ include ApplicationHelperWithDefaults
145
+
146
+ it "should return a link for a given page number with the specified page parameter" do
147
+ link_to_page(2, collection).should == '<a href="/collections?pagina=2#dude_so_many_pages">2</a>'
148
+ end
149
+
150
+ it "should return a link for a given page number with the specified anchor" do
151
+ link_to_page(2, collection).should == '<a href="/collections?pagina=2#dude_so_many_pages">2</a>'
152
+ end
153
+
154
+ it "should return a link with the class current if it's for the currently selected page" do
155
+ collection.stubs(:current_page?).with(2).returns(true)
156
+ link_to_page(2, collection, :current_class => 'looking_at').should == '<a href="/collections?pagina=2#dude_so_many_pages" class="looking_at">2</a>'
157
+ end
158
+
159
+ it "should return a list of page numbers that should be included in the pagination list with the specified number of :max_visible" do
160
+ collection.stubs(:current_page).returns(3)
161
+ pages_to_link_to(collection).should == [1, 2, 3, '...', 125]
162
+ end
163
+
164
+ it "should return a list of page numbers with the specified separator instead of the default ellips" do
165
+ collection.stubs(:current_page).returns(83)
166
+ pages_to_link_to(collection).should == [1, '...', 83, '...', 125]
167
+ end
168
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: peiji-san
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Eloy Duran
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-22 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: PeijiSan is a Rails plugin which uses named scopes to create a thin pagination layer.
17
+ email: eloy.de.enige@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.rdoc
25
+ files:
26
+ - LICENSE
27
+ - README.rdoc
28
+ - Rakefile
29
+ - TODO
30
+ - VERSION.yml
31
+ - lib/peiji_san.rb
32
+ - lib/peiji_san/view_helper.rb
33
+ - peiji-san.gemspec
34
+ - rails/init.rb
35
+ - test/peiji_san_test.rb
36
+ - test/test_helper.rb
37
+ - test/view_helper_test.rb
38
+ has_rdoc: true
39
+ homepage: http://github.com/Fingertips/peiji-san
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options:
44
+ - --charset=UTF-8
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.5
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: PeijiSan is a Rails plugin which uses named scopes to create a thin pagination layer.
66
+ test_files:
67
+ - test/peiji_san_test.rb
68
+ - test/test_helper.rb
69
+ - test/view_helper_test.rb