hobo_will_paginate 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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