hobo_will_paginate 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE +18 -0
  3. data/README.md +61 -0
  4. data/Rakefile +25 -0
  5. data/lib/will_paginate.rb +25 -0
  6. data/lib/will_paginate/active_record.rb +216 -0
  7. data/lib/will_paginate/array.rb +57 -0
  8. data/lib/will_paginate/collection.rb +149 -0
  9. data/lib/will_paginate/core_ext.rb +30 -0
  10. data/lib/will_paginate/data_mapper.rb +95 -0
  11. data/lib/will_paginate/deprecation.rb +55 -0
  12. data/lib/will_paginate/i18n.rb +22 -0
  13. data/lib/will_paginate/locale/en.yml +33 -0
  14. data/lib/will_paginate/page_number.rb +57 -0
  15. data/lib/will_paginate/per_page.rb +27 -0
  16. data/lib/will_paginate/railtie.rb +68 -0
  17. data/lib/will_paginate/sequel.rb +39 -0
  18. data/lib/will_paginate/version.rb +9 -0
  19. data/lib/will_paginate/view_helpers.rb +161 -0
  20. data/lib/will_paginate/view_helpers/action_view.rb +148 -0
  21. data/lib/will_paginate/view_helpers/link_renderer.rb +132 -0
  22. data/lib/will_paginate/view_helpers/link_renderer_base.rb +77 -0
  23. data/lib/will_paginate/view_helpers/merb.rb +26 -0
  24. data/lib/will_paginate/view_helpers/sinatra.rb +41 -0
  25. data/spec/ci.rb +29 -0
  26. data/spec/collection_spec.rb +139 -0
  27. data/spec/console +12 -0
  28. data/spec/console_fixtures.rb +28 -0
  29. data/spec/database.yml +22 -0
  30. data/spec/finders/active_record_spec.rb +543 -0
  31. data/spec/finders/activerecord_test_connector.rb +113 -0
  32. data/spec/finders/data_mapper_spec.rb +103 -0
  33. data/spec/finders/data_mapper_test_connector.rb +54 -0
  34. data/spec/finders/sequel_spec.rb +67 -0
  35. data/spec/finders/sequel_test_connector.rb +9 -0
  36. data/spec/fixtures/admin.rb +3 -0
  37. data/spec/fixtures/developer.rb +13 -0
  38. data/spec/fixtures/developers_projects.yml +13 -0
  39. data/spec/fixtures/project.rb +15 -0
  40. data/spec/fixtures/projects.yml +6 -0
  41. data/spec/fixtures/replies.yml +29 -0
  42. data/spec/fixtures/reply.rb +9 -0
  43. data/spec/fixtures/schema.rb +38 -0
  44. data/spec/fixtures/topic.rb +7 -0
  45. data/spec/fixtures/topics.yml +30 -0
  46. data/spec/fixtures/user.rb +2 -0
  47. data/spec/fixtures/users.yml +35 -0
  48. data/spec/page_number_spec.rb +65 -0
  49. data/spec/per_page_spec.rb +41 -0
  50. data/spec/spec_helper.rb +71 -0
  51. data/spec/view_helpers/action_view_spec.rb +423 -0
  52. data/spec/view_helpers/base_spec.rb +130 -0
  53. data/spec/view_helpers/link_renderer_base_spec.rb +87 -0
  54. data/spec/view_helpers/view_example_group.rb +114 -0
  55. metadata +104 -0
@@ -0,0 +1,113 @@
1
+ require 'active_record'
2
+ require 'active_record/fixtures'
3
+ require 'active_support/multibyte' # needed for Ruby 1.9.1
4
+
5
+ $query_count = 0
6
+ $query_sql = []
7
+
8
+ ignore_sql = /
9
+ ^(
10
+ PRAGMA | SHOW\ max_identifier_length |
11
+ SELECT\ (currval|CAST|@@IDENTITY|@@ROWCOUNT) |
12
+ SHOW\ (FIELDS|TABLES)
13
+ )\b |
14
+ \bFROM\ (sqlite_master|pg_tables|pg_attribute)\b
15
+ /x
16
+
17
+ ActiveSupport::Notifications.subscribe(/^sql\./) do |*args|
18
+ payload = args.last
19
+ unless payload[:name] =~ /^Fixture/ or payload[:sql] =~ ignore_sql
20
+ $query_count += 1
21
+ $query_sql << payload[:sql]
22
+ end
23
+ end
24
+
25
+ module ActiverecordTestConnector
26
+ extend self
27
+
28
+ attr_accessor :able_to_connect
29
+ attr_accessor :connected
30
+
31
+ FIXTURES_PATH = File.expand_path('../../fixtures', __FILE__)
32
+
33
+ Fixtures = defined?(ActiveRecord::Fixtures) ? ActiveRecord::Fixtures : ::Fixtures
34
+
35
+ # Set our defaults
36
+ self.connected = false
37
+ self.able_to_connect = true
38
+
39
+ def setup
40
+ unless self.connected || !self.able_to_connect
41
+ setup_connection
42
+ load_schema
43
+ add_load_path FIXTURES_PATH
44
+ self.connected = true
45
+ end
46
+ rescue Exception => e # errors from ActiveRecord setup
47
+ $stderr.puts "\nSkipping ActiveRecord tests: #{e}\n\n"
48
+ self.able_to_connect = false
49
+ end
50
+
51
+ private
52
+
53
+ def add_load_path(path)
54
+ dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
55
+ dep.autoload_paths.unshift path
56
+ end
57
+
58
+ def setup_connection
59
+ db = ENV['DB'].blank?? 'sqlite3' : ENV['DB']
60
+
61
+ configurations = YAML.load_file(File.expand_path('../../database.yml', __FILE__))
62
+ raise "no configuration for '#{db}'" unless configurations.key? db
63
+ configuration = configurations[db]
64
+
65
+ # ActiveRecord::Base.logger = Logger.new(STDOUT) if $0 == 'irb'
66
+ puts "using #{configuration['adapter']} adapter"
67
+
68
+ ActiveRecord::Base.configurations = { db => configuration }
69
+ ActiveRecord::Base.establish_connection(db)
70
+ ActiveRecord::Base.default_timezone = :utc
71
+ end
72
+
73
+ def load_schema
74
+ ActiveRecord::Base.silence do
75
+ ActiveRecord::Migration.verbose = false
76
+ load File.join(FIXTURES_PATH, 'schema.rb')
77
+ end
78
+ end
79
+
80
+ module FixtureSetup
81
+ def fixtures(*tables)
82
+ table_names = tables.map { |t| t.to_s }
83
+
84
+ fixtures = Fixtures.create_fixtures ActiverecordTestConnector::FIXTURES_PATH, table_names
85
+ @@loaded_fixtures = {}
86
+ @@fixture_cache = {}
87
+
88
+ unless fixtures.nil?
89
+ if fixtures.instance_of?(Fixtures)
90
+ @@loaded_fixtures[fixtures.table_name] = fixtures
91
+ else
92
+ fixtures.each { |f| @@loaded_fixtures[f.table_name] = f }
93
+ end
94
+ end
95
+
96
+ table_names.each do |table_name|
97
+ define_method(table_name) do |*fixtures|
98
+ @@fixture_cache[table_name] ||= {}
99
+
100
+ instances = fixtures.map do |fixture|
101
+ if @@loaded_fixtures[table_name][fixture.to_s]
102
+ @@fixture_cache[table_name][fixture] ||= @@loaded_fixtures[table_name][fixture.to_s].find
103
+ else
104
+ raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
105
+ end
106
+ end
107
+
108
+ instances.size == 1 ? instances.first : instances
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,103 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require 'will_paginate/data_mapper'
5
+ require File.expand_path('../data_mapper_test_connector', __FILE__)
6
+ rescue LoadError => error
7
+ warn "Error running DataMapper specs: #{error.message}"
8
+ datamapper_loaded = false
9
+ else
10
+ datamapper_loaded = true
11
+ end
12
+
13
+ describe WillPaginate::DataMapper do
14
+
15
+ it "has per_page" do
16
+ Animal.per_page.should == 30
17
+ begin
18
+ Animal.per_page = 10
19
+ Animal.per_page.should == 10
20
+
21
+ subclass = Class.new(Animal)
22
+ subclass.per_page.should == 10
23
+ ensure
24
+ Animal.per_page = 30
25
+ end
26
+ end
27
+
28
+ it "doesn't make normal collections appear paginated" do
29
+ Animal.all.should_not be_paginated
30
+ end
31
+
32
+ it "paginates to first page by default" do
33
+ animals = Animal.paginate(:page => nil)
34
+
35
+ animals.should be_paginated
36
+ animals.current_page.should == 1
37
+ animals.per_page.should == 30
38
+ animals.offset.should == 0
39
+ animals.total_entries.should == 3
40
+ animals.total_pages.should == 1
41
+ end
42
+
43
+ it "paginates to first page, explicit limit" do
44
+ animals = Animal.paginate(:page => 1, :per_page => 2)
45
+
46
+ animals.current_page.should == 1
47
+ animals.per_page.should == 2
48
+ animals.total_entries.should == 3
49
+ animals.total_pages.should == 2
50
+ animals.map {|a| a.name }.should == %w[ Dog Cat ]
51
+ end
52
+
53
+ it "paginates to second page" do
54
+ animals = Animal.paginate(:page => 2, :per_page => 2)
55
+
56
+ animals.current_page.should == 2
57
+ animals.offset.should == 2
58
+ animals.map {|a| a.name }.should == %w[ Lion ]
59
+ end
60
+
61
+ it "paginates a collection" do
62
+ friends = Animal.all(:notes.like => '%friend%')
63
+ friends.paginate(:page => 1).per_page.should == 30
64
+ friends.paginate(:page => 1, :per_page => 1).total_entries.should == 2
65
+ end
66
+
67
+ it "paginates a limited collection" do
68
+ animals = Animal.all(:limit => 2).paginate(:page => 1)
69
+ animals.per_page.should == 2
70
+ end
71
+
72
+ it "has page() method" do
73
+ Animal.page(2).per_page.should == 30
74
+ Animal.page(2).offset.should == 30
75
+ Animal.page(2).current_page.should == 2
76
+ Animal.all(:limit => 2).page(2).per_page.should == 2
77
+ end
78
+
79
+ it "has total_pages at 1 for empty collections" do
80
+ Animal.all(:conditions => ['1=2']).page(1).total_pages.should == 1
81
+ end
82
+
83
+ it "can iterate and then call WP methods" do
84
+ animals = Animal.all(:limit => 2).page(1)
85
+ animals.each { |a| }
86
+ animals.total_entries.should == 3
87
+ end
88
+
89
+ it "augments to_a to return a WP::Collection" do
90
+ animals = Animal.all(:limit => 2).page(1)
91
+ array = animals.to_a
92
+ array.size.should == 2
93
+ array.is_a? WillPaginate::Collection
94
+ array.current_page.should == 1
95
+ array.per_page.should == 2
96
+ end
97
+
98
+ it "doesn't have a problem assigning has-one-through relationship" do
99
+ human = Human.create :name => "Mislav"
100
+ human.pet = Animal.first
101
+ end
102
+
103
+ end if datamapper_loaded
@@ -0,0 +1,54 @@
1
+ require 'sqlite3'
2
+ require 'dm-core'
3
+ require 'dm-core/support/logger'
4
+ require 'dm-migrations'
5
+
6
+ DataMapper.setup :default, 'sqlite3::memory:'
7
+
8
+ # Define models
9
+ class Animal
10
+ include DataMapper::Resource
11
+ property :id, Serial
12
+ property :name, String
13
+ property :notes, Text
14
+
15
+ def self.setup
16
+ Animal.create(:name => 'Dog', :notes => "Man's best friend")
17
+ Animal.create(:name => 'Cat', :notes => "Woman's best friend")
18
+ Animal.create(:name => 'Lion', :notes => 'King of the Jungle')
19
+ end
20
+ end
21
+
22
+ class Ownership
23
+ include DataMapper::Resource
24
+
25
+ belongs_to :animal, :key => true
26
+ belongs_to :human, :key => true
27
+
28
+ def self.setup
29
+ end
30
+ end
31
+
32
+ class Human
33
+ include DataMapper::Resource
34
+
35
+ property :id, Serial
36
+ property :name, String
37
+
38
+ has n, :ownerships
39
+ has 1, :pet, :model => 'Animal', :through => :ownerships, :via => :animal
40
+
41
+ def self.setup
42
+ end
43
+ end
44
+
45
+ # Load fixtures
46
+ [Animal, Ownership, Human].each do |klass|
47
+ klass.auto_migrate!
48
+ klass.setup
49
+ end
50
+
51
+ if 'irb' == $0
52
+ DataMapper.logger.set_log($stdout, :debug)
53
+ DataMapper.logger.auto_flush = true
54
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ begin
4
+ require 'will_paginate/sequel'
5
+ require File.expand_path('../sequel_test_connector', __FILE__)
6
+ rescue LoadError, ArgumentError => error
7
+ warn "Error running Sequel specs: #{error.message}"
8
+ sequel_loaded = false
9
+ else
10
+ sequel_loaded = true
11
+ end
12
+
13
+ describe Sequel::Dataset::Pagination, 'extension' do
14
+
15
+ class Car < Sequel::Model
16
+ end
17
+
18
+ it "should have the #paginate method" do
19
+ Car.should respond_to(:paginate)
20
+ end
21
+
22
+ it "should NOT have the #paginate_by_sql method" do
23
+ Car.should_not respond_to(:paginate_by_sql)
24
+ end
25
+
26
+ describe 'pagination' do
27
+ before(:all) do
28
+ Car.create(:name => 'Shelby', :notes => "Man's best friend")
29
+ Car.create(:name => 'Aston Martin', :notes => "Woman's best friend")
30
+ Car.create(:name => 'Corvette', :notes => 'King of the Jungle')
31
+ end
32
+
33
+ it "should imitate WillPaginate::Collection" do
34
+ result = Car.paginate(1, 2)
35
+
36
+ result.should_not be_empty
37
+ result.size.should == 2
38
+ result.length.should == 2
39
+ result.total_entries.should == 3
40
+ result.total_pages.should == 2
41
+ result.per_page.should == 2
42
+ result.current_page.should == 1
43
+ end
44
+
45
+ it "should perform" do
46
+ Car.paginate(1, 2).all.should == [Car[1], Car[2]]
47
+ end
48
+
49
+ it "should be empty" do
50
+ result = Car.paginate(3, 2)
51
+ result.should be_empty
52
+ end
53
+
54
+ it "should perform with #select and #order" do
55
+ result = Car.select("name as foo".lit).order(:name).paginate(1, 2).all
56
+ result.size.should == 2
57
+ result.first.values[:foo].should == "Aston Martin"
58
+ end
59
+
60
+ it "should perform with #filter" do
61
+ results = Car.filter(:name => 'Shelby').paginate(1, 2).all
62
+ results.size.should == 1
63
+ results.first.should == Car.find(:name => 'Shelby')
64
+ end
65
+ end
66
+
67
+ end if sequel_loaded
@@ -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,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
+ 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 only_recent(params = {})
10
+ scoped.where(['replies.created_at > ?', 15.minutes.ago])
11
+ end
12
+ end
13
+
14
+ has_many :unique_replies, :through => :topics, :source => :replies, :uniq => true
15
+ end
@@ -0,0 +1,6 @@
1
+ active_record:
2
+ id: 1
3
+ name: Active Record
4
+ action_controller:
5
+ id: 2
6
+ name: Action Controller
@@ -0,0 +1,29 @@
1
+ witty_retort:
2
+ id: 1
3
+ topic_id: 1
4
+ content: Birdman is better!
5
+ created_at: <%= 6.hours.ago.utc.to_s(:db) %>
6
+
7
+ another:
8
+ id: 2
9
+ topic_id: 2
10
+ content: Nuh uh!
11
+ created_at: <%= 1.hour.ago.utc.to_s(:db) %>
12
+
13
+ spam:
14
+ id: 3
15
+ topic_id: 1
16
+ content: Nice site!
17
+ created_at: <%= 1.hour.ago.utc.to_s(:db) %>
18
+
19
+ decisive:
20
+ id: 4
21
+ topic_id: 4
22
+ content: "I'm getting to the bottom of this"
23
+ created_at: <%= 30.minutes.ago.utc.to_s(:db) %>
24
+
25
+ brave:
26
+ id: 5
27
+ topic_id: 4
28
+ content: "AR doesn't scare me a bit"
29
+ created_at: <%= 10.minutes.ago.utc.to_s(:db) %>
@@ -0,0 +1,9 @@
1
+ class Reply < ActiveRecord::Base
2
+ belongs_to :topic, :include => [:replies]
3
+
4
+ scope :recent,
5
+ :conditions => ['replies.created_at > ?', 15.minutes.ago],
6
+ :order => 'replies.created_at DESC'
7
+
8
+ validates_presence_of :content
9
+ end