will_paginate-3.1.6/0000755000004100000410000000000013154516406014375 5ustar www-datawww-datawill_paginate-3.1.6/spec/0000755000004100000410000000000013154516405015326 5ustar www-datawww-datawill_paginate-3.1.6/spec/fake_rubygems.rb0000644000004100000410000000073013154516405020476 0ustar www-datawww-data# Makes the test suite compatible with Bundler standalone mode (used in CI) # because Active Record uses `gem` for loading adapters. Kernel.module_eval do remove_method :gem if 'method' == defined? gem def gem(*args) return if $VERBOSE.nil? $stderr << "warning: gem(#{args.map {|o| o.inspect }.join(', ')}) ignored" $stderr << "; called from:\n " << caller[0,5].join("\n ") if $DEBUG $stderr << "\n" end private :gem end $" << "rubygems.rb" will_paginate-3.1.6/spec/spec_helper.rb0000644000004100000410000000165713154516405020155 0ustar www-datawww-datarequire 'rspec' require 'view_helpers/view_example_group' begin require 'ruby-debug' rescue LoadError # no debugger available end Dir[File.expand_path('../matchers/*_matcher.rb', __FILE__)].each { |matcher| require matcher } RSpec.configure do |config| config.include Module.new { protected def include_phrase(string) PhraseMatcher.new(string) end def have_deprecation(msg) DeprecationMatcher.new(msg) end def run_queries(num) QueryCountMatcher.new(num) end def ignore_deprecation ActiveSupport::Deprecation.silence { yield } end def show_queries(&block) counter = QueryCountMatcher.new(nil) counter.run block ensure queries = counter.performed_queries if queries.any? puts queries else puts "no queries" end end } config.mock_with :mocha config.backtrace_clean_patterns << /view_example_group/ end will_paginate-3.1.6/spec/per_page_spec.rb0000644000004100000410000000142013154516405020444 0ustar www-datawww-datarequire 'spec_helper' require 'will_paginate/per_page' describe WillPaginate::PerPage do class MyModel extend WillPaginate::PerPage end it "has the default value" do MyModel.per_page.should == 30 WillPaginate.per_page = 10 begin MyModel.per_page.should == 10 ensure WillPaginate.per_page = 30 end end it "casts values to int" do WillPaginate.per_page = '10' begin MyModel.per_page.should == 10 ensure WillPaginate.per_page = 30 end end it "has an explicit value" do MyModel.per_page = 12 begin MyModel.per_page.should == 12 subclass = Class.new(MyModel) subclass.per_page.should == 12 ensure MyModel.send(:remove_instance_variable, '@per_page') end end end will_paginate-3.1.6/spec/finders/0000755000004100000410000000000013154516405016760 5ustar www-datawww-datawill_paginate-3.1.6/spec/finders/active_record_spec.rb0000644000004100000410000003143313154516405023134 0ustar www-datawww-datarequire 'spec_helper' require 'will_paginate/active_record' require File.expand_path('../activerecord_test_connector', __FILE__) ActiverecordTestConnector.setup describe WillPaginate::ActiveRecord do extend ActiverecordTestConnector::FixtureSetup fixtures :topics, :replies, :users, :projects, :developers_projects it "should integrate with ActiveRecord::Base" do ActiveRecord::Base.should respond_to(:paginate) end it "should paginate" do lambda { users = User.paginate(:page => 1, :per_page => 5).to_a users.length.should == 5 }.should run_queries(2) end it "should fail when encountering unknown params" do lambda { User.paginate :foo => 'bar', :page => 1, :per_page => 4 }.should raise_error(ArgumentError) end describe "relation" do it "should return a relation" do rel = nil lambda { rel = Developer.paginate(:page => 1) rel.per_page.should == 10 rel.current_page.should == 1 }.should run_queries(0) lambda { rel.total_pages.should == 2 }.should run_queries(1) end it "should keep per-class per_page number" do rel = Developer.order('id').paginate(:page => 1) rel.per_page.should == 10 end it "should be able to change per_page number" do rel = Developer.order('id').paginate(:page => 1).limit(5) rel.per_page.should == 5 end it "remembers pagination in sub-relations" do rel = Topic.paginate(:page => 2, :per_page => 3) lambda { rel.total_entries.should == 4 }.should run_queries(1) rel = rel.mentions_activerecord rel.current_page.should == 2 rel.per_page.should == 3 lambda { rel.total_entries.should == 1 }.should run_queries(1) end it "supports the page() method" do rel = Developer.page('1').order('id') rel.current_page.should == 1 rel.per_page.should == 10 rel.offset.should == 0 rel = rel.limit(5).page(2) rel.per_page.should == 5 rel.offset.should == 5 end it "raises on invalid page number" do lambda { Developer.page('foo') }.should raise_error(ArgumentError) end it "supports first limit() then page()" do rel = Developer.limit(3).page(3) rel.offset.should == 6 end it "supports first page() then limit()" do rel = Developer.page(3).limit(3) rel.offset.should == 6 end it "supports #first" do rel = Developer.order('id').page(2).per_page(4) rel.first.should == users(:dev_5) rel.first(2).should == users(:dev_5, :dev_6) end it "supports #last" do rel = Developer.order('id').page(2).per_page(4) rel.last.should == users(:dev_8) rel.last(2).should == users(:dev_7, :dev_8) rel.page(3).last.should == users(:poor_jamis) end end describe "counting" do it "should guess the total count" do lambda { topics = Topic.paginate :page => 2, :per_page => 3 topics.total_entries.should == 4 }.should run_queries(1) end it "should guess that there are no records" do lambda { topics = Topic.where(:project_id => 999).paginate :page => 1, :per_page => 3 topics.total_entries.should == 0 }.should run_queries(1) end it "forgets count in sub-relations" do lambda { topics = Topic.paginate :page => 1, :per_page => 3 topics.total_entries.should == 4 topics.where('1 = 1').total_entries.should == 4 }.should run_queries(2) end it "supports empty? method" do topics = Topic.paginate :page => 1, :per_page => 3 lambda { topics.should_not be_empty }.should run_queries(1) end it "support empty? for grouped queries" do topics = Topic.group(:project_id).paginate :page => 1, :per_page => 3 lambda { topics.should_not be_empty }.should run_queries(1) end it "supports `size` for grouped queries" do topics = Topic.group(:project_id).paginate :page => 1, :per_page => 3 lambda { topics.size.should == {nil=>2, 1=>2} }.should run_queries(1) end it "overrides total_entries count with a fixed value" do lambda { topics = Topic.paginate :page => 1, :per_page => 3, :total_entries => 999 topics.total_entries.should == 999 # value is kept even in sub-relations topics.where('1 = 1').total_entries.should == 999 }.should run_queries(0) end it "supports a non-int for total_entries" do topics = Topic.paginate :page => 1, :per_page => 3, :total_entries => "999" topics.total_entries.should == 999 end it "removes :include for count" do lambda { developers = Developer.paginate(:page => 1, :per_page => 1).includes(:projects) developers.total_entries.should == 11 $query_sql.last.should_not =~ /\bJOIN\b/ }.should run_queries(1) end it "keeps :include for count when they are referenced in :conditions" do developers = Developer.paginate(:page => 1, :per_page => 1).includes(:projects) with_condition = developers.where('projects.id > 1') with_condition = with_condition.references(:projects) if with_condition.respond_to?(:references) with_condition.total_entries.should == 1 $query_sql.last.should =~ /\bJOIN\b/ end it "should count with group" do Developer.group(:salary).page(1).total_entries.should == 4 end it "should count with select" do Topic.select('title, content').page(1).total_entries.should == 4 end it "removes :reorder for count with group" do Project.group(:id).reorder(:id).page(1).total_entries $query_sql.last.should_not =~ /\ORDER\b/ end it "should not have zero total_pages when the result set is empty" do Developer.where("1 = 2").page(1).total_pages.should == 1 end end it "should not ignore :select parameter when it says DISTINCT" do users = User.select('DISTINCT salary').paginate :page => 2 users.total_entries.should == 5 end describe "paginate_by_sql" do it "should respond" do User.should respond_to(:paginate_by_sql) end it "should paginate" do lambda { sql = "select content from topics where content like '%futurama%'" topics = Topic.paginate_by_sql sql, :page => 1, :per_page => 1 topics.total_entries.should == 1 topics.first.attributes.has_key?('title').should be_false }.should run_queries(2) end it "should respect total_entries setting" do lambda { sql = "select content from topics" topics = Topic.paginate_by_sql sql, :page => 1, :per_page => 1, :total_entries => 999 topics.total_entries.should == 999 }.should run_queries(1) end it "defaults to page 1" do sql = "select content from topics" topics = Topic.paginate_by_sql sql, :page => nil, :per_page => 1 topics.current_page.should == 1 topics.size.should == 1 end it "should strip the order when counting" do expected = topics(:ar) lambda { sql = "select id, title, content from topics order by topics.title" topics = Topic.paginate_by_sql sql, :page => 1, :per_page => 2 topics.first.should == expected }.should run_queries(2) $query_sql.last.should include('COUNT') $query_sql.last.should_not include('order by topics.title') end it "shouldn't change the original query string" do query = 'select * from topics where 1 = 2' original_query = query.dup Topic.paginate_by_sql(query, :page => 1) query.should == original_query end end it "doesn't mangle options" do options = { :page => 1 } options.expects(:delete).never options_before = options.dup Topic.paginate(options) options.should == options_before end it "should get first page of Topics with a single query" do lambda { result = Topic.paginate :page => nil result.to_a # trigger loading of records result.current_page.should == 1 result.total_pages.should == 1 result.size.should == 4 }.should run_queries(1) end it "should get second (inexistent) page of Topics, requiring 2 queries" do lambda { result = Topic.paginate :page => 2 result.total_pages.should == 1 result.should be_empty }.should run_queries(2) end describe "associations" do it "should paginate" do dhh = users(:david) expected_name_ordered = projects(:action_controller, :active_record) expected_id_ordered = projects(:active_record, :action_controller) lambda { # with association-specified order result = ignore_deprecation { dhh.projects.includes(:topics).order('projects.name').paginate(:page => 1) } result.to_a.should == expected_name_ordered result.total_entries.should == 2 }.should run_queries(2) # with explicit order result = dhh.projects.paginate(:page => 1).reorder('projects.id') result.should == expected_id_ordered result.total_entries.should == 2 lambda { dhh.projects.order('projects.id').limit(4).to_a }.should_not raise_error result = dhh.projects.paginate(:page => 1, :per_page => 4).reorder('projects.id') result.should == expected_id_ordered # has_many with implicit order topic = Topic.find(1) expected = replies(:spam, :witty_retort) # FIXME: wow, this is ugly topic.replies.paginate(:page => 1).map(&:id).sort.should == expected.map(&:id).sort topic.replies.paginate(:page => 1).reorder('replies.id ASC').should == expected.reverse end it "should paginate through association extension" do project = Project.order('id').first expected = [replies(:brave)] lambda { result = project.replies.only_recent.paginate(:page => 1) result.should == expected }.should run_queries(1) end end it "should paginate with joins" do result = nil join_sql = 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id' lambda { result = Developer.where('developers_projects.project_id = 1').joins(join_sql).paginate(:page => 1) result.to_a # trigger loading of records result.size.should == 2 developer_names = result.map(&:name) developer_names.should include('David') developer_names.should include('Jamis') }.should run_queries(1) lambda { expected = result.to_a result = Developer.where('developers_projects.project_id = 1').joins(join_sql).paginate(:page => 1) result.should == expected result.total_entries.should == 2 }.should run_queries(1) end it "should paginate with group" do result = nil lambda { result = Developer.select('salary').order('salary').group('salary'). paginate(:page => 1, :per_page => 10).to_a }.should run_queries(1) expected = users(:david, :jamis, :dev_10, :poor_jamis).map(&:salary).sort result.map(&:salary).should == expected end it "should not paginate with dynamic finder" do lambda { Developer.paginate_by_salary(100000, :page => 1, :per_page => 5) }.should raise_error(NoMethodError) end describe "scopes" do it "should paginate" do result = Developer.poor.paginate :page => 1, :per_page => 1 result.size.should == 1 result.total_entries.should == 2 end it "should paginate on habtm association" do project = projects(:active_record) lambda { result = ignore_deprecation { project.developers.poor.paginate :page => 1, :per_page => 1 } result.size.should == 1 result.total_entries.should == 1 }.should run_queries(2) end it "should paginate on hmt association" do project = projects(:active_record) expected = [replies(:brave)] lambda { result = project.replies.recent.paginate :page => 1, :per_page => 1 result.should == expected result.total_entries.should == 1 }.should run_queries(2) end it "should paginate on has_many association" do project = projects(:active_record) expected = [topics(:ar)] lambda { result = project.topics.mentions_activerecord.paginate :page => 1, :per_page => 1 result.should == expected result.total_entries.should == 1 }.should run_queries(2) end end it "should not paginate an array of IDs" do lambda { Developer.paginate((1..8).to_a, :per_page => 3, :page => 2, :order => 'id') }.should raise_error(ArgumentError) end it "errors out for invalid values" do |variable| lambda { # page that results in an offset larger than BIGINT Project.page(307445734561825862) }.should raise_error(WillPaginate::InvalidPage, "invalid offset: 9223372036854775830") end end will_paginate-3.1.6/spec/finders/sequel_spec.rb0000644000004100000410000000334313154516405021620 0ustar www-datawww-datarequire 'spec_helper' if !ENV['SKIP_NONRAILS_TESTS'] require 'will_paginate/sequel' require File.expand_path('../sequel_test_connector', __FILE__) sequel_loaded = true else sequel_loaded = false end describe Sequel::Dataset::Pagination, 'extension' do class Car < Sequel::Model end it "should have the #paginate method" do Car.should respond_to(:paginate) end it "should NOT have the #paginate_by_sql method" do Car.should_not respond_to(:paginate_by_sql) end describe 'pagination' do before(:all) do Car.create(:name => 'Shelby', :notes => "Man's best friend") Car.create(:name => 'Aston Martin', :notes => "Woman's best friend") Car.create(:name => 'Corvette', :notes => 'King of the Jungle') end it "should imitate WillPaginate::Collection" do result = Car.paginate(1, 2) result.should_not be_empty result.size.should == 2 result.length.should == 2 result.total_entries.should == 3 result.total_pages.should == 2 result.per_page.should == 2 result.current_page.should == 1 end it "should perform" do Car.paginate(1, 2).all.should == [Car[1], Car[2]] end it "should be empty" do result = Car.paginate(3, 2) result.should be_empty end it "should perform with #select and #order" do result = Car.select("name as foo".lit).order(:name).paginate(1, 2).all result.size.should == 2 result.first.values[:foo].should == "Aston Martin" end it "should perform with #filter" do results = Car.filter(:name => 'Shelby').paginate(1, 2).all results.size.should == 1 results.first.should == Car.find(:name => 'Shelby') end end end if sequel_loaded will_paginate-3.1.6/spec/finders/data_mapper_spec.rb0000644000004100000410000000617113154516405022601 0ustar www-datawww-datarequire 'spec_helper' if !ENV['SKIP_NONRAILS_TESTS'] require 'will_paginate/data_mapper' require File.expand_path('../data_mapper_test_connector', __FILE__) datamapper_loaded = true else datamapper_loaded = false end describe WillPaginate::DataMapper do it "has per_page" do Animal.per_page.should == 30 begin Animal.per_page = 10 Animal.per_page.should == 10 subclass = Class.new(Animal) subclass.per_page.should == 10 ensure Animal.per_page = 30 end end it "doesn't make normal collections appear paginated" do Animal.all.should_not be_paginated end it "paginates to first page by default" do animals = Animal.paginate(:page => nil) animals.should be_paginated animals.current_page.should == 1 animals.per_page.should == 30 animals.offset.should == 0 animals.total_entries.should == 3 animals.total_pages.should == 1 end it "paginates to first page, explicit limit" do animals = Animal.paginate(:page => 1, :per_page => 2) animals.current_page.should == 1 animals.per_page.should == 2 animals.total_entries.should == 3 animals.total_pages.should == 2 animals.map {|a| a.name }.should == %w[ Dog Cat ] end it "paginates to second page" do animals = Animal.paginate(:page => 2, :per_page => 2) animals.current_page.should == 2 animals.offset.should == 2 animals.map {|a| a.name }.should == %w[ Lion ] end it "paginates a collection" do friends = Animal.all(:notes.like => '%friend%') friends.paginate(:page => 1).per_page.should == 30 friends.paginate(:page => 1, :per_page => 1).total_entries.should == 2 end it "paginates a limited collection" do animals = Animal.all(:limit => 2).paginate(:page => 1) animals.per_page.should == 2 end it "has page() method" do Animal.page(2).per_page.should == 30 Animal.page(2).offset.should == 30 Animal.page(2).current_page.should == 2 Animal.all(:limit => 2).page(2).per_page.should == 2 end it "has total_pages at 1 for empty collections" do Animal.all(:conditions => ['1=2']).page(1).total_pages.should == 1 end it "overrides total_entries count with a fixed value" do lambda { animals = Animal.paginate :page => 1, :per_page => 3, :total_entries => 999 animals.total_entries.should == 999 }.should run_queries(0) end it "supports a non-int for total_entries" do topics = Animal.paginate :page => 1, :per_page => 3, :total_entries => "999" topics.total_entries.should == 999 end it "can iterate and then call WP methods" do animals = Animal.all(:limit => 2).page(1) animals.each { |a| } animals.total_entries.should == 3 end it "augments to_a to return a WP::Collection" do animals = Animal.all(:limit => 2).page(1) array = animals.to_a array.size.should == 2 array.should be_kind_of(WillPaginate::Collection) array.current_page.should == 1 array.per_page.should == 2 end it "doesn't have a problem assigning has-one-through relationship" do human = Human.create :name => "Mislav" human.pet = Animal.first end end if datamapper_loaded will_paginate-3.1.6/spec/finders/mongoid_spec.rb0000644000004100000410000001100213154516405021745 0ustar www-datawww-datarequire 'spec_helper' if !ENV['SKIP_NONRAILS_TESTS'] if defined?(Rails) old_rails = Rails # Mongoid sees the `Rails` constant and then proceeds to `require "rails"` # from its railtie. This tricks it into believing there is no Rails. Object.send(:remove_const, :Rails) end require 'will_paginate/mongoid' Object.send(:const_set, :Rails, old_rails) if old_rails Mongoid.connect_to 'will_paginate_test' class MongoidModel include Mongoid::Document end mongoid_loaded = true else mongoid_loaded = false end describe WillPaginate::Mongoid do before(:all) do MongoidModel.delete_all 4.times { MongoidModel.create! } end let(:criteria) { MongoidModel.criteria } describe "#page" do it "should forward to the paginate method" do criteria.expects(:paginate).with(:page => 2).returns("itself") criteria.page(2).should == "itself" end it "should not override per_page if set earlier in the chain" do criteria.paginate(:per_page => 10).page(1).per_page.should == 10 criteria.paginate(:per_page => 20).page(1).per_page.should == 20 end end describe "#per_page" do it "should set the limit if given an argument" do criteria.per_page(10).options[:limit].should == 10 end it "should return the current limit if no argument is given" do criteria.per_page.should == nil criteria.per_page(10).per_page.should == 10 end it "should be interchangable with limit" do criteria.limit(15).per_page.should == 15 end it "should be nil'able" do criteria.per_page(nil).per_page.should be_nil end end describe "#paginate" do it "should use criteria" do criteria.paginate.should be_instance_of(::Mongoid::Criteria) end it "should not override page number if set earlier in the chain" do criteria.page(3).paginate.current_page.should == 3 end it "should limit according to per_page parameter" do criteria.paginate(:per_page => 10).options.should include(:limit => 10) end it "should skip according to page and per_page parameters" do criteria.paginate(:page => 2, :per_page => 5).options.should include(:skip => 5) end specify "first fallback value for per_page option is the current limit" do criteria.limit(12).paginate.options.should include(:limit => 12) end specify "second fallback value for per_page option is WillPaginate.per_page" do criteria.paginate.options.should include(:limit => WillPaginate.per_page) end specify "page should default to 1" do criteria.paginate.options.should include(:skip => 0) end it "should convert strings to integers" do criteria.paginate(:page => "2", :per_page => "3").options.should include(:limit => 3) end describe "collection compatibility" do describe "#total_count" do it "should be calculated correctly" do criteria.paginate(:per_page => 1).total_entries.should == 4 criteria.paginate(:per_page => 3).total_entries.should == 4 end it "should be cached" do criteria.expects(:count).once.returns(123) criteria.paginate 2.times { criteria.total_entries.should == 123 } end end it "should calculate total_pages" do criteria.paginate(:per_page => 1).total_pages.should == 4 criteria.paginate(:per_page => 3).total_pages.should == 2 criteria.paginate(:per_page => 10).total_pages.should == 1 end it "should return per_page" do criteria.paginate(:per_page => 1).per_page.should == 1 criteria.paginate(:per_page => 5).per_page.should == 5 end describe "#current_page" do it "should return current_page" do criteria.paginate(:page => 1).current_page.should == 1 criteria.paginate(:page => 3).current_page.should == 3 end it "should be casted to PageNumber" do page = criteria.paginate(:page => 1).current_page (page.instance_of? WillPaginate::PageNumber).should be end end it "should return offset" do criteria.paginate(:page => 1).offset.should == 0 criteria.paginate(:page => 2, :per_page => 5).offset.should == 5 criteria.paginate(:page => 3, :per_page => 10).offset.should == 20 end it "should not pollute plain mongoid criterias" do %w(total_entries total_pages current_page).each do |method| criteria.should_not respond_to(method) end end end end end if mongoid_loaded will_paginate-3.1.6/spec/finders/activerecord_test_connector.rb0000644000004100000410000000664713154516405025105 0ustar www-datawww-datarequire 'active_record' require 'active_record/fixtures' require 'active_support/multibyte' # needed for Ruby 1.9.1 require 'stringio' require 'erb' # https://travis-ci.org/mislav/will_paginate/jobs/99999001 require 'active_support/core_ext/string/conversions' class String alias to_datetime_without_patch to_datetime def to_datetime to_datetime_without_patch rescue ArgumentError return nil end end $query_count = 0 $query_sql = [] ignore_sql = / ^( PRAGMA | SHOW\ (max_identifier_length|search_path) | SELECT\ (currval|CAST|@@IDENTITY|@@ROWCOUNT) | SHOW\ ((FULL\ )?FIELDS|TABLES) )\b | \bFROM\ (sqlite_master|pg_tables|pg_attribute)\b /x ActiveSupport::Notifications.subscribe(/^sql\./) do |*args| payload = args.last unless payload[:name] =~ /^Fixture/ or payload[:sql] =~ ignore_sql $query_count += 1 $query_sql << payload[:sql] end end module ActiverecordTestConnector extend self attr_accessor :connected FIXTURES_PATH = File.expand_path('../../fixtures', __FILE__) Fixtures = defined?(ActiveRecord::FixtureSet) ? ActiveRecord::FixtureSet : defined?(ActiveRecord::Fixtures) ? ActiveRecord::Fixtures : ::Fixtures # Set our defaults self.connected = false def setup unless self.connected setup_connection load_schema add_load_path FIXTURES_PATH self.connected = true end end private def add_load_path(path) dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies dep.autoload_paths.unshift path end def setup_connection db = ENV['DB'].blank?? 'sqlite3' : ENV['DB'] erb = ERB.new(File.read(File.expand_path('../../database.yml', __FILE__))) configurations = YAML.load(erb.result) raise "no configuration for '#{db}'" unless configurations.key? db configuration = configurations[db] # ActiveRecord::Base.logger = Logger.new(STDOUT) if $0 == 'irb' puts "using #{configuration['adapter']} adapter" ActiveRecord::Base.configurations = { db => configuration } ActiveRecord::Base.establish_connection(db.to_sym) ActiveRecord::Base.default_timezone = :utc end def load_schema begin $stdout = StringIO.new ActiveRecord::Migration.verbose = false load File.join(FIXTURES_PATH, 'schema.rb') ensure $stdout = STDOUT end end module FixtureSetup def fixtures(*tables) table_names = tables.map { |t| t.to_s } fixtures = Fixtures.create_fixtures ActiverecordTestConnector::FIXTURES_PATH, table_names @@loaded_fixtures = {} @@fixture_cache = {} unless fixtures.nil? if fixtures.instance_of?(Fixtures) @@loaded_fixtures[fixtures.table_name] = fixtures else fixtures.each { |f| @@loaded_fixtures[f.table_name] = f } end end table_names.each do |table_name| define_method(table_name) do |*fixtures| @@fixture_cache[table_name] ||= {} instances = fixtures.map do |fixture| if @@loaded_fixtures[table_name][fixture.to_s] @@fixture_cache[table_name][fixture] ||= @@loaded_fixtures[table_name][fixture.to_s].find else raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'" end end instances.size == 1 ? instances.first : instances end end end end end will_paginate-3.1.6/spec/finders/sequel_test_connector.rb0000644000004100000410000000056613154516405023723 0ustar www-datawww-datarequire 'sequel' Symbol.class_eval do # Active Record calculations tries `as` on some objects but chokes when that # object was a Symbol and it gets a Sequel::SQL::AliasedExpression. undef as if method_defined? :as end db = Sequel.sqlite db.create_table :cars do primary_key :id, :integer, :auto_increment => true column :name, :text column :notes, :text end will_paginate-3.1.6/spec/finders/data_mapper_test_connector.rb0000644000004100000410000000205513154516405024675 0ustar www-datawww-datarequire 'sqlite3' require 'dm-core' require 'dm-core/support/logger' require 'dm-migrations' DataMapper.setup :default, 'sqlite3::memory:' # Define models class Animal include DataMapper::Resource property :id, Serial property :name, String property :notes, Text def self.setup Animal.create(:name => 'Dog', :notes => "Man's best friend") Animal.create(:name => 'Cat', :notes => "Woman's best friend") Animal.create(:name => 'Lion', :notes => 'King of the Jungle') end end class Ownership include DataMapper::Resource belongs_to :animal, :key => true belongs_to :human, :key => true def self.setup end end class Human include DataMapper::Resource property :id, Serial property :name, String has n, :ownerships has 1, :pet, :model => 'Animal', :through => :ownerships, :via => :animal def self.setup end end # Load fixtures [Animal, Ownership, Human].each do |klass| klass.auto_migrate! klass.setup end if 'irb' == $0 DataMapper.logger.set_log($stdout, :debug) DataMapper.logger.auto_flush = true end will_paginate-3.1.6/spec/fixtures/0000755000004100000410000000000013154516405017177 5ustar www-datawww-datawill_paginate-3.1.6/spec/fixtures/replies.yml0000644000004100000410000000106013154516405021362 0ustar www-datawww-datawitty_retort: id: 1 topic_id: 1 content: Birdman is better! created_at: <%= 6.hours.ago.utc.to_s(:db) %> another: id: 2 topic_id: 2 content: Nuh uh! created_at: <%= 1.hour.ago.utc.to_s(:db) %> spam: id: 3 topic_id: 1 content: Nice site! created_at: <%= 1.hour.ago.utc.to_s(:db) %> decisive: id: 4 topic_id: 4 content: "I'm getting to the bottom of this" created_at: <%= 30.minutes.ago.utc.to_s(:db) %> brave: id: 5 topic_id: 4 content: "AR doesn't scare me a bit" created_at: <%= 10.minutes.ago.utc.to_s(:db) %> will_paginate-3.1.6/spec/fixtures/project.rb0000644000004100000410000000070513154516405021174 0ustar www-datawww-dataclass Project < ActiveRecord::Base has_and_belongs_to_many :developers, :join_table => 'developers_projects' has_many :topics # :finder_sql => 'SELECT * FROM topics WHERE (topics.project_id = #{id})', # :counter_sql => 'SELECT COUNT(*) FROM topics WHERE (topics.project_id = #{id})' has_many :replies, :through => :topics do def only_recent(params = {}) where(['replies.created_at > ?', 15.minutes.ago]) end end end will_paginate-3.1.6/spec/fixtures/admin.rb0000644000004100000410000000005513154516405020614 0ustar www-datawww-dataclass Admin < User has_many :companies end will_paginate-3.1.6/spec/fixtures/topic.rb0000644000004100000410000000031213154516405020636 0ustar www-datawww-dataclass Topic < ActiveRecord::Base has_many :replies, :dependent => :destroy belongs_to :project scope :mentions_activerecord, lambda { where(['topics.title LIKE ?', '%ActiveRecord%']) } end will_paginate-3.1.6/spec/fixtures/schema.rb0000644000004100000410000000212613154516405020765 0ustar www-datawww-dataActiveRecord::Schema.define do create_table "users", :force => true do |t| t.column "name", :text t.column "salary", :integer, :default => 70000 t.column "created_at", :datetime t.column "updated_at", :datetime t.column "type", :text end create_table "projects", :force => true do |t| t.column "name", :text end create_table "developers_projects", :id => false, :force => true do |t| t.column "developer_id", :integer, :null => false t.column "project_id", :integer, :null => false t.column "joined_on", :date t.column "access_level", :integer, :default => 1 end create_table "topics", :force => true do |t| t.column "project_id", :integer t.column "title", :string t.column "subtitle", :string t.column "content", :text t.column "created_at", :datetime t.column "updated_at", :datetime end create_table "replies", :force => true do |t| t.column "content", :text t.column "created_at", :datetime t.column "updated_at", :datetime t.column "topic_id", :integer end end will_paginate-3.1.6/spec/fixtures/reply.rb0000644000004100000410000000030313154516405020653 0ustar www-datawww-dataclass Reply < ActiveRecord::Base scope :recent, lambda { where(['replies.created_at > ?', 15.minutes.ago]). order('replies.created_at DESC') } validates_presence_of :content end will_paginate-3.1.6/spec/fixtures/developer.rb0000644000004100000410000000032213154516405021506 0ustar www-datawww-dataclass Developer < User has_and_belongs_to_many :projects, :join_table => 'developers_projects' scope :poor, lambda { where(['salary <= ?', 80000]).order('salary') } def self.per_page() 10 end end will_paginate-3.1.6/spec/fixtures/projects.yml0000644000004100000410000000014213154516405021550 0ustar www-datawww-dataactive_record: id: 1 name: Active Record action_controller: id: 2 name: Action Controller will_paginate-3.1.6/spec/fixtures/user.rb0000644000004100000410000000004413154516405020500 0ustar www-datawww-dataclass User < ActiveRecord::Base end will_paginate-3.1.6/spec/fixtures/users.yml0000644000004100000410000000065013154516405021064 0ustar www-datawww-datadavid: id: 1 name: David salary: 80000 type: Developer jamis: id: 2 name: Jamis salary: 150000 type: Developer <% for digit in 3..10 %> dev_<%= digit %>: id: <%= digit %> name: fixture_<%= digit %> salary: 100000 type: Developer <% end %> poor_jamis: id: 11 name: Jamis salary: 9000 type: Developer admin: id: 12 name: admin type: Admin goofy: id: 13 name: Goofy type: Admin will_paginate-3.1.6/spec/fixtures/topics.yml0000644000004100000410000000135413154516405021226 0ustar www-datawww-datafuturama: id: 1 title: Isnt futurama awesome? subtitle: It really is, isnt it. content: I like futurama created_at: <%= 1.day.ago.utc.to_s(:db) %> updated_at: harvey_birdman: id: 2 title: Harvey Birdman is the king of all men subtitle: yup content: He really is created_at: <%= 2.hours.ago.utc.to_s(:db) %> updated_at: rails: id: 3 project_id: 1 title: Rails is nice subtitle: It makes me happy content: except when I have to hack internals to fix pagination. even then really. created_at: <%= 20.minutes.ago.utc.to_s(:db) %> ar: id: 4 project_id: 1 title: ActiveRecord sometimes freaks me out content: "I mean, what's the deal with eager loading?" created_at: <%= 15.minutes.ago.utc.to_s(:db) %> will_paginate-3.1.6/spec/fixtures/developers_projects.yml0000644000004100000410000000033213154516405024001 0ustar www-datawww-datadavid_action_controller: developer_id: 1 project_id: 2 joined_on: 2004-10-10 david_active_record: developer_id: 1 project_id: 1 joined_on: 2004-10-10 jamis_active_record: developer_id: 2 project_id: 1will_paginate-3.1.6/spec/page_number_spec.rb0000644000004100000410000000424313154516405021154 0ustar www-datawww-datarequire 'spec_helper' require 'will_paginate/page_number' describe WillPaginate::PageNumber do describe "valid" do def num WillPaginate::PageNumber.new('12', 'page') end it "== 12" do num.should eq(12) end it "inspects to 'page 12'" do num.inspect.should eq('page 12') end it "is a PageNumber" do (num.instance_of? WillPaginate::PageNumber).should be end it "is a kind of Numeric" do (num.is_a? Numeric).should be end it "is a kind of Integer" do (num.is_a? Integer).should be end it "isn't directly a Integer" do (num.instance_of? Integer).should_not be end it "passes the PageNumber=== type check" do |variable| (WillPaginate::PageNumber === num).should be end it "passes the Numeric=== type check" do |variable| (Numeric === num).should be (Integer === num).should be end end describe "invalid" do def create(value, name = 'page') described_class.new(value, name) end it "errors out on non-int values" do lambda { create(nil) }.should raise_error(WillPaginate::InvalidPage) lambda { create('') }.should raise_error(WillPaginate::InvalidPage) lambda { create('Schnitzel') }.should raise_error(WillPaginate::InvalidPage) end it "errors out on zero or less" do lambda { create(0) }.should raise_error(WillPaginate::InvalidPage) lambda { create(-1) }.should raise_error(WillPaginate::InvalidPage) end it "doesn't error out on zero for 'offset'" do lambda { create(0, 'offset') }.should_not raise_error lambda { create(-1, 'offset') }.should raise_error(WillPaginate::InvalidPage) end end describe "coercion method" do it "defaults to 'page' name" do num = WillPaginate::PageNumber(12) num.inspect.should eq('page 12') end it "accepts a custom name" do num = WillPaginate::PageNumber(12, 'monkeys') num.inspect.should eq('monkeys 12') end it "doesn't affect PageNumber instances" do num = WillPaginate::PageNumber(12) num2 = WillPaginate::PageNumber(num) num2.object_id.should eq(num.object_id) end end end will_paginate-3.1.6/spec/database.yml0000644000004100000410000000106113154516405017613 0ustar www-datawww-datasqlite3: database: ":memory:" adapter: sqlite3 timeout: 500 mysql: &mysql adapter: mysql database: will_paginate username: root encoding: utf8 <% if File.exist?("/var/run/mysql5/mysqld.sock") %> host: localhost socket: /var/run/mysql5/mysqld.sock <% elsif File.exist? "/tmp/mysql.sock" %> host: localhost socket: /tmp/mysql.sock <% else %> host: 127.0.0.1 <% end %> mysql2: <<: *mysql adapter: mysql2 postgres: adapter: postgresql database: will_paginate username: <%= "postgres" if ENV["TRAVIS"] %> min_messages: warning will_paginate-3.1.6/spec/matchers/0000755000004100000410000000000013154516405017134 5ustar www-datawww-datawill_paginate-3.1.6/spec/matchers/phrase_matcher.rb0000644000004100000410000000063613154516405022453 0ustar www-datawww-dataclass PhraseMatcher def initialize(string) @string = string @pattern = /\b#{Regexp.escape string}\b/ end def matches?(actual) @actual = actual.to_s @actual =~ @pattern end def failure_message "expected #{@actual.inspect} to contain phrase #{@string.inspect}" end def negative_failure_message "expected #{@actual.inspect} not to contain phrase #{@string.inspect}" end end will_paginate-3.1.6/spec/matchers/query_count_matcher.rb0000644000004100000410000000121413154516405023537 0ustar www-datawww-dataclass QueryCountMatcher def initialize(num) @expected_count = num end def matches?(block) run(block) if @expected_count.respond_to? :include? @expected_count.include? @count else @count == @expected_count end end def run(block) $query_count = 0 $query_sql = [] block.call ensure @queries = $query_sql.dup @count = $query_count end def performed_queries @queries end def failure_message "expected #{@expected_count} queries, got #{@count}\n#{@queries.join("\n")}" end def negative_failure_message "expected query count not to be #{@expected_count}" end end will_paginate-3.1.6/spec/matchers/deprecation_matcher.rb0000644000004100000410000000076313154516405023467 0ustar www-datawww-datarequire 'stringio' class DeprecationMatcher def initialize(message) @message = message end def matches?(block) @actual = hijack_stderr(&block) PhraseMatcher.new("DEPRECATION WARNING: #{@message}").matches?(@actual) end def failure_message "expected deprecation warning #{@message.inspect}, got #{@actual.inspect}" end private def hijack_stderr err = $stderr $stderr = StringIO.new yield $stderr.string.rstrip ensure $stderr = err end end will_paginate-3.1.6/spec/view_helpers/0000755000004100000410000000000013154516405020022 5ustar www-datawww-datawill_paginate-3.1.6/spec/view_helpers/link_renderer_base_spec.rb0000644000004100000410000000523413154516405025202 0ustar www-datawww-datarequire 'spec_helper' require 'will_paginate/view_helpers/link_renderer_base' require 'will_paginate/collection' describe WillPaginate::ViewHelpers::LinkRendererBase do before do @renderer = described_class.new end it "should raise error when unprepared" do lambda { @renderer.pagination }.should raise_error end it "should prepare with collection and options" do prepare({}) @renderer.send(:current_page).should == 1 end it "should have total_pages accessor" do prepare :total_pages => 42 @renderer.send(:total_pages).should == 42 end it "should clear old cached values when prepared" do prepare(:total_pages => 1) @renderer.send(:total_pages).should == 1 # prepare with different object: prepare(:total_pages => 2) @renderer.send(:total_pages).should == 2 end it "should have pagination definition" do prepare({ :total_pages => 1 }, :page_links => true) @renderer.pagination.should == [:previous_page, 1, :next_page] end describe "visible page numbers" do it "should calculate windowed visible links" do prepare({ :page => 6, :total_pages => 11 }, :inner_window => 1, :outer_window => 1) showing_pages 1, 2, :gap, 5, 6, 7, :gap, 10, 11 end it "should eliminate small gaps" do prepare({ :page => 6, :total_pages => 11 }, :inner_window => 2, :outer_window => 1) # pages 4 and 8 appear instead of the gap showing_pages 1..11 end it "should support having no windows at all" do prepare({ :page => 4, :total_pages => 7 }, :inner_window => 0, :outer_window => 0) showing_pages 1, :gap, 4, :gap, 7 end it "should adjust upper limit if lower is out of bounds" do prepare({ :page => 1, :total_pages => 10 }, :inner_window => 2, :outer_window => 1) showing_pages 1, 2, 3, 4, 5, :gap, 9, 10 end it "should adjust lower limit if upper is out of bounds" do prepare({ :page => 10, :total_pages => 10 }, :inner_window => 2, :outer_window => 1) showing_pages 1, 2, :gap, 6, 7, 8, 9, 10 end def showing_pages(*pages) pages = pages.first.to_a if Array === pages.first or Range === pages.first @renderer.send(:windowed_page_numbers).should == pages end end protected def collection(params = {}) if params[:total_pages] params[:per_page] = 1 params[:total_entries] = params[:total_pages] end WillPaginate::Collection.new(params[:page] || 1, params[:per_page] || 30, params[:total_entries]) end def prepare(collection_options, options = {}) @renderer.prepare(collection(collection_options), options) end end will_paginate-3.1.6/spec/view_helpers/base_spec.rb0000644000004100000410000001113313154516405022272 0ustar www-datawww-datarequire 'spec_helper' require 'will_paginate/view_helpers' require 'will_paginate/array' require 'active_support' require 'active_support/core_ext/string/inflections' require 'active_support/inflections' describe WillPaginate::ViewHelpers do before(:all) do # make sure default translations aren't loaded I18n.load_path.clear I18n.enforce_available_locales = false end before(:each) do I18n.reload! end include WillPaginate::ViewHelpers describe "will_paginate" do it "should render" do collection = WillPaginate::Collection.new(1, 2, 4) renderer = mock 'Renderer' renderer.expects(:prepare).with(collection, instance_of(Hash), self) renderer.expects(:to_html).returns('') will_paginate(collection, :renderer => renderer).should == '' end it "should return nil for single-page collections" do collection = mock 'Collection', :total_pages => 1 will_paginate(collection).should be_nil end it "should call html_safe on result" do collection = WillPaginate::Collection.new(1, 2, 4) html = mock 'HTML' html.expects(:html_safe).returns(html) renderer = mock 'Renderer' renderer.stubs(:prepare) renderer.expects(:to_html).returns(html) will_paginate(collection, :renderer => renderer).should eql(html) end end describe "pagination_options" do let(:pagination_options) { WillPaginate::ViewHelpers.pagination_options } it "deprecates setting :renderer" do begin lambda { pagination_options[:renderer] = 'test' }.should have_deprecation("pagination_options[:renderer] shouldn't be set") ensure pagination_options.delete :renderer end end end describe "page_entries_info" do before :all do @array = ('a'..'z').to_a end def info(params, options = {}) collection = Hash === params ? @array.paginate(params) : params page_entries_info collection, {:html => false}.merge(options) end it "should display middle results and total count" do info(:page => 2, :per_page => 5).should == "Displaying strings 6 - 10 of 26 in total" end it "uses translation if available" do translation :will_paginate => { :page_entries_info => {:multi_page => 'Showing %{from} - %{to}'} } info(:page => 2, :per_page => 5).should == "Showing 6 - 10" end it "uses specific translation if available" do translation :will_paginate => { :page_entries_info => {:multi_page => 'Showing %{from} - %{to}'}, :string => { :page_entries_info => {:multi_page => 'Strings %{from} to %{to}'} } } info(:page => 2, :per_page => 5).should == "Strings 6 to 10" end it "should output HTML by default" do info({ :page => 2, :per_page => 5 }, :html => true).should == "Displaying strings 6 - 10 of 26 in total" end it "should display shortened end results" do info(:page => 7, :per_page => 4).should include_phrase('strings 25 - 26') end it "should handle longer class names" do collection = @array.paginate(:page => 2, :per_page => 5) model = stub('Class', :name => 'ProjectType', :to_s => 'ProjectType') collection.first.stubs(:class).returns(model) info(collection).should include_phrase('project types') end it "should adjust output for single-page collections" do info(('a'..'d').to_a.paginate(:page => 1, :per_page => 5)).should == "Displaying all 4 strings" info(['a'].paginate(:page => 1, :per_page => 5)).should == "Displaying 1 string" end it "should display 'no entries found' for empty collections" do info([].paginate(:page => 1, :per_page => 5)).should == "No entries found" end it "uses model_name.human when available" do name = stub('model name', :i18n_key => :flower_key) name.expects(:human).with(:count => 1).returns('flower') model = stub('Class', :model_name => name) collection = [1].paginate(:page => 1) info(collection, :model => model).should == "Displaying 1 flower" end it "uses custom translation instead of model_name.human" do name = stub('model name', :i18n_key => :flower_key) name.expects(:human).never model = stub('Class', :model_name => name) translation :will_paginate => {:models => {:flower_key => 'tulip'}} collection = [1].paginate(:page => 1) info(collection, :model => model).should == "Displaying 1 tulip" end private def translation(data) I18n.backend.store_translations(:en, data) end end end will_paginate-3.1.6/spec/view_helpers/action_view_spec.rb0000644000004100000410000003135313154516405023675 0ustar www-datawww-data# encoding: utf-8 require 'spec_helper' require 'active_support/rescuable' # needed for Ruby 1.9.1 require 'action_controller' require 'action_view' require 'will_paginate/view_helpers/action_view' require 'will_paginate/collection' Routes = ActionDispatch::Routing::RouteSet.new Routes.draw do get 'dummy/page/:page' => 'dummy#index' get 'dummy/dots/page.:page' => 'dummy#dots' get 'ibocorp(/:page)' => 'ibocorp#index', :constraints => { :page => /\d+/ }, :defaults => { :page => 1 } get ':controller(/:action(/:id(.:format)))' end describe WillPaginate::ActionView do before(:all) do I18n.load_path.concat WillPaginate::I18n.load_path I18n.enforce_available_locales = false end before(:each) do I18n.reload! end before(:each) do @assigns = {} @controller = DummyController.new @request = @controller.request @template = '<%= will_paginate collection, options %>' end attr_reader :assigns, :controller, :request def render(locals) @view = ActionView::Base.new([], @assigns, @controller) @view.request = @request @view.singleton_class.send(:include, @controller._routes.url_helpers) @view.render(:inline => @template, :locals => locals) end ## basic pagination ## it "should render" do paginate do |pagination| assert_select 'a[href]', 3 do |elements| validate_page_numbers [2,3,2], elements text(elements[2]).should == 'Next →' end assert_select 'span', 1 do |spans| spans[0]['class'].should == 'previous_page disabled' text(spans[0]).should == '← Previous' end assert_select 'em.current', '1' text(pagination[0]).should == '← Previous 1 2 3 Next →' end end it "should override existing page param value" do request.params :page => 1 paginate do |pagination| assert_select 'a[href]', 3 do |elements| validate_page_numbers [2,3,2], elements end end end it "should render nothing when there is only 1 page" do paginate(:per_page => 30).should be_empty end it "should paginate with options" do paginate({ :page => 2 }, :class => 'will_paginate', :previous_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: text(elements[0]).should == 'Prev' elements[0]['rel'].should == 'prev' text(elements[1]).should == '1' elements[1]['rel'].should == 'prev' text(elements[3]).should == 'Next' elements[3]['rel'].should == 'next' end assert_select '.current', '2' end end it "should paginate using a custom renderer class" do paginate({}, :renderer => AdditionalLinkAttributesRenderer) do assert_select 'a[default=true]', 3 end end it "should paginate using a custom renderer instance" do renderer = WillPaginate::ActionView::LinkRenderer.new def renderer.gap() '~~' end 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 it "should have classnames on previous/next links" do paginate do |pagination| assert_select 'span.disabled.previous_page:first-child' assert_select 'a.next_page[href]:last-child' end end it "should match expected markup" do paginate expected = <<-HTML HTML expected.strip!.gsub!(/\s{2,}/, ' ') expected_dom = parse_html_document(expected).root html_document.root.should == expected_dom end it "should output escaped URLs" do paginate({:page => 1, :per_page => 1, :total_entries => 2}, :page_links => false, :params => { :tag => '
' }) assert_select 'a[href]', 1 do |links| query = links.first['href'].split('?', 2)[1] parts = query.gsub('&', '&').split('&').sort parts.should == %w(page=2 tag=%3Cbr%3E) end end ## advanced options for pagination ## it "should be able to render without container" do paginate({}, :container => false) assert_select 'div.pagination', 0, 'main DIV present when it shouldn\'t' assert_select 'a[href]', 3 end it "should be able to render without page links" do paginate({ :page => 2 }, :page_links => false) do assert_select 'a[href]', 2 do |elements| validate_page_numbers [1,3], elements end end end ## other helpers ## it "should render a paginated section" do @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 it "should not render a paginated section with a single page" do @template = <<-ERB <%= paginated_section collection, options do %> <%= content_tag :div, '', :id => "developers" %> <% end %> ERB paginate(:total_entries => 1) assert_select 'div.pagination', 0 assert_select 'div#developers', 1 end ## parameter handling in page links ## it "should preserve parameters on GET" do request.params :foo => { :bar => 'baz' } paginate assert_links_match /foo\[bar\]=baz/ end it "doesn't allow tampering with host, port, protocol" do request.params :host => 'disney.com', :port => '99', :protocol => 'ftp' paginate assert_links_match %r{^/foo/bar} assert_no_links_match /disney/ assert_no_links_match /99/ assert_no_links_match /ftp/ end it "doesn't allow tampering with script_name" do request.params :script_name => 'p0wned', :original_script_name => 'p0wned' paginate assert_links_match %r{^/foo/bar} assert_no_links_match /p0wned/ end it "should not preserve parameters on POST" do request.post request.params :foo => 'bar' paginate assert_no_links_match /foo=bar/ end it "should add additional parameters to links" do paginate({}, :params => { :foo => 'bar' }) assert_links_match /foo=bar/ end it "should add anchor parameter" do paginate({}, :params => { :anchor => 'anchor' }) assert_links_match /#anchor$/ end it "should remove arbitrary parameters" do request.params :foo => 'bar' paginate({}, :params => { :foo => nil }) assert_no_links_match /foo=bar/ end it "should override default route parameters" do paginate({}, :params => { :controller => 'baz', :action => 'list' }) assert_links_match %r{\Wbaz/list\W} end it "should paginate with custom page parameter" do 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 it "should paginate with complex custom page parameter" do request.params :developers => { :page => 2 } paginate({ :page => 2 }, :param_name => 'developers[page]') do assert_select 'a[href]', 4 do |links| assert_links_match /\?developers\[page\]=\d+$/, links validate_page_numbers [1,1,3,3], links, 'developers[page]' end end end it "should paginate with custom route page parameter" do request.symbolized_path_parameters.update :controller => 'dummy', :action => 'index' 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 it "should paginate with custom route with dot separator page parameter" do 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 it "should paginate with custom route and first page number implicit" do request.symbolized_path_parameters.update :controller => 'ibocorp', :action => 'index' 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 # Routes.recognize_path('/ibocorp/2').should == {:page=>'2', :action=>'index', :controller=>'ibocorp'} # Routes.recognize_path('/ibocorp/foo').should == {:action=>'foo', :controller=>'ibocorp'} end ## internal hardcore stuff ## it "should be able to guess the collection name" do collection = mock collection.expects(:total_pages).returns(1) @template = '<%= will_paginate options %>' controller.controller_name = 'developers' assigns['developers'] = collection paginate(nil) end it "should fail if the inferred collection is nil" do @template = '<%= will_paginate options %>' controller.controller_name = 'developers' lambda { paginate(nil) }.should raise_error(ActionView::TemplateError, /@developers/) end ## i18n it "is able to translate previous/next labels" do translation :will_paginate => { :previous_label => 'Go back', :next_label => 'Load more' } paginate do |pagination| assert_select 'span.disabled:first-child', 'Go back' assert_select 'a[rel=next]', 'Load more' end end it "renders using ActionView helpers on a custom object" do helper = Class.new { attr_reader :controller include ActionView::Helpers::UrlHelper include Routes.url_helpers include WillPaginate::ActionView }.new helper.default_url_options[:controller] = 'dummy' collection = WillPaginate::Collection.new(2, 1, 3) @render_output = helper.will_paginate(collection) assert_select 'a[href]', 4 do |links| urls = links.map {|l| l['href'] }.uniq urls.should == ['/dummy/page/1', '/dummy/page/3'] end end it "renders using ActionDispatch helper on a custom object" do helper = Class.new { include ActionDispatch::Routing::UrlFor include Routes.url_helpers include WillPaginate::ActionView }.new helper.default_url_options.update \ :only_path => true, :controller => 'dummy' collection = WillPaginate::Collection.new(2, 1, 3) @render_output = helper.will_paginate(collection) assert_select 'a[href]', 4 do |links| urls = links.map {|l| l['href'] }.uniq urls.should == ['/dummy/page/1', '/dummy/page/3'] end end private def translation(data) I18n.available_locales # triggers loading existing translations I18n.backend.store_translations(:en, data) end # Normalizes differences between HTML::Document and Nokogiri::HTML def text(node) node.inner_text.gsub('→', '→').gsub('←', '←') end end class AdditionalLinkAttributesRenderer < WillPaginate::ActionView::LinkRenderer def initialize(link_attributes = nil) super() @additional_link_attributes = link_attributes || { :default => 'true' } end def link(text, target, attributes = {}) super(text, target, attributes.merge(@additional_link_attributes)) end end class DummyController attr_reader :request attr_accessor :controller_name include ActionController::UrlFor include Routes.url_helpers def initialize @request = DummyRequest.new(self) end def params @request.params end def env {} end def _prefixes [] end end class IbocorpController < DummyController end class DummyRequest attr_accessor :symbolized_path_parameters alias :path_parameters :symbolized_path_parameters def initialize(controller) @controller = controller @get = true @params = {}.with_indifferent_access @symbolized_path_parameters = { :controller => 'foo', :action => 'bar' } end def routes @controller._routes end def get? @get end def post @get = false end def relative_url_root '' end def script_name '' end def params(more = nil) @params.update(more) if more if defined?(ActionController::Parameters) ActionController::Parameters.new(@params) else @params end end def host_with_port 'example.com' end alias host host_with_port def optional_port '' end def protocol 'http:' end end if defined?(ActionController::Parameters) ActionController::Parameters.permit_all_parameters = false end will_paginate-3.1.6/spec/view_helpers/view_example_group.rb0000644000004100000410000000636213154516405024257 0ustar www-datawww-datarequire 'active_support' require 'stringio' begin $stderr = StringIO.new require 'minitest/unit' rescue LoadError # Fails on Ruby 1.8, but it's OK since we only need MiniTest::Assertions # on Rails 4 which doesn't support 1.8 anyway. ensure $stderr = STDERR end begin require 'rails/dom/testing/assertions' rescue LoadError require 'action_dispatch/testing/assertions' end require 'will_paginate/array' module ViewExampleGroup if defined?(Rails::Dom::Testing::Assertions) include Rails::Dom::Testing::Assertions::SelectorAssertions else include ActionDispatch::Assertions::SelectorAssertions end include MiniTest::Assertions if defined? MiniTest def assert(value, message) raise message unless value end 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 } @render_output = render(locals) @html_document = nil if block_given? classname = options[:class] || WillPaginate::ViewHelpers.pagination_options[:class] assert_select("div.#{classname}", 1, 'no main DIV', &block) end @render_output end def parse_html_document(html) @html_document ||= if defined?(Rails::Dom::Testing::Assertions) Nokogiri::HTML::Document.parse(html) else HTML::Document.new(html, true, false) end end def html_document @html_document ||= parse_html_document(@render_output) end def document_root_element html_document.root end def response_from_page_or_rjs html_document.root end def validate_page_numbers(expected, links, param_name = :page) param_pattern = /\W#{Regexp.escape(param_name.to_s)}=([^&]*)/ links.map { |el| unescape_href(el) =~ param_pattern $1 ? $1.to_i : $1 }.should == expected 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| href = unescape_href(el) href.should =~ pattern if numbers href =~ pattern pages << ($1.nil?? nil : $1.to_i) end end pages.should == numbers if numbers end def assert_no_links_match(pattern) assert_select 'div.pagination a[href]' do |elements| elements.each do |el| unescape_href(el).should_not =~ pattern end end end def unescape_href(el) CGI.unescape CGI.unescapeHTML(el['href']) end def build_message(message, pattern, *args) built_message = pattern.dup for value in args built_message.sub! '?', value.inspect end built_message end end RSpec.configure do |config| config.include ViewExampleGroup, :type => :view, :example_group => { :file_path => %r{spec/view_helpers/} } 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 if defined?(HTML) will_paginate-3.1.6/spec/console0000755000004100000410000000064413154516405016722 0ustar www-datawww-data#!/usr/bin/env ruby irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb' opts = %w[ --simple-prompt -rirb/completion ] if ARGV.include? '-dm' opts << '-rwill_paginate/data_mapper' << '-rfinders/data_mapper_test_connector' elsif ARGV.include? '-seq' opts << '-rwill_paginate/sequel' << '-rfinders/sequel_test_connector' else opts << '-rconsole_fixtures' end exec 'bundle', 'exec', irb, '-Ilib:spec', *opts will_paginate-3.1.6/spec/collection_spec.rb0000644000004100000410000001000413154516405021013 0ustar www-datawww-datarequire 'will_paginate/array' require 'spec_helper' describe WillPaginate::Collection do before :all do @simple = ('a'..'e').to_a end it "should be a subset of original collection" do @simple.paginate(:page => 1, :per_page => 3).should == %w( a b c ) end it "can be shorter than per_page if on last page" do @simple.paginate(:page => 2, :per_page => 3).should == %w( d e ) end it "should include whole collection if per_page permits" do @simple.paginate(:page => 1, :per_page => 5).should == @simple end it "should be empty if out of bounds" do @simple.paginate(:page => 2, :per_page => 5).should be_empty end it "should default to 1 as current page and 30 per-page" do result = (1..50).to_a.paginate result.current_page.should == 1 result.size.should == 30 end it "should give total_entries precedence over actual size" do %w(a b c).paginate(:total_entries => 5).total_entries.should == 5 end it "should be an augmented Array" do entries = %w(a b c) collection = create(2, 3, 10) do |pager| pager.replace(entries).should == entries end collection.should == entries for method in %w(total_pages each offset size current_page per_page total_entries) collection.should respond_to(method) end collection.should be_kind_of(Array) collection.entries.should be_instance_of(Array) # TODO: move to another expectation: collection.offset.should == 3 collection.total_pages.should == 4 collection.should_not be_out_of_bounds end describe "previous/next pages" do it "should have previous_page nil when on first page" do collection = create(1, 1, 3) collection.previous_page.should be_nil collection.next_page.should == 2 end it "should have both prev/next pages" do collection = create(2, 1, 3) collection.previous_page.should == 1 collection.next_page.should == 3 end it "should have next_page nil when on last page" do collection = create(3, 1, 3) collection.previous_page.should == 2 collection.next_page.should be_nil end end describe "out of bounds" do it "is out of bounds when page number is too high" do create(2, 3, 2).should be_out_of_bounds end it "isn't out of bounds when inside collection" do create(1, 3, 2).should_not be_out_of_bounds end it "isn't out of bounds when the collection is empty" do collection = create(1, 3, 0) collection.should_not be_out_of_bounds collection.total_pages.should == 1 end end describe "guessing total count" do it "can guess when collection is shorter than limit" do collection = create { |p| p.replace array } collection.total_entries.should == 8 end it "should allow explicit total count to override guessed" do collection = create(2, 5, 10) { |p| p.replace array } collection.total_entries.should == 10 end it "should not be able to guess when collection is same as limit" do collection = create { |p| p.replace array(5) } collection.total_entries.should be_nil end it "should not be able to guess when collection is empty" do collection = create { |p| p.replace array(0) } collection.total_entries.should be_nil end it "should be able to guess when collection is empty and this is the first page" do collection = create(1) { |p| p.replace array(0) } collection.total_entries.should == 0 end end it "should not respond to page_count anymore" do Proc.new { create.page_count }.should raise_error(NoMethodError) end it "inherits per_page from global value" do collection = described_class.new(1) collection.per_page.should == 30 end private def create(page = 2, limit = 5, total = nil, &block) if block_given? described_class.create(page, limit, total, &block) else described_class.new(page, limit, total) end end def array(size = 3) Array.new(size) end end will_paginate-3.1.6/spec/console_fixtures.rb0000644000004100000410000000143413154516405021250 0ustar www-datawww-datarequire 'bundler' Bundler.setup require 'will_paginate/active_record' require 'finders/activerecord_test_connector' ActiverecordTestConnector.setup windows = RUBY_PLATFORM =~ /(:?mswin|mingw)/ # used just for the `color` method log_subscriber = ActiveSupport::LogSubscriber.log_subscribers.first IGNORE_SQL = /\b(sqlite_master|sqlite_version)\b|^(CREATE TABLE|PRAGMA)\b/ ActiveSupport::Notifications.subscribe(/^sql\./) do |*args| data = args.last unless data[:name] =~ /^Fixture/ or data[:sql] =~ IGNORE_SQL if windows puts data[:sql] else puts log_subscriber.send(:color, data[:sql], :cyan) end end end # load all fixtures ActiverecordTestConnector::Fixtures.create_fixtures \ ActiverecordTestConnector::FIXTURES_PATH, ActiveRecord::Base.connection.tables will_paginate-3.1.6/lib/0000755000004100000410000000000013154516405015142 5ustar www-datawww-datawill_paginate-3.1.6/lib/will_paginate/0000755000004100000410000000000013154516405017761 5ustar www-datawww-datawill_paginate-3.1.6/lib/will_paginate/core_ext.rb0000644000004100000410000000134113154516405022115 0ustar www-datawww-datarequire 'set' # copied from ActiveSupport so we don't depend on it unless Hash.method_defined? :except Hash.class_eval do # Returns a new hash without the given keys. def except(*keys) rejected = Set.new(respond_to?(:convert_key) ? keys.map { |key| convert_key(key) } : keys) reject { |key,| rejected.include?(key) } end # Replaces the hash without only the given keys. def except!(*keys) replace(except(*keys)) end end end unless String.method_defined? :underscore String.class_eval do def underscore self.to_s.gsub(/::/, '/'). gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). gsub(/([a-z\d])([A-Z])/,'\1_\2'). tr("-", "_"). downcase end end end will_paginate-3.1.6/lib/will_paginate/active_record.rb0000644000004100000410000001677713154516405023141 0ustar www-datawww-datarequire 'will_paginate/per_page' require 'will_paginate/page_number' require 'will_paginate/collection' require 'active_record' module WillPaginate # = Paginating finders for ActiveRecord models # # WillPaginate adds +paginate+, +per_page+ and other methods to # ActiveRecord::Base class methods and associations. # # In short, paginating finders are equivalent to ActiveRecord finders; the # only difference is that we start with "paginate" instead of "find" and # that :page is required parameter: # # @posts = Post.paginate :all, :page => params[:page], :order => 'created_at DESC' # module ActiveRecord # makes a Relation look like WillPaginate::Collection module RelationMethods include WillPaginate::CollectionMethods attr_accessor :current_page attr_writer :total_entries def per_page(value = nil) if value.nil? then limit_value else limit(value) end end # TODO: solve with less relation clones and code dups def limit(num) rel = super if rel.current_page rel.offset rel.current_page.to_offset(rel.limit_value).to_i else rel end end # dirty hack to enable `first` after `limit` behavior above def first(*args) if current_page rel = clone rel.current_page = nil rel.first(*args) else super end end # fix for Rails 3.0 def find_last(*args) if !loaded? && args.empty? && (offset_value || limit_value) @last ||= to_a.last else super end end def offset(value = nil) if value.nil? then offset_value else super(value) end end def total_entries @total_entries ||= begin if loaded? and size < limit_value and (current_page == 1 or size > 0) offset_value + size else @total_entries_queried = true result = count result = result.size if result.respond_to?(:size) and !result.is_a?(Integer) result end end end def count(*args) if limit_value excluded = [:order, :limit, :offset, :reorder] excluded << :includes unless eager_loading? rel = self.except(*excluded) column_name = (select_for_count(rel) || :all) rel.count(column_name) else super(*args) end end # workaround for Active Record 3.0 def size if !loaded? and limit_value and group_values.empty? [super, limit_value].min else super end end # overloaded to be pagination-aware def empty? if !loaded? and offset_value result = count result = result.size if result.respond_to?(:size) and !result.is_a?(Integer) result <= offset_value else super end end def clone copy_will_paginate_data super end # workaround for Active Record 3.0 def scoped(options = nil) copy_will_paginate_data super end def to_a if current_page.nil? then super # workaround for Active Record 3.0 else ::WillPaginate::Collection.create(current_page, limit_value) do |col| col.replace super col.total_entries ||= total_entries end end end private def copy_will_paginate_data(other) other.current_page = current_page unless other.current_page other.total_entries = nil if defined? @total_entries_queried other end def select_for_count(rel) if rel.select_values.present? select = rel.select_values.join(", ") select if select !~ /[,*]/ end end end module Pagination def paginate(options) options = options.dup pagenum = options.fetch(:page) { raise ArgumentError, ":page parameter required" } options.delete(:page) per_page = options.delete(:per_page) || self.per_page total = options.delete(:total_entries) if options.any? raise ArgumentError, "unsupported parameters: %p" % options.keys end rel = limit(per_page.to_i).page(pagenum) rel.total_entries = total.to_i unless total.blank? rel end def page(num) rel = if ::ActiveRecord::Relation === self self elsif !defined?(::ActiveRecord::Scoping) or ::ActiveRecord::Scoping::ClassMethods.method_defined? :with_scope # Active Record 3 scoped else # Active Record 4 all end rel = rel.extending(RelationMethods) pagenum = ::WillPaginate::PageNumber(num.nil? ? 1 : num) per_page = rel.limit_value || self.per_page rel = rel.offset(pagenum.to_offset(per_page).to_i) rel = rel.limit(per_page) unless rel.limit_value rel.current_page = pagenum rel end end module BaseMethods # 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 # +per_page+. # # Example: # # @developers = Developer.paginate_by_sql ['select * from developers where salary > ?', 80000], # :page => params[:page], :per_page => 3 # # A query for counting rows will automatically be generated if you don't # supply :total_entries. If you experience problems with this # generated SQL, you might want to perform the count manually in your # application. # def paginate_by_sql(sql, options) pagenum = options.fetch(:page) { raise ArgumentError, ":page parameter required" } || 1 per_page = options[:per_page] || self.per_page total = options[:total_entries] WillPaginate::Collection.create(pagenum, per_page, total) do |pager| query = sanitize_sql(sql.dup) original_query = query.dup oracle = self.connection.adapter_name =~ /^(oracle|oci$)/i # add limit, offset if oracle query = <<-SQL SELECT * FROM ( SELECT rownum rnum, a.* FROM (#{query}) a WHERE rownum <= #{pager.offset + pager.per_page} ) WHERE rnum >= #{pager.offset} SQL else query << " LIMIT #{pager.per_page} OFFSET #{pager.offset}" end # perfom the find pager.replace find_by_sql(query) unless pager.total_entries count_query = original_query.sub /\bORDER\s+BY\s+[\w`,\s.]+$/mi, '' count_query = "SELECT COUNT(*) FROM (#{count_query})" count_query << ' AS count_table' unless oracle # perform the count query pager.total_entries = count_by_sql(count_query) end end end end # mix everything into Active Record ::ActiveRecord::Base.extend PerPage ::ActiveRecord::Base.extend Pagination ::ActiveRecord::Base.extend BaseMethods klasses = [::ActiveRecord::Relation] if defined? ::ActiveRecord::Associations::CollectionProxy klasses << ::ActiveRecord::Associations::CollectionProxy else klasses << ::ActiveRecord::Associations::AssociationCollection end # support pagination on associations and scopes klasses.each { |klass| klass.send(:include, Pagination) } end end will_paginate-3.1.6/lib/will_paginate/deprecation.rb0000644000004100000410000000232513154516405022605 0ustar www-datawww-datamodule WillPaginate::Deprecation class << self def warn(message, stack = caller) offending_line = origin_of_call(stack) full_message = "DEPRECATION WARNING: #{message} (called from #{offending_line})" logger = rails_logger || Kernel logger.warn full_message end private def rails_logger defined?(Rails.logger) && Rails.logger end def origin_of_call(stack) lib_root = File.expand_path('../../..', __FILE__) stack.find { |line| line.index(lib_root) != 0 } || stack.first end end class Hash < ::Hash def initialize(values = {}) super() update values @deprecated = {} end def []=(key, value) check_deprecated(key, value) super end def deprecate_key(*keys) message = block_given? ? Proc.new : keys.pop Array(keys).each { |key| @deprecated[key] = message } end def merge(another) to_hash.update(another) end def to_hash ::Hash.new.update(self) end private def check_deprecated(key, value) if msg = @deprecated[key] and (!msg.respond_to?(:call) or (msg = msg.call(key, value))) WillPaginate::Deprecation.warn(msg) end end end end will_paginate-3.1.6/lib/will_paginate/sequel.rb0000644000004100000410000000141613154516405021606 0ustar www-datawww-datarequire 'sequel' require 'sequel/extensions/pagination' require 'will_paginate/collection' module WillPaginate # Sequel already supports pagination; we only need to make the # resulting dataset look a bit more like WillPaginate::Collection module SequelMethods include WillPaginate::CollectionMethods def total_pages page_count end def per_page page_size end def size current_page_record_count end alias length size def total_entries pagination_record_count end def out_of_bounds? current_page > total_pages end # Current offset of the paginated collection def offset (current_page - 1) * per_page end end Sequel::Dataset::Pagination.send(:include, SequelMethods) end will_paginate-3.1.6/lib/will_paginate/version.rb0000644000004100000410000000023013154516405021766 0ustar www-datawww-datamodule WillPaginate #:nodoc: module VERSION #:nodoc: MAJOR = 3 MINOR = 1 TINY = 6 STRING = [MAJOR, MINOR, TINY].join('.') end end will_paginate-3.1.6/lib/will_paginate/view_helpers.rb0000644000004100000410000001526413154516405023012 0ustar www-datawww-data# encoding: utf-8 require 'will_paginate/core_ext' require 'will_paginate/i18n' require 'will_paginate/deprecation' module WillPaginate # = Will Paginate view helpers # # The main view helper is +will_paginate+. It renders the pagination links # for the given collection. The helper itself is lightweight and serves only # as a wrapper around LinkRenderer instantiation; the renderer then does # all the hard work of generating the HTML. module ViewHelpers class << self # Write to this hash to override default options on the global level: # # WillPaginate::ViewHelpers.pagination_options[:page_links] = false # attr_accessor :pagination_options end # default view options self.pagination_options = Deprecation::Hash.new \ :class => 'pagination', :previous_label => nil, :next_label => nil, :inner_window => 4, # links around the current page :outer_window => 1, # links around beginning and end :link_separator => ' ', # single space is friendly to spiders and non-graphic browsers :param_name => :page, :params => nil, :page_links => true, :container => true label_deprecation = Proc.new { |key, value| "set the 'will_paginate.#{key}' key in your i18n locale instead of editing pagination_options" if defined? Rails } pagination_options.deprecate_key(:previous_label, :next_label, &label_deprecation) pagination_options.deprecate_key(:renderer) { |key, _| "pagination_options[#{key.inspect}] shouldn't be set globally" } include WillPaginate::I18n # Returns HTML representing page links for a WillPaginate::Collection-like object. # In case there is no more than one page in total, nil is returned. # # ==== Options # * :class -- CSS class name for the generated DIV (default: "pagination") # * :previous_label -- default: "« Previous" # * :next_label -- default: "Next »" # * :inner_window -- how many links are shown around the current page (default: 4) # * :outer_window -- how many links are around the first and the last page (default: 1) # * :link_separator -- string separator for page HTML elements (default: single space) # * :param_name -- parameter name for page number in URLs (default: :page) # * :params -- additional parameters when generating pagination links # (eg. :controller => "foo", :action => nil) # * :renderer -- class name, class or instance of a link renderer (default in Rails: # WillPaginate::ActionView::LinkRenderer) # * :page_links -- when false, only previous/next links are rendered (default: true) # * :container -- toggles rendering of the DIV container for pagination links, set to # false only when you are rendering your own pagination markup (default: true) # # All options not recognized by will_paginate will become HTML attributes on the container # element for pagination links (the DIV). For example: # # <%= will_paginate @posts, :style => 'color:blue' %> # # will result in: # # # def will_paginate(collection, options = {}) # early exit if there is nothing to render return nil unless collection.total_pages > 1 options = WillPaginate::ViewHelpers.pagination_options.merge(options) options[:previous_label] ||= will_paginate_translate(:previous_label) { '← Previous' } options[:next_label] ||= will_paginate_translate(:next_label) { 'Next →' } # get the renderer instance renderer = case options[:renderer] when nil raise ArgumentError, ":renderer not specified" when String klass = if options[:renderer].respond_to? :constantize then options[:renderer].constantize else Object.const_get(options[:renderer]) # poor man's constantize end klass.new when Class then options[:renderer].new else options[:renderer] end # render HTML for pagination renderer.prepare collection, options, self output = renderer.to_html output = output.html_safe if output.respond_to?(:html_safe) output end # Renders a message containing number of displayed vs. total entries. # # <%= page_entries_info @posts %> # #-> Displaying posts 6 - 12 of 26 in total # # The default output contains HTML. Use ":html => false" for plain text. def page_entries_info(collection, options = {}) model = options[:model] model = collection.first.class unless model or collection.empty? model ||= 'entry' model_key = if model.respond_to? :model_name model.model_name.i18n_key # ActiveModel::Naming else model.to_s.underscore end if options.fetch(:html, true) b, eb = '', '' sp = ' ' html_key = '_html' else b = eb = html_key = '' sp = ' ' end model_count = collection.total_pages > 1 ? 5 : collection.size defaults = ["models.#{model_key}"] defaults << Proc.new { |_, opts| if model.respond_to? :model_name model.model_name.human(:count => opts[:count]) else name = model_key.to_s.tr('_', ' ') raise "can't pluralize model name: #{model.inspect}" unless name.respond_to? :pluralize opts[:count] == 1 ? name : name.pluralize end } model_name = will_paginate_translate defaults, :count => model_count if collection.total_pages < 2 i18n_key = :"page_entries_info.single_page#{html_key}" keys = [:"#{model_key}.#{i18n_key}", i18n_key] will_paginate_translate keys, :count => collection.total_entries, :model => model_name do |_, opts| case opts[:count] when 0; "No #{opts[:model]} found" when 1; "Displaying #{b}1#{eb} #{opts[:model]}" else "Displaying #{b}all#{sp}#{opts[:count]}#{eb} #{opts[:model]}" end end else i18n_key = :"page_entries_info.multi_page#{html_key}" keys = [:"#{model_key}.#{i18n_key}", i18n_key] params = { :model => model_name, :count => collection.total_entries, :from => collection.offset + 1, :to => collection.offset + collection.length } will_paginate_translate keys, params do |_, opts| %{Displaying %s #{b}%d#{sp}-#{sp}%d#{eb} of #{b}%d#{eb} in total} % [ opts[:model], opts[:from], opts[:to], opts[:count] ] end end end end end will_paginate-3.1.6/lib/will_paginate/mongoid.rb0000644000004100000410000000211613154516405021742 0ustar www-datawww-datarequire 'mongoid' require 'will_paginate/collection' module WillPaginate module Mongoid module CriteriaMethods def paginate(options = {}) extend CollectionMethods @current_page = WillPaginate::PageNumber(options[:page] || @current_page || 1) @page_multiplier = current_page - 1 pp = (options[:per_page] || per_page || WillPaginate.per_page).to_i limit(pp).skip(@page_multiplier * pp) end def per_page(value = :non_given) if value == :non_given options[:limit] == 0 ? nil : options[:limit] # in new Mongoid versions a nil limit is saved as 0 else limit(value) end end def page(page) paginate(:page => page) end end module CollectionMethods attr_reader :current_page def total_entries @total_entries ||= count end def total_pages (total_entries / per_page.to_f).ceil end def offset @page_multiplier * per_page end end ::Mongoid::Criteria.send(:include, CriteriaMethods) end end will_paginate-3.1.6/lib/will_paginate/array.rb0000644000004100000410000000242213154516405021424 0ustar www-datawww-datarequire 'will_paginate/collection' class Array # Paginates a static array (extracting a subset of it). The result is a # WillPaginate::Collection instance, which is an array with a few more # properties about its paginated state. # # Parameters: # * :page - current page, defaults to 1 # * :per_page - limit of items per page, defaults to 30 # * :total_entries - total number of items in the array, defaults to # array.length (obviously) # # Example: # arr = ['a', 'b', 'c', 'd', 'e'] # paged = arr.paginate(:per_page => 2) #-> ['a', 'b'] # paged.total_entries #-> 5 # arr.paginate(:page => 2, :per_page => 2) #-> ['c', 'd'] # arr.paginate(:page => 3, :per_page => 2) #-> ['e'] # # This method was originally {suggested by Desi # McAdam}[http://www.desimcadam.com/archives/8] and later proved to be the # most useful method of will_paginate library. def paginate(options = {}) page = options[:page] || 1 per_page = options[:per_page] || WillPaginate.per_page total = options[:total_entries] || self.length WillPaginate::Collection.create(page, per_page, total) do |pager| pager.replace self[pager.offset, pager.per_page].to_a end end end will_paginate-3.1.6/lib/will_paginate/i18n.rb0000644000004100000410000000105713154516405021070 0ustar www-datawww-datamodule WillPaginate module I18n def self.locale_dir File.expand_path('../locale', __FILE__) end def self.load_path Dir["#{locale_dir}/*.{rb,yml}"] end def will_paginate_translate(keys, options = {}) if defined? ::I18n defaults = Array(keys).dup defaults << Proc.new if block_given? ::I18n.translate(defaults.shift, options.merge(:default => defaults, :scope => :will_paginate)) else key = Array === keys ? keys.first : keys yield key, options end end end end will_paginate-3.1.6/lib/will_paginate/collection.rb0000644000004100000410000001205413154516405022443 0ustar www-datawww-datarequire 'will_paginate/per_page' require 'will_paginate/page_number' module WillPaginate # Any will_paginate-compatible collection should have these methods: # # current_page, per_page, offset, total_entries, total_pages # # It can also define some of these optional methods: # # out_of_bounds?, previous_page, next_page # # This module provides few of these methods. module CollectionMethods def total_pages total_entries.zero? ? 1 : (total_entries / per_page.to_f).ceil end # current_page - 1 or nil if there is no previous page def previous_page current_page > 1 ? (current_page - 1) : nil end # current_page + 1 or nil if there is no next page def next_page current_page < total_pages ? (current_page + 1) : nil 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 > total_pages end end # = 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 this library and do: # # require 'will_paginate/collection' # # WillPaginate::Collection is now available for use class Collection < Array include CollectionMethods attr_reader :current_page, :per_page, :total_entries # 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 = WillPaginate.per_page, total = nil) @current_page = WillPaginate::PageNumber(page) @per_page = per_page.to_i self.total_entries = total if total end # Just like +new+, but yields the object after instantiation and returns it # afterwards. This is very useful for manual pagination: # # @entries = WillPaginate::Collection.create(1, 10) do |pager| # result = Post.find(:all, :limit => pager.per_page, :offset => pager.offset) # # inject the result array into the paginated collection: # pager.replace(result) # # unless pager.total_entries # # the pager didn't manage to guess the total count, do it manually # pager.total_entries = Post.count # end # end # # The possibilities with this are endless. For another example, here is how # WillPaginate used to define pagination for Array instances: # # Array.class_eval do # def paginate(page = 1, per_page = 15) # WillPaginate::Collection.create(page, per_page, size) do |pager| # pager.replace self[pager.offset, pager.per_page].to_a # end # 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) pager = new(page, per_page, total) yield pager pager 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 # side by side with records in the view: simply start with offset + 1. def offset current_page.to_offset(per_page).to_i end def total_entries=(number) @total_entries = number.to_i end # This is a magic wrapper for the original Array#replace method. It serves # for populating the paginated collection after initialization. # # Why magic? Because it tries to guess the total number of entries judging # by the size of given array. If it is shorter than +per_page+ limit, then we # know we're on the last page. This trick is very useful for avoiding # unnecessary hits to the database to do the counting after we fetched the # data for the current page. # # However, after using +replace+ you should always test the value of # +total_entries+ and set it to a proper value if it's +nil+. See the example # in +create+. def replace(array) 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 will_paginate-3.1.6/lib/will_paginate/per_page.rb0000644000004100000410000000075113154516405022073 0ustar www-datawww-datamodule WillPaginate module PerPage def per_page defined?(@per_page) ? @per_page : WillPaginate.per_page end def per_page=(limit) @per_page = limit.to_i end def self.extended(base) base.extend Inheritance if base.is_a? Class end module Inheritance def inherited(subclass) super subclass.per_page = self.per_page end end end extend PerPage # default number of items per page self.per_page = 30 end will_paginate-3.1.6/lib/will_paginate/view_helpers/0000755000004100000410000000000013154516405022455 5ustar www-datawww-datawill_paginate-3.1.6/lib/will_paginate/view_helpers/sinatra.rb0000644000004100000410000000172513154516405024450 0ustar www-datawww-datarequire 'sinatra/base' require 'will_paginate/view_helpers' require 'will_paginate/view_helpers/link_renderer' module WillPaginate module Sinatra module Helpers include ViewHelpers def will_paginate(collection, options = {}) #:nodoc: options = options.merge(:renderer => LinkRenderer) unless options[:renderer] super(collection, options) end end class LinkRenderer < ViewHelpers::LinkRenderer protected def url(page) str = File.join(request.script_name.to_s, request.path_info) params = request.GET.merge(param_name.to_s => page.to_s) params.update @options[:params] if @options[:params] str << '?' << build_query(params) end def request @template.request end def build_query(params) Rack::Utils.build_nested_query params end end def self.registered(app) app.helpers Helpers end ::Sinatra.register self end end will_paginate-3.1.6/lib/will_paginate/view_helpers/merb.rb0000644000004100000410000000123313154516405023726 0ustar www-datawww-datarequire 'will_paginate/core_ext' require 'will_paginate/view_helpers' require 'will_paginate/view_helpers/link_renderer' module WillPaginate module Merb include ViewHelpers def will_paginate(collection, options = {}) #:nodoc: options = options.merge(:renderer => LinkRenderer) unless options[:renderer] super(collection, options) end class LinkRenderer < ViewHelpers::LinkRenderer protected def url(page) params = @template.request.params.except(:action, :controller).merge(param_name => page) @template.url(:this, params) end end ::Merb::AbstractController.send(:include, self) end end will_paginate-3.1.6/lib/will_paginate/view_helpers/action_view.rb0000644000004100000410000001063413154516405025315 0ustar www-datawww-datarequire 'will_paginate/view_helpers' require 'will_paginate/view_helpers/link_renderer' module WillPaginate # = ActionView helpers # # This module serves for availability in ActionView templates. It also adds a new # view helper: +paginated_section+. # # == Using the helper without arguments # If the helper is called without passing in the collection object, it will # try to read from the instance variable inferred by the controller name. # For example, calling +will_paginate+ while the current controller is # PostsController will result in trying to read from the @posts # variable. Example: # # <%= will_paginate :id => true %> # # ... will result in @post collection getting paginated: # # # module ActionView include ViewHelpers def will_paginate(collection = nil, options = {}) #:nodoc: options, collection = collection, nil if collection.is_a? Hash collection ||= infer_collection_from_controller options = options.symbolize_keys options[:renderer] ||= LinkRenderer super(collection, options) end def page_entries_info(collection = nil, options = {}) #:nodoc: options, collection = collection, nil if collection.is_a? Hash collection ||= infer_collection_from_controller super(collection, options.symbolize_keys) end # Wrapper for rendering pagination links at both top and bottom of a block # of content. # # <% paginated_section @posts do %> #
    # <% for post in @posts %> #
  1. ...
  2. # <% end %> #
# <% end %> # # will result in: # # #
    # ... #
# # # Arguments are passed to a will_paginate call, so the same options # apply. Don't use the :id 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) if pagination pagination + capture(&block) + pagination else capture(&block) end end def will_paginate_translate(keys, options = {}) if respond_to? :translate if Array === keys defaults = keys.dup key = defaults.shift else defaults = nil key = keys end translate(key, options.merge(:default => defaults, :scope => :will_paginate)) else super end end protected def infer_collection_from_controller 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 pass the collection object for will_paginate?" if collection.nil? collection end class LinkRenderer < ViewHelpers::LinkRenderer protected GET_PARAMS_BLACKLIST = [:script_name, :original_script_name] def default_url_params {} end def url(page) @base_url_params ||= begin url_params = merge_get_params(default_url_params) url_params[:only_path] = true merge_optional_params(url_params) end url_params = @base_url_params.dup add_current_page_param(url_params, page) @template.url_for(url_params) end def merge_get_params(url_params) if @template.respond_to? :request and @template.request and @template.request.get? symbolized_update(url_params, @template.params, GET_PARAMS_BLACKLIST) end url_params end def merge_optional_params(url_params) symbolized_update(url_params, @options[:params]) if @options[:params] url_params end def add_current_page_param(url_params, page) unless param_name.index(/[^\w-]/) url_params[param_name.to_sym] = page else page_param = parse_query_parameters("#{param_name}=#{page}") symbolized_update(url_params, page_param) end end private def parse_query_parameters(params) Rack::Utils.parse_nested_query(params) end end ::ActionView::Base.send :include, self end end will_paginate-3.1.6/lib/will_paginate/view_helpers/link_renderer_base.rb0000644000004100000410000000445513154516405026627 0ustar www-datawww-datamodule WillPaginate module ViewHelpers # This class does the heavy lifting of actually building the pagination # links. It is used by +will_paginate+ helper internally. class LinkRendererBase # * +collection+ is a WillPaginate::Collection instance or any other object # that conforms to that API # * +options+ are forwarded from +will_paginate+ view helper def prepare(collection, options) @collection = collection @options = options # reset values in case we're re-using this instance @total_pages = nil end def pagination items = @options[:page_links] ? windowed_page_numbers : [] items.unshift :previous_page items.push :next_page end protected # Calculates visible page numbers using the :inner_window and # :outer_window options. def windowed_page_numbers inner_window, outer_window = @options[:inner_window].to_i, @options[:outer_window].to_i window_from = current_page - inner_window window_to = current_page + inner_window # adjust lower or upper limit if either is out of bounds if window_to > total_pages window_from -= window_to - total_pages window_to = total_pages end if window_from < 1 window_to += 1 - window_from window_from = 1 window_to = total_pages if window_to > total_pages end # these are always visible middle = window_from..window_to # left window if outer_window + 3 < middle.first # there's a gap left = (1..(outer_window + 1)).to_a left << :gap else # runs into visible pages left = 1...middle.first end # right window if total_pages - outer_window - 2 > middle.last # again, gap right = ((total_pages - outer_window)..total_pages).to_a right.unshift :gap else # runs into visible pages right = (middle.last + 1)..total_pages end left.to_a + middle.to_a + right.to_a end private def current_page @collection.current_page end def total_pages @total_pages ||= @collection.total_pages end end end end will_paginate-3.1.6/lib/will_paginate/view_helpers/link_renderer.rb0000644000004100000410000001010413154516405025621 0ustar www-datawww-datarequire 'cgi' require 'will_paginate/core_ext' require 'will_paginate/view_helpers' require 'will_paginate/view_helpers/link_renderer_base' module WillPaginate module ViewHelpers # This class does the heavy lifting of actually building the pagination # links. It is used by +will_paginate+ helper internally. class LinkRenderer < LinkRendererBase # * +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) super(collection, options) @template = template @container_attributes = @base_url_params = 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 html = pagination.map do |item| item.is_a?(Integer) ? page_number(item) : send(item) end.join(@options[:link_separator]) @options[:container] ? html_container(html) : html end # Returns the subset of +options+ this instance was initialized with that # represent HTML attributes for the container element of pagination links. def container_attributes @container_attributes ||= @options.except(*(ViewHelpers.pagination_options.keys + [:renderer] - [:class])) end protected def page_number(page) if page == current_page tag(:em, page, :class => 'current') else link(page, page, :rel => rel_value(page)) end end def gap text = @template.will_paginate_translate(:page_gap) { '…' } %(#{text}) end def previous_page num = @collection.current_page > 1 && @collection.current_page - 1 previous_or_next_page(num, @options[:previous_label], 'previous_page') end def next_page num = @collection.current_page < total_pages && @collection.current_page + 1 previous_or_next_page(num, @options[:next_label], 'next_page') end def previous_or_next_page(page, text, classname) if page link(text, page, :class => classname) else tag(:span, text, :class => classname + ' disabled') end end def html_container(html) tag(:div, html, container_attributes) end # Returns URL params for +page_link_or_span+, taking the current GET params # and :params option into account. def url(page) raise NotImplementedError end private def param_name @options[:param_name].to_s end def link(text, target, attributes = {}) if target.is_a?(Integer) attributes[:rel] = rel_value(target) target = url(target) end attributes[:href] = target tag(:a, text, attributes) end def tag(name, value, attributes = {}) string_attributes = attributes.inject('') do |attrs, pair| unless pair.last.nil? attrs << %( #{pair.first}="#{CGI::escapeHTML(pair.last.to_s)}") end attrs end "<#{name}#{string_attributes}>#{value}" end def rel_value(page) case page when @collection.current_page - 1; 'prev' when @collection.current_page + 1; 'next' end end def symbolized_update(target, other, blacklist = nil) other.each_pair do |key, value| key = key.to_sym existing = target[key] next if blacklist && blacklist.include?(key) if value.respond_to?(:each_pair) and (existing.is_a?(Hash) or existing.nil?) symbolized_update(existing || (target[key] = {}), value) else target[key] = value end end end end end end will_paginate-3.1.6/lib/will_paginate/data_mapper.rb0000644000004100000410000000527713154516405022576 0ustar www-datawww-datarequire 'dm-core' require 'dm-aggregates' require 'will_paginate/per_page' require 'will_paginate/page_number' require 'will_paginate/collection' module WillPaginate module DataMapper module Pagination def page(num) pagenum = ::WillPaginate::PageNumber(num.nil? ? 1 : num) per_page = query.limit || self.per_page options = {:offset => pagenum.to_offset(per_page).to_i} options[:limit] = per_page unless query.limit col = new_collection(query.merge(options)) col.current_page = pagenum col end def paginate(options) options = options.dup pagenum = options.fetch(:page) { raise ArgumentError, ":page parameter required" } per_page = options.delete(:per_page) || self.per_page total = options.delete(:total_entries) options.delete(:page) options[:limit] = per_page.to_i col = all(options).page(pagenum) col.total_entries = total.to_i unless total.nil? || (total.kind_of?(String) && total.strip.empty?) col end end module CollectionMethods include WillPaginate::CollectionMethods attr_accessor :current_page attr_writer :total_entries def paginated? !current_page.nil? end def per_page query.limit || model.per_page end def offset query.offset end def total_entries @total_entries ||= begin if loaded? and @array.size < per_page and (current_page == 1 or @array.size > 0) offset + @array.size else # :reload prevents Collection.filter from being run, which # would cause a stack overflow clean_query = query.merge(:reload => true) # seems like the only way clean_query.instance_variable_set('@limit', nil) clean_query.instance_variable_set('@offset', 0) new_collection(clean_query).count end end end def to_a if paginated? ::WillPaginate::Collection.create(current_page, per_page) do |col| col.replace super col.total_entries ||= total_entries end else super end end private def new_collection(query, resources = nil) col = super col.current_page = self.current_page col end def initialize_copy(original) super @total_entries = nil end end ::DataMapper::Model.append_extensions PerPage ::DataMapper::Model.append_extensions Pagination ::DataMapper::Collection.send(:include, Pagination) ::DataMapper::Collection.send(:include, CollectionMethods) end end will_paginate-3.1.6/lib/will_paginate/page_number.rb0000644000004100000410000000246313154516405022577 0ustar www-datawww-datarequire 'delegate' require 'forwardable' module WillPaginate # a module that page number exceptions are tagged with module InvalidPage; end # integer representing a page number class PageNumber < DelegateClass(Integer) # a value larger than this is not supported in SQL queries BIGINT = 9223372036854775807 extend Forwardable def initialize(value, name) value = Integer(value) if 'offset' == name ? (value < 0 or value > BIGINT) : value < 1 raise RangeError, "invalid #{name}: #{value.inspect}" end @name = name super(value) rescue ArgumentError, TypeError, RangeError => error error.extend InvalidPage raise error end alias_method :to_i, :__getobj__ def inspect "#{@name} #{to_i}" end def to_offset(per_page) PageNumber.new((to_i - 1) * per_page.to_i, 'offset') end def kind_of?(klass) super || to_i.kind_of?(klass) end alias is_a? kind_of? end # Ultrahax: makes `Integer === current_page` checks pass Numeric.extend Module.new { def ===(obj) obj.instance_of? PageNumber or super end } # An idemptotent coercion method def self.PageNumber(value, name = 'page') case value when PageNumber then value else PageNumber.new(value, name) end end end will_paginate-3.1.6/lib/will_paginate/railtie.rb0000644000004100000410000000433113154516405021740 0ustar www-datawww-datarequire 'will_paginate' require 'will_paginate/page_number' require 'will_paginate/collection' require 'will_paginate/i18n' module WillPaginate class Railtie < Rails::Railtie initializer "will_paginate" do |app| ActiveSupport.on_load :active_record do require 'will_paginate/active_record' end ActiveSupport.on_load :action_controller do WillPaginate::Railtie.setup_actioncontroller end ActiveSupport.on_load :action_view do require 'will_paginate/view_helpers/action_view' end # early access to ViewHelpers.pagination_options require 'will_paginate/view_helpers' end def self.setup_actioncontroller ( defined?(ActionDispatch::ExceptionWrapper) ? ActionDispatch::ExceptionWrapper : ActionDispatch::ShowExceptions ).send :include, ShowExceptionsPatch ActionController::Base.extend ControllerRescuePatch end # Extending the exception handler middleware so it properly detects # WillPaginate::InvalidPage regardless of it being a tag module. module ShowExceptionsPatch extend ActiveSupport::Concern included do alias_method :status_code_without_paginate, :status_code alias_method :status_code, :status_code_with_paginate end def status_code_with_paginate(exception = @exception) actual_exception = if exception.respond_to?(:cause) exception.cause elsif exception.respond_to?(:original_exception) exception.original_exception else exception end if actual_exception.is_a?(WillPaginate::InvalidPage) Rack::Utils.status_code(:not_found) else original_method = method(:status_code_without_paginate) if original_method.arity != 0 original_method.call(exception) else original_method.call() end end end end module ControllerRescuePatch def rescue_from(*args, &block) if idx = args.index(WillPaginate::InvalidPage) args[idx] = args[idx].name end super(*args, &block) end end end end ActiveSupport.on_load :i18n do I18n.load_path.concat(WillPaginate::I18n.load_path) end will_paginate-3.1.6/lib/will_paginate/locale/0000755000004100000410000000000013154516405021220 5ustar www-datawww-datawill_paginate-3.1.6/lib/will_paginate/locale/en.yml0000644000004100000410000000204613154516405022347 0ustar www-datawww-dataen: will_paginate: previous_label: "← Previous" next_label: "Next →" page_gap: "…" page_entries_info: single_page: zero: "No %{model} found" one: "Displaying 1 %{model}" other: "Displaying all %{count} %{model}" single_page_html: zero: "No %{model} found" one: "Displaying 1 %{model}" other: "Displaying all %{count} %{model}" multi_page: "Displaying %{model} %{from} - %{to} of %{count} in total" multi_page_html: "Displaying %{model} %{from} - %{to} of %{count} in total" # models: # entry: # zero: entries # one: entry # few: entries # other: entries # line_item: # page_entries_info: # single_page: # zero: "Your shopping cart is empty" # one: "Displaying one item in your cart" # other: "Displaying all %{count} items" # multi_page: "Displaying items %{from} - %{to} of %{count} in total" will_paginate-3.1.6/lib/will_paginate.rb0000644000004100000410000000125313154516405020307 0ustar www-datawww-data# You will paginate! module WillPaginate end if defined?(Rails::Railtie) require 'will_paginate/railtie' elsif defined?(Rails::Initializer) raise "will_paginate 3.0 is not compatible with Rails 2.3 or older" end if defined?(Merb::AbstractController) require 'will_paginate/view_helpers/merb' Merb::BootLoader.before_app_loads do adapters = { :datamapper => 'data_mapper', :activerecord => 'active_record', :sequel => 'sequel' } # auto-load the right ORM adapter if adapter = adapters[Merb.orm] require "will_paginate/#{adapter}" end end end if defined?(Sinatra) and Sinatra.respond_to? :register require 'will_paginate/view_helpers/sinatra' end will_paginate-3.1.6/LICENSE0000644000004100000410000000205713154516405015405 0ustar www-datawww-dataCopyright (c) 2009 Mislav Marohnić Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. will_paginate-3.1.6/will_paginate.gemspec0000644000004100000410000000605713154516406020571 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- Gem::Specification.new do |s| s.name = "will_paginate" s.version = "3.1.6" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Mislav Marohni\u{107}"] s.date = "2017-06-07" s.description = "will_paginate provides a simple API for performing paginated queries with Active Record, DataMapper and Sequel, and includes helpers for rendering pagination links in Rails, Sinatra and Merb web apps." s.email = "mislav.marohnic@gmail.com" s.extra_rdoc_files = ["LICENSE", "README.md"] s.files = ["LICENSE", "README.md", "lib/will_paginate.rb", "lib/will_paginate/active_record.rb", "lib/will_paginate/array.rb", "lib/will_paginate/collection.rb", "lib/will_paginate/core_ext.rb", "lib/will_paginate/data_mapper.rb", "lib/will_paginate/deprecation.rb", "lib/will_paginate/i18n.rb", "lib/will_paginate/locale/en.yml", "lib/will_paginate/mongoid.rb", "lib/will_paginate/page_number.rb", "lib/will_paginate/per_page.rb", "lib/will_paginate/railtie.rb", "lib/will_paginate/sequel.rb", "lib/will_paginate/version.rb", "lib/will_paginate/view_helpers.rb", "lib/will_paginate/view_helpers/action_view.rb", "lib/will_paginate/view_helpers/link_renderer.rb", "lib/will_paginate/view_helpers/link_renderer_base.rb", "lib/will_paginate/view_helpers/merb.rb", "lib/will_paginate/view_helpers/sinatra.rb", "spec/collection_spec.rb", "spec/console", "spec/console_fixtures.rb", "spec/database.yml", "spec/fake_rubygems.rb", "spec/finders/active_record_spec.rb", "spec/finders/activerecord_test_connector.rb", "spec/finders/data_mapper_spec.rb", "spec/finders/data_mapper_test_connector.rb", "spec/finders/mongoid_spec.rb", "spec/finders/sequel_spec.rb", "spec/finders/sequel_test_connector.rb", "spec/fixtures/admin.rb", "spec/fixtures/developer.rb", "spec/fixtures/developers_projects.yml", "spec/fixtures/project.rb", "spec/fixtures/projects.yml", "spec/fixtures/replies.yml", "spec/fixtures/reply.rb", "spec/fixtures/schema.rb", "spec/fixtures/topic.rb", "spec/fixtures/topics.yml", "spec/fixtures/user.rb", "spec/fixtures/users.yml", "spec/matchers/deprecation_matcher.rb", "spec/matchers/phrase_matcher.rb", "spec/matchers/query_count_matcher.rb", "spec/page_number_spec.rb", "spec/per_page_spec.rb", "spec/spec_helper.rb", "spec/view_helpers/action_view_spec.rb", "spec/view_helpers/base_spec.rb", "spec/view_helpers/link_renderer_base_spec.rb", "spec/view_helpers/view_example_group.rb"] s.homepage = "https://github.com/mislav/will_paginate/wiki" s.licenses = ["MIT"] s.rdoc_options = ["--main", "README.md", "--charset=UTF-8"] s.require_paths = ["lib"] s.rubygems_version = "1.8.23" s.summary = "Pagination plugin for web frameworks and other apps" if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then else end else end end will_paginate-3.1.6/README.md0000644000004100000410000000313613154516405015656 0ustar www-datawww-data# will_paginate will_paginate is a pagination library that integrates with Ruby on Rails, Sinatra, Merb, DataMapper and Sequel. Installation: ``` ruby ## Gemfile for Rails 3+, Sinatra, and Merb gem 'will_paginate', '~> 3.1.0' ``` See [installation instructions][install] on the wiki for more info. ## Basic will_paginate use ``` ruby ## perform a paginated query: @posts = Post.paginate(:page => params[:page]) # or, use an explicit "per page" limit: Post.paginate(:page => params[:page], :per_page => 30) ## render page links in the view: <%= will_paginate @posts %> ``` And that's it! You're done. You just need to add some CSS styles to [make those pagination links prettier][css]. You can customize the default "per_page" value: ``` ruby # for the Post model class Post self.per_page = 10 end # set per_page globally WillPaginate.per_page = 10 ``` New in Active Record 3: ``` ruby # paginate in Active Record now returns a Relation Post.where(:published => true).paginate(:page => params[:page]).order('id DESC') # the new, shorter page() method Post.page(params[:page]).order('created_at DESC') ``` See [the wiki][wiki] for more documentation. [Ask on the group][group] if you have usage questions. [Report bugs][issues] on GitHub. Happy paginating. [wiki]: https://github.com/mislav/will_paginate/wiki [install]: https://github.com/mislav/will_paginate/wiki/Installation "will_paginate installation" [group]: http://groups.google.com/group/will_paginate "will_paginate discussion and support group" [issues]: https://github.com/mislav/will_paginate/issues [css]: http://mislav.github.io/will_paginate/