will_paginate 2.1.0 → 2.2.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.

Potentially problematic release.


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

data/test/finder_test.rb CHANGED
@@ -1,8 +1,9 @@
1
- require File.dirname(__FILE__) + '/helper'
2
- require File.dirname(__FILE__) + '/lib/activerecord_test_case'
1
+ require 'helper'
2
+ require 'lib/activerecord_test_case'
3
3
 
4
4
  require 'will_paginate'
5
5
  WillPaginate.enable_activerecord
6
+ WillPaginate.enable_named_scope
6
7
 
7
8
  class FinderTest < ActiveRecordTestCase
8
9
  fixtures :topics, :replies, :users, :projects, :developers_projects
@@ -12,18 +13,18 @@ class FinderTest < ActiveRecordTestCase
12
13
  end
13
14
 
14
15
  def test_simple_paginate
15
- entries = Topic.paginate :page => nil
16
- assert_equal 1, entries.current_page
17
- assert_nil entries.previous_page
18
- assert_nil entries.next_page
19
- assert_equal 1, entries.page_count
20
- assert_equal 4, entries.size
16
+ assert_queries(1) do
17
+ entries = Topic.paginate :page => nil
18
+ assert_equal 1, entries.current_page
19
+ assert_equal 1, entries.total_pages
20
+ assert_equal 4, entries.size
21
+ end
21
22
 
22
- entries = Topic.paginate :page => 2
23
- assert_equal 2, entries.current_page
24
- assert_equal 1, entries.previous_page
25
- assert_equal 1, entries.page_count
26
- assert entries.empty?
23
+ assert_queries(2) do
24
+ entries = Topic.paginate :page => 2
25
+ assert_equal 1, entries.total_pages
26
+ assert entries.empty?
27
+ end
27
28
  end
28
29
 
29
30
  def test_parameter_api
@@ -41,31 +42,31 @@ class FinderTest < ActiveRecordTestCase
41
42
  def test_paginate_with_per_page
42
43
  entries = Topic.paginate :page => 1, :per_page => 1
43
44
  assert_equal 1, entries.size
44
- assert_equal 4, entries.page_count
45
+ assert_equal 4, entries.total_pages
45
46
 
46
47
  # Developer class has explicit per_page at 10
47
48
  entries = Developer.paginate :page => 1
48
49
  assert_equal 10, entries.size
49
- assert_equal 2, entries.page_count
50
+ assert_equal 2, entries.total_pages
50
51
 
51
52
  entries = Developer.paginate :page => 1, :per_page => 5
52
53
  assert_equal 11, entries.total_entries
53
54
  assert_equal 5, entries.size
54
- assert_equal 3, entries.page_count
55
+ assert_equal 3, entries.total_pages
55
56
  end
56
57
 
57
58
  def test_paginate_with_order
58
59
  entries = Topic.paginate :page => 1, :order => 'created_at desc'
59
60
  expected = [topics(:futurama), topics(:harvey_birdman), topics(:rails), topics(:ar)].reverse
60
61
  assert_equal expected, entries.to_a
61
- assert_equal 1, entries.page_count
62
+ assert_equal 1, entries.total_pages
62
63
  end
63
64
 
64
65
  def test_paginate_with_conditions
65
66
  entries = Topic.paginate :page => 1, :conditions => ["created_at > ?", 30.minutes.ago]
66
67
  expected = [topics(:rails), topics(:ar)]
67
68
  assert_equal expected, entries.to_a
68
- assert_equal 1, entries.page_count
69
+ assert_equal 1, entries.total_pages
69
70
  end
70
71
 
71
72
  def test_paginate_with_include_and_conditions
@@ -85,11 +86,14 @@ class FinderTest < ActiveRecordTestCase
85
86
  end
86
87
 
87
88
  def test_paginate_with_include_and_order
88
- entries = Topic.paginate \
89
- :page => 1,
90
- :include => :replies,
91
- :order => 'replies.created_at asc, topics.created_at asc',
92
- :per_page => 10
89
+ entries = nil
90
+ assert_queries(2) do
91
+ entries = Topic.paginate \
92
+ :page => 1,
93
+ :include => :replies,
94
+ :order => 'replies.created_at asc, topics.created_at asc',
95
+ :per_page => 10
96
+ end
93
97
 
94
98
  expected = Topic.find :all,
95
99
  :include => 'replies',
@@ -104,7 +108,7 @@ class FinderTest < ActiveRecordTestCase
104
108
  entries, project = nil, projects(:active_record)
105
109
 
106
110
  assert_nothing_raised "THIS IS A BUG in Rails 1.2.3 that was fixed in [7326]. " +
107
- "Please upgrade to the 1-2-stable branch or edge Rails." do
111
+ "Please upgrade to a newer version of Rails." do
108
112
  entries = project.topics.paginate \
109
113
  :page => 1,
110
114
  :include => :replies,
@@ -125,10 +129,12 @@ class FinderTest < ActiveRecordTestCase
125
129
  expected_name_ordered = [projects(:action_controller), projects(:active_record)]
126
130
  expected_id_ordered = [projects(:active_record), projects(:action_controller)]
127
131
 
128
- # with association-specified order
129
- entries = dhh.projects.paginate(:page => 1)
130
- assert_equal expected_name_ordered, entries
131
- assert_equal 2, entries.total_entries
132
+ assert_queries(2) do
133
+ # with association-specified order
134
+ entries = dhh.projects.paginate(:page => 1)
135
+ assert_equal expected_name_ordered, entries
136
+ assert_equal 2, entries.total_entries
137
+ end
132
138
 
133
139
  # with explicit order
134
140
  entries = dhh.projects.paginate(:page => 1, :order => 'projects.id')
@@ -148,29 +154,43 @@ class FinderTest < ActiveRecordTestCase
148
154
 
149
155
  def test_paginate_association_extension
150
156
  project = Project.find(:first)
151
- entries = project.replies.paginate_recent :page => 1
152
- assert_equal [replies(:brave)], entries
157
+
158
+ assert_queries(2) do
159
+ entries = project.replies.paginate_recent :page => 1
160
+ assert_equal [replies(:brave)], entries
161
+ end
153
162
  end
154
163
 
155
164
  def test_paginate_with_joins
156
- entries = Developer.paginate :page => 1,
157
- :joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
158
- :conditions => 'project_id = 1'
159
- assert_equal 2, entries.size
160
- developer_names = entries.map { |d| d.name }
161
- assert developer_names.include?('David')
162
- assert developer_names.include?('Jamis')
163
-
164
- expected = entries.to_a
165
- entries = Developer.paginate :page => 1,
166
- :joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
167
- :conditions => 'project_id = 1', :count => { :select => "users.id" }
168
- assert_equal expected, entries.to_a
165
+ entries = nil
166
+
167
+ assert_queries(1) do
168
+ entries = Developer.paginate :page => 1,
169
+ :joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
170
+ :conditions => 'project_id = 1'
171
+ assert_equal 2, entries.size
172
+ developer_names = entries.map &:name
173
+ assert developer_names.include?('David')
174
+ assert developer_names.include?('Jamis')
175
+ end
176
+
177
+ assert_queries(1) do
178
+ expected = entries.to_a
179
+ entries = Developer.paginate :page => 1,
180
+ :joins => 'LEFT JOIN developers_projects ON users.id = developers_projects.developer_id',
181
+ :conditions => 'project_id = 1', :count => { :select => "users.id" }
182
+ assert_equal expected, entries.to_a
183
+ assert_equal 2, entries.total_entries
184
+ end
169
185
  end
170
186
 
171
187
  def test_paginate_with_group
172
- entries = Developer.paginate :page => 1, :per_page => 10,
173
- :group => 'salary', :select => 'salary', :order => 'salary'
188
+ entries = nil
189
+ assert_queries(1) do
190
+ entries = Developer.paginate :page => 1, :per_page => 10,
191
+ :group => 'salary', :select => 'salary', :order => 'salary'
192
+ end
193
+
174
194
  expected = [ users(:david), users(:jamis), users(:dev_10), users(:poor_jamis) ].map(&:salary).sort
175
195
  assert_equal expected, entries.map(&:salary)
176
196
  end
@@ -201,6 +221,56 @@ class FinderTest < ActiveRecordTestCase
201
221
  assert_equal 2, entries.total_entries
202
222
  end
203
223
 
224
+ ## named_scope ##
225
+
226
+ def test_paginate_in_named_scope
227
+ entries = Developer.poor.paginate :page => 1, :per_page => 1
228
+
229
+ assert_equal 1, entries.size
230
+ assert_equal 2, entries.total_entries
231
+ end
232
+
233
+ def test_paginate_in_named_scope_on_habtm_association
234
+ project = projects(:active_record)
235
+ assert_queries(2) do
236
+ entries = project.developers.poor.paginate :page => 1, :per_page => 1
237
+
238
+ assert_equal 1, entries.size, 'one developer should be found'
239
+ assert_equal 1, entries.total_entries, 'only one developer should be found'
240
+ end
241
+ end
242
+
243
+ def test_paginate_in_named_scope_on_hmt_association
244
+ project = projects(:active_record)
245
+ expected = [replies(:brave)]
246
+
247
+ assert_queries(2) do
248
+ entries = project.replies.recent.paginate :page => 1, :per_page => 1
249
+ assert_equal expected, entries
250
+ assert_equal 1, entries.total_entries, 'only one reply should be found'
251
+ end
252
+ end
253
+
254
+ def test_paginate_in_named_scope_on_has_many_association
255
+ project = projects(:active_record)
256
+ expected = [topics(:ar)]
257
+
258
+ assert_queries(2) do
259
+ entries = project.topics.mentions_activerecord.paginate :page => 1, :per_page => 1
260
+ assert_equal expected, entries
261
+ assert_equal 1, entries.total_entries, 'only one topic should be found'
262
+ end
263
+ end
264
+
265
+ ## misc ##
266
+
267
+ def test_count_and_total_entries_options_are_mutually_exclusive
268
+ e = assert_raise ArgumentError do
269
+ Developer.paginate :page => 1, :count => {}, :total_entries => 1
270
+ end
271
+ assert_match /exclusive/, e.to_s
272
+ end
273
+
204
274
  def test_readonly
205
275
  assert_nothing_raised { Developer.paginate :readonly => true, :page => 1 }
206
276
  end
@@ -216,13 +286,15 @@ class FinderTest < ActiveRecordTestCase
216
286
  end
217
287
 
218
288
  # Is this Rails 2.0? Find out by testing find_all which was removed in [6998]
219
- unless Developer.respond_to? :find_all
289
+ unless ActiveRecord::Base.respond_to? :find_all
220
290
  def test_paginate_array_of_ids
221
291
  # AR finders also accept arrays of IDs
222
292
  # (this was broken in Rails before [6912])
223
- entries = Developer.paginate((1..8).to_a, :per_page => 3, :page => 2, :order => 'id')
224
- assert_equal (4..6).to_a, entries.map(&:id)
225
- assert_equal 8, entries.total_entries
293
+ assert_queries(1) do
294
+ entries = Developer.paginate((1..8).to_a, :per_page => 3, :page => 2, :order => 'id')
295
+ assert_equal (4..6).to_a, entries.map(&:id)
296
+ assert_equal 8, entries.total_entries
297
+ end
226
298
  end
227
299
  end
228
300
 
@@ -230,7 +302,7 @@ class FinderTest < ActiveRecordTestCase
230
302
  def test_implicit_all_with_dynamic_finders
231
303
  Topic.expects(:find_all_by_foo).returns([])
232
304
  Topic.expects(:count).returns(0)
233
- Topic.paginate_by_foo :page => 1
305
+ Topic.paginate_by_foo :page => 2
234
306
  end
235
307
 
236
308
  def test_guessing_the_total_count
@@ -241,6 +313,14 @@ class FinderTest < ActiveRecordTestCase
241
313
  assert_equal 6, entries.total_entries
242
314
  end
243
315
 
316
+ def test_guessing_that_there_are_no_records
317
+ Topic.expects(:find).returns([])
318
+ Topic.expects(:count).never
319
+
320
+ entries = Topic.paginate :page => 1, :per_page => 4
321
+ assert_equal 0, entries.total_entries
322
+ end
323
+
244
324
  def test_extra_parameters_stay_untouched
245
325
  Topic.expects(:find).with(:all, {:foo => 'bar', :limit => 4, :offset => 0 }).returns(Array.new(5))
246
326
  Topic.expects(:count).with({:foo => 'bar'}).returns(1)
@@ -251,13 +331,13 @@ class FinderTest < ActiveRecordTestCase
251
331
  def test_count_skips_select
252
332
  Developer.stubs(:find).returns([])
253
333
  Developer.expects(:count).with({}).returns(0)
254
- Developer.paginate :select => 'salary', :page => 1
334
+ Developer.paginate :select => 'salary', :page => 2
255
335
  end
256
336
 
257
337
  def test_count_select_when_distinct
258
338
  Developer.stubs(:find).returns([])
259
339
  Developer.expects(:count).with(:select => 'DISTINCT salary').returns(0)
260
- Developer.paginate :select => 'DISTINCT salary', :page => 1
340
+ Developer.paginate :select => 'DISTINCT salary', :page => 2
261
341
  end
262
342
 
263
343
  def test_should_use_scoped_finders_if_present
@@ -288,16 +368,16 @@ class FinderTest < ActiveRecordTestCase
288
368
  Developer.expects(:find_by_sql).returns([])
289
369
  Developer.expects(:count_by_sql).with("SELECT COUNT(*) FROM (sql\n ) AS count_table").returns(0)
290
370
 
291
- entries = Developer.paginate_by_sql "sql\n ORDER\nby foo, bar, `baz` ASC", :page => 1
371
+ Developer.paginate_by_sql "sql\n ORDER\nby foo, bar, `baz` ASC", :page => 2
292
372
  end
293
373
 
294
374
  # TODO: counts are still wrong
295
375
  def test_ability_to_use_with_custom_finders
296
376
  # acts_as_taggable defines find_tagged_with(tag, options)
297
- Topic.expects(:find_tagged_with).with('will_paginate', :offset => 0, :limit => 5).returns([])
377
+ Topic.expects(:find_tagged_with).with('will_paginate', :offset => 5, :limit => 5).returns([])
298
378
  Topic.expects(:count).with({}).returns(0)
299
379
 
300
- Topic.paginate_tagged_with 'will_paginate', :page => 1, :per_page => 5
380
+ Topic.paginate_tagged_with 'will_paginate', :page => 2, :per_page => 5
301
381
  end
302
382
 
303
383
  def test_array_argument_doesnt_eliminate_count
@@ -310,7 +390,6 @@ class FinderTest < ActiveRecordTestCase
310
390
 
311
391
  def test_paginating_finder_doesnt_mangle_options
312
392
  Developer.expects(:find).returns([])
313
- Developer.expects(:count).returns(0)
314
393
  options = { :page => 1 }
315
394
  options.expects(:delete).never
316
395
  options_before = options.dup
@@ -318,5 +397,20 @@ class FinderTest < ActiveRecordTestCase
318
397
  Developer.paginate(options)
319
398
  assert_equal options, options_before
320
399
  end
400
+
401
+ def test_paginated_each
402
+ collection = stub('collection', :size => 5, :empty? => false, :per_page => 5)
403
+ collection.expects(:each).times(2).returns(collection)
404
+ last_collection = stub('collection', :size => 4, :empty? => false, :per_page => 5)
405
+ last_collection.expects(:each).returns(last_collection)
406
+
407
+ params = { :order => 'id', :total_entries => 0 }
408
+
409
+ Developer.expects(:paginate).with(params.merge(:page => 2)).returns(collection)
410
+ Developer.expects(:paginate).with(params.merge(:page => 3)).returns(collection)
411
+ Developer.expects(:paginate).with(params.merge(:page => 4)).returns(last_collection)
412
+
413
+ assert_equal 14, Developer.paginated_each(:page => '2') { }
414
+ end
321
415
  end
322
416
  end
@@ -7,5 +7,7 @@ class Developer < User
7
7
  end
8
8
  end
9
9
 
10
+ named_scope :poor, :conditions => ['salary <= ?', 80000], :order => 'salary'
11
+
10
12
  def self.per_page() 10 end
11
13
  end
@@ -1,7 +1,6 @@
1
- action_controller:
2
- id: 2
3
- name: Active Controller
4
-
5
1
  active_record:
6
2
  id: 1
7
3
  name: Active Record
4
+ action_controller:
5
+ id: 2
6
+ name: Active Controller
@@ -1,5 +1,7 @@
1
1
  class Reply < ActiveRecord::Base
2
2
  belongs_to :topic, :include => [:replies]
3
+
4
+ named_scope :recent, :conditions => ['replies.created_at > ?', 15.minutes.ago]
3
5
 
4
6
  validates_presence_of :content
5
7
  end
@@ -1,4 +1,6 @@
1
1
  class Topic < ActiveRecord::Base
2
2
  has_many :replies, :dependent => :destroy, :order => 'replies.created_at DESC'
3
3
  belongs_to :project
4
+
5
+ named_scope :mentions_activerecord, :conditions => ['topics.title LIKE ?', '%ActiveRecord%']
4
6
  end
data/test/helper.rb CHANGED
@@ -4,7 +4,7 @@ require 'rubygems'
4
4
  # gem install redgreen for colored test output
5
5
  begin require 'redgreen'; rescue LoadError; end
6
6
 
7
- require File.join(File.dirname(__FILE__), 'boot') unless defined?(ActiveRecord)
7
+ require 'boot' unless defined?(ActiveRecord)
8
8
 
9
9
  class Test::Unit::TestCase
10
10
  protected
@@ -13,6 +13,18 @@ class Test::Unit::TestCase
13
13
  [method.to_s, method.to_sym].each { |m| assert_respond_to object, m }
14
14
  end
15
15
  end
16
+
17
+ def collect_deprecations
18
+ old_behavior = WillPaginate::Deprecation.behavior
19
+ deprecations = []
20
+ WillPaginate::Deprecation.behavior = Proc.new do |message, callstack|
21
+ deprecations << message
22
+ end
23
+ result = yield
24
+ [result, deprecations]
25
+ ensure
26
+ WillPaginate::Deprecation.behavior = old_behavior
27
+ end
16
28
  end
17
29
 
18
30
  # Wrap tests that use Mocha and skip if unavailable.
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'activerecord_test_connector')
1
+ require 'lib/activerecord_test_connector'
2
2
 
3
3
  class ActiveRecordTestCase < Test::Unit::TestCase
4
4
  # Set our fixture path
@@ -18,6 +18,19 @@ class ActiveRecordTestCase < Test::Unit::TestCase
18
18
  # Default so Test::Unit::TestCase doesn't complain
19
19
  def test_truth
20
20
  end
21
+
22
+ protected
23
+
24
+ def assert_queries(num = 1)
25
+ $query_count = 0
26
+ yield
27
+ ensure
28
+ assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed."
29
+ end
30
+
31
+ def assert_no_queries(&block)
32
+ assert_queries(0, &block)
33
+ end
21
34
  end
22
35
 
23
36
  ActiveRecordTestConnector.setup
@@ -6,6 +6,8 @@ class ActiveRecordTestConnector
6
6
  cattr_accessor :able_to_connect
7
7
  cattr_accessor :connected
8
8
 
9
+ FIXTURES_PATH = File.join(File.dirname(__FILE__), '..', 'fixtures')
10
+
9
11
  # Set our defaults
10
12
  self.connected = false
11
13
  self.able_to_connect = true
@@ -14,13 +16,12 @@ class ActiveRecordTestConnector
14
16
  unless self.connected || !self.able_to_connect
15
17
  setup_connection
16
18
  load_schema
17
- # require_fixture_models
18
- Dependencies.load_paths.unshift(File.dirname(__FILE__) + "/../fixtures")
19
+ Dependencies.load_paths.unshift FIXTURES_PATH
19
20
  self.connected = true
20
21
  end
21
22
  rescue Exception => e # errors from ActiveRecord setup
22
- $stderr.puts "\nSkipping ActiveRecord assertion tests: #{e}"
23
- #$stderr.puts " #{e.backtrace.join("\n ")}\n"
23
+ $stderr.puts "\nSkipping ActiveRecord tests: #{e}"
24
+ $stderr.puts "Install SQLite3 to run the full test suite for will_paginate.\n\n"
24
25
  self.able_to_connect = false
25
26
  end
26
27
 
@@ -38,7 +39,7 @@ class ActiveRecordTestConnector
38
39
 
39
40
  ActiveRecord::Base.establish_connection(configuration)
40
41
  ActiveRecord::Base.configurations = { db => configuration }
41
- ActiveRecord::Base.connection
42
+ prepare ActiveRecord::Base.connection
42
43
 
43
44
  unless Object.const_defined?(:QUOTED_TYPE)
44
45
  Object.send :const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')
@@ -48,13 +49,21 @@ class ActiveRecordTestConnector
48
49
  def self.load_schema
49
50
  ActiveRecord::Base.silence do
50
51
  ActiveRecord::Migration.verbose = false
51
- load File.dirname(__FILE__) + "/../fixtures/schema.rb"
52
+ load File.join(FIXTURES_PATH, 'schema.rb')
52
53
  end
53
54
  end
54
55
 
55
- def self.require_fixture_models
56
- models = Dir.glob(File.dirname(__FILE__) + "/../fixtures/*.rb")
57
- models = (models.grep(/user.rb/) + models).uniq
58
- models.each { |f| require f }
56
+ def self.prepare(conn)
57
+ class << conn
58
+ IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SHOW FIELDS /]
59
+
60
+ def execute_with_counting(sql, name = nil, &block)
61
+ $query_count ||= 0
62
+ $query_count += 1 unless IGNORED_SQL.any? { |r| sql =~ r }
63
+ execute_without_counting(sql, name, &block)
64
+ end
65
+
66
+ alias_method_chain :execute, :counting
67
+ end
59
68
  end
60
69
  end