agnostic-will_paginate 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.autotest +54 -0
  2. data/.gitignore +4 -0
  3. data/.gitmodules +3 -0
  4. data/.manifest +61 -0
  5. data/CHANGELOG.rdoc +105 -0
  6. data/LICENSE +18 -0
  7. data/README.rdoc +125 -0
  8. data/Rakefile +58 -0
  9. data/init.rb +1 -0
  10. data/lib/will_paginate.rb +45 -0
  11. data/lib/will_paginate/array.rb +33 -0
  12. data/lib/will_paginate/collection.rb +145 -0
  13. data/lib/will_paginate/core_ext.rb +69 -0
  14. data/lib/will_paginate/deprecation.rb +50 -0
  15. data/lib/will_paginate/finders.rb +9 -0
  16. data/lib/will_paginate/finders/active_record.rb +192 -0
  17. data/lib/will_paginate/finders/active_record/named_scope.rb +170 -0
  18. data/lib/will_paginate/finders/active_record/named_scope_patch.rb +39 -0
  19. data/lib/will_paginate/finders/active_resource.rb +51 -0
  20. data/lib/will_paginate/finders/base.rb +112 -0
  21. data/lib/will_paginate/finders/data_mapper.rb +30 -0
  22. data/lib/will_paginate/finders/sequel.rb +22 -0
  23. data/lib/will_paginate/version.rb +9 -0
  24. data/lib/will_paginate/view_helpers.rb +42 -0
  25. data/lib/will_paginate/view_helpers/action_view.rb +158 -0
  26. data/lib/will_paginate/view_helpers/base.rb +126 -0
  27. data/lib/will_paginate/view_helpers/link_renderer.rb +130 -0
  28. data/lib/will_paginate/view_helpers/link_renderer_base.rb +83 -0
  29. data/lib/will_paginate/view_helpers/merb.rb +13 -0
  30. data/spec/collection_spec.rb +147 -0
  31. data/spec/console +8 -0
  32. data/spec/console_fixtures.rb +8 -0
  33. data/spec/database.yml +22 -0
  34. data/spec/finders/active_record_spec.rb +461 -0
  35. data/spec/finders/active_resource_spec.rb +52 -0
  36. data/spec/finders/activerecord_test_connector.rb +108 -0
  37. data/spec/finders/data_mapper_spec.rb +62 -0
  38. data/spec/finders/data_mapper_test_connector.rb +20 -0
  39. data/spec/finders/sequel_spec.rb +53 -0
  40. data/spec/finders/sequel_test_connector.rb +9 -0
  41. data/spec/finders_spec.rb +76 -0
  42. data/spec/fixtures/admin.rb +3 -0
  43. data/spec/fixtures/developer.rb +13 -0
  44. data/spec/fixtures/developers_projects.yml +13 -0
  45. data/spec/fixtures/project.rb +15 -0
  46. data/spec/fixtures/projects.yml +6 -0
  47. data/spec/fixtures/replies.yml +29 -0
  48. data/spec/fixtures/reply.rb +7 -0
  49. data/spec/fixtures/schema.rb +38 -0
  50. data/spec/fixtures/topic.rb +6 -0
  51. data/spec/fixtures/topics.yml +30 -0
  52. data/spec/fixtures/user.rb +2 -0
  53. data/spec/fixtures/users.yml +35 -0
  54. data/spec/rcov.opts +2 -0
  55. data/spec/spec.opts +2 -0
  56. data/spec/spec_helper.rb +75 -0
  57. data/spec/tasks.rake +60 -0
  58. data/spec/view_helpers/action_view_spec.rb +344 -0
  59. data/spec/view_helpers/base_spec.rb +64 -0
  60. data/spec/view_helpers/link_renderer_base_spec.rb +84 -0
  61. data/spec/view_helpers/view_example_group.rb +111 -0
  62. metadata +152 -0
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require 'will_paginate/finders/active_resource'
3
+ require 'active_resource/http_mock'
4
+
5
+ class AresProject < ActiveResource::Base
6
+ self.site = 'http://localhost:4000'
7
+ end
8
+
9
+ describe WillPaginate::Finders::ActiveResource do
10
+
11
+ before :all do
12
+ # ActiveResource::HttpMock.respond_to do |mock|
13
+ # mock.get "/ares_projects.xml?page=1&per_page=5", {}, [].to_xml
14
+ # end
15
+ end
16
+
17
+ it "should integrate with ActiveResource::Base" do
18
+ ActiveResource::Base.should respond_to(:paginate)
19
+ end
20
+
21
+ it "should error when no parameters for #paginate" do
22
+ lambda { AresProject.paginate }.should raise_error(ArgumentError)
23
+ end
24
+
25
+ it "should paginate" do
26
+ AresProject.expects(:find_every).with(:params => { :page => 1, :per_page => 5 }).returns([])
27
+ AresProject.paginate(:page => 1, :per_page => 5)
28
+ end
29
+
30
+ it "should have 30 per_page as default" do
31
+ AresProject.expects(:find_every).with(:params => { :page => 1, :per_page => 30 }).returns([])
32
+ AresProject.paginate(:page => 1)
33
+ end
34
+
35
+ it "should support #paginate(:all)" do
36
+ lambda { AresProject.paginate(:all) }.should raise_error(ArgumentError)
37
+ end
38
+
39
+ it "should error #paginate(:other)" do
40
+ lambda { AresProject.paginate(:first) }.should raise_error(ArgumentError)
41
+ end
42
+
43
+ protected
44
+
45
+ def create(page = 2, limit = 5, total = nil, &block)
46
+ if block_given?
47
+ WillPaginate::Collection.create(page, limit, total, &block)
48
+ else
49
+ WillPaginate::Collection.new(page, limit, total)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,108 @@
1
+ require 'active_record'
2
+ require 'active_record/version'
3
+ require 'active_record/fixtures'
4
+ require 'active_support/multibyte' # needed for Ruby 1.9.1
5
+
6
+ class ActiverecordTestConnector
7
+ cattr_accessor :able_to_connect
8
+ cattr_accessor :connected
9
+
10
+ FIXTURES_PATH = File.join(File.dirname(__FILE__), '..', 'fixtures')
11
+
12
+ # Set our defaults
13
+ self.connected = false
14
+ self.able_to_connect = true
15
+
16
+ def self.setup
17
+ unless self.connected || !self.able_to_connect
18
+ setup_connection
19
+ load_schema
20
+ add_load_path FIXTURES_PATH
21
+ self.connected = true
22
+ end
23
+ rescue Exception => e # errors from ActiveRecord setup
24
+ $stderr.puts "\nSkipping ActiveRecord tests: #{e}\n\n"
25
+ self.able_to_connect = false
26
+ end
27
+
28
+ private
29
+
30
+ def self.add_load_path(path)
31
+ dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
32
+ dep.load_paths.unshift path
33
+ end
34
+
35
+ def self.setup_connection
36
+ db = ENV['DB'].blank?? 'sqlite3' : ENV['DB']
37
+
38
+ configurations = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'database.yml'))
39
+ raise "no configuration for '#{db}'" unless configurations.key? db
40
+ configuration = configurations[db]
41
+
42
+ ActiveRecord::Base.logger = Logger.new(STDOUT) if $0 == 'irb'
43
+ puts "using #{configuration['adapter']} adapter" unless ENV['DB'].blank?
44
+
45
+ ActiveRecord::Base.establish_connection(configuration)
46
+ ActiveRecord::Base.configurations = { db => configuration }
47
+ prepare ActiveRecord::Base.connection
48
+
49
+ unless Object.const_defined?(:QUOTED_TYPE)
50
+ Object.send :const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')
51
+ end
52
+ end
53
+
54
+ def self.load_schema
55
+ ActiveRecord::Base.silence do
56
+ ActiveRecord::Migration.verbose = false
57
+ load File.join(FIXTURES_PATH, 'schema.rb')
58
+ end
59
+ end
60
+
61
+ def self.prepare(conn)
62
+ class << conn
63
+ IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SHOW FIELDS /]
64
+
65
+ def execute_with_counting(sql, name = nil, &block)
66
+ $query_count ||= 0
67
+ $query_count += 1 unless IGNORED_SQL.any? { |r| sql =~ r }
68
+ execute_without_counting(sql, name, &block)
69
+ end
70
+
71
+ alias_method_chain :execute, :counting
72
+ end
73
+ end
74
+
75
+ module FixtureSetup
76
+ def fixtures(*tables)
77
+ table_names = tables.map { |t| t.to_s }
78
+
79
+ fixtures = Fixtures.create_fixtures ActiverecordTestConnector::FIXTURES_PATH, table_names
80
+ @@loaded_fixtures = {}
81
+ @@fixture_cache = {}
82
+
83
+ unless fixtures.nil?
84
+ if fixtures.instance_of?(Fixtures)
85
+ @@loaded_fixtures[fixtures.table_name] = fixtures
86
+ else
87
+ fixtures.each { |f| @@loaded_fixtures[f.table_name] = f }
88
+ end
89
+ end
90
+
91
+ table_names.each do |table_name|
92
+ define_method(table_name) do |*fixtures|
93
+ @@fixture_cache[table_name] ||= {}
94
+
95
+ instances = fixtures.map do |fixture|
96
+ if @@loaded_fixtures[table_name][fixture.to_s]
97
+ @@fixture_cache[table_name][fixture] ||= @@loaded_fixtures[table_name][fixture.to_s].find
98
+ else
99
+ raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
100
+ end
101
+ end
102
+
103
+ instances.size == 1 ? instances.first : instances
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+ require 'will_paginate/finders/data_mapper'
3
+ require File.dirname(__FILE__) + '/data_mapper_test_connector'
4
+
5
+ require 'will_paginate'
6
+
7
+ describe WillPaginate::Finders::DataMapper do
8
+
9
+ it "should make #paginate available to DM resource classes" do
10
+ Animal.should respond_to(:paginate)
11
+ end
12
+
13
+ it "should paginate" do
14
+ Animal.expects(:all).with(:limit => 5, :offset => 0).returns([])
15
+ Animal.paginate(:page => 1, :per_page => 5)
16
+ end
17
+
18
+ it "should NOT to paginate_by_sql" do
19
+ Animal.should_not respond_to(:paginate_by_sql)
20
+ end
21
+
22
+ it "should support explicit :all argument" do
23
+ Animal.expects(:all).with(instance_of(Hash)).returns([])
24
+ Animal.paginate(:all, :page => nil)
25
+ end
26
+
27
+ it "should support conditional pagination" do
28
+ filtered_result = Animal.paginate(:all, :name => 'Dog', :page => nil)
29
+ filtered_result.size.should == 1
30
+ filtered_result.first.should == Animal.first(:name => 'Dog')
31
+ end
32
+
33
+ it "should leave extra parameters intact" do
34
+ Animal.expects(:all).with(:name => 'Dog', :limit => 4, :offset => 0 ).returns(Array.new(5))
35
+ Animal.expects(:count).with({:name => 'Dog'}).returns(1)
36
+
37
+ Animal.paginate :name => 'Dog', :page => 1, :per_page => 4
38
+ end
39
+
40
+ describe "counting" do
41
+ it "should ignore nil in :count parameter" do
42
+ lambda { Animal.paginate :page => nil, :count => nil }.should_not raise_error
43
+ end
44
+
45
+ it "should guess the total count" do
46
+ Animal.expects(:all).returns(Array.new(2))
47
+ Animal.expects(:count).never
48
+
49
+ result = Animal.paginate :page => 2, :per_page => 4
50
+ result.total_entries.should == 6
51
+ end
52
+
53
+ it "should guess that there are no records" do
54
+ Animal.expects(:all).returns([])
55
+ Animal.expects(:count).never
56
+
57
+ result = Animal.paginate :page => 1, :per_page => 4
58
+ result.total_entries.should == 0
59
+ end
60
+ end
61
+
62
+ end
@@ -0,0 +1,20 @@
1
+ require 'dm-core'
2
+ DataMapper.setup :default, 'sqlite3::memory:'
3
+
4
+ # Define models
5
+ class Animal
6
+ include DataMapper::Resource
7
+ property :id, Serial
8
+ property :name, String
9
+ property :notes, Text
10
+
11
+ def self.setup
12
+ Animal.create(:name => 'Dog', :notes => "Man's best friend")
13
+ Animal.create(:name => 'Cat', :notes => "Woman's best friend")
14
+ Animal.create(:name => 'Lion', :notes => 'King of the Jungle')
15
+ end
16
+ end
17
+
18
+ # Load fixtures
19
+ Animal.auto_migrate!
20
+ Animal.setup
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'will_paginate/finders/sequel'
3
+ require File.dirname(__FILE__) + '/sequel_test_connector'
4
+
5
+ describe Sequel::Dataset::Pagination, 'extension' do
6
+
7
+ class Car < Sequel::Model
8
+ end
9
+
10
+ it "should have the #paginate method" do
11
+ Car.should respond_to(:paginate)
12
+ end
13
+
14
+ it "should NOT have the #paginate_by_sql method" do
15
+ Car.should_not respond_to(:paginate_by_sql)
16
+ end
17
+
18
+ describe 'pagination' do
19
+ before(:all) do
20
+ Car.create(:name => 'Shelby', :notes => "Man's best friend")
21
+ Car.create(:name => 'Aston Martin', :notes => "Woman's best friend")
22
+ Car.create(:name => 'Corvette', :notes => 'King of the Jungle')
23
+ end
24
+
25
+ it "should imitate WillPaginate::Collection" do
26
+ result = Car.paginate(1, 2)
27
+
28
+ result.total_entries.should == 3
29
+ result.total_pages.should == 2
30
+ result.per_page.should == 2
31
+ result.current_page.should == 1
32
+ result.previous_page.should be_nil
33
+ result.next_page.should == 2
34
+ end
35
+
36
+ it "should perform" do
37
+ Car.paginate(1, 2).all.should == [Car[1], Car[2]]
38
+ end
39
+
40
+ it "should perform with #select and #order" do
41
+ result = Car.select("name as foo".lit).order(:name).paginate(1, 2).all
42
+ result.size.should == 2
43
+ result.first.values[:foo].should == "Aston Martin"
44
+ end
45
+
46
+ it "should perform with #filter" do
47
+ results = Car.filter(:name => 'Shelby').paginate(1, 2).all
48
+ results.size.should == 1
49
+ results.first.should == Car.find(:name => 'Shelby')
50
+ end
51
+ end
52
+
53
+ end
@@ -0,0 +1,9 @@
1
+ require 'sequel'
2
+
3
+ db = Sequel.sqlite
4
+
5
+ db.create_table :cars do
6
+ primary_key :id, :integer, :auto_increment => true
7
+ column :name, :text
8
+ column :notes, :text
9
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ require 'will_paginate/finders/base'
3
+
4
+ class Model
5
+ extend WillPaginate::Finders::Base
6
+ end
7
+
8
+ describe WillPaginate::Finders::Base do
9
+ it "should define default per_page of 30" do
10
+ Model.per_page.should == 30
11
+ end
12
+
13
+ it "should allow to set custom per_page" do
14
+ begin
15
+ Model.per_page = 25
16
+ Model.per_page.should == 25
17
+ ensure
18
+ Model.per_page = 30
19
+ end
20
+ end
21
+
22
+ it "should result with WillPaginate::Collection" do
23
+ Model.expects(:wp_query)
24
+ Model.paginate(:page => nil).should be_instance_of(WillPaginate::Collection)
25
+ end
26
+
27
+ it "should delegate pagination to wp_query" do
28
+ Model.expects(:wp_query).with({}, instance_of(WillPaginate::Collection), [])
29
+ Model.paginate :page => nil
30
+ end
31
+
32
+ it "should complain when no hash parameters given" do
33
+ lambda {
34
+ Model.paginate
35
+ }.should raise_error(ArgumentError, 'parameter hash expected')
36
+ end
37
+
38
+ it "should complain when no :page parameter present" do
39
+ lambda {
40
+ Model.paginate :per_page => 6
41
+ }.should raise_error(ArgumentError, ':page parameter required')
42
+ end
43
+
44
+ it "should complain when both :count and :total_entries are given" do
45
+ lambda {
46
+ Model.paginate :page => 1, :count => {}, :total_entries => 1
47
+ }.should raise_error(ArgumentError, ':count and :total_entries are mutually exclusive')
48
+ end
49
+
50
+ it "should never mangle options" do
51
+ options = { :page => 1 }
52
+ options.expects(:delete).never
53
+ options_before = options.dup
54
+
55
+ Model.expects(:wp_query)
56
+ Model.paginate(options)
57
+
58
+ options.should == options_before
59
+ end
60
+
61
+ it "should provide paginated_each functionality" do
62
+ collection = stub('collection', :size => 5, :empty? => false, :per_page => 5)
63
+ collection.expects(:each).times(2).returns(collection)
64
+ last_collection = stub('collection', :size => 4, :empty? => false, :per_page => 5)
65
+ last_collection.expects(:each).returns(last_collection)
66
+
67
+ params = { :order => 'id', :total_entries => 0 }
68
+
69
+ Model.expects(:paginate).with(params.merge(:page => 2)).returns(collection)
70
+ Model.expects(:paginate).with(params.merge(:page => 3)).returns(collection)
71
+ Model.expects(:paginate).with(params.merge(:page => 4)).returns(last_collection)
72
+
73
+ total = Model.paginated_each(:page => '2') { }
74
+ total.should == 14
75
+ end
76
+ end
@@ -0,0 +1,3 @@
1
+ class Admin < User
2
+ has_many :companies, :finder_sql => 'SELECT * FROM companies'
3
+ end
@@ -0,0 +1,13 @@
1
+ class Developer < User
2
+ has_and_belongs_to_many :projects, :include => :topics, :order => 'projects.name'
3
+
4
+ def self.with_poor_ones(&block)
5
+ with_scope :find => { :conditions => ['salary <= ?', 80000], :order => 'salary' } do
6
+ yield
7
+ end
8
+ end
9
+
10
+ named_scope :poor, :conditions => ['salary <= ?', 80000], :order => 'salary'
11
+
12
+ def self.per_page() 10 end
13
+ end
@@ -0,0 +1,13 @@
1
+ david_action_controller:
2
+ developer_id: 1
3
+ project_id: 2
4
+ joined_on: 2004-10-10
5
+
6
+ david_active_record:
7
+ developer_id: 1
8
+ project_id: 1
9
+ joined_on: 2004-10-10
10
+
11
+ jamis_active_record:
12
+ developer_id: 2
13
+ project_id: 1
@@ -0,0 +1,15 @@
1
+ class Project < ActiveRecord::Base
2
+ has_and_belongs_to_many :developers, :uniq => true
3
+
4
+ has_many :topics
5
+ # :finder_sql => 'SELECT * FROM topics WHERE (topics.project_id = #{id})',
6
+ # :counter_sql => 'SELECT COUNT(*) FROM topics WHERE (topics.project_id = #{id})'
7
+
8
+ has_many :replies, :through => :topics do
9
+ def find_recent(params = {})
10
+ with_scope :find => { :conditions => ['replies.created_at > ?', 15.minutes.ago] } do
11
+ find :all, params
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ active_record:
2
+ id: 1
3
+ name: Active Record
4
+ action_controller:
5
+ id: 2
6
+ name: Active Controller