will_paginate 3.0.pre4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of will_paginate might be problematic. Click here for more details.

Files changed (51) hide show
  1. data/README.md +61 -0
  2. data/Rakefile +19 -36
  3. data/lib/will_paginate.rb +16 -14
  4. data/lib/will_paginate/{finders/active_record.rb → active_record.rb} +66 -35
  5. data/lib/will_paginate/array.rb +5 -5
  6. data/lib/will_paginate/collection.rb +12 -36
  7. data/lib/will_paginate/core_ext.rb +0 -28
  8. data/lib/will_paginate/data_mapper.rb +91 -0
  9. data/lib/will_paginate/i18n.rb +22 -0
  10. data/lib/will_paginate/locale/en.yml +33 -0
  11. data/lib/will_paginate/page_number.rb +57 -0
  12. data/lib/will_paginate/per_page.rb +27 -0
  13. data/lib/will_paginate/railtie.rb +13 -4
  14. data/lib/will_paginate/sequel.rb +36 -0
  15. data/lib/will_paginate/version.rb +1 -1
  16. data/lib/will_paginate/view_helpers.rb +136 -22
  17. data/lib/will_paginate/view_helpers/action_view.rb +129 -117
  18. data/lib/will_paginate/view_helpers/link_renderer.rb +10 -11
  19. data/lib/will_paginate/view_helpers/link_renderer_base.rb +2 -8
  20. data/lib/will_paginate/view_helpers/merb.rb +20 -7
  21. data/lib/will_paginate/view_helpers/sinatra.rb +41 -0
  22. data/spec/ci.rb +29 -0
  23. data/spec/collection_spec.rb +7 -23
  24. data/spec/console +9 -1
  25. data/spec/console_fixtures.rb +1 -3
  26. data/spec/database.yml +10 -10
  27. data/spec/finders/active_record_spec.rb +82 -28
  28. data/spec/finders/activerecord_test_connector.rb +9 -1
  29. data/spec/finders/data_mapper_spec.rb +59 -48
  30. data/spec/finders/data_mapper_test_connector.rb +8 -1
  31. data/spec/finders/sequel_spec.rb +9 -3
  32. data/spec/fixtures/project.rb +2 -0
  33. data/spec/page_number_spec.rb +65 -0
  34. data/spec/per_page_spec.rb +41 -0
  35. data/spec/spec_helper.rb +5 -29
  36. data/spec/view_helpers/action_view_spec.rb +48 -32
  37. data/spec/view_helpers/base_spec.rb +59 -7
  38. data/spec/view_helpers/link_renderer_base_spec.rb +7 -12
  39. data/spec/view_helpers/view_example_group.rb +1 -0
  40. metadata +22 -23
  41. data/CHANGELOG.rdoc +0 -105
  42. data/README.rdoc +0 -111
  43. data/lib/will_paginate/deprecation.rb +0 -50
  44. data/lib/will_paginate/finders.rb +0 -9
  45. data/lib/will_paginate/finders/active_resource.rb +0 -51
  46. data/lib/will_paginate/finders/base.rb +0 -112
  47. data/lib/will_paginate/finders/data_mapper.rb +0 -30
  48. data/lib/will_paginate/finders/sequel.rb +0 -23
  49. data/lib/will_paginate/view_helpers/base.rb +0 -126
  50. data/spec/finders/active_resource_spec.rb +0 -52
  51. data/spec/finders_spec.rb +0 -76
@@ -29,17 +29,6 @@ describe WillPaginate::Collection do
29
29
  result.size.should == 30
30
30
  end
31
31
 
32
- describe "old API" do
33
- it "should fail with numeric params" do
34
- Proc.new { [].paginate(2) }.should raise_error(ArgumentError)
35
- Proc.new { [].paginate(2, 10) }.should raise_error(ArgumentError)
36
- end
37
-
38
- it "should fail with both options and numeric param" do
39
- Proc.new { [].paginate({}, 5) }.should raise_error(ArgumentError)
40
- end
41
- end
42
-
43
32
  it "should give total_entries precedence over actual size" do
44
33
  %w(a b c).paginate(:total_entries => 5).total_entries.should == 5
45
34
  end
@@ -117,27 +106,22 @@ describe WillPaginate::Collection do
117
106
  end
118
107
  end
119
108
 
120
- it "should raise WillPaginate::InvalidPage on invalid input" do
121
- for bad_input in [0, -1, nil, '', 'Schnitzel']
122
- Proc.new { create bad_input }.should raise_error(WillPaginate::InvalidPage)
123
- end
124
- end
125
-
126
- it "should raise Argument error on invalid per_page setting" do
127
- Proc.new { create(1, -1) }.should raise_error(ArgumentError)
128
- end
129
-
130
109
  it "should not respond to page_count anymore" do
131
110
  Proc.new { create.page_count }.should raise_error(NoMethodError)
132
111
  end
133
112
 
113
+ it "inherits per_page from global value" do
114
+ collection = described_class.new(1)
115
+ collection.per_page.should == 30
116
+ end
117
+
134
118
  private
135
119
 
136
120
  def create(page = 2, limit = 5, total = nil, &block)
137
121
  if block_given?
138
- WillPaginate::Collection.create(page, limit, total, &block)
122
+ described_class.create(page, limit, total, &block)
139
123
  else
140
- WillPaginate::Collection.new(page, limit, total)
124
+ described_class.new(page, limit, total)
141
125
  end
142
126
  end
143
127
 
data/spec/console CHANGED
@@ -1,4 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
  irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
3
- opts = %w[--simple-prompt -rirb/completion -rconsole_fixtures]
3
+ opts = %w[ --simple-prompt -rirb/completion ]
4
+ if ARGV.include? '-dm'
5
+ opts << '-rwill_paginate/data_mapper' << '-rfinders/data_mapper_test_connector'
6
+ elsif ARGV.include? '-seq'
7
+ opts << '-rwill_paginate/sequel' << '-rfinders/sequel_test_connector'
8
+ else
9
+ opts << '-rconsole_fixtures'
10
+ end
11
+
4
12
  exec 'bundle', 'exec', irb, '-Ilib:spec', *opts
@@ -1,7 +1,7 @@
1
1
  require 'bundler'
2
2
  Bundler.setup
3
3
 
4
- require 'will_paginate/finders/active_record'
4
+ require 'will_paginate/active_record'
5
5
  require 'finders/activerecord_test_connector'
6
6
 
7
7
  ActiverecordTestConnector.setup
@@ -26,5 +26,3 @@ end
26
26
  # load all fixtures
27
27
  ActiverecordTestConnector::Fixtures.create_fixtures \
28
28
  ActiverecordTestConnector::FIXTURES_PATH, ActiveRecord::Base.connection.tables
29
-
30
- WillPaginate::Finders::ActiveRecord.enable!
data/spec/database.yml CHANGED
@@ -3,20 +3,20 @@ sqlite3:
3
3
  adapter: sqlite3
4
4
  timeout: 500
5
5
 
6
- sqlite2:
7
- database: ":memory:"
8
- adapter: sqlite2
9
-
10
6
  mysql:
11
7
  adapter: mysql
12
- username: rails
13
- password: mislav
8
+ database: will_paginate
9
+ username:
10
+ encoding: utf8
11
+
12
+ mysql2:
13
+ adapter: mysql2
14
+ database: will_paginate
15
+ username:
14
16
  encoding: utf8
15
- database: will_paginate_unittest
16
17
 
17
18
  postgres:
18
19
  adapter: postgresql
19
- username: mislav
20
- password: mislav
21
- database: will_paginate_unittest
20
+ database: will_paginate
21
+ username: postgres
22
22
  min_messages: warning
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
- require 'will_paginate/finders/active_record'
2
+ require 'will_paginate/active_record'
3
3
  require File.expand_path('../activerecord_test_connector', __FILE__)
4
- ActiverecordTestConnector.setup
5
4
 
6
- WillPaginate::Finders::ActiveRecord.enable!
5
+ ActiverecordTestConnector.setup
6
+ abort unless ActiverecordTestConnector.able_to_connect
7
7
 
8
- describe WillPaginate::Finders::ActiveRecord do
8
+ describe WillPaginate::ActiveRecord do
9
9
 
10
10
  extend ActiverecordTestConnector::FixtureSetup
11
11
 
@@ -52,6 +52,19 @@ describe WillPaginate::Finders::ActiveRecord do
52
52
  rel.per_page.should == 5
53
53
  end
54
54
 
55
+ it "remembers pagination in sub-relations" do
56
+ rel = Topic.paginate(:page => 2, :per_page => 3)
57
+ lambda {
58
+ rel.total_entries.should == 4
59
+ }.should run_queries(1)
60
+ rel = rel.mentions_activerecord
61
+ rel.current_page.should == 2
62
+ rel.per_page.should == 3
63
+ lambda {
64
+ rel.total_entries.should == 1
65
+ }.should run_queries(1)
66
+ end
67
+
55
68
  it "supports the page() method" do
56
69
  rel = Developer.page('1').order('id')
57
70
  rel.current_page.should == 1
@@ -81,13 +94,6 @@ describe WillPaginate::Finders::ActiveRecord do
81
94
  end
82
95
 
83
96
  describe "counting" do
84
- it "should not accept :count parameter" do
85
- pending
86
- lambda {
87
- User.paginate :page => 1, :count => {}
88
- }.should raise_error(ArgumentError)
89
- end
90
-
91
97
  it "should guess the total count" do
92
98
  lambda {
93
99
  topics = Topic.paginate :page => 2, :per_page => 3
@@ -101,6 +107,64 @@ describe WillPaginate::Finders::ActiveRecord do
101
107
  topics.total_entries.should == 0
102
108
  }.should run_queries(1)
103
109
  end
110
+
111
+ it "forgets count in sub-relations" do
112
+ lambda {
113
+ topics = Topic.paginate :page => 1, :per_page => 3
114
+ topics.total_entries.should == 4
115
+ topics.where('1 = 1').total_entries.should == 4
116
+ }.should run_queries(2)
117
+ end
118
+
119
+ it "remembers custom count options in sub-relations" do
120
+ topics = Topic.paginate :page => 1, :per_page => 3, :count => {:conditions => "title LIKE '%futurama%'"}
121
+ topics.total_entries.should == 1
122
+ topics.length.should == 3
123
+ lambda {
124
+ topics.order('id').total_entries.should == 1
125
+ }.should run_queries(1)
126
+ end
127
+
128
+ it "supports empty? method" do
129
+ topics = Topic.paginate :page => 1, :per_page => 3
130
+ lambda {
131
+ topics.should_not be_empty
132
+ }.should run_queries(1)
133
+ end
134
+
135
+ it "overrides total_entries count with a fixed value" do
136
+ lambda {
137
+ topics = Topic.paginate :page => 1, :per_page => 3, :total_entries => 999
138
+ topics.total_entries.should == 999
139
+ # value is kept even in sub-relations
140
+ topics.where('1 = 1').total_entries.should == 999
141
+ }.should run_queries(0)
142
+ end
143
+
144
+ it "supports a non-int for total_entries" do
145
+ topics = Topic.paginate :page => 1, :per_page => 3, :total_entries => "999"
146
+ topics.total_entries.should == 999
147
+ end
148
+
149
+ it "removes :include for count" do
150
+ lambda {
151
+ developers = Developer.paginate(:page => 1, :per_page => 1).includes(:projects)
152
+ developers.total_entries.should == 11
153
+ $query_sql.last.should_not =~ /\bJOIN\b/
154
+ }.should run_queries(1)
155
+ end
156
+
157
+ it "keeps :include for count when they are referenced in :conditions" do
158
+ developers = Developer.paginate(:page => 1, :per_page => 1).includes(:projects)
159
+ with_condition = developers.where('projects.id > 1')
160
+ with_condition.total_entries.should == 1
161
+
162
+ $query_sql.last.should =~ /\bJOIN\b/
163
+ end
164
+
165
+ it "should count with group" do
166
+ Developer.group(:salary).page(1).total_entries.should == 4
167
+ end
104
168
  end
105
169
 
106
170
  it "should not ignore :select parameter when it says DISTINCT" do
@@ -222,23 +286,6 @@ describe WillPaginate::Finders::ActiveRecord do
222
286
  result.total_entries.should == 4
223
287
  end
224
288
 
225
- it "should remove :include for count" do
226
- lambda {
227
- Developer.paginate(:page => 1, :per_page => 1, :include => :projects).to_a
228
- $query_sql.last.should_not =~ /\bJOIN\b/
229
- }.should run_queries(3..4)
230
- end
231
-
232
- it "should keep :include for count when they are referenced in :conditions" do
233
- Developer.paginate(
234
- :page => 1, :per_page => 1,
235
- :include => :projects,
236
- :conditions => 'projects.id > 2'
237
- ).to_a
238
-
239
- $query_sql.last.should =~ /\bJOIN\b/
240
- end
241
-
242
289
  describe "associations" do
243
290
  it "should paginate with include" do
244
291
  project = projects(:active_record)
@@ -395,6 +442,13 @@ describe WillPaginate::Finders::ActiveRecord do
395
442
  Developer.paginate((1..8).to_a, :per_page => 3, :page => 2, :order => 'id')
396
443
  }.should raise_error(ArgumentError)
397
444
  end
445
+
446
+ it "errors out for invalid values" do |variable|
447
+ lambda {
448
+ # page that results in an offset larger than BIGINT
449
+ Project.page(307445734561825862)
450
+ }.should raise_error(WillPaginate::InvalidPage, "invalid offset: 9223372036854775830")
451
+ end
398
452
 
399
453
  protected
400
454
 
@@ -5,7 +5,14 @@ require 'active_support/multibyte' # needed for Ruby 1.9.1
5
5
  $query_count = 0
6
6
  $query_sql = []
7
7
 
8
- ignore_sql = /^(?:PRAGMA|SELECT (?:currval|CAST|@@IDENTITY|@@ROWCOUNT)|SHOW FIELDS)\b|\bFROM sqlite_master\b/
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
9
16
 
10
17
  ActiveSupport::Notifications.subscribe(/^sql\./) do |*args|
11
18
  payload = args.last
@@ -60,6 +67,7 @@ module ActiverecordTestConnector
60
67
 
61
68
  ActiveRecord::Base.configurations = { db => configuration }
62
69
  ActiveRecord::Base.establish_connection(db)
70
+ ActiveRecord::Base.default_timezone = :utc
63
71
  end
64
72
 
65
73
  def load_schema
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  begin
4
- require 'will_paginate/finders/data_mapper'
4
+ require 'will_paginate/data_mapper'
5
5
  require File.expand_path('../data_mapper_test_connector', __FILE__)
6
6
  rescue LoadError => error
7
7
  warn "Error running DataMapper specs: #{error.message}"
@@ -10,59 +10,70 @@ else
10
10
  datamapper_loaded = true
11
11
  end
12
12
 
13
- describe WillPaginate::Finders::DataMapper do
14
-
15
- it "should make #paginate available to DM resource classes" do
16
- Animal.should respond_to(:paginate)
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
17
26
  end
18
-
19
- it "should paginate" do
20
- Animal.expects(:all).with(:limit => 5, :offset => 0).returns([])
21
- Animal.paginate(:page => 1, :per_page => 5)
27
+
28
+ it "doesn't make normal collections appear paginated" do
29
+ Animal.all.should_not be_paginated
22
30
  end
23
-
24
- it "should NOT to paginate_by_sql" do
25
- Animal.should_not respond_to(:paginate_by_sql)
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
26
41
  end
27
-
28
- it "should support explicit :all argument" do
29
- Animal.expects(:all).with(instance_of(Hash)).returns([])
30
- Animal.paginate(:all, :page => nil)
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 ]
31
51
  end
32
-
33
- it "should support conditional pagination" do
34
- filtered_result = Animal.paginate(:all, :name => 'Dog', :page => nil)
35
- filtered_result.size.should == 1
36
- filtered_result.first.should == Animal.first(:name => 'Dog')
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 ]
37
59
  end
38
-
39
- it "should leave extra parameters intact" do
40
- Animal.expects(:all).with(:name => 'Dog', :limit => 4, :offset => 0 ).returns(Array.new(5))
41
- Animal.expects(:count).with({:name => 'Dog'}).returns(1)
42
-
43
- Animal.paginate :name => 'Dog', :page => 1, :per_page => 4
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
44
65
  end
45
66
 
46
- describe "counting" do
47
- it "should ignore nil in :count parameter" do
48
- lambda { Animal.paginate :page => nil, :count => nil }.should_not raise_error
49
- end
50
-
51
- it "should guess the total count" do
52
- Animal.expects(:all).returns(Array.new(2))
53
- Animal.expects(:count).never
54
-
55
- result = Animal.paginate :page => 2, :per_page => 4
56
- result.total_entries.should == 6
57
- end
58
-
59
- it "should guess that there are no records" do
60
- Animal.expects(:all).returns([])
61
- Animal.expects(:count).never
62
-
63
- result = Animal.paginate :page => 1, :per_page => 4
64
- result.total_entries.should == 0
65
- end
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
66
77
  end
67
-
78
+
68
79
  end if datamapper_loaded
@@ -1,4 +1,6 @@
1
+ require 'sqlite3'
1
2
  require 'dm-core'
3
+ require 'dm-core/support/logger'
2
4
  require 'dm-migrations'
3
5
 
4
6
  DataMapper.setup :default, 'sqlite3::memory:'
@@ -19,4 +21,9 @@ end
19
21
 
20
22
  # Load fixtures
21
23
  Animal.auto_migrate!
22
- Animal.setup
24
+ Animal.setup
25
+
26
+ if 'irb' == $0
27
+ DataMapper.logger.set_log($stdout, :debug)
28
+ DataMapper.logger.auto_flush = true
29
+ end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  begin
4
- require 'will_paginate/finders/sequel'
4
+ require 'will_paginate/sequel'
5
5
  require File.expand_path('../sequel_test_connector', __FILE__)
6
6
  rescue LoadError, ArgumentError => error
7
7
  warn "Error running Sequel specs: #{error.message}"
@@ -33,17 +33,23 @@ describe Sequel::Dataset::Pagination, 'extension' do
33
33
  it "should imitate WillPaginate::Collection" do
34
34
  result = Car.paginate(1, 2)
35
35
 
36
+ result.should_not be_empty
37
+ result.size.should == 2
38
+ result.length.should == 2
36
39
  result.total_entries.should == 3
37
40
  result.total_pages.should == 2
38
41
  result.per_page.should == 2
39
42
  result.current_page.should == 1
40
- result.previous_page.should be_nil
41
- result.next_page.should == 2
42
43
  end
43
44
 
44
45
  it "should perform" do
45
46
  Car.paginate(1, 2).all.should == [Car[1], Car[2]]
46
47
  end
48
+
49
+ it "should be empty" do
50
+ result = Car.paginate(3, 2)
51
+ result.should be_empty
52
+ end
47
53
 
48
54
  it "should perform with #select and #order" do
49
55
  result = Car.select("name as foo".lit).order(:name).paginate(1, 2).all