mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-27 01:24:07 +01:00
Upgraded to Rails 2.1. This can have wide ranging consequences, so please help track down any issues introduced by the upgrade. Requires environment.rb modifications.
Changes you will need to make: * In your environment.rb, you will need to update references to a few files per environment.rb.tmpl * In your environment.rb, you will need to specify the local time zone of the computer that is running your Tracks install. Other notes on my changes: * Modified our code to take advantage of Rails 2.1's slick time zone support. * Upgraded will_paginate for compatibility * Hacked the Selenium on Rails plugin, which has not been updated in some time and does not support Rails 2.1 * Verified that all tests pass on my machine, including Selenium tests -- I'd like confirmation from others, too.
This commit is contained in:
parent
f3bae73868
commit
901a58f8a3
1086 changed files with 51452 additions and 19526 deletions
2
vendor/plugins/selenium-on-rails/init.rb
vendored
2
vendor/plugins/selenium-on-rails/init.rb
vendored
|
|
@ -7,6 +7,8 @@ if envs.include? RAILS_ENV
|
|||
require 'selenium_controller'
|
||||
require File.dirname(__FILE__) + '/routes'
|
||||
|
||||
SeleniumController.prepend_view_path File.expand_path(File.dirname(__FILE__) + '/lib/views')
|
||||
|
||||
else
|
||||
#erase all traces
|
||||
$LOAD_PATH.delete lib_path
|
||||
|
|
|
|||
|
|
@ -13,13 +13,8 @@ module SeleniumOnRails
|
|||
File.expand_path(File.dirname(__FILE__) + '/../views/' + view)
|
||||
end
|
||||
|
||||
# Returns the path to the layout template. The path is relative in relation
|
||||
# to the app/views/ directory since Rails doesn't support absolute paths
|
||||
# to layout templates.
|
||||
def layout_path
|
||||
rails_root = Pathname.new File.expand_path(File.join(RAILS_ROOT, 'app/views'))
|
||||
view_path = Pathname.new view_path('layout')
|
||||
view_path.relative_path_from(rails_root).to_s
|
||||
'/layout.rhtml'
|
||||
end
|
||||
|
||||
def fixtures_path
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
# See SeleniumOnRails::TestBuilder for a list of available commands.
|
||||
class SeleniumOnRails::RSelenese < SeleniumOnRails::TestBuilder
|
||||
end
|
||||
ActionView::Base.register_template_handler 'rsel', SeleniumOnRails::RSelenese
|
||||
ActionView::Template.register_template_handler 'rsel', SeleniumOnRails::RSelenese
|
||||
|
||||
class SeleniumOnRails::RSelenese < SeleniumOnRails::TestBuilder
|
||||
attr_accessor :view
|
||||
|
|
@ -20,16 +20,16 @@ class SeleniumOnRails::RSelenese < SeleniumOnRails::TestBuilder
|
|||
end
|
||||
|
||||
# Render _template_ using _local_assigns_.
|
||||
def render template, local_assigns
|
||||
title = (@view.assigns['page_title'] or local_assigns['page_title'])
|
||||
def render template
|
||||
title = @view.assigns['page_title']
|
||||
table(title) do
|
||||
test = self #to enable test.command
|
||||
|
||||
assign_locals_code = ''
|
||||
local_assigns.each_key {|key| assign_locals_code << "#{key} = local_assigns[#{key.inspect}];"}
|
||||
|
||||
eval assign_locals_code + "\n" + template
|
||||
eval template.source
|
||||
end
|
||||
end
|
||||
|
||||
def compilable?
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
class SeleniumOnRails::Selenese
|
||||
end
|
||||
ActionView::Base.register_template_handler 'sel', SeleniumOnRails::Selenese
|
||||
ActionView::Template.register_template_handler 'sel', SeleniumOnRails::Selenese
|
||||
|
||||
|
||||
class SeleniumOnRails::Selenese
|
||||
|
|
@ -8,8 +8,8 @@ class SeleniumOnRails::Selenese
|
|||
@view = view
|
||||
end
|
||||
|
||||
def render template, local_assigns
|
||||
name = (@view.assigns['page_title'] or local_assigns['page_title'])
|
||||
def render template
|
||||
name = @view.assigns['page_title']
|
||||
lines = template.strip.split "\n"
|
||||
html = ''
|
||||
html << extract_comments(lines)
|
||||
|
|
@ -18,6 +18,10 @@ class SeleniumOnRails::Selenese
|
|||
raise 'You cannot have comments in the middle of commands!' if next_line lines, :any
|
||||
html
|
||||
end
|
||||
|
||||
def compilable?
|
||||
false
|
||||
end
|
||||
|
||||
private
|
||||
def next_line lines, expects
|
||||
|
|
|
|||
4
vendor/plugins/will_paginate/.gitignore
vendored
4
vendor/plugins/will_paginate/.gitignore
vendored
|
|
@ -1,2 +1,4 @@
|
|||
/pkg
|
||||
/doc
|
||||
/rails
|
||||
*.gem
|
||||
/coverage
|
||||
|
|
|
|||
49
vendor/plugins/will_paginate/.manifest
vendored
Normal file
49
vendor/plugins/will_paginate/.manifest
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
CHANGELOG
|
||||
LICENSE
|
||||
README.rdoc
|
||||
Rakefile
|
||||
examples
|
||||
examples/apple-circle.gif
|
||||
examples/index.haml
|
||||
examples/index.html
|
||||
examples/pagination.css
|
||||
examples/pagination.sass
|
||||
init.rb
|
||||
lib
|
||||
lib/will_paginate
|
||||
lib/will_paginate.rb
|
||||
lib/will_paginate/array.rb
|
||||
lib/will_paginate/collection.rb
|
||||
lib/will_paginate/core_ext.rb
|
||||
lib/will_paginate/finder.rb
|
||||
lib/will_paginate/named_scope.rb
|
||||
lib/will_paginate/named_scope_patch.rb
|
||||
lib/will_paginate/version.rb
|
||||
lib/will_paginate/view_helpers.rb
|
||||
test
|
||||
test/boot.rb
|
||||
test/collection_test.rb
|
||||
test/console
|
||||
test/database.yml
|
||||
test/finder_test.rb
|
||||
test/fixtures
|
||||
test/fixtures/admin.rb
|
||||
test/fixtures/developer.rb
|
||||
test/fixtures/developers_projects.yml
|
||||
test/fixtures/project.rb
|
||||
test/fixtures/projects.yml
|
||||
test/fixtures/replies.yml
|
||||
test/fixtures/reply.rb
|
||||
test/fixtures/schema.rb
|
||||
test/fixtures/topic.rb
|
||||
test/fixtures/topics.yml
|
||||
test/fixtures/user.rb
|
||||
test/fixtures/users.yml
|
||||
test/helper.rb
|
||||
test/lib
|
||||
test/lib/activerecord_test_case.rb
|
||||
test/lib/activerecord_test_connector.rb
|
||||
test/lib/load_fixtures.rb
|
||||
test/lib/view_test_process.rb
|
||||
test/tasks.rake
|
||||
test/view_test.rb
|
||||
92
vendor/plugins/will_paginate/CHANGELOG
vendored
Normal file
92
vendor/plugins/will_paginate/CHANGELOG
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
== master
|
||||
|
||||
* ActiveRecord 2.1: remove :include from count query when tables are not
|
||||
referenced in :conditions
|
||||
|
||||
== 2.3.2, released 2008-05-16
|
||||
|
||||
* Fixed LinkRenderer#stringified_merge by removing "return" from iterator block
|
||||
* Ensure that 'href' values in pagination links are escaped URLs
|
||||
|
||||
== 2.3.1, released 2008-05-04
|
||||
|
||||
* Fixed page numbers not showing with custom routes and implicit first page
|
||||
* Try to use Hanna for documentation (falls back to default RDoc template if not)
|
||||
|
||||
== 2.3.0, released 2008-04-29
|
||||
|
||||
* Changed LinkRenderer to receive collection, options and reference to view template NOT in
|
||||
constructor, but with the #prepare method. This is a step towards supporting passing of
|
||||
LinkRenderer (or subclass) instances that may be preconfigured in some way
|
||||
* LinkRenderer now has #page_link and #page_span methods for easier customization of output in
|
||||
subclasses
|
||||
* Changed page_entries_info() method to adjust its output according to humanized class name of
|
||||
collection items. Override this with :entry_name parameter (singular).
|
||||
|
||||
page_entries_info(@posts)
|
||||
#-> "Displaying all 12 posts"
|
||||
page_entries_info(@posts, :entry_name => 'item')
|
||||
#-> "Displaying all 12 items"
|
||||
|
||||
== 2.2.3, released 2008-04-26
|
||||
|
||||
* will_paginate gem is no longer published on RubyForge, but on
|
||||
gems.github.com:
|
||||
|
||||
gem sources -a http://gems.github.com/ (you only need to do this once)
|
||||
gem install mislav-will_paginate
|
||||
|
||||
* extract reusable pagination testing stuff into WillPaginate::View
|
||||
* rethink the page URL construction mechanizm to be more bulletproof when
|
||||
combined with custom routing for page parameter
|
||||
* test that anchor parameter can be used in pagination links
|
||||
|
||||
== 2.2.2, released 2008-04-21
|
||||
|
||||
* Add support for page parameter in custom routes like "/foo/page/2"
|
||||
* Change output of "page_entries_info" on single-page collection and erraneous
|
||||
output with empty collection as reported by Tim Chater
|
||||
|
||||
== 2.2.1, released 2008-04-08
|
||||
|
||||
* take less risky path when monkeypatching named_scope; fix that it no longer
|
||||
requires ActiveRecord::VERSION
|
||||
* use strings in "respond_to?" calls to work around a bug in acts_as_ferret
|
||||
stable (ugh)
|
||||
* add rake release task
|
||||
|
||||
|
||||
== 2.2.0, released 2008-04-07
|
||||
|
||||
=== API changes
|
||||
* Rename WillPaginate::Collection#page_count to "total_pages" for consistency.
|
||||
If you implemented this interface, change your implementation accordingly.
|
||||
* Remove old, deprecated style of calling Array#paginate as "paginate(page,
|
||||
per_page)". If you want to specify :page, :per_page or :total_entries, use a
|
||||
parameter hash.
|
||||
* Rename LinkRenderer#url_options to "url_for" and drastically optimize it
|
||||
|
||||
=== View changes
|
||||
* Added "prev_page" and "next_page" CSS classes on previous/next page buttons
|
||||
* Add examples of pagination links styling in "examples/index.html"
|
||||
* Change gap in pagination links from "..." to
|
||||
"<span class="gap">…</span>".
|
||||
* Add "paginated_section", a block helper that renders pagination both above and
|
||||
below content in the block
|
||||
* Add rel="prev|next|start" to page links
|
||||
|
||||
=== Other
|
||||
|
||||
* Add ability to opt-in for Rails 2.1 feature "named_scope" by calling
|
||||
WillPaginate.enable_named_scope (tested in Rails 1.2.6 and 2.0.2)
|
||||
* Support complex page parameters like "developers[page]"
|
||||
* Move Array#paginate definition to will_paginate/array.rb. You can now easily
|
||||
use pagination on arrays outside of Rails:
|
||||
|
||||
gem 'will_paginate'
|
||||
require 'will_paginate/array'
|
||||
|
||||
* Add "paginated_each" method for iterating through every record by loading only
|
||||
one page of records at the time
|
||||
* Rails 2: Rescue from WillPaginate::InvalidPage error with 404 Not Found by
|
||||
default
|
||||
180
vendor/plugins/will_paginate/README
vendored
180
vendor/plugins/will_paginate/README
vendored
|
|
@ -1,180 +0,0 @@
|
|||
= WillPaginate
|
||||
|
||||
Pagination is just limiting the number of records displayed. Why should you let
|
||||
it get in your way while developing, then? This plugin makes magic happen. Did
|
||||
you ever want to be able to do just this on a model:
|
||||
|
||||
Post.paginate :page => 1, :order => 'created_at DESC'
|
||||
|
||||
... and then render the page links with a single view helper? Well, now you
|
||||
can.
|
||||
|
||||
Ryan Bates made an awesome screencast[http://railscasts.com/episodes/51],
|
||||
check it out.
|
||||
|
||||
Your mind reels with questions? Join our Google
|
||||
group[http://groups.google.com/group/will_paginate].
|
||||
|
||||
== Installation
|
||||
|
||||
Will Paginate officially supports Rails versions 1.2.6 and 2.0.x.
|
||||
|
||||
Previously, the plugin was available on the following SVN location:
|
||||
|
||||
svn://errtheblog.com/svn/plugins/will_paginate
|
||||
|
||||
In February 2008, it moved to GitHub[http://github.com/mislav/will_paginate/tree]
|
||||
to be tracked with git. The SVN repo continued to have updates, but not
|
||||
forever. Therefore you should switch to using the gem:
|
||||
|
||||
gem install will_paginate --no-ri
|
||||
|
||||
After that, you can remove the plugin from your applications and add
|
||||
a simple require to the end of config/environment.rb:
|
||||
|
||||
require 'will_paginate'
|
||||
|
||||
That's it, just remember to install the gem on all machines that
|
||||
you are deploying to.
|
||||
|
||||
The second option is to download and extract the tarball from GitHub. Here is the
|
||||
link for downloading the current state of the master branch:
|
||||
http://github.com/mislav/will_paginate/tarball/master
|
||||
|
||||
Extract it to <tt>vendor/plugins</tt>. The directory will have a default name
|
||||
like "mislav-will_paginate-master"; you can rename it to "will_paginate" for
|
||||
simplicity.
|
||||
|
||||
== Example usage
|
||||
|
||||
Use a paginate finder in the controller:
|
||||
|
||||
@posts = Post.paginate_by_board_id @board.id, :page => params[:page], :order => 'updated_at DESC'
|
||||
|
||||
Yeah, +paginate+ works just like +find+ -- it just doesn't fetch all the
|
||||
records. Don't forget to tell it which page you want, or it will complain!
|
||||
Read more on WillPaginate::Finder::ClassMethods.
|
||||
|
||||
Render the posts in your view like you would normally do. When you need to render
|
||||
pagination, just stick this in:
|
||||
|
||||
<%= will_paginate @posts %>
|
||||
|
||||
You're done. (Copy and paste the example fancy CSS styles from the bottom.) You
|
||||
can find the option list at WillPaginate::ViewHelpers.
|
||||
|
||||
How does it know how much items to fetch per page? It asks your model by calling
|
||||
its <tt>per_page</tt> class method. You can define it like this:
|
||||
|
||||
class Post < ActiveRecord::Base
|
||||
cattr_reader :per_page
|
||||
@@per_page = 50
|
||||
end
|
||||
|
||||
... or like this:
|
||||
|
||||
class Post < ActiveRecord::Base
|
||||
def self.per_page
|
||||
50
|
||||
end
|
||||
end
|
||||
|
||||
... or don't worry about it at all. WillPaginate defines it to be <b>30</b> by default.
|
||||
But you can always specify the count explicitly when calling +paginate+:
|
||||
|
||||
@posts = Post.paginate :page => params[:page], :per_page => 50
|
||||
|
||||
The +paginate+ finder wraps the original finder and returns your resultset that now has
|
||||
some new properties. You can use the collection as you would with any ActiveRecord
|
||||
resultset. WillPaginate view helpers also need that object to be able to render pagination:
|
||||
|
||||
<ol>
|
||||
<% for post in @posts -%>
|
||||
<li>Render `post` in some nice way.</li>
|
||||
<% end -%>
|
||||
</ol>
|
||||
|
||||
<p>Now let's render us some pagination!</p>
|
||||
<%= will_paginate @posts %>
|
||||
|
||||
More detailed documentation:
|
||||
|
||||
* WillPaginate::Finder::ClassMethods for pagination on your models;
|
||||
* WillPaginate::ViewHelpers for your views.
|
||||
|
||||
== Oh noes, a bug!
|
||||
|
||||
Tell us what happened so we can fix it, quick! Issues are filed on the Lighthouse project:
|
||||
http://err.lighthouseapp.com/projects/466-plugins/tickets?q=tagged:will_paginate
|
||||
|
||||
Steps to make an awesome bug report:
|
||||
|
||||
1. Run <tt>rake test</tt> in the <i>will_paginate</i> directory. (You will need SQLite3.)
|
||||
Copy the output if there are failing tests.
|
||||
2. Register on Lighthouse to create a new ticket.
|
||||
3. Write a descriptive, short title. Provide as much info as you can in the body.
|
||||
Assign the ticket to Mislav and tag it with meaningful tags, <tt>"will_paginate"</tt>
|
||||
being among them.
|
||||
4. Yay! You will be notified on updates automatically.
|
||||
|
||||
Here is an example of a great bug report and patch:
|
||||
http://err.lighthouseapp.com/projects/466/tickets/172-total_entries-ignored-in-paginate_by_sql
|
||||
|
||||
== Authors, credits, contact
|
||||
|
||||
Want to discuss, request features, ask questions? Join the Google group:
|
||||
http://groups.google.com/group/will_paginate
|
||||
|
||||
Authors:: Mislav Marohnić, PJ Hyett
|
||||
Original announcement:: http://errtheblog.com/post/929
|
||||
Original PHP source:: http://www.strangerstudios.com/sandbox/pagination/diggstyle.php
|
||||
|
||||
All these people helped making will_paginate what it is now with their code
|
||||
contributions or simply awesome ideas:
|
||||
|
||||
Chris Wanstrath, Dr. Nic Williams, K. Adam Christensen, Mike Garey, Bence
|
||||
Golda, Matt Aimonetti, Charles Brian Quinn, Desi McAdam, James Coglan, Matijs
|
||||
van Zuijlen, Maria, Brendan Ribera, Todd Willey, Bryan Helmkamp, Jan Berkel.
|
||||
|
||||
== Usable pagination in the UI
|
||||
|
||||
Copy the following CSS into your stylesheet for a good start:
|
||||
|
||||
.pagination {
|
||||
padding: 3px;
|
||||
margin: 3px;
|
||||
}
|
||||
.pagination a {
|
||||
padding: 2px 5px 2px 5px;
|
||||
margin: 2px;
|
||||
border: 1px solid #aaaadd;
|
||||
text-decoration: none;
|
||||
color: #000099;
|
||||
}
|
||||
.pagination a:hover, .pagination a:active {
|
||||
border: 1px solid #000099;
|
||||
color: #000;
|
||||
}
|
||||
.pagination span.current {
|
||||
padding: 2px 5px 2px 5px;
|
||||
margin: 2px;
|
||||
border: 1px solid #000099;
|
||||
font-weight: bold;
|
||||
background-color: #000099;
|
||||
color: #FFF;
|
||||
}
|
||||
.pagination span.disabled {
|
||||
padding: 2px 5px 2px 5px;
|
||||
margin: 2px;
|
||||
border: 1px solid #eee;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
More reading about pagination as design pattern:
|
||||
|
||||
* Pagination 101:
|
||||
http://kurafire.net/log/archive/2007/06/22/pagination-101
|
||||
* Pagination gallery:
|
||||
http://www.smashingmagazine.com/2007/11/16/pagination-gallery-examples-and-good-practices/
|
||||
* Pagination on Yahoo Design Pattern Library:
|
||||
http://developer.yahoo.com/ypatterns/parent.php?pattern=pagination
|
||||
131
vendor/plugins/will_paginate/README.rdoc
vendored
Normal file
131
vendor/plugins/will_paginate/README.rdoc
vendored
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
= WillPaginate
|
||||
|
||||
Pagination is just limiting the number of records displayed. Why should you let
|
||||
it get in your way while developing, then? This plugin makes magic happen. Did
|
||||
you ever want to be able to do just this on a model:
|
||||
|
||||
Post.paginate :page => 1, :order => 'created_at DESC'
|
||||
|
||||
... and then render the page links with a single view helper? Well, now you
|
||||
can.
|
||||
|
||||
Some resources to get you started:
|
||||
|
||||
* Your mind reels with questions? Join our
|
||||
{Google group}[http://groups.google.com/group/will_paginate].
|
||||
* The will_paginate project page: http://github.com/mislav/will_paginate
|
||||
* How to report bugs: http://github.com/mislav/will_paginate/wikis/report-bugs
|
||||
* Ryan Bates made an awesome screencast[http://railscasts.com/episodes/51],
|
||||
check it out.
|
||||
|
||||
== Installation
|
||||
|
||||
The recommended way is that you get the gem:
|
||||
|
||||
gem install mislav-will_paginate --source http://gems.github.com/
|
||||
|
||||
After that you don't need the will_paginate <i>plugin</i> in your Rails
|
||||
application anymore. Just add a simple require to the end of
|
||||
"config/environment.rb":
|
||||
|
||||
gem 'mislav-will_paginate', '~> 2.2'
|
||||
require 'will_paginate'
|
||||
|
||||
That's it. Remember to install the gem on <b>all</b> machines that you are
|
||||
deploying to.
|
||||
|
||||
<i>There are extensive
|
||||
{installation instructions}[http://github.com/mislav/will_paginate/wikis/installation]
|
||||
on {the wiki}[http://github.com/mislav/will_paginate/wikis].</i>
|
||||
|
||||
|
||||
== Example usage
|
||||
|
||||
Use a paginate finder in the controller:
|
||||
|
||||
@posts = Post.paginate_by_board_id @board.id, :page => params[:page], :order => 'updated_at DESC'
|
||||
|
||||
Yeah, +paginate+ works just like +find+ -- it just doesn't fetch all the
|
||||
records. Don't forget to tell it which page you want, or it will complain!
|
||||
Read more on WillPaginate::Finder::ClassMethods.
|
||||
|
||||
Render the posts in your view like you would normally do. When you need to render
|
||||
pagination, just stick this in:
|
||||
|
||||
<%= will_paginate @posts %>
|
||||
|
||||
You're done. (Copy and paste the example fancy CSS styles from the bottom.) You
|
||||
can find the option list at WillPaginate::ViewHelpers.
|
||||
|
||||
How does it know how much items to fetch per page? It asks your model by calling
|
||||
its <tt>per_page</tt> class method. You can define it like this:
|
||||
|
||||
class Post < ActiveRecord::Base
|
||||
cattr_reader :per_page
|
||||
@@per_page = 50
|
||||
end
|
||||
|
||||
... or like this:
|
||||
|
||||
class Post < ActiveRecord::Base
|
||||
def self.per_page
|
||||
50
|
||||
end
|
||||
end
|
||||
|
||||
... or don't worry about it at all. WillPaginate defines it to be <b>30</b> by default.
|
||||
But you can always specify the count explicitly when calling +paginate+:
|
||||
|
||||
@posts = Post.paginate :page => params[:page], :per_page => 50
|
||||
|
||||
The +paginate+ finder wraps the original finder and returns your resultset that now has
|
||||
some new properties. You can use the collection as you would with any ActiveRecord
|
||||
resultset. WillPaginate view helpers also need that object to be able to render pagination:
|
||||
|
||||
<ol>
|
||||
<% for post in @posts -%>
|
||||
<li>Render `post` in some nice way.</li>
|
||||
<% end -%>
|
||||
</ol>
|
||||
|
||||
<p>Now let's render us some pagination!</p>
|
||||
<%= will_paginate @posts %>
|
||||
|
||||
More detailed documentation:
|
||||
|
||||
* WillPaginate::Finder::ClassMethods for pagination on your models;
|
||||
* WillPaginate::ViewHelpers for your views.
|
||||
|
||||
|
||||
== Authors and credits
|
||||
|
||||
Authors:: Mislav Marohnić, PJ Hyett
|
||||
Original announcement:: http://errtheblog.com/post/929
|
||||
Original PHP source:: http://www.strangerstudios.com/sandbox/pagination/diggstyle.php
|
||||
|
||||
All these people helped making will_paginate what it is now with their code
|
||||
contributions or just simply awesome ideas:
|
||||
|
||||
Chris Wanstrath, Dr. Nic Williams, K. Adam Christensen, Mike Garey, Bence
|
||||
Golda, Matt Aimonetti, Charles Brian Quinn, Desi McAdam, James Coglan, Matijs
|
||||
van Zuijlen, Maria, Brendan Ribera, Todd Willey, Bryan Helmkamp, Jan Berkel,
|
||||
Lourens Naudé, Rick Olson, Russell Norris, Piotr Usewicz, Chris Eppstein.
|
||||
|
||||
|
||||
== Usable pagination in the UI
|
||||
|
||||
There are some CSS styles to get you started in the "examples/" directory. They
|
||||
are showcased in the <b>"examples/index.html"</b> file.
|
||||
|
||||
More reading about pagination as design pattern:
|
||||
|
||||
* Pagination 101:
|
||||
http://kurafire.net/log/archive/2007/06/22/pagination-101
|
||||
* Pagination gallery:
|
||||
http://www.smashingmagazine.com/2007/11/16/pagination-gallery-examples-and-good-practices/
|
||||
* Pagination on Yahoo Design Pattern Library:
|
||||
http://developer.yahoo.com/ypatterns/parent.php?pattern=pagination
|
||||
|
||||
Want to discuss, request features, ask questions? Join the
|
||||
{Google group}[http://groups.google.com/group/will_paginate].
|
||||
|
||||
107
vendor/plugins/will_paginate/Rakefile
vendored
107
vendor/plugins/will_paginate/Rakefile
vendored
|
|
@ -1,65 +1,62 @@
|
|||
require 'rake'
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
require 'rubygems'
|
||||
begin
|
||||
hanna_dir = '/home/mislav/projects/hanna/lib'
|
||||
$:.unshift hanna_dir if File.exists? hanna_dir
|
||||
require 'hanna/rdoctask'
|
||||
rescue LoadError
|
||||
require 'rake'
|
||||
require 'rake/rdoctask'
|
||||
end
|
||||
load 'test/tasks.rake'
|
||||
|
||||
desc 'Default: run unit tests.'
|
||||
task :default => :test
|
||||
|
||||
desc 'Test the will_paginate plugin.'
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = true
|
||||
end
|
||||
|
||||
# I want to specify environment variables at call time
|
||||
class EnvTestTask < Rake::TestTask
|
||||
attr_accessor :env
|
||||
|
||||
def ruby(*args)
|
||||
env.each { |key, value| ENV[key] = value } if env
|
||||
super
|
||||
env.keys.each { |key| ENV.delete key } if env
|
||||
end
|
||||
end
|
||||
|
||||
for configuration in %w( sqlite3 mysql postgres )
|
||||
EnvTestTask.new("test_#{configuration}") do |t|
|
||||
t.pattern = 'test/finder_test.rb'
|
||||
t.verbose = true
|
||||
t.env = { 'DB' => configuration }
|
||||
end
|
||||
end
|
||||
|
||||
task :test_databases => %w(test_mysql test_sqlite3 test_postgres)
|
||||
|
||||
desc %{Test everything on SQLite3, MySQL and PostgreSQL}
|
||||
task :test_full => %w(test test_mysql test_postgres)
|
||||
|
||||
desc %{Test everything with Rails 1.2.x and 2.0.x gems}
|
||||
task :test_all do
|
||||
all = Rake::Task['test_full']
|
||||
ENV['RAILS_VERSION'] = '~>1.2.6'
|
||||
all.invoke
|
||||
# reset the invoked flag
|
||||
%w( test_full test test_mysql test_postgres ).each do |name|
|
||||
Rake::Task[name].instance_variable_set '@already_invoked', false
|
||||
end
|
||||
# do it again
|
||||
ENV['RAILS_VERSION'] = '~>2.0.2'
|
||||
all.invoke
|
||||
end
|
||||
|
||||
desc 'Generate RDoc documentation for the will_paginate plugin.'
|
||||
Rake::RDocTask.new(:rdoc) do |rdoc|
|
||||
files = ['README', 'LICENSE', 'lib/**/*.rb']
|
||||
rdoc.rdoc_files.add(files)
|
||||
rdoc.main = "README" # page to start on
|
||||
rdoc.title = "will_paginate"
|
||||
rdoc.rdoc_files.include('README.rdoc', 'LICENSE', 'CHANGELOG').
|
||||
include('lib/**/*.rb').
|
||||
exclude('lib/will_paginate/named_scope*').
|
||||
exclude('lib/will_paginate/array.rb').
|
||||
exclude('lib/will_paginate/version.rb')
|
||||
|
||||
templates = %w[/Users/chris/ruby/projects/err/rock/template.rb /var/www/rock/template.rb]
|
||||
rdoc.template = templates.find { |t| File.exists? t }
|
||||
rdoc.main = "README.rdoc" # page to start on
|
||||
rdoc.title = "will_paginate documentation"
|
||||
|
||||
rdoc.rdoc_dir = 'doc' # rdoc output folder
|
||||
rdoc.options << '--inline-source'
|
||||
rdoc.options << '--charset=UTF-8'
|
||||
rdoc.options << '--inline-source' << '--charset=UTF-8'
|
||||
rdoc.options << '--webcvs=http://github.com/mislav/will_paginate/tree/master/'
|
||||
end
|
||||
|
||||
desc %{Update ".manifest" with the latest list of project filenames. Respect\
|
||||
.gitignore by excluding everything that git ignores. Update `files` and\
|
||||
`test_files` arrays in "*.gemspec" file if it's present.}
|
||||
task :manifest do
|
||||
list = Dir['**/*'].sort
|
||||
spec_file = Dir['*.gemspec'].first
|
||||
list -= [spec_file] if spec_file
|
||||
|
||||
File.read('.gitignore').each_line do |glob|
|
||||
glob = glob.chomp.sub(/^\//, '')
|
||||
list -= Dir[glob]
|
||||
list -= Dir["#{glob}/**/*"] if File.directory?(glob) and !File.symlink?(glob)
|
||||
puts "excluding #{glob}"
|
||||
end
|
||||
|
||||
if spec_file
|
||||
spec = File.read spec_file
|
||||
spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
|
||||
assignment = $1
|
||||
bunch = $2 ? list.grep(/^test\//) : list
|
||||
'%s%%w(%s)' % [assignment, bunch.join(' ')]
|
||||
end
|
||||
|
||||
File.open(spec_file, 'w') {|f| f << spec }
|
||||
end
|
||||
File.open('.manifest', 'w') {|f| f << list.join("\n") }
|
||||
end
|
||||
|
||||
task :examples do
|
||||
%x(haml examples/index.haml examples/index.html)
|
||||
%x(sass examples/pagination.sass examples/pagination.css)
|
||||
end
|
||||
|
|
|
|||
BIN
vendor/plugins/will_paginate/examples/apple-circle.gif
vendored
Normal file
BIN
vendor/plugins/will_paginate/examples/apple-circle.gif
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 178 B |
69
vendor/plugins/will_paginate/examples/index.haml
vendored
Normal file
69
vendor/plugins/will_paginate/examples/index.haml
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
!!!
|
||||
%html
|
||||
%head
|
||||
%title Samples of pagination styling for will_paginate
|
||||
%link{ :rel => 'stylesheet', :type => 'text/css', :href => 'pagination.css' }
|
||||
%style{ :type => 'text/css' }
|
||||
:sass
|
||||
html
|
||||
:margin 0
|
||||
:padding 0
|
||||
:background #999
|
||||
:font normal 76% "Lucida Grande", Verdana, Helvetica, sans-serif
|
||||
body
|
||||
:margin 2em
|
||||
:padding 2em
|
||||
:border 2px solid gray
|
||||
:background white
|
||||
:color #222
|
||||
h1
|
||||
:font-size 2em
|
||||
:font-weight normal
|
||||
:margin 0 0 1em 0
|
||||
h2
|
||||
:font-size 1.4em
|
||||
:margin 1em 0 .5em 0
|
||||
pre
|
||||
:font-size 13px
|
||||
:font-family Monaco, "DejaVu Sans Mono", "Bitstream Vera Mono", "Courier New", monospace
|
||||
|
||||
- pagination = '<span class="disabled prev_page">« Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">…</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next »</a>'
|
||||
- pagination_no_page_links = '<span class="disabled prev_page">« Previous</span> <a href="./?page=2" rel="next" class="next_page">Next »</a>'
|
||||
|
||||
%body
|
||||
%h1 Samples of pagination styling for will_paginate
|
||||
%p
|
||||
Find these styles in <b>"examples/pagination.css"</b> of <i>will_paginate</i> library.
|
||||
There is a Sass version of it for all you sassy people.
|
||||
%p
|
||||
Read about good rules for pagination:
|
||||
%a{ :href => 'http://kurafire.net/log/archive/2007/06/22/pagination-101' } Pagination 101
|
||||
%p
|
||||
%em Warning:
|
||||
page links below don't lead anywhere (so don't click on them).
|
||||
|
||||
%h2 Unstyled pagination <span style="font-weight:normal">(<i>ewww!</i>)</span>
|
||||
%div= pagination
|
||||
|
||||
%h2 Digg.com
|
||||
.digg_pagination= pagination
|
||||
|
||||
%h2 Digg-style, no page links
|
||||
.digg_pagination= pagination_no_page_links
|
||||
%p Code that renders this:
|
||||
%pre= '<code>%s</code>' % %[<%= will_paginate @posts, :page_links => false %>].gsub('<', '<').gsub('>', '>')
|
||||
|
||||
%h2 Digg-style, extra content
|
||||
.digg_pagination
|
||||
.page_info Displaying entries <b>1 - 6</b> of <b>180</b> in total
|
||||
= pagination
|
||||
%p Code that renders this:
|
||||
%pre= '<code>%s</code>' % %[<div class="digg_pagination">\n <div clas="page_info">\n <%= page_entries_info @posts %>\n </div>\n <%= will_paginate @posts, :container => false %>\n</div>].gsub('<', '<').gsub('>', '>')
|
||||
|
||||
%h2 Apple.com store
|
||||
.apple_pagination= pagination
|
||||
|
||||
%h2 Flickr.com
|
||||
.flickr_pagination
|
||||
= pagination
|
||||
.page_info (118 photos)
|
||||
92
vendor/plugins/will_paginate/examples/index.html
vendored
Normal file
92
vendor/plugins/will_paginate/examples/index.html
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html>
|
||||
</html>
|
||||
<head>
|
||||
<title>Samples of pagination styling for will_paginate</title>
|
||||
<link href='pagination.css' rel='stylesheet' type='text/css' />
|
||||
<style type='text/css'>
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #999;
|
||||
font: normal 76% "Lucida Grande", Verdana, Helvetica, sans-serif; }
|
||||
|
||||
body {
|
||||
margin: 2em;
|
||||
padding: 2em;
|
||||
border: 2px solid gray;
|
||||
background: white;
|
||||
color: #222; }
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
font-weight: normal;
|
||||
margin: 0 0 1em 0; }
|
||||
|
||||
h2 {
|
||||
font-size: 1.4em;
|
||||
margin: 1em 0 .5em 0; }
|
||||
|
||||
pre {
|
||||
font-size: 13px;
|
||||
font-family: Monaco, "DejaVu Sans Mono", "Bitstream Vera Mono", "Courier New", monospace; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Samples of pagination styling for will_paginate</h1>
|
||||
<p>
|
||||
Find these styles in <b>"examples/pagination.css"</b> of <i>will_paginate</i> library.
|
||||
There is a Sass version of it for all you sassy people.
|
||||
</p>
|
||||
<p>
|
||||
Read about good rules for pagination:
|
||||
<a href='http://kurafire.net/log/archive/2007/06/22/pagination-101'>Pagination 101</a>
|
||||
</p>
|
||||
<p>
|
||||
<em>Warning:</em>
|
||||
page links below don't lead anywhere (so don't click on them).
|
||||
</p>
|
||||
<h2>
|
||||
Unstyled pagination <span style="font-weight:normal">(<i>ewww!</i>)</span>
|
||||
</h2>
|
||||
<div>
|
||||
<span class="disabled prev_page">« Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">…</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next »</a>
|
||||
</div>
|
||||
<h2>Digg.com</h2>
|
||||
<div class='digg_pagination'>
|
||||
<span class="disabled prev_page">« Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">…</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next »</a>
|
||||
</div>
|
||||
<h2>Digg-style, no page links</h2>
|
||||
<div class='digg_pagination'>
|
||||
<span class="disabled prev_page">« Previous</span> <a href="./?page=2" rel="next" class="next_page">Next »</a>
|
||||
</div>
|
||||
<p>Code that renders this:</p>
|
||||
<pre>
|
||||
<code><%= will_paginate @posts, :page_links => false %></code>
|
||||
</pre>
|
||||
<h2>Digg-style, extra content</h2>
|
||||
<div class='digg_pagination'>
|
||||
<div class='page_info'>
|
||||
Displaying entries <b>1 - 6</b> of <b>180</b> in total
|
||||
</div>
|
||||
<span class="disabled prev_page">« Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">…</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next »</a>
|
||||
</div>
|
||||
<p>Code that renders this:</p>
|
||||
<pre>
|
||||
<code><div class="digg_pagination">
|
||||
<div clas="page_info">
|
||||
<%= page_entries_info @posts %>
|
||||
</div>
|
||||
<%= will_paginate @posts, :container => false %>
|
||||
</div></code>
|
||||
</pre>
|
||||
<h2>Apple.com store</h2>
|
||||
<div class='apple_pagination'>
|
||||
<span class="disabled prev_page">« Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">…</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next »</a>
|
||||
</div>
|
||||
<h2>Flickr.com</h2>
|
||||
<div class='flickr_pagination'>
|
||||
<span class="disabled prev_page">« Previous</span> <span class="current">1</span> <a href="./?page=2" rel="next">2</a> <a href="./?page=3">3</a> <a href="./?page=4">4</a> <a href="./?page=5">5</a> <a href="./?page=6">6</a> <a href="./?page=7">7</a> <a href="./?page=8">8</a> <a href="./?page=9">9</a> <span class="gap">…</span> <a href="./?page=29">29</a> <a href="./?page=30">30</a> <a href="./?page=2" rel="next" class="next_page">Next »</a>
|
||||
<div class='page_info'>(118 photos)</div>
|
||||
</div>
|
||||
</body>
|
||||
90
vendor/plugins/will_paginate/examples/pagination.css
vendored
Normal file
90
vendor/plugins/will_paginate/examples/pagination.css
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
.digg_pagination {
|
||||
background: white;
|
||||
/* self-clearing method: */ }
|
||||
.digg_pagination a, .digg_pagination span {
|
||||
padding: .2em .5em;
|
||||
display: block;
|
||||
float: left;
|
||||
margin-right: 1px; }
|
||||
.digg_pagination span.disabled {
|
||||
color: #999;
|
||||
border: 1px solid #DDD; }
|
||||
.digg_pagination span.current {
|
||||
font-weight: bold;
|
||||
background: #2E6AB1;
|
||||
color: white;
|
||||
border: 1px solid #2E6AB1; }
|
||||
.digg_pagination a {
|
||||
text-decoration: none;
|
||||
color: #105CB6;
|
||||
border: 1px solid #9AAFE5; }
|
||||
.digg_pagination a:hover, .digg_pagination a:focus {
|
||||
color: #003;
|
||||
border-color: #003; }
|
||||
.digg_pagination .page_info {
|
||||
background: #2E6AB1;
|
||||
color: white;
|
||||
padding: .4em .6em;
|
||||
width: 22em;
|
||||
margin-bottom: .3em;
|
||||
text-align: center; }
|
||||
.digg_pagination .page_info b {
|
||||
color: #003;
|
||||
background: #6aa6ed;
|
||||
padding: .1em .25em; }
|
||||
.digg_pagination:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden; }
|
||||
* html .digg_pagination {
|
||||
height: 1%; }
|
||||
*:first-child+html .digg_pagination {
|
||||
overflow: hidden; }
|
||||
|
||||
.apple_pagination {
|
||||
background: #F1F1F1;
|
||||
border: 1px solid #E5E5E5;
|
||||
text-align: center;
|
||||
padding: 1em; }
|
||||
.apple_pagination a, .apple_pagination span {
|
||||
padding: .2em .3em; }
|
||||
.apple_pagination span.disabled {
|
||||
color: #AAA; }
|
||||
.apple_pagination span.current {
|
||||
font-weight: bold;
|
||||
background: transparent url(apple-circle.gif) no-repeat 50% 50%; }
|
||||
.apple_pagination a {
|
||||
text-decoration: none;
|
||||
color: black; }
|
||||
.apple_pagination a:hover, .apple_pagination a:focus {
|
||||
text-decoration: underline; }
|
||||
|
||||
.flickr_pagination {
|
||||
text-align: center;
|
||||
padding: .3em; }
|
||||
.flickr_pagination a, .flickr_pagination span {
|
||||
padding: .2em .5em; }
|
||||
.flickr_pagination span.disabled {
|
||||
color: #AAA; }
|
||||
.flickr_pagination span.current {
|
||||
font-weight: bold;
|
||||
color: #FF0084; }
|
||||
.flickr_pagination a {
|
||||
border: 1px solid #DDDDDD;
|
||||
color: #0063DC;
|
||||
text-decoration: none; }
|
||||
.flickr_pagination a:hover, .flickr_pagination a:focus {
|
||||
border-color: #003366;
|
||||
background: #0063DC;
|
||||
color: white; }
|
||||
.flickr_pagination .page_info {
|
||||
color: #aaa;
|
||||
padding-top: .8em; }
|
||||
.flickr_pagination .prev_page, .flickr_pagination .next_page {
|
||||
border-width: 2px; }
|
||||
.flickr_pagination .prev_page {
|
||||
margin-right: 1em; }
|
||||
.flickr_pagination .next_page {
|
||||
margin-left: 1em; }
|
||||
91
vendor/plugins/will_paginate/examples/pagination.sass
vendored
Normal file
91
vendor/plugins/will_paginate/examples/pagination.sass
vendored
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
.digg_pagination
|
||||
:background white
|
||||
a, span
|
||||
:padding .2em .5em
|
||||
:display block
|
||||
:float left
|
||||
:margin-right 1px
|
||||
span.disabled
|
||||
:color #999
|
||||
:border 1px solid #DDD
|
||||
span.current
|
||||
:font-weight bold
|
||||
:background #2E6AB1
|
||||
:color white
|
||||
:border 1px solid #2E6AB1
|
||||
a
|
||||
:text-decoration none
|
||||
:color #105CB6
|
||||
:border 1px solid #9AAFE5
|
||||
&:hover, &:focus
|
||||
:color #003
|
||||
:border-color #003
|
||||
.page_info
|
||||
:background #2E6AB1
|
||||
:color white
|
||||
:padding .4em .6em
|
||||
:width 22em
|
||||
:margin-bottom .3em
|
||||
:text-align center
|
||||
b
|
||||
:color #003
|
||||
:background = #2E6AB1 + 60
|
||||
:padding .1em .25em
|
||||
|
||||
/* self-clearing method:
|
||||
&:after
|
||||
:content "."
|
||||
:display block
|
||||
:height 0
|
||||
:clear both
|
||||
:visibility hidden
|
||||
* html &
|
||||
:height 1%
|
||||
*:first-child+html &
|
||||
:overflow hidden
|
||||
|
||||
.apple_pagination
|
||||
:background #F1F1F1
|
||||
:border 1px solid #E5E5E5
|
||||
:text-align center
|
||||
:padding 1em
|
||||
a, span
|
||||
:padding .2em .3em
|
||||
span.disabled
|
||||
:color #AAA
|
||||
span.current
|
||||
:font-weight bold
|
||||
:background transparent url(apple-circle.gif) no-repeat 50% 50%
|
||||
a
|
||||
:text-decoration none
|
||||
:color black
|
||||
&:hover, &:focus
|
||||
:text-decoration underline
|
||||
|
||||
.flickr_pagination
|
||||
:text-align center
|
||||
:padding .3em
|
||||
a, span
|
||||
:padding .2em .5em
|
||||
span.disabled
|
||||
:color #AAA
|
||||
span.current
|
||||
:font-weight bold
|
||||
:color #FF0084
|
||||
a
|
||||
:border 1px solid #DDDDDD
|
||||
:color #0063DC
|
||||
:text-decoration none
|
||||
&:hover, &:focus
|
||||
:border-color #003366
|
||||
:background #0063DC
|
||||
:color white
|
||||
.page_info
|
||||
:color #aaa
|
||||
:padding-top .8em
|
||||
.prev_page, .next_page
|
||||
:border-width 2px
|
||||
.prev_page
|
||||
:margin-right 1em
|
||||
.next_page
|
||||
:margin-left 1em
|
||||
1
vendor/plugins/will_paginate/init.rb
vendored
1
vendor/plugins/will_paginate/init.rb
vendored
|
|
@ -1,2 +1 @@
|
|||
require 'will_paginate'
|
||||
WillPaginate.enable
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ module WillPaginate
|
|||
require 'will_paginate/view_helpers'
|
||||
ActionView::Base.class_eval { include ViewHelpers }
|
||||
|
||||
if ActionController::Base.respond_to? :rescue_responses
|
||||
if defined?(ActionController::Base) and ActionController::Base.respond_to? :rescue_responses
|
||||
ActionController::Base.rescue_responses['WillPaginate::InvalidPage'] = :not_found
|
||||
end
|
||||
end
|
||||
|
|
@ -33,28 +33,45 @@ module WillPaginate
|
|||
require 'will_paginate/finder'
|
||||
ActiveRecord::Base.class_eval { include Finder }
|
||||
|
||||
associations = ActiveRecord::Associations
|
||||
collection = associations::AssociationCollection
|
||||
|
||||
# to support paginating finders on associations, we have to mix in the
|
||||
# method_missing magic from WillPaginate::Finder::ClassMethods to AssociationProxy
|
||||
# subclasses, but in a different way for Rails 1.2.x and 2.0
|
||||
(collection.instance_methods.include?(:create!) ?
|
||||
collection : collection.subclasses.map(&:constantize)
|
||||
).push(associations::HasManyThroughAssociation).each do |klass|
|
||||
# support pagination on associations
|
||||
a = ActiveRecord::Associations
|
||||
returning([ a::AssociationCollection ]) { |classes|
|
||||
# detect http://dev.rubyonrails.org/changeset/9230
|
||||
unless a::HasManyThroughAssociation.superclass == a::HasManyAssociation
|
||||
classes << a::HasManyThroughAssociation
|
||||
end
|
||||
}.each do |klass|
|
||||
klass.class_eval do
|
||||
include Finder::ClassMethods
|
||||
alias_method_chain :method_missing, :paginate
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Enable named_scope, a feature of Rails 2.1, even if you have older Rails
|
||||
# (tested on Rails 2.0.2 and 1.2.6).
|
||||
#
|
||||
# You can pass +false+ for +patch+ parameter to skip monkeypatching
|
||||
# *associations*. Use this if you feel that <tt>named_scope</tt> broke
|
||||
# has_many, has_many :through or has_and_belongs_to_many associations in
|
||||
# your app. By passing +false+, you can still use <tt>named_scope</tt> in
|
||||
# your models, but not through associations.
|
||||
def enable_named_scope(patch = true)
|
||||
return if defined? ActiveRecord::NamedScope
|
||||
require 'will_paginate/named_scope'
|
||||
require 'will_paginate/named_scope_patch' if patch
|
||||
|
||||
ActiveRecord::Base.class_eval do
|
||||
include WillPaginate::NamedScope
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Deprecation #:nodoc:
|
||||
extend ActiveSupport::Deprecation
|
||||
|
||||
def self.warn(message, callstack = caller)
|
||||
message = 'WillPaginate: ' + message.strip.gsub(/ {3,}/, ' ')
|
||||
message = 'WillPaginate: ' + message.strip.gsub(/\s+/, ' ')
|
||||
behavior.call(message, callstack) if behavior && !silenced?
|
||||
end
|
||||
|
||||
|
|
@ -63,3 +80,7 @@ module WillPaginate
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
if defined?(Rails) and defined?(ActiveRecord) and defined?(ActionController)
|
||||
WillPaginate.enable
|
||||
end
|
||||
|
|
|
|||
16
vendor/plugins/will_paginate/lib/will_paginate/array.rb
vendored
Normal file
16
vendor/plugins/will_paginate/lib/will_paginate/array.rb
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
require 'will_paginate/collection'
|
||||
|
||||
# http://www.desimcadam.com/archives/8
|
||||
Array.class_eval do
|
||||
def paginate(options = {})
|
||||
raise ArgumentError, "parameter hash expected (got #{options.inspect})" unless Hash === options
|
||||
|
||||
WillPaginate::Collection.create(
|
||||
options[:page] || 1,
|
||||
options[:per_page] || 30,
|
||||
options[:total_entries] || self.length
|
||||
) { |pager|
|
||||
pager.replace self[pager.offset, pager.per_page].to_a
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -1,11 +1,18 @@
|
|||
require 'will_paginate'
|
||||
|
||||
module WillPaginate
|
||||
# = OMG, invalid page number!
|
||||
# = Invalid page number error
|
||||
# This is an ArgumentError raised in case a page was requested that is either
|
||||
# zero or negative number. You should decide how do deal with such errors in
|
||||
# the controller.
|
||||
#
|
||||
# If you're using Rails 2, then this error will automatically get handled like
|
||||
# 404 Not Found. The hook is in "will_paginate.rb":
|
||||
#
|
||||
# ActionController::Base.rescue_responses['WillPaginate::InvalidPage'] = :not_found
|
||||
#
|
||||
# If you don't like this, use your preffered method of rescuing exceptions in
|
||||
# public from your controllers to handle this differently. The +rescue_from+
|
||||
# method is a nice addition to Rails 2.
|
||||
#
|
||||
# This error is *not* raised when a page further than the last page is
|
||||
# requested. Use <tt>WillPaginate::Collection#out_of_bounds?</tt> method to
|
||||
# check for those cases and manually deal with them as you see fit.
|
||||
|
|
@ -15,26 +22,34 @@ module WillPaginate
|
|||
end
|
||||
end
|
||||
|
||||
# Arrays returned from paginating finds are, in fact, instances of this.
|
||||
# You may think of WillPaginate::Collection as an ordinary array with some
|
||||
# extra properties. Those properties are used by view helpers to generate
|
||||
# = The key to pagination
|
||||
# Arrays returned from paginating finds are, in fact, instances of this little
|
||||
# class. You may think of WillPaginate::Collection as an ordinary array with
|
||||
# some extra properties. Those properties are used by view helpers to generate
|
||||
# correct page links.
|
||||
#
|
||||
# WillPaginate::Collection also assists in rolling out your own pagination
|
||||
# solutions: see +create+.
|
||||
#
|
||||
# If you are writing a library that provides a collection which you would like
|
||||
# to conform to this API, you don't have to copy these methods over; simply
|
||||
# make your plugin/gem dependant on the "will_paginate" gem:
|
||||
#
|
||||
# gem 'will_paginate'
|
||||
# require 'will_paginate/collection'
|
||||
#
|
||||
# # now use WillPaginate::Collection directly or subclass it
|
||||
class Collection < Array
|
||||
attr_reader :current_page, :per_page, :total_entries
|
||||
attr_reader :current_page, :per_page, :total_entries, :total_pages
|
||||
|
||||
# Arguments to this constructor are the current page number, per-page limit
|
||||
# Arguments to the constructor are the current page number, per-page limit
|
||||
# and the total number of entries. The last argument is optional because it
|
||||
# is best to do lazy counting; in other words, count *conditionally* after
|
||||
# populating the collection using the +replace+ method.
|
||||
#
|
||||
def initialize(page, per_page, total = nil)
|
||||
@current_page = page.to_i
|
||||
raise InvalidPage.new(page, @current_page) if @current_page < 1
|
||||
@per_page = per_page.to_i
|
||||
@per_page = per_page.to_i
|
||||
raise ArgumentError, "`per_page` setting cannot be less than 1 (#{@per_page} given)" if @per_page < 1
|
||||
|
||||
self.total_entries = total if total
|
||||
|
|
@ -65,29 +80,25 @@ module WillPaginate
|
|||
# end
|
||||
# end
|
||||
#
|
||||
# The Array#paginate API has since then changed, but this still serves as a
|
||||
# fine example of WillPaginate::Collection usage.
|
||||
def self.create(page, per_page, total = nil, &block)
|
||||
pager = new(page, per_page, total)
|
||||
yield pager
|
||||
pager
|
||||
end
|
||||
|
||||
# The total number of pages.
|
||||
def page_count
|
||||
@total_pages
|
||||
end
|
||||
|
||||
# Helper method that is true when someone tries to fetch a page with a
|
||||
# larger number than the last page. Can be used in combination with flashes
|
||||
# and redirecting.
|
||||
def out_of_bounds?
|
||||
current_page > page_count
|
||||
current_page > total_pages
|
||||
end
|
||||
|
||||
# Current offset of the paginated collection. If we're on the first page,
|
||||
# it is always 0. If we're on the 2nd page and there are 30 entries per page,
|
||||
# the offset is 30. This property is useful if you want to render ordinals
|
||||
# besides your records: simply start with offset + 1.
|
||||
#
|
||||
def offset
|
||||
(current_page - 1) * per_page
|
||||
end
|
||||
|
|
@ -99,7 +110,7 @@ module WillPaginate
|
|||
|
||||
# current_page + 1 or nil if there is no next page
|
||||
def next_page
|
||||
current_page < page_count ? (current_page + 1) : nil
|
||||
current_page < total_pages ? (current_page + 1) : nil
|
||||
end
|
||||
|
||||
def total_entries=(number)
|
||||
|
|
@ -120,13 +131,15 @@ module WillPaginate
|
|||
# +total_entries+ and set it to a proper value if it's +nil+. See the example
|
||||
# in +create+.
|
||||
def replace(array)
|
||||
returning super do
|
||||
# The collection is shorter then page limit? Rejoice, because
|
||||
# then we know that we are on the last page!
|
||||
if total_entries.nil? and length > 0 and length < per_page
|
||||
self.total_entries = offset + length
|
||||
end
|
||||
result = super
|
||||
|
||||
# The collection is shorter then page limit? Rejoice, because
|
||||
# then we know that we are on the last page!
|
||||
if total_entries.nil? and length < per_page and (current_page == 1 or length > 0)
|
||||
self.total_entries = offset + length
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
require 'will_paginate'
|
||||
require 'set'
|
||||
require 'will_paginate/array'
|
||||
|
||||
unless Hash.instance_methods.include? 'except'
|
||||
Hash.class_eval do
|
||||
|
|
@ -30,51 +30,3 @@ unless Hash.instance_methods.include? 'slice'
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless Hash.instance_methods.include? 'rec_merge!'
|
||||
Hash.class_eval do
|
||||
# Same as Hash#merge!, but recursively merges sub-hashes
|
||||
# (stolen from Haml)
|
||||
def rec_merge!(other)
|
||||
other.each do |key, other_value|
|
||||
value = self[key]
|
||||
if value.is_a?(Hash) and other_value.is_a?(Hash)
|
||||
value.rec_merge! other_value
|
||||
else
|
||||
self[key] = other_value
|
||||
end
|
||||
end
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require 'will_paginate/collection'
|
||||
|
||||
unless Array.instance_methods.include? 'paginate'
|
||||
# http://www.desimcadam.com/archives/8
|
||||
Array.class_eval do
|
||||
def paginate(options_or_page = {}, per_page = nil)
|
||||
if options_or_page.nil? or Fixnum === options_or_page
|
||||
if defined? WillPaginate::Deprecation
|
||||
WillPaginate::Deprecation.warn <<-DEPR
|
||||
Array#paginate now conforms to the main, ActiveRecord::Base#paginate API. You should \
|
||||
call it with a parameters hash (:page, :per_page). The old API (numbers as arguments) \
|
||||
has been deprecated and is going to be unsupported in future versions of will_paginate.
|
||||
DEPR
|
||||
end
|
||||
page = options_or_page
|
||||
options = {}
|
||||
else
|
||||
options = options_or_page
|
||||
page = options[:page]
|
||||
raise ArgumentError, "wrong number of arguments (1 hash or 2 Fixnums expected)" if per_page
|
||||
per_page = options[:per_page]
|
||||
end
|
||||
|
||||
WillPaginate::Collection.create(page || 1, per_page || 30, options[:total_entries] || size) do |pager|
|
||||
pager.replace self[pager.offset, pager.per_page].to_a
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ require 'will_paginate/core_ext'
|
|||
|
||||
module WillPaginate
|
||||
# A mixin for ActiveRecord::Base. Provides +per_page+ class method
|
||||
# and makes +paginate+ finders possible with some method_missing magic.
|
||||
# and hooks things up to provide paginating finders.
|
||||
#
|
||||
# Find out more in WillPaginate::Finder::ClassMethods
|
||||
#
|
||||
|
|
@ -18,9 +18,9 @@ module WillPaginate
|
|||
|
||||
# = Paginating finders for ActiveRecord models
|
||||
#
|
||||
# WillPaginate adds +paginate+ and +per_page+ methods to ActiveRecord::Base
|
||||
# class methods and associations. It also hooks into +method_missing+ to
|
||||
# intercept pagination calls to dynamic finders such as
|
||||
# WillPaginate adds +paginate+, +per_page+ and other methods to
|
||||
# ActiveRecord::Base class methods and associations. It also hooks into
|
||||
# +method_missing+ to intercept pagination calls to dynamic finders such as
|
||||
# +paginate_by_user_id+ and translate them to ordinary finders
|
||||
# (+find_all_by_user_id+ in this case).
|
||||
#
|
||||
|
|
@ -85,6 +85,31 @@ module WillPaginate
|
|||
pager.total_entries = wp_count(count_options, args, finder) unless pager.total_entries
|
||||
end
|
||||
end
|
||||
|
||||
# Iterates through all records by loading one page at a time. This is useful
|
||||
# for migrations or any other use case where you don't want to load all the
|
||||
# records in memory at once.
|
||||
#
|
||||
# It uses +paginate+ internally; therefore it accepts all of its options.
|
||||
# You can specify a starting page with <tt>:page</tt> (default is 1). Default
|
||||
# <tt>:order</tt> is <tt>"id"</tt>, override if necessary.
|
||||
#
|
||||
# See http://weblog.jamisbuck.org/2007/4/6/faking-cursors-in-activerecord where
|
||||
# Jamis Buck describes this and also uses a more efficient way for MySQL.
|
||||
def paginated_each(options = {}, &block)
|
||||
options = { :order => 'id', :page => 1 }.merge options
|
||||
options[:page] = options[:page].to_i
|
||||
options[:total_entries] = 0 # skip the individual count queries
|
||||
total = 0
|
||||
|
||||
begin
|
||||
collection = paginate(options)
|
||||
total += collection.each(&block).size
|
||||
options[:page] += 1
|
||||
end until collection.size < collection.per_page
|
||||
|
||||
total
|
||||
end
|
||||
|
||||
# Wraps +find_by_sql+ by simply adding LIMIT and OFFSET to your SQL string
|
||||
# based on the params otherwise used by paginating finds: +page+ and
|
||||
|
|
@ -159,19 +184,27 @@ module WillPaginate
|
|||
unless options[:select] and options[:select] =~ /^\s*DISTINCT\b/i
|
||||
excludees << :select # only exclude the select param if it doesn't begin with DISTINCT
|
||||
end
|
||||
|
||||
# count expects (almost) the same options as find
|
||||
count_options = options.except *excludees
|
||||
|
||||
# merge the hash found in :count
|
||||
# this allows you to specify :select, :order, or anything else just for the count query
|
||||
count_options.update options[:count] if options[:count]
|
||||
|
||||
# we may be in a model or an association proxy
|
||||
klass = (@owner and @reflection) ? @reflection.klass : self
|
||||
|
||||
# forget about includes if they are irrelevant (Rails 2.1)
|
||||
if count_options[:include] and
|
||||
klass.private_methods.include?('references_eager_loaded_tables?') and
|
||||
!klass.send(:references_eager_loaded_tables?, count_options)
|
||||
count_options.delete :include
|
||||
end
|
||||
|
||||
# we may have to scope ...
|
||||
counter = Proc.new { count(count_options) }
|
||||
|
||||
# we may be in a model or an association proxy!
|
||||
klass = (@owner and @reflection) ? @reflection.klass : self
|
||||
|
||||
count = if finder.index('find_') == 0 and klass.respond_to?(scoper = finder.sub('find', 'with'))
|
||||
# scope_out adds a 'with_finder' method which acts like with_scope, if it's present
|
||||
# then execute the count with the scoping provided by the with_finder
|
||||
|
|
|
|||
132
vendor/plugins/will_paginate/lib/will_paginate/named_scope.rb
vendored
Normal file
132
vendor/plugins/will_paginate/lib/will_paginate/named_scope.rb
vendored
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
## stolen from: http://dev.rubyonrails.org/browser/trunk/activerecord/lib/active_record/named_scope.rb?rev=9084
|
||||
|
||||
module WillPaginate
|
||||
# This is a feature backported from Rails 2.1 because of its usefullness not only with will_paginate,
|
||||
# but in other aspects when managing complex conditions that you want to be reusable.
|
||||
module NamedScope
|
||||
# All subclasses of ActiveRecord::Base have two named_scopes:
|
||||
# * <tt>all</tt>, which is similar to a <tt>find(:all)</tt> query, and
|
||||
# * <tt>scoped</tt>, which allows for the creation of anonymous scopes, on the fly:
|
||||
#
|
||||
# Shirt.scoped(:conditions => {:color => 'red'}).scoped(:include => :washing_instructions)
|
||||
#
|
||||
# These anonymous scopes tend to be useful when procedurally generating complex queries, where passing
|
||||
# intermediate values (scopes) around as first-class objects is convenient.
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
extend ClassMethods
|
||||
named_scope :all
|
||||
named_scope :scoped, lambda { |scope| scope }
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def scopes #:nodoc:
|
||||
read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
|
||||
end
|
||||
|
||||
# Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query,
|
||||
# such as <tt>:conditions => {:color => :red}, :select => 'shirts.*', :include => :washing_instructions</tt>.
|
||||
#
|
||||
# class Shirt < ActiveRecord::Base
|
||||
# named_scope :red, :conditions => {:color => 'red'}
|
||||
# named_scope :dry_clean_only, :joins => :washing_instructions, :conditions => ['washing_instructions.dry_clean_only = ?', true]
|
||||
# end
|
||||
#
|
||||
# The above calls to <tt>named_scope</tt> define class methods <tt>Shirt.red</tt> and <tt>Shirt.dry_clean_only</tt>. <tt>Shirt.red</tt>,
|
||||
# in effect, represents the query <tt>Shirt.find(:all, :conditions => {:color => 'red'})</tt>.
|
||||
#
|
||||
# Unlike Shirt.find(...), however, the object returned by <tt>Shirt.red</tt> is not an Array; it resembles the association object
|
||||
# constructed by a <tt>has_many</tt> declaration. For instance, you can invoke <tt>Shirt.red.find(:first)</tt>, <tt>Shirt.red.count</tt>,
|
||||
# <tt>Shirt.red.find(:all, :conditions => {:size => 'small'})</tt>. Also, just
|
||||
# as with the association objects, name scopes acts like an Array, implementing Enumerable; <tt>Shirt.red.each(&block)</tt>,
|
||||
# <tt>Shirt.red.first</tt>, and <tt>Shirt.red.inject(memo, &block)</tt> all behave as if Shirt.red really were an Array.
|
||||
#
|
||||
# These named scopes are composable. For instance, <tt>Shirt.red.dry_clean_only</tt> will produce all shirts that are both red and dry clean only.
|
||||
# Nested finds and calculations also work with these compositions: <tt>Shirt.red.dry_clean_only.count</tt> returns the number of garments
|
||||
# for which these criteria obtain. Similarly with <tt>Shirt.red.dry_clean_only.average(:thread_count)</tt>.
|
||||
#
|
||||
# All scopes are available as class methods on the ActiveRecord descendent upon which the scopes were defined. But they are also available to
|
||||
# <tt>has_many</tt> associations. If,
|
||||
#
|
||||
# class Person < ActiveRecord::Base
|
||||
# has_many :shirts
|
||||
# end
|
||||
#
|
||||
# then <tt>elton.shirts.red.dry_clean_only</tt> will return all of Elton's red, dry clean
|
||||
# only shirts.
|
||||
#
|
||||
# Named scopes can also be procedural.
|
||||
#
|
||||
# class Shirt < ActiveRecord::Base
|
||||
# named_scope :colored, lambda { |color|
|
||||
# { :conditions => { :color => color } }
|
||||
# }
|
||||
# end
|
||||
#
|
||||
# In this example, <tt>Shirt.colored('puce')</tt> finds all puce shirts.
|
||||
#
|
||||
# Named scopes can also have extensions, just as with <tt>has_many</tt> declarations:
|
||||
#
|
||||
# class Shirt < ActiveRecord::Base
|
||||
# named_scope :red, :conditions => {:color => 'red'} do
|
||||
# def dom_id
|
||||
# 'red_shirts'
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
#
|
||||
def named_scope(name, options = {}, &block)
|
||||
scopes[name] = lambda do |parent_scope, *args|
|
||||
Scope.new(parent_scope, case options
|
||||
when Hash
|
||||
options
|
||||
when Proc
|
||||
options.call(*args)
|
||||
end, &block)
|
||||
end
|
||||
(class << self; self end).instance_eval do
|
||||
define_method name do |*args|
|
||||
scopes[name].call(self, *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Scope #:nodoc:
|
||||
attr_reader :proxy_scope, :proxy_options
|
||||
[].methods.each { |m| delegate m, :to => :proxy_found unless m =~ /(^__|^nil\?|^send|class|extend|find|count|sum|average|maximum|minimum|paginate)/ }
|
||||
delegate :scopes, :with_scope, :to => :proxy_scope
|
||||
|
||||
def initialize(proxy_scope, options, &block)
|
||||
[options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
|
||||
extend Module.new(&block) if block_given?
|
||||
@proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
|
||||
end
|
||||
|
||||
def reload
|
||||
load_found; self
|
||||
end
|
||||
|
||||
protected
|
||||
def proxy_found
|
||||
@found || load_found
|
||||
end
|
||||
|
||||
private
|
||||
def method_missing(method, *args, &block)
|
||||
if scopes.include?(method)
|
||||
scopes[method].call(self, *args)
|
||||
else
|
||||
with_scope :find => proxy_options do
|
||||
proxy_scope.send(method, *args, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def load_found
|
||||
@found = find(:all)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
39
vendor/plugins/will_paginate/lib/will_paginate/named_scope_patch.rb
vendored
Normal file
39
vendor/plugins/will_paginate/lib/will_paginate/named_scope_patch.rb
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
## based on http://dev.rubyonrails.org/changeset/9084
|
||||
|
||||
ActiveRecord::Associations::AssociationProxy.class_eval do
|
||||
protected
|
||||
def with_scope(*args, &block)
|
||||
@reflection.klass.send :with_scope, *args, &block
|
||||
end
|
||||
end
|
||||
|
||||
[ ActiveRecord::Associations::AssociationCollection,
|
||||
ActiveRecord::Associations::HasManyThroughAssociation ].each do |klass|
|
||||
klass.class_eval do
|
||||
protected
|
||||
alias :method_missing_without_scopes :method_missing_without_paginate
|
||||
def method_missing_without_paginate(method, *args, &block)
|
||||
if @reflection.klass.scopes.include?(method)
|
||||
@reflection.klass.scopes[method].call(self, *args, &block)
|
||||
else
|
||||
method_missing_without_scopes(method, *args, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Rails 1.2.6
|
||||
ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
||||
protected
|
||||
def method_missing(method, *args, &block)
|
||||
if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
|
||||
super
|
||||
elsif @reflection.klass.scopes.include?(method)
|
||||
@reflection.klass.scopes[method].call(self, *args)
|
||||
else
|
||||
@reflection.klass.with_scope(:find => { :conditions => @finder_sql, :joins => @join_sql, :readonly => false }) do
|
||||
@reflection.klass.send(method, *args, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end if ActiveRecord::Base.respond_to? :find_first
|
||||
9
vendor/plugins/will_paginate/lib/will_paginate/version.rb
vendored
Normal file
9
vendor/plugins/will_paginate/lib/will_paginate/version.rb
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
module WillPaginate
|
||||
module VERSION
|
||||
MAJOR = 2
|
||||
MINOR = 3
|
||||
TINY = 3
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
end
|
||||
|
|
@ -49,12 +49,13 @@ module WillPaginate
|
|||
# * <tt>:param_name</tt> -- parameter name for page number in URLs (default: <tt>:page</tt>)
|
||||
# * <tt>:params</tt> -- additional parameters when generating pagination links
|
||||
# (eg. <tt>:controller => "foo", :action => nil</tt>)
|
||||
# * <tt>:renderer</tt> -- class name of the link renderer (default: WillPaginate::LinkRenderer)
|
||||
# * <tt>:renderer</tt> -- class name, class or instance of a link renderer (default:
|
||||
# <tt>WillPaginate::LinkRenderer</tt>)
|
||||
# * <tt>:page_links</tt> -- when false, only previous/next links are rendered (default: true)
|
||||
# * <tt>:container</tt> -- toggles rendering of the DIV container for pagination links, set to
|
||||
# false only when you are rendering your own pagination markup (default: true)
|
||||
# * <tt>:id</tt> -- HTML ID for the container (default: nil). Pass +true+ to have the ID automatically
|
||||
# generated from the class name of objects in collection: for example, paginating
|
||||
# * <tt>:id</tt> -- HTML ID for the container (default: nil). Pass +true+ to have the ID
|
||||
# automatically generated from the class name of objects in collection: for example, paginating
|
||||
# ArticleComment models would yield an ID of "article_comments_pagination".
|
||||
#
|
||||
# All options beside listed ones are passed as HTML attributes to the container
|
||||
|
|
@ -85,29 +86,99 @@ module WillPaginate
|
|||
collection_name = "@#{controller.controller_name}"
|
||||
collection = instance_variable_get(collection_name)
|
||||
raise ArgumentError, "The #{collection_name} variable appears to be empty. Did you " +
|
||||
"forget to specify the collection object for will_paginate?" unless collection
|
||||
"forget to pass the collection object for will_paginate?" unless collection
|
||||
end
|
||||
# early exit if there is nothing to render
|
||||
return nil unless collection.page_count > 1
|
||||
return nil unless WillPaginate::ViewHelpers.total_pages_for_collection(collection) > 1
|
||||
|
||||
options = options.symbolize_keys.reverse_merge WillPaginate::ViewHelpers.pagination_options
|
||||
# create the renderer instance
|
||||
renderer_class = options[:renderer].to_s.constantize
|
||||
renderer = renderer_class.new collection, options, self
|
||||
|
||||
# get the renderer instance
|
||||
renderer = case options[:renderer]
|
||||
when String
|
||||
options[:renderer].to_s.constantize.new
|
||||
when Class
|
||||
options[:renderer].new
|
||||
else
|
||||
options[:renderer]
|
||||
end
|
||||
# render HTML for pagination
|
||||
renderer.prepare collection, options, self
|
||||
renderer.to_html
|
||||
end
|
||||
|
||||
# Wrapper for rendering pagination links at both top and bottom of a block
|
||||
# of content.
|
||||
#
|
||||
# <% paginated_section @posts do %>
|
||||
# <ol id="posts">
|
||||
# <% for post in @posts %>
|
||||
# <li> ... </li>
|
||||
# <% end %>
|
||||
# </ol>
|
||||
# <% end %>
|
||||
#
|
||||
# will result in:
|
||||
#
|
||||
# <div class="pagination"> ... </div>
|
||||
# <ol id="posts">
|
||||
# ...
|
||||
# </ol>
|
||||
# <div class="pagination"> ... </div>
|
||||
#
|
||||
# Arguments are passed to a <tt>will_paginate</tt> call, so the same options
|
||||
# apply. Don't use the <tt>:id</tt> option; otherwise you'll finish with two
|
||||
# blocks of pagination links sharing the same ID (which is invalid HTML).
|
||||
def paginated_section(*args, &block)
|
||||
pagination = will_paginate(*args).to_s
|
||||
content = pagination + capture(&block) + pagination
|
||||
concat content, block.binding
|
||||
end
|
||||
|
||||
# Renders a helpful message with numbers of displayed vs. total entries.
|
||||
# You can use this as a blueprint for your own, similar helpers.
|
||||
#
|
||||
# <%= page_entries_info @posts %>
|
||||
# #-> Displaying entries 6 - 10 of 26 in total
|
||||
def page_entries_info(collection)
|
||||
%{Displaying entries <b>%d - %d</b> of <b>%d</b> in total} % [
|
||||
collection.offset + 1,
|
||||
collection.offset + collection.length,
|
||||
collection.total_entries
|
||||
]
|
||||
# #-> Displaying posts 6 - 10 of 26 in total
|
||||
#
|
||||
# By default, the message will use the humanized class name of objects
|
||||
# in collection: for instance, "project types" for ProjectType models.
|
||||
# Override this to your liking with the <tt>:entry_name</tt> parameter:
|
||||
#
|
||||
# <%= page_entries_info @posts, :entry_name => 'item' %>
|
||||
# #-> Displaying items 6 - 10 of 26 in total
|
||||
def page_entries_info(collection, options = {})
|
||||
entry_name = options[:entry_name] ||
|
||||
(collection.empty?? 'entry' : collection.first.class.name.underscore.sub('_', ' '))
|
||||
|
||||
if collection.total_pages < 2
|
||||
case collection.size
|
||||
when 0; "No #{entry_name.pluralize} found"
|
||||
when 1; "Displaying <b>1</b> #{entry_name}"
|
||||
else; "Displaying <b>all #{collection.size}</b> #{entry_name.pluralize}"
|
||||
end
|
||||
else
|
||||
%{Displaying #{entry_name.pluralize} <b>%d - %d</b> of <b>%d</b> in total} % [
|
||||
collection.offset + 1,
|
||||
collection.offset + collection.length,
|
||||
collection.total_entries
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
def self.total_pages_for_collection(collection) #:nodoc:
|
||||
if collection.respond_to?('page_count') and !collection.respond_to?('total_pages')
|
||||
WillPaginate::Deprecation.warn <<-MSG
|
||||
You are using a paginated collection of class #{collection.class.name}
|
||||
which conforms to the old API of WillPaginate::Collection by using
|
||||
`page_count`, while the current method name is `total_pages`. Please
|
||||
upgrade yours or 3rd-party code that provides the paginated collection.
|
||||
MSG
|
||||
class << collection
|
||||
def total_pages; page_count; end
|
||||
end
|
||||
end
|
||||
collection.total_pages
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -115,22 +186,43 @@ module WillPaginate
|
|||
# links. It is used by +will_paginate+ helper internally.
|
||||
class LinkRenderer
|
||||
|
||||
def initialize(collection, options, template)
|
||||
# The gap in page links is represented by:
|
||||
#
|
||||
# <span class="gap">…</span>
|
||||
attr_accessor :gap_marker
|
||||
|
||||
def initialize
|
||||
@gap_marker = '<span class="gap">…</span>'
|
||||
end
|
||||
|
||||
# * +collection+ is a WillPaginate::Collection instance or any other object
|
||||
# that conforms to that API
|
||||
# * +options+ are forwarded from +will_paginate+ view helper
|
||||
# * +template+ is the reference to the template being rendered
|
||||
def prepare(collection, options, template)
|
||||
@collection = collection
|
||||
@options = options
|
||||
@template = template
|
||||
|
||||
# reset values in case we're re-using this instance
|
||||
@total_pages = @param_name = @url_string = nil
|
||||
end
|
||||
|
||||
# Process it! This method returns the complete HTML string which contains
|
||||
# pagination links. Feel free to subclass LinkRenderer and change this
|
||||
# method as you see fit.
|
||||
def to_html
|
||||
links = @options[:page_links] ? windowed_links : []
|
||||
# previous/next buttons
|
||||
links.unshift page_link_or_span(@collection.previous_page, 'disabled', @options[:prev_label])
|
||||
links.push page_link_or_span(@collection.next_page, 'disabled', @options[:next_label])
|
||||
links.unshift page_link_or_span(@collection.previous_page, 'disabled prev_page', @options[:prev_label])
|
||||
links.push page_link_or_span(@collection.next_page, 'disabled next_page', @options[:next_label])
|
||||
|
||||
html = links.join(@options[:separator])
|
||||
@options[:container] ? @template.content_tag(:div, html, html_attributes) : html
|
||||
end
|
||||
|
||||
# Returns the subset of +options+ this instance was initialized with that
|
||||
# represent HTML attributes for the container element of pagination links.
|
||||
def html_attributes
|
||||
return @html_attributes if @html_attributes
|
||||
@html_attributes = @options.except *(WillPaginate::ViewHelpers.pagination_options.keys - [:class])
|
||||
|
|
@ -143,20 +235,21 @@ module WillPaginate
|
|||
|
||||
protected
|
||||
|
||||
def gap_marker; '...'; end
|
||||
|
||||
# Collects link items for visible page numbers.
|
||||
def windowed_links
|
||||
prev = nil
|
||||
|
||||
visible_page_numbers.inject [] do |links, n|
|
||||
# detect gaps:
|
||||
links << gap_marker if prev and n > prev + 1
|
||||
links << page_link_or_span(n)
|
||||
links << page_link_or_span(n, 'current')
|
||||
prev = n
|
||||
links
|
||||
end
|
||||
end
|
||||
|
||||
# Calculates visible page numbers using the <tt>:inner_window</tt> and
|
||||
# <tt>:outer_window</tt> options.
|
||||
def visible_page_numbers
|
||||
inner_window, outer_window = @options[:inner_window].to_i, @options[:outer_window].to_i
|
||||
window_from = current_page - inner_window
|
||||
|
|
@ -166,9 +259,11 @@ module WillPaginate
|
|||
if window_to > total_pages
|
||||
window_from -= window_to - total_pages
|
||||
window_to = total_pages
|
||||
elsif window_from < 1
|
||||
end
|
||||
if window_from < 1
|
||||
window_to += 1 - window_from
|
||||
window_from = 1
|
||||
window_to = total_pages if window_to > total_pages
|
||||
end
|
||||
|
||||
visible = (1..total_pages).to_a
|
||||
|
|
@ -180,21 +275,63 @@ module WillPaginate
|
|||
visible
|
||||
end
|
||||
|
||||
def page_link_or_span(page, span_class = 'current', text = nil)
|
||||
def page_link_or_span(page, span_class, text = nil)
|
||||
text ||= page.to_s
|
||||
|
||||
if page and page != current_page
|
||||
@template.link_to text, url_options(page), :rel => rel_value(page)
|
||||
classnames = span_class && span_class.index(' ') && span_class.split(' ', 2).last
|
||||
page_link page, text, :rel => rel_value(page), :class => classnames
|
||||
else
|
||||
@template.content_tag :span, text, :class => span_class
|
||||
page_span page, text, :class => span_class
|
||||
end
|
||||
end
|
||||
|
||||
def url_options(page)
|
||||
options = { param_name => page }
|
||||
# page links should preserve GET parameters
|
||||
options = params.merge(options) if @template.request.get?
|
||||
options.rec_merge!(@options[:params]) if @options[:params]
|
||||
return options
|
||||
def page_link(page, text, attributes = {})
|
||||
@template.link_to text, url_for(page), attributes
|
||||
end
|
||||
|
||||
def page_span(page, text, attributes = {})
|
||||
@template.content_tag :span, text, attributes
|
||||
end
|
||||
|
||||
# Returns URL params for +page_link_or_span+, taking the current GET params
|
||||
# and <tt>:params</tt> option into account.
|
||||
def url_for(page)
|
||||
page_one = page == 1
|
||||
unless @url_string and !page_one
|
||||
@url_params = {}
|
||||
# page links should preserve GET parameters
|
||||
stringified_merge @url_params, @template.params if @template.request.get?
|
||||
stringified_merge @url_params, @options[:params] if @options[:params]
|
||||
|
||||
if complex = param_name.index(/[^\w-]/)
|
||||
page_param = (defined?(CGIMethods) ? CGIMethods : ActionController::AbstractRequest).
|
||||
parse_query_parameters("#{param_name}=#{page}")
|
||||
|
||||
stringified_merge @url_params, page_param
|
||||
else
|
||||
@url_params[param_name] = page_one ? 1 : 2
|
||||
end
|
||||
|
||||
url = @template.url_for(@url_params)
|
||||
return url if page_one
|
||||
|
||||
if complex
|
||||
@url_string = url.sub(%r!((?:\?|&)#{CGI.escape param_name}=)#{page}!, '\1@')
|
||||
return url
|
||||
else
|
||||
@url_string = url
|
||||
@url_params[param_name] = 3
|
||||
@template.url_for(@url_params).split(//).each_with_index do |char, i|
|
||||
if char == '3' and url[i, 1] == '2'
|
||||
@url_string[i] = '@'
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# finally!
|
||||
@url_string.sub '@', page.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -212,15 +349,25 @@ module WillPaginate
|
|||
end
|
||||
|
||||
def total_pages
|
||||
@collection.page_count
|
||||
@total_pages ||= WillPaginate::ViewHelpers.total_pages_for_collection(@collection)
|
||||
end
|
||||
|
||||
def param_name
|
||||
@param_name ||= @options[:param_name].to_sym
|
||||
@param_name ||= @options[:param_name].to_s
|
||||
end
|
||||
|
||||
def params
|
||||
@params ||= @template.params.to_hash.symbolize_keys
|
||||
# Recursively merge into target hash by using stringified keys from the other one
|
||||
def stringified_merge(target, other)
|
||||
other.each do |key, value|
|
||||
key = key.to_s # this line is what it's all about!
|
||||
existing = target[key]
|
||||
|
||||
if value.is_a?(Hash) and (existing.is_a?(Hash) or existing.nil?)
|
||||
stringified_merge(existing || (target[key] = {}), value)
|
||||
else
|
||||
target[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
2
vendor/plugins/will_paginate/test/boot.rb
vendored
2
vendor/plugins/will_paginate/test/boot.rb
vendored
|
|
@ -19,5 +19,3 @@ else
|
|||
gem 'activerecord'
|
||||
end
|
||||
end
|
||||
|
||||
$:.unshift "#{plugin_root}/lib"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
require File.dirname(__FILE__) + '/helper'
|
||||
require 'will_paginate/core_ext'
|
||||
require 'helper'
|
||||
require 'will_paginate/array'
|
||||
|
||||
class ArrayPaginationTest < Test::Unit::TestCase
|
||||
def test_simple
|
||||
|
|
@ -11,7 +11,8 @@ class ArrayPaginationTest < Test::Unit::TestCase
|
|||
{ :page => 3, :per_page => 5, :expected => [] },
|
||||
].
|
||||
each do |conditions|
|
||||
assert_equal conditions[:expected], collection.paginate(conditions.slice(:page, :per_page))
|
||||
expected = conditions.delete :expected
|
||||
assert_equal expected, collection.paginate(conditions)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -22,14 +23,8 @@ class ArrayPaginationTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_deprecated_api
|
||||
assert_deprecated 'paginate API' do
|
||||
result = (1..50).to_a.paginate(2, 10)
|
||||
assert_equal 2, result.current_page
|
||||
assert_equal (11..20).to_a, result
|
||||
assert_equal 50, result.total_entries
|
||||
end
|
||||
|
||||
assert_deprecated { [].paginate nil }
|
||||
assert_raise(ArgumentError) { [].paginate(2) }
|
||||
assert_raise(ArgumentError) { [].paginate(2, 10) }
|
||||
end
|
||||
|
||||
def test_total_entries_has_precedence
|
||||
|
|
@ -50,14 +45,28 @@ class ArrayPaginationTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
assert_equal entries, collection
|
||||
assert_respond_to_all collection, %w(page_count each offset size current_page per_page total_entries)
|
||||
assert_respond_to_all collection, %w(total_pages each offset size current_page per_page total_entries)
|
||||
assert_kind_of Array, collection
|
||||
assert_instance_of Array, collection.entries
|
||||
assert_equal 3, collection.offset
|
||||
assert_equal 4, collection.page_count
|
||||
assert_equal 4, collection.total_pages
|
||||
assert !collection.out_of_bounds?
|
||||
end
|
||||
|
||||
def test_previous_next_pages
|
||||
collection = create(1, 1, 3)
|
||||
assert_nil collection.previous_page
|
||||
assert_equal 2, collection.next_page
|
||||
|
||||
collection = create(2, 1, 3)
|
||||
assert_equal 1, collection.previous_page
|
||||
assert_equal 3, collection.next_page
|
||||
|
||||
collection = create(3, 1, 3)
|
||||
assert_equal 2, collection.previous_page
|
||||
assert_nil collection.next_page
|
||||
end
|
||||
|
||||
def test_out_of_bounds
|
||||
entries = create(2, 3, 2){}
|
||||
assert entries.out_of_bounds?
|
||||
|
|
@ -90,13 +99,20 @@ class ArrayPaginationTest < Test::Unit::TestCase
|
|||
pager.replace array(0)
|
||||
end
|
||||
assert_equal nil, entries.total_entries
|
||||
|
||||
entries = create(1) do |pager|
|
||||
# collection is empty and we're on page 1,
|
||||
# so the whole thing must be empty, too
|
||||
pager.replace array(0)
|
||||
end
|
||||
assert_equal 0, entries.total_entries
|
||||
end
|
||||
|
||||
def test_invalid_page
|
||||
bad_input = [0, -1, nil, '', 'Schnitzel']
|
||||
bad_inputs = [0, -1, nil, '', 'Schnitzel']
|
||||
|
||||
bad_input.each do |bad|
|
||||
assert_raise(WillPaginate::InvalidPage) { create(bad) }
|
||||
bad_inputs.each do |bad|
|
||||
assert_raise(WillPaginate::InvalidPage) { create bad }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -104,6 +120,11 @@ class ArrayPaginationTest < Test::Unit::TestCase
|
|||
assert_raise(ArgumentError) { create(1, -1) }
|
||||
end
|
||||
|
||||
def test_page_count_was_removed
|
||||
assert_raise(NoMethodError) { create.page_count }
|
||||
# It's `total_pages` now.
|
||||
end
|
||||
|
||||
private
|
||||
def create(page = 2, limit = 5, total = nil, &block)
|
||||
if block_given?
|
||||
|
|
@ -116,16 +137,4 @@ class ArrayPaginationTest < Test::Unit::TestCase
|
|||
def array(size = 3)
|
||||
Array.new(size)
|
||||
end
|
||||
|
||||
def collect_deprecations
|
||||
old_behavior = WillPaginate::Deprecation.behavior
|
||||
deprecations = []
|
||||
WillPaginate::Deprecation.behavior = Proc.new do |message, callstack|
|
||||
deprecations << message
|
||||
end
|
||||
result = yield
|
||||
[result, deprecations]
|
||||
ensure
|
||||
WillPaginate::Deprecation.behavior = old_behavior
|
||||
end
|
||||
end
|
||||
5
vendor/plugins/will_paginate/test/console
vendored
5
vendor/plugins/will_paginate/test/console
vendored
|
|
@ -1,9 +1,8 @@
|
|||
#!/usr/bin/env ruby
|
||||
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
||||
libs = []
|
||||
dirname = File.dirname(__FILE__)
|
||||
|
||||
libs << 'irb/completion'
|
||||
libs << File.join(dirname, 'lib', 'load_fixtures')
|
||||
libs << File.join('lib', 'load_fixtures')
|
||||
|
||||
exec "#{irb}#{libs.map{ |l| " -r #{l}" }.join} --simple-prompt"
|
||||
exec "#{irb} -Ilib:test#{libs.map{ |l| " -r #{l}" }.join} --simple-prompt"
|
||||
|
|
|
|||
222
vendor/plugins/will_paginate/test/finder_test.rb
vendored
222
vendor/plugins/will_paginate/test/finder_test.rb
vendored
|
|
@ -1,8 +1,9 @@
|
|||
require File.dirname(__FILE__) + '/helper'
|
||||
require File.dirname(__FILE__) + '/lib/activerecord_test_case'
|
||||
require 'helper'
|
||||
require 'lib/activerecord_test_case'
|
||||
|
||||
require 'will_paginate'
|
||||
WillPaginate.enable_activerecord
|
||||
WillPaginate.enable_named_scope
|
||||
|
||||
class FinderTest < ActiveRecordTestCase
|
||||
fixtures :topics, :replies, :users, :projects, :developers_projects
|
||||
|
|
@ -12,18 +13,18 @@ class FinderTest < ActiveRecordTestCase
|
|||
end
|
||||
|
||||
def test_simple_paginate
|
||||
entries = Topic.paginate :page => nil
|
||||
assert_equal 1, entries.current_page
|
||||
assert_nil entries.previous_page
|
||||
assert_nil entries.next_page
|
||||
assert_equal 1, entries.page_count
|
||||
assert_equal 4, entries.size
|
||||
assert_queries(1) do
|
||||
entries = Topic.paginate :page => nil
|
||||
assert_equal 1, entries.current_page
|
||||
assert_equal 1, entries.total_pages
|
||||
assert_equal 4, entries.size
|
||||
end
|
||||
|
||||
entries = Topic.paginate :page => 2
|
||||
assert_equal 2, entries.current_page
|
||||
assert_equal 1, entries.previous_page
|
||||
assert_equal 1, entries.page_count
|
||||
assert entries.empty?
|
||||
assert_queries(2) do
|
||||
entries = Topic.paginate :page => 2
|
||||
assert_equal 1, entries.total_pages
|
||||
assert entries.empty?
|
||||
end
|
||||
end
|
||||
|
||||
def test_parameter_api
|
||||
|
|
@ -41,31 +42,31 @@ class FinderTest < ActiveRecordTestCase
|
|||
def test_paginate_with_per_page
|
||||
entries = Topic.paginate :page => 1, :per_page => 1
|
||||
assert_equal 1, entries.size
|
||||
assert_equal 4, entries.page_count
|
||||
assert_equal 4, entries.total_pages
|
||||
|
||||
# Developer class has explicit per_page at 10
|
||||
entries = Developer.paginate :page => 1
|
||||
assert_equal 10, entries.size
|
||||
assert_equal 2, entries.page_count
|
||||
assert_equal 2, entries.total_pages
|
||||
|
||||
entries = Developer.paginate :page => 1, :per_page => 5
|
||||
assert_equal 11, entries.total_entries
|
||||
assert_equal 5, entries.size
|
||||
assert_equal 3, entries.page_count
|
||||
assert_equal 3, entries.total_pages
|
||||
end
|
||||
|
||||
def test_paginate_with_order
|
||||
entries = Topic.paginate :page => 1, :order => 'created_at desc'
|
||||
expected = [topics(:futurama), topics(:harvey_birdman), topics(:rails), topics(:ar)].reverse
|
||||
assert_equal expected, entries.to_a
|
||||
assert_equal 1, entries.page_count
|
||||
assert_equal 1, entries.total_pages
|
||||
end
|
||||
|
||||
def test_paginate_with_conditions
|
||||
entries = Topic.paginate :page => 1, :conditions => ["created_at > ?", 30.minutes.ago]
|
||||
expected = [topics(:rails), topics(:ar)]
|
||||
assert_equal expected, entries.to_a
|
||||
assert_equal 1, entries.page_count
|
||||
assert_equal 1, entries.total_pages
|
||||
end
|
||||
|
||||
def test_paginate_with_include_and_conditions
|
||||
|
|
@ -85,11 +86,14 @@ class FinderTest < ActiveRecordTestCase
|
|||
end
|
||||
|
||||
def test_paginate_with_include_and_order
|
||||
entries = Topic.paginate \
|
||||
:page => 1,
|
||||
:include => :replies,
|
||||
:order => 'replies.created_at asc, topics.created_at asc',
|
||||
:per_page => 10
|
||||
entries = nil
|
||||
assert_queries(2) do
|
||||
entries = Topic.paginate \
|
||||
:page => 1,
|
||||
:include => :replies,
|
||||
:order => 'replies.created_at asc, topics.created_at asc',
|
||||
:per_page => 10
|
||||
end
|
||||
|
||||
expected = Topic.find :all,
|
||||
:include => 'replies',
|
||||
|
|
@ -104,7 +108,7 @@ class FinderTest < ActiveRecordTestCase
|
|||
entries, project = nil, projects(:active_record)
|
||||
|
||||
assert_nothing_raised "THIS IS A BUG in Rails 1.2.3 that was fixed in [7326]. " +
|
||||
"Please upgrade to the 1-2-stable branch or edge Rails." do
|
||||
"Please upgrade to a newer version of Rails." do
|
||||
entries = project.topics.paginate \
|
||||
:page => 1,
|
||||
:include => :replies,
|
||||
|
|
@ -125,10 +129,12 @@ class FinderTest < ActiveRecordTestCase
|
|||
expected_name_ordered = [projects(:action_controller), projects(:active_record)]
|
||||
expected_id_ordered = [projects(:active_record), projects(:action_controller)]
|
||||
|
||||
# with association-specified order
|
||||
entries = dhh.projects.paginate(:page => 1)
|
||||
assert_equal expected_name_ordered, entries
|
||||
assert_equal 2, entries.total_entries
|
||||
assert_queries(2) do
|
||||
# with association-specified order
|
||||
entries = dhh.projects.paginate(:page => 1)
|
||||
assert_equal expected_name_ordered, entries
|
||||
assert_equal 2, entries.total_entries
|
||||
end
|
||||
|
||||
# with explicit order
|
||||
entries = dhh.projects.paginate(:page => 1, :order => 'projects.id')
|
||||
|
|
@ -148,29 +154,43 @@ class FinderTest < ActiveRecordTestCase
|
|||
|
||||
def test_paginate_association_extension
|
||||
project = Project.find(:first)
|
||||
entries = project.replies.paginate_recent :page => 1
|
||||
assert_equal [replies(:brave)], entries
|
||||
|
||||
assert_queries(2) do
|
||||
entries = project.replies.paginate_recent :page => 1
|
||||
assert_equal [replies(:brave)], entries
|
||||
end
|
||||
end
|
||||
|
||||
def test_paginate_with_joins
|
||||
entries = Developer.paginate :page => 1,
|
||||
:joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
|
||||
:conditions => 'project_id = 1'
|
||||
assert_equal 2, entries.size
|
||||
developer_names = entries.map { |d| d.name }
|
||||
assert developer_names.include?('David')
|
||||
assert developer_names.include?('Jamis')
|
||||
entries = nil
|
||||
|
||||
assert_queries(1) do
|
||||
entries = Developer.paginate :page => 1,
|
||||
:joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
|
||||
:conditions => 'project_id = 1'
|
||||
assert_equal 2, entries.size
|
||||
developer_names = entries.map &:name
|
||||
assert developer_names.include?('David')
|
||||
assert developer_names.include?('Jamis')
|
||||
end
|
||||
|
||||
expected = entries.to_a
|
||||
entries = Developer.paginate :page => 1,
|
||||
:joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
|
||||
:conditions => 'project_id = 1', :count => { :select => "users.id" }
|
||||
assert_equal expected, entries.to_a
|
||||
assert_queries(1) do
|
||||
expected = entries.to_a
|
||||
entries = Developer.paginate :page => 1,
|
||||
:joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
|
||||
:conditions => 'project_id = 1', :count => { :select => "users.id" }
|
||||
assert_equal expected, entries.to_a
|
||||
assert_equal 2, entries.total_entries
|
||||
end
|
||||
end
|
||||
|
||||
def test_paginate_with_group
|
||||
entries = Developer.paginate :page => 1, :per_page => 10,
|
||||
:group => 'salary', :select => 'salary', :order => 'salary'
|
||||
entries = nil
|
||||
assert_queries(1) do
|
||||
entries = Developer.paginate :page => 1, :per_page => 10,
|
||||
:group => 'salary', :select => 'salary', :order => 'salary'
|
||||
end
|
||||
|
||||
expected = [ users(:david), users(:jamis), users(:dev_10), users(:poor_jamis) ].map(&:salary).sort
|
||||
assert_equal expected, entries.map(&:salary)
|
||||
end
|
||||
|
|
@ -201,6 +221,56 @@ class FinderTest < ActiveRecordTestCase
|
|||
assert_equal 2, entries.total_entries
|
||||
end
|
||||
|
||||
## named_scope ##
|
||||
|
||||
def test_paginate_in_named_scope
|
||||
entries = Developer.poor.paginate :page => 1, :per_page => 1
|
||||
|
||||
assert_equal 1, entries.size
|
||||
assert_equal 2, entries.total_entries
|
||||
end
|
||||
|
||||
def test_paginate_in_named_scope_on_habtm_association
|
||||
project = projects(:active_record)
|
||||
assert_queries(2) do
|
||||
entries = project.developers.poor.paginate :page => 1, :per_page => 1
|
||||
|
||||
assert_equal 1, entries.size, 'one developer should be found'
|
||||
assert_equal 1, entries.total_entries, 'only one developer should be found'
|
||||
end
|
||||
end
|
||||
|
||||
def test_paginate_in_named_scope_on_hmt_association
|
||||
project = projects(:active_record)
|
||||
expected = [replies(:brave)]
|
||||
|
||||
assert_queries(2) do
|
||||
entries = project.replies.recent.paginate :page => 1, :per_page => 1
|
||||
assert_equal expected, entries
|
||||
assert_equal 1, entries.total_entries, 'only one reply should be found'
|
||||
end
|
||||
end
|
||||
|
||||
def test_paginate_in_named_scope_on_has_many_association
|
||||
project = projects(:active_record)
|
||||
expected = [topics(:ar)]
|
||||
|
||||
assert_queries(2) do
|
||||
entries = project.topics.mentions_activerecord.paginate :page => 1, :per_page => 1
|
||||
assert_equal expected, entries
|
||||
assert_equal 1, entries.total_entries, 'only one topic should be found'
|
||||
end
|
||||
end
|
||||
|
||||
## misc ##
|
||||
|
||||
def test_count_and_total_entries_options_are_mutually_exclusive
|
||||
e = assert_raise ArgumentError do
|
||||
Developer.paginate :page => 1, :count => {}, :total_entries => 1
|
||||
end
|
||||
assert_match /exclusive/, e.to_s
|
||||
end
|
||||
|
||||
def test_readonly
|
||||
assert_nothing_raised { Developer.paginate :readonly => true, :page => 1 }
|
||||
end
|
||||
|
|
@ -216,13 +286,15 @@ class FinderTest < ActiveRecordTestCase
|
|||
end
|
||||
|
||||
# Is this Rails 2.0? Find out by testing find_all which was removed in [6998]
|
||||
unless Developer.respond_to? :find_all
|
||||
unless ActiveRecord::Base.respond_to? :find_all
|
||||
def test_paginate_array_of_ids
|
||||
# AR finders also accept arrays of IDs
|
||||
# (this was broken in Rails before [6912])
|
||||
entries = Developer.paginate((1..8).to_a, :per_page => 3, :page => 2, :order => 'id')
|
||||
assert_equal (4..6).to_a, entries.map(&:id)
|
||||
assert_equal 8, entries.total_entries
|
||||
assert_queries(1) do
|
||||
entries = Developer.paginate((1..8).to_a, :per_page => 3, :page => 2, :order => 'id')
|
||||
assert_equal (4..6).to_a, entries.map(&:id)
|
||||
assert_equal 8, entries.total_entries
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -230,7 +302,7 @@ class FinderTest < ActiveRecordTestCase
|
|||
def test_implicit_all_with_dynamic_finders
|
||||
Topic.expects(:find_all_by_foo).returns([])
|
||||
Topic.expects(:count).returns(0)
|
||||
Topic.paginate_by_foo :page => 1
|
||||
Topic.paginate_by_foo :page => 2
|
||||
end
|
||||
|
||||
def test_guessing_the_total_count
|
||||
|
|
@ -241,6 +313,14 @@ class FinderTest < ActiveRecordTestCase
|
|||
assert_equal 6, entries.total_entries
|
||||
end
|
||||
|
||||
def test_guessing_that_there_are_no_records
|
||||
Topic.expects(:find).returns([])
|
||||
Topic.expects(:count).never
|
||||
|
||||
entries = Topic.paginate :page => 1, :per_page => 4
|
||||
assert_equal 0, entries.total_entries
|
||||
end
|
||||
|
||||
def test_extra_parameters_stay_untouched
|
||||
Topic.expects(:find).with(:all, {:foo => 'bar', :limit => 4, :offset => 0 }).returns(Array.new(5))
|
||||
Topic.expects(:count).with({:foo => 'bar'}).returns(1)
|
||||
|
|
@ -251,13 +331,13 @@ class FinderTest < ActiveRecordTestCase
|
|||
def test_count_skips_select
|
||||
Developer.stubs(:find).returns([])
|
||||
Developer.expects(:count).with({}).returns(0)
|
||||
Developer.paginate :select => 'salary', :page => 1
|
||||
Developer.paginate :select => 'salary', :page => 2
|
||||
end
|
||||
|
||||
def test_count_select_when_distinct
|
||||
Developer.stubs(:find).returns([])
|
||||
Developer.expects(:count).with(:select => 'DISTINCT salary').returns(0)
|
||||
Developer.paginate :select => 'DISTINCT salary', :page => 1
|
||||
Developer.paginate :select => 'DISTINCT salary', :page => 2
|
||||
end
|
||||
|
||||
def test_should_use_scoped_finders_if_present
|
||||
|
|
@ -288,16 +368,16 @@ class FinderTest < ActiveRecordTestCase
|
|||
Developer.expects(:find_by_sql).returns([])
|
||||
Developer.expects(:count_by_sql).with("SELECT COUNT(*) FROM (sql\n ) AS count_table").returns(0)
|
||||
|
||||
entries = Developer.paginate_by_sql "sql\n ORDER\nby foo, bar, `baz` ASC", :page => 1
|
||||
Developer.paginate_by_sql "sql\n ORDER\nby foo, bar, `baz` ASC", :page => 2
|
||||
end
|
||||
|
||||
# TODO: counts are still wrong
|
||||
def test_ability_to_use_with_custom_finders
|
||||
# acts_as_taggable defines find_tagged_with(tag, options)
|
||||
Topic.expects(:find_tagged_with).with('will_paginate', :offset => 0, :limit => 5).returns([])
|
||||
Topic.expects(:find_tagged_with).with('will_paginate', :offset => 5, :limit => 5).returns([])
|
||||
Topic.expects(:count).with({}).returns(0)
|
||||
|
||||
Topic.paginate_tagged_with 'will_paginate', :page => 1, :per_page => 5
|
||||
Topic.paginate_tagged_with 'will_paginate', :page => 2, :per_page => 5
|
||||
end
|
||||
|
||||
def test_array_argument_doesnt_eliminate_count
|
||||
|
|
@ -310,7 +390,6 @@ class FinderTest < ActiveRecordTestCase
|
|||
|
||||
def test_paginating_finder_doesnt_mangle_options
|
||||
Developer.expects(:find).returns([])
|
||||
Developer.expects(:count).returns(0)
|
||||
options = { :page => 1 }
|
||||
options.expects(:delete).never
|
||||
options_before = options.dup
|
||||
|
|
@ -318,5 +397,38 @@ class FinderTest < ActiveRecordTestCase
|
|||
Developer.paginate(options)
|
||||
assert_equal options, options_before
|
||||
end
|
||||
|
||||
def test_paginated_each
|
||||
collection = stub('collection', :size => 5, :empty? => false, :per_page => 5)
|
||||
collection.expects(:each).times(2).returns(collection)
|
||||
last_collection = stub('collection', :size => 4, :empty? => false, :per_page => 5)
|
||||
last_collection.expects(:each).returns(last_collection)
|
||||
|
||||
params = { :order => 'id', :total_entries => 0 }
|
||||
|
||||
Developer.expects(:paginate).with(params.merge(:page => 2)).returns(collection)
|
||||
Developer.expects(:paginate).with(params.merge(:page => 3)).returns(collection)
|
||||
Developer.expects(:paginate).with(params.merge(:page => 4)).returns(last_collection)
|
||||
|
||||
assert_equal 14, Developer.paginated_each(:page => '2') { }
|
||||
end
|
||||
|
||||
# detect ActiveRecord 2.1
|
||||
if ActiveRecord::Base.private_methods.include?('references_eager_loaded_tables?')
|
||||
def test_removes_irrelevant_includes_in_count
|
||||
Developer.expects(:find).returns([1])
|
||||
Developer.expects(:count).with({}).returns(0)
|
||||
|
||||
Developer.paginate :page => 1, :per_page => 1, :include => :projects
|
||||
end
|
||||
|
||||
def test_doesnt_remove_referenced_includes_in_count
|
||||
Developer.expects(:find).returns([1])
|
||||
Developer.expects(:count).with({ :include => :projects, :conditions => 'projects.id > 2' }).returns(0)
|
||||
|
||||
Developer.paginate :page => 1, :per_page => 1,
|
||||
:include => :projects, :conditions => 'projects.id > 2'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,5 +7,7 @@ class Developer < User
|
|||
end
|
||||
end
|
||||
|
||||
named_scope :poor, :conditions => ['salary <= ?', 80000], :order => 'salary'
|
||||
|
||||
def self.per_page() 10 end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
action_controller:
|
||||
id: 2
|
||||
name: Active Controller
|
||||
|
||||
active_record:
|
||||
id: 1
|
||||
name: Active Record
|
||||
action_controller:
|
||||
id: 2
|
||||
name: Active Controller
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
class Reply < ActiveRecord::Base
|
||||
belongs_to :topic, :include => [:replies]
|
||||
|
||||
named_scope :recent, :conditions => ['replies.created_at > ?', 15.minutes.ago]
|
||||
|
||||
validates_presence_of :content
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
class Topic < ActiveRecord::Base
|
||||
has_many :replies, :dependent => :destroy, :order => 'replies.created_at DESC'
|
||||
belongs_to :project
|
||||
|
||||
named_scope :mentions_activerecord, :conditions => ['topics.title LIKE ?', '%ActiveRecord%']
|
||||
end
|
||||
|
|
|
|||
14
vendor/plugins/will_paginate/test/helper.rb
vendored
14
vendor/plugins/will_paginate/test/helper.rb
vendored
|
|
@ -4,7 +4,7 @@ require 'rubygems'
|
|||
# gem install redgreen for colored test output
|
||||
begin require 'redgreen'; rescue LoadError; end
|
||||
|
||||
require File.join(File.dirname(__FILE__), 'boot') unless defined?(ActiveRecord)
|
||||
require 'boot' unless defined?(ActiveRecord)
|
||||
|
||||
class Test::Unit::TestCase
|
||||
protected
|
||||
|
|
@ -13,6 +13,18 @@ class Test::Unit::TestCase
|
|||
[method.to_s, method.to_sym].each { |m| assert_respond_to object, m }
|
||||
end
|
||||
end
|
||||
|
||||
def collect_deprecations
|
||||
old_behavior = WillPaginate::Deprecation.behavior
|
||||
deprecations = []
|
||||
WillPaginate::Deprecation.behavior = Proc.new do |message, callstack|
|
||||
deprecations << message
|
||||
end
|
||||
result = yield
|
||||
[result, deprecations]
|
||||
ensure
|
||||
WillPaginate::Deprecation.behavior = old_behavior
|
||||
end
|
||||
end
|
||||
|
||||
# Wrap tests that use Mocha and skip if unavailable.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
require File.join(File.dirname(__FILE__), 'activerecord_test_connector')
|
||||
require 'lib/activerecord_test_connector'
|
||||
|
||||
class ActiveRecordTestCase < Test::Unit::TestCase
|
||||
# Set our fixture path
|
||||
|
|
@ -18,6 +18,19 @@ class ActiveRecordTestCase < Test::Unit::TestCase
|
|||
# Default so Test::Unit::TestCase doesn't complain
|
||||
def test_truth
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def assert_queries(num = 1)
|
||||
$query_count = 0
|
||||
yield
|
||||
ensure
|
||||
assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed."
|
||||
end
|
||||
|
||||
def assert_no_queries(&block)
|
||||
assert_queries(0, &block)
|
||||
end
|
||||
end
|
||||
|
||||
ActiveRecordTestConnector.setup
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ class ActiveRecordTestConnector
|
|||
cattr_accessor :able_to_connect
|
||||
cattr_accessor :connected
|
||||
|
||||
FIXTURES_PATH = File.join(File.dirname(__FILE__), '..', 'fixtures')
|
||||
|
||||
# Set our defaults
|
||||
self.connected = false
|
||||
self.able_to_connect = true
|
||||
|
|
@ -14,13 +16,12 @@ class ActiveRecordTestConnector
|
|||
unless self.connected || !self.able_to_connect
|
||||
setup_connection
|
||||
load_schema
|
||||
# require_fixture_models
|
||||
Dependencies.load_paths.unshift(File.dirname(__FILE__) + "/../fixtures")
|
||||
Dependencies.load_paths.unshift FIXTURES_PATH
|
||||
self.connected = true
|
||||
end
|
||||
rescue Exception => e # errors from ActiveRecord setup
|
||||
$stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}"
|
||||
#$stderr.puts " #{e.backtrace.join("\n ")}\n"
|
||||
$stderr.puts "\nSkipping ActiveRecord tests: #{e}"
|
||||
$stderr.puts "Install SQLite3 to run the full test suite for will_paginate.\n\n"
|
||||
self.able_to_connect = false
|
||||
end
|
||||
|
||||
|
|
@ -38,7 +39,7 @@ class ActiveRecordTestConnector
|
|||
|
||||
ActiveRecord::Base.establish_connection(configuration)
|
||||
ActiveRecord::Base.configurations = { db => configuration }
|
||||
ActiveRecord::Base.connection
|
||||
prepare ActiveRecord::Base.connection
|
||||
|
||||
unless Object.const_defined?(:QUOTED_TYPE)
|
||||
Object.send :const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')
|
||||
|
|
@ -48,13 +49,21 @@ class ActiveRecordTestConnector
|
|||
def self.load_schema
|
||||
ActiveRecord::Base.silence do
|
||||
ActiveRecord::Migration.verbose = false
|
||||
load File.dirname(__FILE__) + "/../fixtures/schema.rb"
|
||||
load File.join(FIXTURES_PATH, 'schema.rb')
|
||||
end
|
||||
end
|
||||
|
||||
def self.require_fixture_models
|
||||
models = Dir.glob(File.dirname(__FILE__) + "/../fixtures/*.rb")
|
||||
models = (models.grep(/user.rb/) + models).uniq
|
||||
models.each { |f| require f }
|
||||
def self.prepare(conn)
|
||||
class << conn
|
||||
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SHOW FIELDS /]
|
||||
|
||||
def execute_with_counting(sql, name = nil, &block)
|
||||
$query_count ||= 0
|
||||
$query_count += 1 unless IGNORED_SQL.any? { |r| sql =~ r }
|
||||
execute_without_counting(sql, name, &block)
|
||||
end
|
||||
|
||||
alias_method_chain :execute, :counting
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
require 'action_controller/test_process'
|
||||
|
||||
module HTML
|
||||
class Node
|
||||
def inner_text
|
||||
children.map(&:inner_text).join('')
|
||||
end
|
||||
end
|
||||
|
||||
class Text
|
||||
def inner_text
|
||||
self.to_s
|
||||
end
|
||||
end
|
||||
|
||||
class Tag
|
||||
def inner_text
|
||||
childless?? '' : super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,13 +1,11 @@
|
|||
dirname = File.dirname(__FILE__)
|
||||
require File.join(dirname, '..', 'boot')
|
||||
require File.join(dirname, 'activerecord_test_connector')
|
||||
require 'boot'
|
||||
require 'lib/activerecord_test_connector'
|
||||
|
||||
# setup the connection
|
||||
ActiveRecordTestConnector.setup
|
||||
|
||||
# load all fixtures
|
||||
fixture_path = File.join(dirname, '..', 'fixtures')
|
||||
Fixtures.create_fixtures(fixture_path, ActiveRecord::Base.connection.tables)
|
||||
Fixtures.create_fixtures(ActiveRecordTestConnector::FIXTURES_PATH, ActiveRecord::Base.connection.tables)
|
||||
|
||||
require 'will_paginate'
|
||||
WillPaginate.enable_activerecord
|
||||
|
|
|
|||
165
vendor/plugins/will_paginate/test/lib/view_test_process.rb
vendored
Normal file
165
vendor/plugins/will_paginate/test/lib/view_test_process.rb
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
require 'action_controller'
|
||||
require 'action_controller/test_process'
|
||||
|
||||
require 'will_paginate'
|
||||
WillPaginate.enable_actionpack
|
||||
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
map.connect 'dummy/page/:page', :controller => 'dummy'
|
||||
map.connect 'dummy/dots/page.:page', :controller => 'dummy', :action => 'dots'
|
||||
map.connect 'ibocorp/:page', :controller => 'ibocorp',
|
||||
:requirements => { :page => /\d+/ },
|
||||
:defaults => { :page => 1 }
|
||||
|
||||
map.connect ':controller/:action/:id'
|
||||
end
|
||||
|
||||
ActionController::Base.perform_caching = false
|
||||
|
||||
class WillPaginate::ViewTestCase < Test::Unit::TestCase
|
||||
def setup
|
||||
super
|
||||
@controller = DummyController.new
|
||||
@request = @controller.request
|
||||
@html_result = nil
|
||||
@template = '<%= will_paginate collection, options %>'
|
||||
|
||||
@view = ActionView::Base.new
|
||||
@view.assigns['controller'] = @controller
|
||||
@view.assigns['_request'] = @request
|
||||
@view.assigns['_params'] = @request.params
|
||||
end
|
||||
|
||||
def test_no_complain; end
|
||||
|
||||
protected
|
||||
|
||||
def paginate(collection = {}, options = {}, &block)
|
||||
if collection.instance_of? Hash
|
||||
page_options = { :page => 1, :total_entries => 11, :per_page => 4 }.merge(collection)
|
||||
collection = [1].paginate(page_options)
|
||||
end
|
||||
|
||||
locals = { :collection => collection, :options => options }
|
||||
|
||||
if defined? ActionView::InlineTemplate
|
||||
# Rails 2.1
|
||||
args = [ ActionView::InlineTemplate.new(@view, @template, locals) ]
|
||||
else
|
||||
# older Rails versions
|
||||
args = [nil, @template, nil, locals]
|
||||
end
|
||||
|
||||
@html_result = @view.render_template(*args)
|
||||
@html_document = HTML::Document.new(@html_result, true, false)
|
||||
|
||||
if block_given?
|
||||
classname = options[:class] || WillPaginate::ViewHelpers.pagination_options[:class]
|
||||
assert_select("div.#{classname}", 1, 'no main DIV', &block)
|
||||
end
|
||||
end
|
||||
|
||||
def response_from_page_or_rjs
|
||||
@html_document.root
|
||||
end
|
||||
|
||||
def validate_page_numbers expected, links, param_name = :page
|
||||
param_pattern = /\W#{CGI.escape(param_name.to_s)}=([^&]*)/
|
||||
|
||||
assert_equal(expected, links.map { |e|
|
||||
e['href'] =~ param_pattern
|
||||
$1 ? $1.to_i : $1
|
||||
})
|
||||
end
|
||||
|
||||
def assert_links_match pattern, links = nil, numbers = nil
|
||||
links ||= assert_select 'div.pagination a[href]' do |elements|
|
||||
elements
|
||||
end
|
||||
|
||||
pages = [] if numbers
|
||||
|
||||
links.each do |el|
|
||||
assert_match pattern, el['href']
|
||||
if numbers
|
||||
el['href'] =~ pattern
|
||||
pages << ($1.nil?? nil : $1.to_i)
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal numbers, pages, "page numbers don't match" if numbers
|
||||
end
|
||||
|
||||
def assert_no_links_match pattern
|
||||
assert_select 'div.pagination a[href]' do |elements|
|
||||
elements.each do |el|
|
||||
assert_no_match pattern, el['href']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class DummyRequest
|
||||
attr_accessor :symbolized_path_parameters
|
||||
|
||||
def initialize
|
||||
@get = true
|
||||
@params = {}
|
||||
@symbolized_path_parameters = { :controller => 'foo', :action => 'bar' }
|
||||
end
|
||||
|
||||
def get?
|
||||
@get
|
||||
end
|
||||
|
||||
def post
|
||||
@get = false
|
||||
end
|
||||
|
||||
def relative_url_root
|
||||
''
|
||||
end
|
||||
|
||||
def params(more = nil)
|
||||
@params.update(more) if more
|
||||
@params
|
||||
end
|
||||
end
|
||||
|
||||
class DummyController
|
||||
attr_reader :request
|
||||
attr_accessor :controller_name
|
||||
|
||||
def initialize
|
||||
@request = DummyRequest.new
|
||||
@url = ActionController::UrlRewriter.new(@request, @request.params)
|
||||
end
|
||||
|
||||
def params
|
||||
@request.params
|
||||
end
|
||||
|
||||
def url_for(params)
|
||||
@url.rewrite(params)
|
||||
end
|
||||
end
|
||||
|
||||
module HTML
|
||||
Node.class_eval do
|
||||
def inner_text
|
||||
children.map(&:inner_text).join('')
|
||||
end
|
||||
end
|
||||
|
||||
Text.class_eval do
|
||||
def inner_text
|
||||
self.to_s
|
||||
end
|
||||
end
|
||||
|
||||
Tag.class_eval do
|
||||
def inner_text
|
||||
childless?? '' : super
|
||||
end
|
||||
end
|
||||
end
|
||||
272
vendor/plugins/will_paginate/test/pagination_test.rb
vendored
272
vendor/plugins/will_paginate/test/pagination_test.rb
vendored
|
|
@ -1,272 +0,0 @@
|
|||
require File.dirname(__FILE__) + '/helper'
|
||||
require 'action_controller'
|
||||
require File.dirname(__FILE__) + '/lib/html_inner_text'
|
||||
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
map.connect ':controller/:action/:id'
|
||||
end
|
||||
|
||||
ActionController::Base.perform_caching = false
|
||||
|
||||
require 'will_paginate'
|
||||
WillPaginate.enable_actionpack
|
||||
|
||||
class PaginationTest < Test::Unit::TestCase
|
||||
|
||||
class DevelopersController < ActionController::Base
|
||||
def list_developers
|
||||
@options = session[:wp] || {}
|
||||
|
||||
@developers = (1..11).to_a.paginate(
|
||||
:page => params[@options[:param_name] || :page] || 1,
|
||||
:per_page => params[:per_page] || 4
|
||||
)
|
||||
|
||||
render :inline => '<%= will_paginate @developers, @options %>'
|
||||
end
|
||||
|
||||
def guess_collection_name
|
||||
@developers = session[:wp]
|
||||
@options = session[:wp_options]
|
||||
render :inline => '<%= will_paginate @options %>'
|
||||
end
|
||||
|
||||
protected
|
||||
def rescue_errors(e) raise e end
|
||||
def rescue_action(e) raise e end
|
||||
end
|
||||
|
||||
def setup
|
||||
@controller = DevelopersController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
super
|
||||
end
|
||||
|
||||
def test_will_paginate
|
||||
get :list_developers
|
||||
|
||||
entries = assigns :developers
|
||||
assert entries
|
||||
assert_equal 4, entries.size
|
||||
|
||||
assert_select 'div.pagination', 1, 'no main DIV' do |pagination|
|
||||
assert_select 'a[href]', 3 do |elements|
|
||||
validate_page_numbers [2,3,2], elements
|
||||
assert_select elements.last, ':last-child', "Next »"
|
||||
end
|
||||
assert_select 'span', 2
|
||||
assert_select 'span.disabled:first-child', "« Previous"
|
||||
assert_select 'span.current', entries.current_page.to_s
|
||||
assert_equal '« Previous 1 2 3 Next »', pagination.first.inner_text
|
||||
end
|
||||
end
|
||||
|
||||
def test_will_paginate_with_options
|
||||
get :list_developers, { :page => 2 }, :wp => {
|
||||
:class => 'will_paginate', :prev_label => 'Prev', :next_label => 'Next'
|
||||
}
|
||||
assert_response :success
|
||||
|
||||
entries = assigns :developers
|
||||
assert entries
|
||||
assert_equal 4, entries.size
|
||||
|
||||
assert_select 'div.will_paginate', 1, 'no main DIV' do
|
||||
assert_select 'a[href]', 4 do |elements|
|
||||
validate_page_numbers [1,1,3,3], elements
|
||||
# test rel attribute values:
|
||||
assert_select elements[1], 'a', '1' do |link|
|
||||
assert_equal 'prev start', link.first['rel']
|
||||
end
|
||||
assert_select elements.first, 'a', "Prev" do |link|
|
||||
assert_equal 'prev start', link.first['rel']
|
||||
end
|
||||
assert_select elements.last, 'a', "Next" do |link|
|
||||
assert_equal 'next', link.first['rel']
|
||||
end
|
||||
end
|
||||
assert_select 'span.current', entries.current_page.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def test_will_paginate_without_container
|
||||
get :list_developers, {}, :wp => { :container => false }
|
||||
assert_select 'div.pagination', 0, 'no main DIV'
|
||||
assert_select 'a[href]', 3
|
||||
end
|
||||
|
||||
def test_will_paginate_without_page_links
|
||||
get :list_developers, { :page => 2 }, :wp => { :page_links => false }
|
||||
assert_select 'a[href]', 2 do |elements|
|
||||
validate_page_numbers [1,3], elements
|
||||
end
|
||||
end
|
||||
|
||||
def test_will_paginate_preserves_parameters_on_get
|
||||
get :list_developers, :foo => { :bar => 'baz' }
|
||||
assert_links_match /foo%5Bbar%5D=baz/
|
||||
end
|
||||
|
||||
def test_will_paginate_doesnt_preserve_parameters_on_post
|
||||
post :list_developers, :foo => 'bar'
|
||||
assert_no_links_match /foo=bar/
|
||||
end
|
||||
|
||||
def test_adding_additional_parameters
|
||||
get :list_developers, {}, :wp => { :params => { :foo => 'bar' } }
|
||||
assert_links_match /foo=bar/
|
||||
end
|
||||
|
||||
def test_removing_arbitrary_parameters
|
||||
get :list_developers, { :foo => 'bar' }, :wp => { :params => { :foo => nil } }
|
||||
assert_no_links_match /foo=bar/
|
||||
end
|
||||
|
||||
def test_adding_additional_route_parameters
|
||||
get :list_developers, {}, :wp => { :params => { :controller => 'baz' } }
|
||||
assert_links_match %r{\Wbaz/list_developers\W}
|
||||
end
|
||||
|
||||
def test_will_paginate_with_custom_page_param
|
||||
get :list_developers, { :developers_page => 2 }, :wp => { :param_name => :developers_page }
|
||||
assert_response :success
|
||||
|
||||
entries = assigns :developers
|
||||
assert entries
|
||||
assert_equal 4, entries.size
|
||||
|
||||
assert_select 'div.pagination', 1, 'no main DIV' do
|
||||
assert_select 'a[href]', 4 do |elements|
|
||||
validate_page_numbers [1,1,3,3], elements, :developers_page
|
||||
end
|
||||
assert_select 'span.current', entries.current_page.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def test_will_paginate_windows
|
||||
get :list_developers, { :page => 6, :per_page => 1 }, :wp => { :inner_window => 1 }
|
||||
assert_response :success
|
||||
|
||||
entries = assigns :developers
|
||||
assert entries
|
||||
assert_equal 1, entries.size
|
||||
|
||||
assert_select 'div.pagination', 1, 'no main DIV' do |pagination|
|
||||
assert_select 'a[href]', 8 do |elements|
|
||||
validate_page_numbers [5,1,2,5,7,10,11,7], elements
|
||||
assert_select elements.first, 'a', "« Previous"
|
||||
assert_select elements.last, 'a', "Next »"
|
||||
end
|
||||
assert_select 'span.current', entries.current_page.to_s
|
||||
assert_equal '« Previous 1 2 ... 5 6 7 ... 10 11 Next »', pagination.first.inner_text
|
||||
end
|
||||
end
|
||||
|
||||
def test_will_paginate_eliminates_small_gaps
|
||||
get :list_developers, { :page => 6, :per_page => 1 }, :wp => { :inner_window => 2 }
|
||||
assert_response :success
|
||||
|
||||
assert_select 'div.pagination', 1, 'no main DIV' do
|
||||
assert_select 'a[href]', 12 do |elements|
|
||||
validate_page_numbers [5,1,2,3,4,5,7,8,9,10,11,7], elements
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_no_pagination
|
||||
get :list_developers, :per_page => 12
|
||||
entries = assigns :developers
|
||||
assert_equal 1, entries.page_count
|
||||
assert_equal 11, entries.size
|
||||
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
|
||||
def test_faulty_input_raises_error
|
||||
assert_raise WillPaginate::InvalidPage do
|
||||
get :list_developers, :page => 'foo'
|
||||
end
|
||||
end
|
||||
|
||||
uses_mocha 'helper internals' do
|
||||
def test_collection_name_can_be_guessed
|
||||
collection = mock
|
||||
collection.expects(:page_count).returns(1)
|
||||
get :guess_collection_name, {}, :wp => collection
|
||||
end
|
||||
end
|
||||
|
||||
def test_inferred_collection_name_raises_error_when_nil
|
||||
ex = assert_raise ArgumentError do
|
||||
get :guess_collection_name, {}, :wp => nil
|
||||
end
|
||||
assert ex.message.include?('@developers')
|
||||
end
|
||||
|
||||
def test_setting_id_for_container
|
||||
get :list_developers
|
||||
assert_select 'div.pagination', 1 do |div|
|
||||
assert_nil div.first['id']
|
||||
end
|
||||
# magic ID
|
||||
get :list_developers, {}, :wp => { :id => true }
|
||||
assert_select 'div.pagination', 1 do |div|
|
||||
assert_equal 'fixnums_pagination', div.first['id']
|
||||
end
|
||||
# explicit ID
|
||||
get :list_developers, {}, :wp => { :id => 'custom_id' }
|
||||
assert_select 'div.pagination', 1 do |div|
|
||||
assert_equal 'custom_id', div.first['id']
|
||||
end
|
||||
end
|
||||
|
||||
if ActionController::Base.respond_to? :rescue_responses
|
||||
def test_rescue_response_hook_presence
|
||||
assert_equal :not_found,
|
||||
DevelopersController.rescue_responses['WillPaginate::InvalidPage']
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def validate_page_numbers expected, links, param_name = :page
|
||||
param_pattern = /\W#{param_name}=([^&]*)/
|
||||
|
||||
assert_equal(expected, links.map { |e|
|
||||
e['href'] =~ param_pattern
|
||||
$1 ? $1.to_i : $1
|
||||
})
|
||||
end
|
||||
|
||||
def assert_links_match pattern
|
||||
assert_select 'div.pagination a[href]' do |elements|
|
||||
elements.each do |el|
|
||||
assert_match pattern, el['href']
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_no_links_match pattern
|
||||
assert_select 'div.pagination a[href]' do |elements|
|
||||
elements.each do |el|
|
||||
assert_no_match pattern, el['href']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ViewHelpersTest < Test::Unit::TestCase
|
||||
include WillPaginate::ViewHelpers
|
||||
|
||||
def test_page_entries_info
|
||||
arr = ('a'..'z').to_a
|
||||
collection = arr.paginate :page => 2, :per_page => 5
|
||||
assert_equal %{Displaying entries <b>6 - 10</b> of <b>26</b> in total},
|
||||
page_entries_info(collection)
|
||||
|
||||
collection = arr.paginate :page => 7, :per_page => 4
|
||||
assert_equal %{Displaying entries <b>25 - 26</b> of <b>26</b> in total},
|
||||
page_entries_info(collection)
|
||||
end
|
||||
end
|
||||
56
vendor/plugins/will_paginate/test/tasks.rake
vendored
Normal file
56
vendor/plugins/will_paginate/test/tasks.rake
vendored
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
require 'rake/testtask'
|
||||
|
||||
desc 'Test the will_paginate plugin.'
|
||||
Rake::TestTask.new(:test) do |t|
|
||||
t.pattern = 'test/**/*_test.rb'
|
||||
t.verbose = true
|
||||
t.libs << 'test'
|
||||
end
|
||||
|
||||
# I want to specify environment variables at call time
|
||||
class EnvTestTask < Rake::TestTask
|
||||
attr_accessor :env
|
||||
|
||||
def ruby(*args)
|
||||
env.each { |key, value| ENV[key] = value } if env
|
||||
super
|
||||
env.keys.each { |key| ENV.delete key } if env
|
||||
end
|
||||
end
|
||||
|
||||
for configuration in %w( sqlite3 mysql postgres )
|
||||
EnvTestTask.new("test_#{configuration}") do |t|
|
||||
t.pattern = 'test/finder_test.rb'
|
||||
t.verbose = true
|
||||
t.env = { 'DB' => configuration }
|
||||
t.libs << 'test'
|
||||
end
|
||||
end
|
||||
|
||||
task :test_databases => %w(test_mysql test_sqlite3 test_postgres)
|
||||
|
||||
desc %{Test everything on SQLite3, MySQL and PostgreSQL}
|
||||
task :test_full => %w(test test_mysql test_postgres)
|
||||
|
||||
desc %{Test everything with Rails 1.2.x and 2.0.x gems}
|
||||
task :test_all do
|
||||
all = Rake::Task['test_full']
|
||||
ENV['RAILS_VERSION'] = '~>1.2.6'
|
||||
all.invoke
|
||||
# reset the invoked flag
|
||||
%w( test_full test test_mysql test_postgres ).each do |name|
|
||||
Rake::Task[name].instance_variable_set '@already_invoked', false
|
||||
end
|
||||
# do it again
|
||||
ENV['RAILS_VERSION'] = '~>2.0.2'
|
||||
all.invoke
|
||||
end
|
||||
|
||||
task :rcov do
|
||||
excludes = %w( lib/will_paginate/named_scope*
|
||||
lib/will_paginate/core_ext.rb
|
||||
lib/will_paginate.rb
|
||||
rails* )
|
||||
|
||||
system %[rcov -Itest:lib test/*.rb -x #{excludes.join(',')}]
|
||||
end
|
||||
355
vendor/plugins/will_paginate/test/view_test.rb
vendored
Normal file
355
vendor/plugins/will_paginate/test/view_test.rb
vendored
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
require 'helper'
|
||||
require 'lib/view_test_process'
|
||||
|
||||
class AdditionalLinkAttributesRenderer < WillPaginate::LinkRenderer
|
||||
def initialize(link_attributes = nil)
|
||||
super()
|
||||
@additional_link_attributes = link_attributes || { :default => 'true' }
|
||||
end
|
||||
|
||||
def page_link(page, text, attributes = {})
|
||||
@template.link_to text, url_for(page), attributes.merge(@additional_link_attributes)
|
||||
end
|
||||
end
|
||||
|
||||
class ViewTest < WillPaginate::ViewTestCase
|
||||
|
||||
## basic pagination ##
|
||||
|
||||
def test_will_paginate
|
||||
paginate do |pagination|
|
||||
assert_select 'a[href]', 3 do |elements|
|
||||
validate_page_numbers [2,3,2], elements
|
||||
assert_select elements.last, ':last-child', "Next »"
|
||||
end
|
||||
assert_select 'span', 2
|
||||
assert_select 'span.disabled:first-child', '« Previous'
|
||||
assert_select 'span.current', '1'
|
||||
assert_equal '« Previous 1 2 3 Next »', pagination.first.inner_text
|
||||
end
|
||||
end
|
||||
|
||||
def test_no_pagination_when_page_count_is_one
|
||||
paginate :per_page => 30
|
||||
assert_equal '', @html_result
|
||||
end
|
||||
|
||||
def test_will_paginate_with_options
|
||||
paginate({ :page => 2 },
|
||||
:class => 'will_paginate', :prev_label => 'Prev', :next_label => 'Next') do
|
||||
assert_select 'a[href]', 4 do |elements|
|
||||
validate_page_numbers [1,1,3,3], elements
|
||||
# test rel attribute values:
|
||||
assert_select elements[1], 'a', '1' do |link|
|
||||
assert_equal 'prev start', link.first['rel']
|
||||
end
|
||||
assert_select elements.first, 'a', "Prev" do |link|
|
||||
assert_equal 'prev start', link.first['rel']
|
||||
end
|
||||
assert_select elements.last, 'a', "Next" do |link|
|
||||
assert_equal 'next', link.first['rel']
|
||||
end
|
||||
end
|
||||
assert_select 'span.current', '2'
|
||||
end
|
||||
end
|
||||
|
||||
def test_will_paginate_using_renderer_class
|
||||
paginate({}, :renderer => AdditionalLinkAttributesRenderer) do
|
||||
assert_select 'a[default=true]', 3
|
||||
end
|
||||
end
|
||||
|
||||
def test_will_paginate_using_renderer_instance
|
||||
renderer = WillPaginate::LinkRenderer.new
|
||||
renderer.gap_marker = '<span class="my-gap">~~</span>'
|
||||
|
||||
paginate({ :per_page => 2 }, :inner_window => 0, :outer_window => 0, :renderer => renderer) do
|
||||
assert_select 'span.my-gap', '~~'
|
||||
end
|
||||
|
||||
renderer = AdditionalLinkAttributesRenderer.new(:title => 'rendered')
|
||||
paginate({}, :renderer => renderer) do
|
||||
assert_select 'a[title=rendered]', 3
|
||||
end
|
||||
end
|
||||
|
||||
def test_prev_next_links_have_classnames
|
||||
paginate do |pagination|
|
||||
assert_select 'span.disabled.prev_page:first-child'
|
||||
assert_select 'a.next_page[href]:last-child'
|
||||
end
|
||||
end
|
||||
|
||||
def test_full_output
|
||||
paginate
|
||||
expected = <<-HTML
|
||||
<div class="pagination"><span class="disabled prev_page">« Previous</span>
|
||||
<span class="current">1</span>
|
||||
<a href="/foo/bar?page=2" rel="next">2</a>
|
||||
<a href="/foo/bar?page=3">3</a>
|
||||
<a href="/foo/bar?page=2" class="next_page" rel="next">Next »</a></div>
|
||||
HTML
|
||||
expected.strip!.gsub!(/\s{2,}/, ' ')
|
||||
|
||||
assert_dom_equal expected, @html_result
|
||||
end
|
||||
|
||||
def test_escaping_of_urls
|
||||
paginate({:page => 1, :per_page => 1, :total_entries => 2},
|
||||
:page_links => false, :params => { :tag => '<br>' })
|
||||
|
||||
assert_select 'a[href]', 1 do |links|
|
||||
query = links.first['href'].split('?', 2)[1]
|
||||
assert_equal %w(page=2 tag=%3Cbr%3E), query.split('&').sort
|
||||
end
|
||||
end
|
||||
|
||||
## advanced options for pagination ##
|
||||
|
||||
def test_will_paginate_without_container
|
||||
paginate({}, :container => false)
|
||||
assert_select 'div.pagination', 0, 'main DIV present when it shouldn\'t'
|
||||
assert_select 'a[href]', 3
|
||||
end
|
||||
|
||||
def test_will_paginate_without_page_links
|
||||
paginate({ :page => 2 }, :page_links => false) do
|
||||
assert_select 'a[href]', 2 do |elements|
|
||||
validate_page_numbers [1,3], elements
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_will_paginate_windows
|
||||
paginate({ :page => 6, :per_page => 1 }, :inner_window => 1) do |pagination|
|
||||
assert_select 'a[href]', 8 do |elements|
|
||||
validate_page_numbers [5,1,2,5,7,10,11,7], elements
|
||||
assert_select elements.first, 'a', '« Previous'
|
||||
assert_select elements.last, 'a', 'Next »'
|
||||
end
|
||||
assert_select 'span.current', '6'
|
||||
assert_equal '« Previous 1 2 … 5 6 7 … 10 11 Next »', pagination.first.inner_text
|
||||
end
|
||||
end
|
||||
|
||||
def test_will_paginate_eliminates_small_gaps
|
||||
paginate({ :page => 6, :per_page => 1 }, :inner_window => 2) do
|
||||
assert_select 'a[href]', 12 do |elements|
|
||||
validate_page_numbers [5,1,2,3,4,5,7,8,9,10,11,7], elements
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_container_id
|
||||
paginate do |div|
|
||||
assert_nil div.first['id']
|
||||
end
|
||||
|
||||
# magic ID
|
||||
paginate({}, :id => true) do |div|
|
||||
assert_equal 'fixnums_pagination', div.first['id']
|
||||
end
|
||||
|
||||
# explicit ID
|
||||
paginate({}, :id => 'custom_id') do |div|
|
||||
assert_equal 'custom_id', div.first['id']
|
||||
end
|
||||
end
|
||||
|
||||
## other helpers ##
|
||||
|
||||
def test_paginated_section
|
||||
@template = <<-ERB
|
||||
<% paginated_section collection, options do %>
|
||||
<%= content_tag :div, '', :id => "developers" %>
|
||||
<% end %>
|
||||
ERB
|
||||
|
||||
paginate
|
||||
assert_select 'div.pagination', 2
|
||||
assert_select 'div.pagination + div#developers', 1
|
||||
end
|
||||
|
||||
def test_page_entries_info
|
||||
@template = '<%= page_entries_info collection %>'
|
||||
array = ('a'..'z').to_a
|
||||
|
||||
paginate array.paginate(:page => 2, :per_page => 5)
|
||||
assert_equal %{Displaying strings <b>6 - 10</b> of <b>26</b> in total},
|
||||
@html_result
|
||||
|
||||
paginate array.paginate(:page => 7, :per_page => 4)
|
||||
assert_equal %{Displaying strings <b>25 - 26</b> of <b>26</b> in total},
|
||||
@html_result
|
||||
end
|
||||
|
||||
def test_page_entries_info_with_longer_class_name
|
||||
@template = '<%= page_entries_info collection %>'
|
||||
collection = ('a'..'z').to_a.paginate
|
||||
collection.first.stubs(:class).returns(mock('class', :name => 'ProjectType'))
|
||||
|
||||
paginate collection
|
||||
assert @html_result.index('project types'), "expected <#{@html_result.inspect}> to mention 'project types'"
|
||||
end
|
||||
|
||||
def test_page_entries_info_with_single_page_collection
|
||||
@template = '<%= page_entries_info collection %>'
|
||||
|
||||
paginate(('a'..'d').to_a.paginate(:page => 1, :per_page => 5))
|
||||
assert_equal %{Displaying <b>all 4</b> strings}, @html_result
|
||||
|
||||
paginate(['a'].paginate(:page => 1, :per_page => 5))
|
||||
assert_equal %{Displaying <b>1</b> string}, @html_result
|
||||
|
||||
paginate([].paginate(:page => 1, :per_page => 5))
|
||||
assert_equal %{No entries found}, @html_result
|
||||
end
|
||||
|
||||
def test_page_entries_info_with_custom_entry_name
|
||||
@template = '<%= page_entries_info collection, :entry_name => "author" %>'
|
||||
|
||||
entries = (1..20).to_a
|
||||
|
||||
paginate(entries.paginate(:page => 1, :per_page => 5))
|
||||
assert_equal %{Displaying authors <b>1 - 5</b> of <b>20</b> in total}, @html_result
|
||||
|
||||
paginate(entries.paginate(:page => 1, :per_page => 20))
|
||||
assert_equal %{Displaying <b>all 20</b> authors}, @html_result
|
||||
|
||||
paginate(['a'].paginate(:page => 1, :per_page => 5))
|
||||
assert_equal %{Displaying <b>1</b> author}, @html_result
|
||||
|
||||
paginate([].paginate(:page => 1, :per_page => 5))
|
||||
assert_equal %{No authors found}, @html_result
|
||||
end
|
||||
|
||||
## parameter handling in page links ##
|
||||
|
||||
def test_will_paginate_preserves_parameters_on_get
|
||||
@request.params :foo => { :bar => 'baz' }
|
||||
paginate
|
||||
assert_links_match /foo%5Bbar%5D=baz/
|
||||
end
|
||||
|
||||
def test_will_paginate_doesnt_preserve_parameters_on_post
|
||||
@request.post
|
||||
@request.params :foo => 'bar'
|
||||
paginate
|
||||
assert_no_links_match /foo=bar/
|
||||
end
|
||||
|
||||
def test_adding_additional_parameters
|
||||
paginate({}, :params => { :foo => 'bar' })
|
||||
assert_links_match /foo=bar/
|
||||
end
|
||||
|
||||
def test_adding_anchor_parameter
|
||||
paginate({}, :params => { :anchor => 'anchor' })
|
||||
assert_links_match /#anchor$/
|
||||
end
|
||||
|
||||
def test_removing_arbitrary_parameters
|
||||
@request.params :foo => 'bar'
|
||||
paginate({}, :params => { :foo => nil })
|
||||
assert_no_links_match /foo=bar/
|
||||
end
|
||||
|
||||
def test_adding_additional_route_parameters
|
||||
paginate({}, :params => { :controller => 'baz', :action => 'list' })
|
||||
assert_links_match %r{\Wbaz/list\W}
|
||||
end
|
||||
|
||||
def test_will_paginate_with_custom_page_param
|
||||
paginate({ :page => 2 }, :param_name => :developers_page) do
|
||||
assert_select 'a[href]', 4 do |elements|
|
||||
validate_page_numbers [1,1,3,3], elements, :developers_page
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_complex_custom_page_param
|
||||
@request.params :developers => { :page => 2 }
|
||||
|
||||
paginate({ :page => 2 }, :param_name => 'developers[page]') do
|
||||
assert_select 'a[href]', 4 do |links|
|
||||
assert_links_match /\?developers%5Bpage%5D=\d+$/, links
|
||||
validate_page_numbers [1,1,3,3], links, 'developers[page]'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_custom_routing_page_param
|
||||
@request.symbolized_path_parameters.update :controller => 'dummy', :action => nil
|
||||
paginate :per_page => 2 do
|
||||
assert_select 'a[href]', 6 do |links|
|
||||
assert_links_match %r{/page/(\d+)$}, links, [2, 3, 4, 5, 6, 2]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_custom_routing_page_param_with_dot_separator
|
||||
@request.symbolized_path_parameters.update :controller => 'dummy', :action => 'dots'
|
||||
paginate :per_page => 2 do
|
||||
assert_select 'a[href]', 6 do |links|
|
||||
assert_links_match %r{/page\.(\d+)$}, links, [2, 3, 4, 5, 6, 2]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_custom_routing_with_first_page_hidden
|
||||
@request.symbolized_path_parameters.update :controller => 'ibocorp', :action => nil
|
||||
paginate :page => 2, :per_page => 2 do
|
||||
assert_select 'a[href]', 7 do |links|
|
||||
assert_links_match %r{/ibocorp(?:/(\d+))?$}, links, [nil, nil, 3, 4, 5, 6, 3]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
## internal hardcore stuff ##
|
||||
|
||||
class LegacyCollection < WillPaginate::Collection
|
||||
alias :page_count :total_pages
|
||||
undef :total_pages
|
||||
end
|
||||
|
||||
def test_deprecation_notices_with_page_count
|
||||
collection = LegacyCollection.new(1, 1, 2)
|
||||
|
||||
assert_deprecated collection.class.name do
|
||||
paginate collection
|
||||
end
|
||||
end
|
||||
|
||||
uses_mocha 'view internals' do
|
||||
def test_collection_name_can_be_guessed
|
||||
collection = mock
|
||||
collection.expects(:total_pages).returns(1)
|
||||
|
||||
@template = '<%= will_paginate options %>'
|
||||
@controller.controller_name = 'developers'
|
||||
@view.assigns['developers'] = collection
|
||||
|
||||
paginate(nil)
|
||||
end
|
||||
end
|
||||
|
||||
def test_inferred_collection_name_raises_error_when_nil
|
||||
@template = '<%= will_paginate options %>'
|
||||
@controller.controller_name = 'developers'
|
||||
|
||||
e = assert_raise ArgumentError do
|
||||
paginate(nil)
|
||||
end
|
||||
assert e.message.include?('@developers')
|
||||
end
|
||||
|
||||
if ActionController::Base.respond_to? :rescue_responses
|
||||
# only on Rails 2
|
||||
def test_rescue_response_hook_presence
|
||||
assert_equal :not_found,
|
||||
ActionController::Base.rescue_responses['WillPaginate::InvalidPage']
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
21
vendor/plugins/will_paginate/will_paginate.gemspec
vendored
Normal file
21
vendor/plugins/will_paginate/will_paginate.gemspec
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
Gem::Specification.new do |s|
|
||||
s.name = 'will_paginate'
|
||||
s.version = '2.3.2'
|
||||
s.date = '2008-05-16'
|
||||
|
||||
s.summary = "Most awesome pagination solution for Rails"
|
||||
s.description = "The will_paginate library provides a simple, yet powerful and extensible API for ActiveRecord pagination and rendering of pagination links in ActionView templates."
|
||||
|
||||
s.authors = ['Mislav Marohnić', 'PJ Hyett']
|
||||
s.email = 'mislav.marohnic@gmail.com'
|
||||
s.homepage = 'http://github.com/mislav/will_paginate/wikis'
|
||||
|
||||
s.has_rdoc = true
|
||||
s.rdoc_options = ['--main', 'README.rdoc']
|
||||
s.rdoc_options << '--inline-source' << '--charset=UTF-8'
|
||||
s.extra_rdoc_files = ['README.rdoc', 'LICENSE', 'CHANGELOG']
|
||||
s.add_dependency 'activesupport', ['>= 1.4.4']
|
||||
|
||||
s.files = %w(CHANGELOG LICENSE README.rdoc Rakefile examples examples/apple-circle.gif examples/index.haml examples/index.html examples/pagination.css examples/pagination.sass init.rb lib lib/will_paginate lib/will_paginate.rb lib/will_paginate/array.rb lib/will_paginate/collection.rb lib/will_paginate/core_ext.rb lib/will_paginate/finder.rb lib/will_paginate/named_scope.rb lib/will_paginate/named_scope_patch.rb lib/will_paginate/version.rb lib/will_paginate/view_helpers.rb test test/boot.rb test/collection_test.rb test/console test/database.yml test/finder_test.rb test/fixtures test/fixtures/admin.rb test/fixtures/developer.rb test/fixtures/developers_projects.yml test/fixtures/project.rb test/fixtures/projects.yml test/fixtures/replies.yml test/fixtures/reply.rb test/fixtures/schema.rb test/fixtures/topic.rb test/fixtures/topics.yml test/fixtures/user.rb test/fixtures/users.yml test/helper.rb test/lib test/lib/activerecord_test_case.rb test/lib/activerecord_test_connector.rb test/lib/load_fixtures.rb test/lib/view_test_process.rb test/tasks.rake test/view_test.rb)
|
||||
s.test_files = %w(test/boot.rb test/collection_test.rb test/console test/database.yml test/finder_test.rb test/fixtures test/fixtures/admin.rb test/fixtures/developer.rb test/fixtures/developers_projects.yml test/fixtures/project.rb test/fixtures/projects.yml test/fixtures/replies.yml test/fixtures/reply.rb test/fixtures/schema.rb test/fixtures/topic.rb test/fixtures/topics.yml test/fixtures/user.rb test/fixtures/users.yml test/helper.rb test/lib test/lib/activerecord_test_case.rb test/lib/activerecord_test_connector.rb test/lib/load_fixtures.rb test/lib/view_test_process.rb test/tasks.rake test/view_test.rb)
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue