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 +20 -0
- data/README.rdoc +22 -0
- data/Rakefile +41 -0
- data/TODO +2 -0
- data/VERSION.yml +4 -0
- data/lib/peiji_san/view_helper.rb +103 -0
- data/lib/peiji_san.rb +124 -0
- data/peiji-san.gemspec +30 -0
- data/rails/init.rb +2 -0
- data/test/peiji_san_test.rb +109 -0
- data/test/test_helper.rb +95 -0
- data/test/view_helper_test.rb +168 -0
- metadata +69 -0
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
data/VERSION.yml
ADDED
@@ -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,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
|
data/test/test_helper.rb
ADDED
@@ -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&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
|