leshill-will_paginate 2.3.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/CHANGELOG.rdoc +110 -0
  2. data/LICENSE +18 -0
  3. data/README.rdoc +111 -0
  4. data/Rakefile +53 -0
  5. data/examples/apple-circle.gif +0 -0
  6. data/examples/index.haml +69 -0
  7. data/examples/index.html +92 -0
  8. data/examples/pagination.css +90 -0
  9. data/examples/pagination.sass +91 -0
  10. data/init.rb +1 -0
  11. data/lib/will_paginate.rb +90 -0
  12. data/lib/will_paginate/array.rb +16 -0
  13. data/lib/will_paginate/collection.rb +146 -0
  14. data/lib/will_paginate/core_ext.rb +43 -0
  15. data/lib/will_paginate/finder.rb +264 -0
  16. data/lib/will_paginate/named_scope.rb +170 -0
  17. data/lib/will_paginate/named_scope_patch.rb +37 -0
  18. data/lib/will_paginate/version.rb +9 -0
  19. data/lib/will_paginate/view_helpers.rb +432 -0
  20. data/test/boot.rb +21 -0
  21. data/test/collection_test.rb +143 -0
  22. data/test/console +8 -0
  23. data/test/database.yml +22 -0
  24. data/test/finder_test.rb +473 -0
  25. data/test/fixtures/admin.rb +3 -0
  26. data/test/fixtures/developer.rb +14 -0
  27. data/test/fixtures/developers_projects.yml +13 -0
  28. data/test/fixtures/project.rb +15 -0
  29. data/test/fixtures/projects.yml +6 -0
  30. data/test/fixtures/replies.yml +29 -0
  31. data/test/fixtures/reply.rb +7 -0
  32. data/test/fixtures/schema.rb +38 -0
  33. data/test/fixtures/topic.rb +10 -0
  34. data/test/fixtures/topics.yml +30 -0
  35. data/test/fixtures/user.rb +2 -0
  36. data/test/fixtures/users.yml +35 -0
  37. data/test/helper.rb +40 -0
  38. data/test/lib/activerecord_test_case.rb +43 -0
  39. data/test/lib/activerecord_test_connector.rb +75 -0
  40. data/test/lib/load_fixtures.rb +11 -0
  41. data/test/lib/view_test_process.rb +180 -0
  42. data/test/tasks.rake +59 -0
  43. data/test/view_test.rb +405 -0
  44. metadata +127 -0
@@ -0,0 +1,59 @@
1
+ require 'rake/testtask'
2
+
3
+ desc 'Test the will_paginate plugin.'
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.pattern = 'test/**/*_test.rb'
6
+ t.verbose = true
7
+ t.libs << 'test'
8
+ end
9
+
10
+ # I want to specify environment variables at call time
11
+ class EnvTestTask < Rake::TestTask
12
+ attr_accessor :env
13
+
14
+ def ruby(*args)
15
+ env.each { |key, value| ENV[key] = value } if env
16
+ super
17
+ env.keys.each { |key| ENV.delete key } if env
18
+ end
19
+ end
20
+
21
+ for configuration in %w( sqlite3 mysql postgres )
22
+ EnvTestTask.new("test_#{configuration}") do |t|
23
+ t.pattern = 'test/finder_test.rb'
24
+ t.verbose = true
25
+ t.env = { 'DB' => configuration }
26
+ t.libs << 'test'
27
+ end
28
+ end
29
+
30
+ task :test_databases => %w(test_mysql test_sqlite3 test_postgres)
31
+
32
+ desc %{Test everything on SQLite3, MySQL and PostgreSQL}
33
+ task :test_full => %w(test test_mysql test_postgres)
34
+
35
+ desc %{Test everything with Rails 2.1.x, 2.0.x & 1.2.x gems}
36
+ task :test_all do
37
+ all = Rake::Task['test_full']
38
+ versions = %w(2.3.2 2.2.2 2.1.0 2.0.4 1.2.6)
39
+ versions.each do |version|
40
+ ENV['RAILS_VERSION'] = "~> #{version}"
41
+ all.invoke
42
+ reset_invoked unless version == versions.last
43
+ end
44
+ end
45
+
46
+ def reset_invoked
47
+ %w( test_full test test_mysql test_postgres ).each do |name|
48
+ Rake::Task[name].instance_variable_set '@already_invoked', false
49
+ end
50
+ end
51
+
52
+ task :rcov do
53
+ excludes = %w( lib/will_paginate/named_scope*
54
+ lib/will_paginate/core_ext.rb
55
+ lib/will_paginate.rb
56
+ rails* )
57
+
58
+ system %[rcov -Itest:lib test/*.rb -x #{excludes.join(',')}]
59
+ end
@@ -0,0 +1,405 @@
1
+ require 'helper'
2
+ require 'lib/view_test_process'
3
+
4
+ class AdditionalLinkAttributesRenderer < WillPaginate::LinkRenderer
5
+ def initialize(link_attributes = nil)
6
+ super()
7
+ @additional_link_attributes = link_attributes || { :default => 'true' }
8
+ end
9
+
10
+ def page_link(page, text, attributes = {})
11
+ @template.link_to text, url_for(page), attributes.merge(@additional_link_attributes)
12
+ end
13
+ end
14
+
15
+ class ViewTest < WillPaginate::ViewTestCase
16
+
17
+ ## basic pagination ##
18
+
19
+ def test_will_paginate
20
+ paginate do |pagination|
21
+ assert_select 'a[href]', 3 do |elements|
22
+ validate_page_numbers [2,3,2], elements
23
+ assert_select elements.last, ':last-child', "Next &raquo;"
24
+ end
25
+ assert_select 'span', 2
26
+ assert_select 'span.disabled:first-child', '&laquo; Previous'
27
+ assert_select 'span.current', '1'
28
+ assert_equal '&laquo; Previous 1 2 3 Next &raquo;', pagination.first.inner_text
29
+ end
30
+ end
31
+
32
+ def test_no_pagination_when_page_count_is_one
33
+ paginate :per_page => 30
34
+ assert_equal '', @html_result
35
+ end
36
+
37
+ def test_will_paginate_with_options
38
+ paginate({ :page => 2 },
39
+ :class => 'will_paginate', :previous_label => 'Prev', :next_label => 'Next') do
40
+ assert_select 'a[href]', 4 do |elements|
41
+ validate_page_numbers [1,1,3,3], elements
42
+ # test rel attribute values:
43
+ assert_select elements[1], 'a', '1' do |link|
44
+ assert_equal 'prev start', link.first['rel']
45
+ end
46
+ assert_select elements.first, 'a', "Prev" do |link|
47
+ assert_equal 'prev start', link.first['rel']
48
+ end
49
+ assert_select elements.last, 'a', "Next" do |link|
50
+ assert_equal 'next', link.first['rel']
51
+ end
52
+ end
53
+ assert_select 'span.current', '2'
54
+ end
55
+ end
56
+
57
+ def test_will_paginate_using_renderer_class
58
+ paginate({}, :renderer => AdditionalLinkAttributesRenderer) do
59
+ assert_select 'a[default=true]', 3
60
+ end
61
+ end
62
+
63
+ def test_will_paginate_using_renderer_instance
64
+ renderer = WillPaginate::LinkRenderer.new
65
+ renderer.gap_marker = '<span class="my-gap">~~</span>'
66
+
67
+ paginate({ :per_page => 2 }, :inner_window => 0, :outer_window => 0, :renderer => renderer) do
68
+ assert_select 'span.my-gap', '~~'
69
+ end
70
+
71
+ renderer = AdditionalLinkAttributesRenderer.new(:title => 'rendered')
72
+ paginate({}, :renderer => renderer) do
73
+ assert_select 'a[title=rendered]', 3
74
+ end
75
+ end
76
+
77
+ def test_prev_next_links_have_classnames
78
+ paginate do |pagination|
79
+ assert_select 'span.disabled.prev_page:first-child'
80
+ assert_select 'a.next_page[href]:last-child'
81
+ end
82
+ end
83
+
84
+ def test_prev_label_deprecated
85
+ assert_deprecated ':previous_label' do
86
+ paginate({ :page => 2 }, :prev_label => 'Deprecated') do
87
+ assert_select 'a[href]:first-child', 'Deprecated'
88
+ end
89
+ end
90
+ end
91
+
92
+ def test_full_output
93
+ paginate
94
+ expected = <<-HTML
95
+ <div class="pagination"><span class="disabled prev_page">&laquo; Previous</span>
96
+ <span class="current">1</span>
97
+ <a href="/foo/bar?page=2" rel="next">2</a>
98
+ <a href="/foo/bar?page=3">3</a>
99
+ <a href="/foo/bar?page=2" class="next_page" rel="next">Next &raquo;</a></div>
100
+ HTML
101
+ expected.strip!.gsub!(/\s{2,}/, ' ')
102
+
103
+ assert_dom_equal expected, @html_result
104
+ end
105
+
106
+ def test_escaping_of_urls
107
+ paginate({:page => 1, :per_page => 1, :total_entries => 2},
108
+ :page_links => false, :params => { :tag => '<br>' })
109
+
110
+ assert_select 'a[href]', 1 do |links|
111
+ query = links.first['href'].split('?', 2)[1]
112
+ assert_equal %w(page=2 tag=%3Cbr%3E), query.split('&amp;').sort
113
+ end
114
+ end
115
+
116
+ ## advanced options for pagination ##
117
+
118
+ def test_will_paginate_without_container
119
+ paginate({}, :container => false)
120
+ assert_select 'div.pagination', 0, 'main DIV present when it shouldn\'t'
121
+ assert_select 'a[href]', 3
122
+ end
123
+
124
+ def test_will_paginate_without_page_links
125
+ paginate({ :page => 2 }, :page_links => false) do
126
+ assert_select 'a[href]', 2 do |elements|
127
+ validate_page_numbers [1,3], elements
128
+ end
129
+ end
130
+ end
131
+
132
+ def test_will_paginate_windows
133
+ paginate({ :page => 6, :per_page => 1 }, :inner_window => 1) do |pagination|
134
+ assert_select 'a[href]', 8 do |elements|
135
+ validate_page_numbers [5,1,2,5,7,10,11,7], elements
136
+ assert_select elements.first, 'a', '&laquo; Previous'
137
+ assert_select elements.last, 'a', 'Next &raquo;'
138
+ end
139
+ assert_select 'span.current', '6'
140
+ assert_equal '&laquo; Previous 1 2 &hellip; 5 6 7 &hellip; 10 11 Next &raquo;', pagination.first.inner_text
141
+ end
142
+ end
143
+
144
+ def test_will_paginate_eliminates_small_gaps
145
+ paginate({ :page => 6, :per_page => 1 }, :inner_window => 2) do
146
+ assert_select 'a[href]', 12 do |elements|
147
+ validate_page_numbers [5,1,2,3,4,5,7,8,9,10,11,7], elements
148
+ end
149
+ end
150
+ end
151
+
152
+ def test_container_id
153
+ paginate do |div|
154
+ assert_nil div.first['id']
155
+ end
156
+
157
+ # magic ID
158
+ paginate({}, :id => true) do |div|
159
+ assert_equal 'fixnums_pagination', div.first['id']
160
+ end
161
+
162
+ # explicit ID
163
+ paginate({}, :id => 'custom_id') do |div|
164
+ assert_equal 'custom_id', div.first['id']
165
+ end
166
+ end
167
+
168
+ ## other helpers ##
169
+
170
+ def test_paginated_section
171
+ @template = <<-ERB
172
+ <% paginated_section collection, options do %>
173
+ <%= content_tag :div, '', :id => "developers" %>
174
+ <% end %>
175
+ ERB
176
+
177
+ paginate
178
+ assert_select 'div.pagination', 2
179
+ assert_select 'div.pagination + div#developers', 1
180
+ end
181
+
182
+ def test_page_entries_info
183
+ @template = '<%= page_entries_info collection %>'
184
+ array = ('a'..'z').to_a
185
+
186
+ paginate array.paginate(:page => 2, :per_page => 5)
187
+ assert_equal %{Displaying strings <b>6&nbsp;-&nbsp;10</b> of <b>26</b> in total},
188
+ @html_result
189
+
190
+ paginate array.paginate(:page => 7, :per_page => 4)
191
+ assert_equal %{Displaying strings <b>25&nbsp;-&nbsp;26</b> of <b>26</b> in total},
192
+ @html_result
193
+ end
194
+
195
+ uses_mocha 'class name' do
196
+ def test_page_entries_info_with_longer_class_name
197
+ @template = '<%= page_entries_info collection %>'
198
+ collection = ('a'..'z').to_a.paginate
199
+ collection.first.stubs(:class).returns(mock('class', :name => 'ProjectType'))
200
+
201
+ paginate collection
202
+ assert @html_result.index('project types'), "expected <#{@html_result.inspect}> to mention 'project types'"
203
+ end
204
+ end
205
+
206
+ def test_page_entries_info_with_single_page_collection
207
+ @template = '<%= page_entries_info collection %>'
208
+
209
+ paginate(('a'..'d').to_a.paginate(:page => 1, :per_page => 5))
210
+ assert_equal %{Displaying <b>all 4</b> strings}, @html_result
211
+
212
+ paginate(['a'].paginate(:page => 1, :per_page => 5))
213
+ assert_equal %{Displaying <b>1</b> string}, @html_result
214
+
215
+ paginate([].paginate(:page => 1, :per_page => 5))
216
+ assert_equal %{No entries found}, @html_result
217
+ end
218
+
219
+ def test_page_entries_info_with_custom_entry_name
220
+ @template = '<%= page_entries_info collection, :entry_name => "author" %>'
221
+
222
+ entries = (1..20).to_a
223
+
224
+ paginate(entries.paginate(:page => 1, :per_page => 5))
225
+ assert_equal %{Displaying authors <b>1&nbsp;-&nbsp;5</b> of <b>20</b> in total}, @html_result
226
+
227
+ paginate(entries.paginate(:page => 1, :per_page => 20))
228
+ assert_equal %{Displaying <b>all 20</b> authors}, @html_result
229
+
230
+ paginate(['a'].paginate(:page => 1, :per_page => 5))
231
+ assert_equal %{Displaying <b>1</b> author}, @html_result
232
+
233
+ paginate([].paginate(:page => 1, :per_page => 5))
234
+ assert_equal %{No authors found}, @html_result
235
+ end
236
+
237
+ ## parameter handling in page links ##
238
+
239
+ def test_will_paginate_preserves_parameters_on_get
240
+ @request.params :foo => { :bar => 'baz' }
241
+ paginate
242
+ assert_links_match /foo%5Bbar%5D=baz/
243
+ end
244
+
245
+ def test_will_paginate_doesnt_preserve_parameters_on_post
246
+ @request.post
247
+ @request.params :foo => 'bar'
248
+ paginate
249
+ assert_no_links_match /foo=bar/
250
+ end
251
+
252
+ def test_adding_additional_parameters
253
+ paginate({}, :params => { :foo => 'bar' })
254
+ assert_links_match /foo=bar/
255
+ end
256
+
257
+ def test_adding_anchor_parameter
258
+ paginate({}, :params => { :anchor => 'anchor' })
259
+ assert_links_match /#anchor$/
260
+ end
261
+
262
+ def test_removing_arbitrary_parameters
263
+ @request.params :foo => 'bar'
264
+ paginate({}, :params => { :foo => nil })
265
+ assert_no_links_match /foo=bar/
266
+ end
267
+
268
+ def test_adding_additional_route_parameters
269
+ paginate({}, :params => { :controller => 'baz', :action => 'list' })
270
+ assert_links_match %r{\Wbaz/list\W}
271
+ end
272
+
273
+ def test_will_paginate_with_custom_page_param
274
+ paginate({ :page => 2 }, :param_name => :developers_page) do
275
+ assert_select 'a[href]', 4 do |elements|
276
+ validate_page_numbers [1,1,3,3], elements, :developers_page
277
+ end
278
+ end
279
+ end
280
+
281
+ def test_will_paginate_with_atmark_url
282
+ @request.symbolized_path_parameters[:action] = "@tag"
283
+ renderer = WillPaginate::LinkRenderer.new
284
+
285
+ paginate({ :page => 1 }, :renderer=>renderer)
286
+ assert_links_match %r[/foo/@tag\?page=\d]
287
+ end
288
+
289
+ def test_complex_custom_page_param
290
+ @request.params :developers => { :page => 2 }
291
+
292
+ paginate({ :page => 2 }, :param_name => 'developers[page]') do
293
+ assert_select 'a[href]', 4 do |links|
294
+ assert_links_match /\?developers%5Bpage%5D=\d+$/, links
295
+ validate_page_numbers [1,1,3,3], links, 'developers[page]'
296
+ end
297
+ end
298
+ end
299
+
300
+ def test_custom_routing_page_param
301
+ @request.symbolized_path_parameters.update :controller => 'dummy', :action => nil
302
+ paginate :per_page => 2 do
303
+ assert_select 'a[href]', 6 do |links|
304
+ assert_links_match %r{/page/(\d+)$}, links, [2, 3, 4, 5, 6, 2]
305
+ end
306
+ end
307
+ end
308
+
309
+ def test_custom_routing_page_param_with_dot_separator
310
+ @request.symbolized_path_parameters.update :controller => 'dummy', :action => 'dots'
311
+ paginate :per_page => 2 do
312
+ assert_select 'a[href]', 6 do |links|
313
+ assert_links_match %r{/page\.(\d+)$}, links, [2, 3, 4, 5, 6, 2]
314
+ end
315
+ end
316
+ end
317
+
318
+ def test_custom_routing_with_first_page_hidden
319
+ @request.symbolized_path_parameters.update :controller => 'ibocorp', :action => nil
320
+ paginate :page => 2, :per_page => 2 do
321
+ assert_select 'a[href]', 7 do |links|
322
+ assert_links_match %r{/ibocorp(?:/(\d+))?$}, links, [nil, nil, 3, 4, 5, 6, 3]
323
+ end
324
+ end
325
+ end
326
+
327
+ ## internal hardcore stuff ##
328
+
329
+ class LegacyCollection < WillPaginate::Collection
330
+ alias :page_count :total_pages
331
+ undef :total_pages
332
+ end
333
+
334
+ def test_deprecation_notices_with_page_count
335
+ collection = LegacyCollection.new(1, 1, 2)
336
+
337
+ assert_deprecated collection.class.name do
338
+ paginate collection
339
+ end
340
+ end
341
+
342
+ uses_mocha 'view internals' do
343
+ def test_collection_name_can_be_guessed
344
+ collection = mock
345
+ collection.expects(:total_pages).returns(1)
346
+
347
+ @template = '<%= will_paginate options %>'
348
+ @controller.controller_name = 'developers'
349
+ @view.assigns['developers'] = collection
350
+
351
+ paginate(nil)
352
+ end
353
+ end
354
+
355
+ def test_inferred_collection_name_raises_error_when_nil
356
+ @template = '<%= will_paginate options %>'
357
+ @controller.controller_name = 'developers'
358
+
359
+ e = assert_raise ArgumentError do
360
+ paginate(nil)
361
+ end
362
+ assert e.message.include?('@developers')
363
+ end
364
+
365
+ if ActionController::Base.respond_to? :rescue_responses
366
+ # only on Rails 2
367
+ def test_rescue_response_hook_presence
368
+ assert_equal :not_found,
369
+ ActionController::Base.rescue_responses['WillPaginate::InvalidPage']
370
+ end
371
+ end
372
+
373
+ ## semantic pagination ##
374
+
375
+ def test_semantic_container
376
+ paginate([1].paginate({ :page => 1, :total_entries => 13, :per_page => 4 }), :container => false, :semantic => true)
377
+ assert_select('ul li', false)
378
+ end
379
+
380
+ def test_specified_semantic_container
381
+ paginate([1].paginate({ :page => 1, :total_entries => 13, :per_page => 4 }), :semantic => true, :semantic_container => :ol)
382
+ assert_select('ol li', true)
383
+ end
384
+
385
+ def test_semantic
386
+ paginate([1].paginate({ :page => 1, :total_entries => 13, :per_page => 4 }), :semantic => true) do |pagination|
387
+ assert_select 'li a[href]', 4 do |elements|
388
+ validate_page_numbers [2,3,4,2], elements
389
+ assert_select elements.last, ':last-child', "Next &raquo;"
390
+ end
391
+ assert_select 'ul li', 6
392
+ assert_select 'li.disabled.prev_page', '&laquo; Previous'
393
+ assert_select 'li.current', '1'
394
+ assert_select 'li a[rel=next]', '2'
395
+ assert_select 'li.next_page a.next_page[rel=next]', 'Next &raquo;'
396
+ assert_equal %Q(<ul class="pagination"><li class="disabled prev_page">&laquo; Previous</li><li class="current">1</li><li><a href="/foo/bar?page=2" rel="next">2</a></li><li><a href="/foo/bar?page=3">3</a></li><li><a href="/foo/bar?page=4">4</a></li><li class="next_page"><a href="/foo/bar?page=2" class="next_page" rel="next">Next &raquo;</a></li></ul>), @html_result
397
+ end
398
+ end
399
+
400
+ def test_semantic_gap
401
+ paginate([1].paginate({ :page => 2, :total_entries => 25, :per_page => 4 }), :inner_window => 1, :semantic => true) do |pagination|
402
+ assert_select 'li.gap', '&hellip;'
403
+ end
404
+ end
405
+ end