hobo_will_paginate 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/LICENSE +18 -0
- data/README.md +61 -0
- data/Rakefile +25 -0
- data/lib/will_paginate.rb +25 -0
- data/lib/will_paginate/active_record.rb +216 -0
- data/lib/will_paginate/array.rb +57 -0
- data/lib/will_paginate/collection.rb +149 -0
- data/lib/will_paginate/core_ext.rb +30 -0
- data/lib/will_paginate/data_mapper.rb +95 -0
- data/lib/will_paginate/deprecation.rb +55 -0
- data/lib/will_paginate/i18n.rb +22 -0
- data/lib/will_paginate/locale/en.yml +33 -0
- data/lib/will_paginate/page_number.rb +57 -0
- data/lib/will_paginate/per_page.rb +27 -0
- data/lib/will_paginate/railtie.rb +68 -0
- data/lib/will_paginate/sequel.rb +39 -0
- data/lib/will_paginate/version.rb +9 -0
- data/lib/will_paginate/view_helpers.rb +161 -0
- data/lib/will_paginate/view_helpers/action_view.rb +148 -0
- data/lib/will_paginate/view_helpers/link_renderer.rb +132 -0
- data/lib/will_paginate/view_helpers/link_renderer_base.rb +77 -0
- data/lib/will_paginate/view_helpers/merb.rb +26 -0
- data/lib/will_paginate/view_helpers/sinatra.rb +41 -0
- data/spec/ci.rb +29 -0
- data/spec/collection_spec.rb +139 -0
- data/spec/console +12 -0
- data/spec/console_fixtures.rb +28 -0
- data/spec/database.yml +22 -0
- data/spec/finders/active_record_spec.rb +543 -0
- data/spec/finders/activerecord_test_connector.rb +113 -0
- data/spec/finders/data_mapper_spec.rb +103 -0
- data/spec/finders/data_mapper_test_connector.rb +54 -0
- data/spec/finders/sequel_spec.rb +67 -0
- data/spec/finders/sequel_test_connector.rb +9 -0
- data/spec/fixtures/admin.rb +3 -0
- data/spec/fixtures/developer.rb +13 -0
- data/spec/fixtures/developers_projects.yml +13 -0
- data/spec/fixtures/project.rb +15 -0
- data/spec/fixtures/projects.yml +6 -0
- data/spec/fixtures/replies.yml +29 -0
- data/spec/fixtures/reply.rb +9 -0
- data/spec/fixtures/schema.rb +38 -0
- data/spec/fixtures/topic.rb +7 -0
- data/spec/fixtures/topics.yml +30 -0
- data/spec/fixtures/user.rb +2 -0
- data/spec/fixtures/users.yml +35 -0
- data/spec/page_number_spec.rb +65 -0
- data/spec/per_page_spec.rb +41 -0
- data/spec/spec_helper.rb +71 -0
- data/spec/view_helpers/action_view_spec.rb +423 -0
- data/spec/view_helpers/base_spec.rb +130 -0
- data/spec/view_helpers/link_renderer_base_spec.rb +87 -0
- data/spec/view_helpers/view_example_group.rb +114 -0
- 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,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,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,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) %>
|