agnostic-will_paginate 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.autotest +54 -0
  2. data/.gitignore +4 -0
  3. data/.gitmodules +3 -0
  4. data/.manifest +61 -0
  5. data/CHANGELOG.rdoc +105 -0
  6. data/LICENSE +18 -0
  7. data/README.rdoc +125 -0
  8. data/Rakefile +58 -0
  9. data/init.rb +1 -0
  10. data/lib/will_paginate.rb +45 -0
  11. data/lib/will_paginate/array.rb +33 -0
  12. data/lib/will_paginate/collection.rb +145 -0
  13. data/lib/will_paginate/core_ext.rb +69 -0
  14. data/lib/will_paginate/deprecation.rb +50 -0
  15. data/lib/will_paginate/finders.rb +9 -0
  16. data/lib/will_paginate/finders/active_record.rb +192 -0
  17. data/lib/will_paginate/finders/active_record/named_scope.rb +170 -0
  18. data/lib/will_paginate/finders/active_record/named_scope_patch.rb +39 -0
  19. data/lib/will_paginate/finders/active_resource.rb +51 -0
  20. data/lib/will_paginate/finders/base.rb +112 -0
  21. data/lib/will_paginate/finders/data_mapper.rb +30 -0
  22. data/lib/will_paginate/finders/sequel.rb +22 -0
  23. data/lib/will_paginate/version.rb +9 -0
  24. data/lib/will_paginate/view_helpers.rb +42 -0
  25. data/lib/will_paginate/view_helpers/action_view.rb +158 -0
  26. data/lib/will_paginate/view_helpers/base.rb +126 -0
  27. data/lib/will_paginate/view_helpers/link_renderer.rb +130 -0
  28. data/lib/will_paginate/view_helpers/link_renderer_base.rb +83 -0
  29. data/lib/will_paginate/view_helpers/merb.rb +13 -0
  30. data/spec/collection_spec.rb +147 -0
  31. data/spec/console +8 -0
  32. data/spec/console_fixtures.rb +8 -0
  33. data/spec/database.yml +22 -0
  34. data/spec/finders/active_record_spec.rb +461 -0
  35. data/spec/finders/active_resource_spec.rb +52 -0
  36. data/spec/finders/activerecord_test_connector.rb +108 -0
  37. data/spec/finders/data_mapper_spec.rb +62 -0
  38. data/spec/finders/data_mapper_test_connector.rb +20 -0
  39. data/spec/finders/sequel_spec.rb +53 -0
  40. data/spec/finders/sequel_test_connector.rb +9 -0
  41. data/spec/finders_spec.rb +76 -0
  42. data/spec/fixtures/admin.rb +3 -0
  43. data/spec/fixtures/developer.rb +13 -0
  44. data/spec/fixtures/developers_projects.yml +13 -0
  45. data/spec/fixtures/project.rb +15 -0
  46. data/spec/fixtures/projects.yml +6 -0
  47. data/spec/fixtures/replies.yml +29 -0
  48. data/spec/fixtures/reply.rb +7 -0
  49. data/spec/fixtures/schema.rb +38 -0
  50. data/spec/fixtures/topic.rb +6 -0
  51. data/spec/fixtures/topics.yml +30 -0
  52. data/spec/fixtures/user.rb +2 -0
  53. data/spec/fixtures/users.yml +35 -0
  54. data/spec/rcov.opts +2 -0
  55. data/spec/spec.opts +2 -0
  56. data/spec/spec_helper.rb +75 -0
  57. data/spec/tasks.rake +60 -0
  58. data/spec/view_helpers/action_view_spec.rb +344 -0
  59. data/spec/view_helpers/base_spec.rb +64 -0
  60. data/spec/view_helpers/link_renderer_base_spec.rb +84 -0
  61. data/spec/view_helpers/view_example_group.rb +111 -0
  62. metadata +152 -0
@@ -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.to_s(:db) %>
6
+
7
+ another:
8
+ id: 2
9
+ topic_id: 2
10
+ content: Nuh uh!
11
+ created_at: <%= 1.hour.ago.to_s(:db) %>
12
+
13
+ spam:
14
+ id: 3
15
+ topic_id: 1
16
+ content: Nice site!
17
+ created_at: <%= 1.hour.ago.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.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.to_s(:db) %>
@@ -0,0 +1,7 @@
1
+ class Reply < ActiveRecord::Base
2
+ belongs_to :topic, :include => [:replies]
3
+
4
+ named_scope :recent, :conditions => ['replies.created_at > ?', 15.minutes.ago]
5
+
6
+ validates_presence_of :content
7
+ end
@@ -0,0 +1,38 @@
1
+ ActiveRecord::Schema.define do
2
+
3
+ create_table "users", :force => true do |t|
4
+ t.column "name", :text
5
+ t.column "salary", :integer, :default => 70000
6
+ t.column "created_at", :datetime
7
+ t.column "updated_at", :datetime
8
+ t.column "type", :text
9
+ end
10
+
11
+ create_table "projects", :force => true do |t|
12
+ t.column "name", :text
13
+ end
14
+
15
+ create_table "developers_projects", :id => false, :force => true do |t|
16
+ t.column "developer_id", :integer, :null => false
17
+ t.column "project_id", :integer, :null => false
18
+ t.column "joined_on", :date
19
+ t.column "access_level", :integer, :default => 1
20
+ end
21
+
22
+ create_table "topics", :force => true do |t|
23
+ t.column "project_id", :integer
24
+ t.column "title", :string
25
+ t.column "subtitle", :string
26
+ t.column "content", :text
27
+ t.column "created_at", :datetime
28
+ t.column "updated_at", :datetime
29
+ end
30
+
31
+ create_table "replies", :force => true do |t|
32
+ t.column "content", :text
33
+ t.column "created_at", :datetime
34
+ t.column "updated_at", :datetime
35
+ t.column "topic_id", :integer
36
+ end
37
+
38
+ end
@@ -0,0 +1,6 @@
1
+ class Topic < ActiveRecord::Base
2
+ has_many :replies, :dependent => :destroy, :order => 'replies.created_at DESC'
3
+ belongs_to :project
4
+
5
+ named_scope :mentions_activerecord, :conditions => ['topics.title LIKE ?', '%ActiveRecord%']
6
+ end
@@ -0,0 +1,30 @@
1
+ futurama:
2
+ id: 1
3
+ title: Isnt futurama awesome?
4
+ subtitle: It really is, isnt it.
5
+ content: I like futurama
6
+ created_at: <%= 1.day.ago.to_s(:db) %>
7
+ updated_at:
8
+
9
+ harvey_birdman:
10
+ id: 2
11
+ title: Harvey Birdman is the king of all men
12
+ subtitle: yup
13
+ content: He really is
14
+ created_at: <%= 2.hours.ago.to_s(:db) %>
15
+ updated_at:
16
+
17
+ rails:
18
+ id: 3
19
+ project_id: 1
20
+ title: Rails is nice
21
+ subtitle: It makes me happy
22
+ content: except when I have to hack internals to fix pagination. even then really.
23
+ created_at: <%= 20.minutes.ago.to_s(:db) %>
24
+
25
+ ar:
26
+ id: 4
27
+ project_id: 1
28
+ title: ActiveRecord sometimes freaks me out
29
+ content: "I mean, what's the deal with eager loading?"
30
+ created_at: <%= 15.minutes.ago.to_s(:db) %>
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,35 @@
1
+ david:
2
+ id: 1
3
+ name: David
4
+ salary: 80000
5
+ type: Developer
6
+
7
+ jamis:
8
+ id: 2
9
+ name: Jamis
10
+ salary: 150000
11
+ type: Developer
12
+
13
+ <% for digit in 3..10 %>
14
+ dev_<%= digit %>:
15
+ id: <%= digit %>
16
+ name: fixture_<%= digit %>
17
+ salary: 100000
18
+ type: Developer
19
+ <% end %>
20
+
21
+ poor_jamis:
22
+ id: 11
23
+ name: Jamis
24
+ salary: 9000
25
+ type: Developer
26
+
27
+ admin:
28
+ id: 12
29
+ name: admin
30
+ type: Admin
31
+
32
+ goofy:
33
+ id: 13
34
+ name: Goofy
35
+ type: Admin
@@ -0,0 +1,2 @@
1
+ --exclude ^\/,^spec\/,core_ext.rb,deprecation.rb
2
+ --no-validator-links
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --reverse
@@ -0,0 +1,75 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ module MyExtras
5
+ protected
6
+
7
+ def include_phrase(string)
8
+ PhraseMatcher.new(string)
9
+ end
10
+
11
+ def collection(params = {})
12
+ if params[:total_pages]
13
+ params[:per_page] = 1
14
+ params[:total_entries] = params[:total_pages]
15
+ end
16
+ WillPaginate::Collection.new(params[:page] || 1, params[:per_page] || 30, params[:total_entries])
17
+ end
18
+
19
+ def have_deprecation
20
+ DeprecationMatcher.new
21
+ end
22
+ end
23
+
24
+ Spec::Runner.configure do |config|
25
+ # config.include My::Pony, My::Horse, :type => :farm
26
+ config.include MyExtras
27
+ # config.predicate_matchers[:swim] = :can_swim?
28
+
29
+ config.mock_with :mocha
30
+ end
31
+
32
+ class PhraseMatcher
33
+ def initialize(string)
34
+ @string = string
35
+ @pattern = /\b#{string}\b/
36
+ end
37
+
38
+ def matches?(actual)
39
+ @actual = actual.to_s
40
+ @actual =~ @pattern
41
+ end
42
+
43
+ def failure_message
44
+ "expected #{@actual.inspect} to contain phrase #{@string.inspect}"
45
+ end
46
+
47
+ def negative_failure_message
48
+ "expected #{@actual.inspect} not to contain phrase #{@string.inspect}"
49
+ end
50
+ end
51
+
52
+ class DeprecationMatcher
53
+ def initialize
54
+ @old_behavior = WillPaginate::Deprecation.behavior
55
+ @messages = []
56
+ WillPaginate::Deprecation.behavior = lambda { |message, callstack|
57
+ @messages << message
58
+ }
59
+ end
60
+
61
+ def matches?(block)
62
+ block.call
63
+ !@messages.empty?
64
+ ensure
65
+ WillPaginate::Deprecation.behavior = @old_behavior
66
+ end
67
+
68
+ def failure_message
69
+ "expected block to raise a deprecation warning"
70
+ end
71
+
72
+ def negative_failure_message
73
+ "expected block not to raise deprecation warnings, #{@messages.size} raised"
74
+ end
75
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ spec_opts = 'spec/spec.opts'
4
+
5
+ desc 'Run framework-agnostic specs'
6
+ Spec::Rake::SpecTask.new(:spec) do |t|
7
+ t.libs << 'lib' << 'spec'
8
+ t.spec_opts = ['--options', spec_opts]
9
+ t.spec_files = FileList.new('spec/**/*_spec.rb') do |files|
10
+ files.exclude(/\b(active_record|active_resource|action_view|data_mapper|sequel)_/)
11
+ end
12
+ end
13
+
14
+ namespace :spec do
15
+ desc 'Run specs for core, ActiveRecord and ActionView'
16
+ Spec::Rake::SpecTask.new(:rails) do |t|
17
+ t.libs << 'lib' << 'spec'
18
+ t.spec_opts = ['--options', spec_opts]
19
+ t.spec_files = FileList.new('spec/**/*_spec.rb') do |files|
20
+ files.exclude(/\b(data_mapper|sequel)_/)
21
+ end
22
+ end
23
+
24
+ desc 'Run specs for DataMapper'
25
+ Spec::Rake::SpecTask.new(:datamapper) do |t|
26
+ t.libs << 'lib' << 'spec'
27
+ t.spec_opts = ['--options', spec_opts]
28
+ t.spec_files = FileList.new('spec/finders_spec.rb', 'spec/finders/data_mapper_spec.rb')
29
+ end
30
+
31
+ desc 'Run specs for Sequel'
32
+ Spec::Rake::SpecTask.new(:sequel) do |t|
33
+ t.libs << 'lib' << 'spec'
34
+ t.spec_opts = ['--options', spec_opts]
35
+ t.spec_files = FileList.new('spec/finders_spec.rb', 'spec/finders/sequel_spec.rb')
36
+ end
37
+
38
+ desc 'Analyze spec coverage with RCov'
39
+ Spec::Rake::SpecTask.new(:rcov) do |t|
40
+ t.libs << 'lib' << 'spec'
41
+ t.spec_opts = ['--options', spec_opts]
42
+ t.rcov = true
43
+ t.rcov_opts = lambda do
44
+ IO.readlines('spec/rcov.opts').map { |l| l.chomp.split(" ") }.flatten
45
+ end
46
+ end
47
+
48
+ desc 'Print Specdoc for all specs'
49
+ Spec::Rake::SpecTask.new(:doc) do |t|
50
+ t.libs << 'lib' << 'spec'
51
+ t.spec_opts = ['--format', 'specdoc', '--dry-run']
52
+ end
53
+
54
+ desc 'Generate HTML report'
55
+ Spec::Rake::SpecTask.new(:html) do |t|
56
+ t.libs << 'lib' << 'spec'
57
+ t.spec_opts = ['--format', 'html:doc/spec_results.html', '--diff']
58
+ t.fail_on_error = false
59
+ end
60
+ end
@@ -0,0 +1,344 @@
1
+ require 'spec_helper'
2
+ require 'active_support/rescuable' # needed for Ruby 1.9.1
3
+ require 'action_controller'
4
+ require 'view_helpers/view_example_group'
5
+ require 'will_paginate/view_helpers/action_view'
6
+ require 'will_paginate/collection'
7
+
8
+ ActionController::Routing::Routes.draw do |map|
9
+ map.connect 'dummy/page/:page', :controller => 'dummy'
10
+ map.connect 'dummy/dots/page.:page', :controller => 'dummy', :action => 'dots'
11
+ map.connect 'ibocorp/:page', :controller => 'ibocorp',
12
+ :requirements => { :page => /\d+/ },
13
+ :defaults => { :page => 1 }
14
+
15
+ map.connect ':controller/:action/:id'
16
+ end
17
+
18
+ describe WillPaginate::ViewHelpers::ActionView do
19
+ before(:each) do
20
+ @view = ActionView::Base.new
21
+ @view.controller = DummyController.new
22
+ @view.request = @view.controller.request
23
+ @template = '<%= will_paginate collection, options %>'
24
+ end
25
+
26
+ def request
27
+ @view.request
28
+ end
29
+
30
+ def render(locals)
31
+ @view.render(:inline => @template, :locals => locals)
32
+ end
33
+
34
+ ## basic pagination ##
35
+
36
+ it "should render" do
37
+ paginate do |pagination|
38
+ assert_select 'a[href]', 3 do |elements|
39
+ validate_page_numbers [2,3,2], elements
40
+ assert_select elements.last, ':last-child', "Next &#8594;"
41
+ end
42
+ assert_select 'span', 1
43
+ assert_select 'span.disabled:first-child', '&#8592; Previous'
44
+ assert_select 'em', '1'
45
+ pagination.first.inner_text.should == '&#8592; Previous 1 2 3 Next &#8594;'
46
+ end
47
+ end
48
+
49
+ it "should render nothing when there is only 1 page" do
50
+ paginate(:per_page => 30).should be_empty
51
+ end
52
+
53
+ it "should paginate with options" do
54
+ paginate({ :page => 2 }, :class => 'will_paginate', :previous_label => 'Prev', :next_label => 'Next') do
55
+ assert_select 'a[href]', 4 do |elements|
56
+ validate_page_numbers [1,1,3,3], elements
57
+ # test rel attribute values:
58
+ assert_select elements[1], 'a', '1' do |link|
59
+ link.first['rel'].should == 'prev start'
60
+ end
61
+ assert_select elements.first, 'a', "Prev" do |link|
62
+ link.first['rel'].should == 'prev start'
63
+ end
64
+ assert_select elements.last, 'a', "Next" do |link|
65
+ link.first['rel'].should == 'next'
66
+ end
67
+ end
68
+ assert_select 'em', '2'
69
+ end
70
+ end
71
+
72
+ it "should paginate using a custom renderer class" do
73
+ paginate({}, :renderer => AdditionalLinkAttributesRenderer) do
74
+ assert_select 'a[default=true]', 3
75
+ end
76
+ end
77
+
78
+ it "should paginate using a custom renderer instance" do
79
+ renderer = WillPaginate::ViewHelpers::LinkRenderer.new
80
+ def renderer.gap() '<span class="my-gap">~~</span>' end
81
+
82
+ paginate({ :per_page => 2 }, :inner_window => 0, :outer_window => 0, :renderer => renderer) do
83
+ assert_select 'span.my-gap', '~~'
84
+ end
85
+
86
+ renderer = AdditionalLinkAttributesRenderer.new(:title => 'rendered')
87
+ paginate({}, :renderer => renderer) do
88
+ assert_select 'a[title=rendered]', 3
89
+ end
90
+ end
91
+
92
+ it "should have classnames on previous/next links" do
93
+ paginate do |pagination|
94
+ assert_select 'span.disabled.previous_page:first-child'
95
+ assert_select 'a.next_page[href]:last-child'
96
+ end
97
+ end
98
+
99
+ it "should warn about :prev_label being deprecated" do
100
+ lambda {
101
+ paginate({ :page => 2 }, :prev_label => 'Deprecated') do
102
+ assert_select 'a[href]:first-child', 'Deprecated'
103
+ end
104
+ }.should have_deprecation
105
+ end
106
+
107
+ it "should match expected markup" do
108
+ paginate
109
+ expected = <<-HTML
110
+ <div class="pagination"><span class="previous_page disabled">&#8592; Previous</span>
111
+ <em>1</em>
112
+ <a href="/foo/bar?page=2" rel="next">2</a>
113
+ <a href="/foo/bar?page=3">3</a>
114
+ <a href="/foo/bar?page=2" class="next_page" rel="next">Next &#8594;</a></div>
115
+ HTML
116
+ expected.strip!.gsub!(/\s{2,}/, ' ')
117
+ expected_dom = HTML::Document.new(expected).root
118
+
119
+ html_document.root.should == expected_dom
120
+ end
121
+
122
+ it "should output escaped URLs" do
123
+ paginate({:page => 1, :per_page => 1, :total_entries => 2},
124
+ :page_links => false, :params => { :tag => '<br>' })
125
+
126
+ assert_select 'a[href]', 1 do |links|
127
+ query = links.first['href'].split('?', 2)[1]
128
+ query.split('&amp;').sort.should == %w(page=2 tag=%3Cbr%3E)
129
+ end
130
+ end
131
+
132
+ ## advanced options for pagination ##
133
+
134
+ it "should be able to render without container" do
135
+ paginate({}, :container => false)
136
+ assert_select 'div.pagination', 0, 'main DIV present when it shouldn\'t'
137
+ assert_select 'a[href]', 3
138
+ end
139
+
140
+ it "should be able to render without page links" do
141
+ paginate({ :page => 2 }, :page_links => false) do
142
+ assert_select 'a[href]', 2 do |elements|
143
+ validate_page_numbers [1,3], elements
144
+ end
145
+ end
146
+ end
147
+
148
+ it "should have magic HTML ID for the container" do
149
+ paginate do |div|
150
+ div.first['id'].should be_nil
151
+ end
152
+
153
+ # magic ID
154
+ paginate({}, :id => true) do |div|
155
+ div.first['id'].should == 'fixnums_pagination'
156
+ end
157
+
158
+ # explicit ID
159
+ paginate({}, :id => 'custom_id') do |div|
160
+ div.first['id'].should == 'custom_id'
161
+ end
162
+ end
163
+
164
+ ## other helpers ##
165
+
166
+ it "should render a paginated section" do
167
+ @template = <<-ERB
168
+ <% paginated_section collection, options do %>
169
+ <%= content_tag :div, '', :id => "developers" %>
170
+ <% end %>
171
+ ERB
172
+
173
+ paginate
174
+ assert_select 'div.pagination', 2
175
+ assert_select 'div.pagination + div#developers', 1
176
+ end
177
+
178
+ ## parameter handling in page links ##
179
+
180
+ it "should preserve parameters on GET" do
181
+ request.params :foo => { :bar => 'baz' }
182
+ paginate
183
+ assert_links_match /foo%5Bbar%5D=baz/
184
+ end
185
+
186
+ it "should not preserve parameters on POST" do
187
+ request.post
188
+ request.params :foo => 'bar'
189
+ paginate
190
+ assert_no_links_match /foo=bar/
191
+ end
192
+
193
+ it "should add additional parameters to links" do
194
+ paginate({}, :params => { :foo => 'bar' })
195
+ assert_links_match /foo=bar/
196
+ end
197
+
198
+ it "should add anchor parameter" do
199
+ paginate({}, :params => { :anchor => 'anchor' })
200
+ assert_links_match /#anchor$/
201
+ end
202
+
203
+ it "should remove arbitrary parameters" do
204
+ request.params :foo => 'bar'
205
+ paginate({}, :params => { :foo => nil })
206
+ assert_no_links_match /foo=bar/
207
+ end
208
+
209
+ it "should override default route parameters" do
210
+ paginate({}, :params => { :controller => 'baz', :action => 'list' })
211
+ assert_links_match %r{\Wbaz/list\W}
212
+ end
213
+
214
+ it "should paginate with custom page parameter" do
215
+ paginate({ :page => 2 }, :param_name => :developers_page) do
216
+ assert_select 'a[href]', 4 do |elements|
217
+ validate_page_numbers [1,1,3,3], elements, :developers_page
218
+ end
219
+ end
220
+ end
221
+
222
+ it "should paginate with complex custom page parameter" do
223
+ request.params :developers => { :page => 2 }
224
+
225
+ paginate({ :page => 2 }, :param_name => 'developers[page]') do
226
+ assert_select 'a[href]', 4 do |links|
227
+ assert_links_match /\?developers%5Bpage%5D=\d+$/, links
228
+ validate_page_numbers [1,1,3,3], links, 'developers[page]'
229
+ end
230
+ end
231
+ end
232
+
233
+ it "should paginate with custom route page parameter" do
234
+ request.symbolized_path_parameters.update :controller => 'dummy', :action => nil
235
+ paginate :per_page => 2 do
236
+ assert_select 'a[href]', 6 do |links|
237
+ assert_links_match %r{/page/(\d+)$}, links, [2, 3, 4, 5, 6, 2]
238
+ end
239
+ end
240
+ end
241
+
242
+ it "should paginate with custom route with dot separator page parameter" do
243
+ request.symbolized_path_parameters.update :controller => 'dummy', :action => 'dots'
244
+ paginate :per_page => 2 do
245
+ assert_select 'a[href]', 6 do |links|
246
+ assert_links_match %r{/page\.(\d+)$}, links, [2, 3, 4, 5, 6, 2]
247
+ end
248
+ end
249
+ end
250
+
251
+ it "should paginate with custom route and first page number implicit" do
252
+ request.symbolized_path_parameters.update :controller => 'ibocorp', :action => nil
253
+ paginate :page => 2, :per_page => 2 do
254
+ assert_select 'a[href]', 7 do |links|
255
+ assert_links_match %r{/ibocorp(?:/(\d+))?$}, links, [nil, nil, 3, 4, 5, 6, 3]
256
+ end
257
+ end
258
+ end
259
+
260
+ ## internal hardcore stuff ##
261
+
262
+ it "should be able to guess the collection name" do
263
+ collection = mock
264
+ collection.expects(:total_pages).returns(1)
265
+
266
+ @template = '<%= will_paginate options %>'
267
+ @view.controller.controller_name = 'developers'
268
+ @view.assigns['developers'] = collection
269
+
270
+ paginate(nil)
271
+ end
272
+
273
+ it "should fail if the inferred collection is nil" do
274
+ @template = '<%= will_paginate options %>'
275
+ @view.controller.controller_name = 'developers'
276
+
277
+ lambda {
278
+ paginate(nil)
279
+ }.should raise_error(ArgumentError, /@developers/)
280
+ end
281
+
282
+ if ActionController::Base.respond_to? :rescue_responses
283
+ # only on Rails 2
284
+ it "should set rescue response hook" do
285
+ ActionController::Base.rescue_responses['WillPaginate::InvalidPage'].should == :not_found
286
+ end
287
+ end
288
+ end
289
+
290
+ class AdditionalLinkAttributesRenderer < WillPaginate::ViewHelpers::LinkRenderer
291
+ def initialize(link_attributes = nil)
292
+ super()
293
+ @additional_link_attributes = link_attributes || { :default => 'true' }
294
+ end
295
+
296
+ def link(text, target, attributes = {})
297
+ super(text, target, attributes.merge(@additional_link_attributes))
298
+ end
299
+ end
300
+
301
+ class DummyController
302
+ attr_reader :request
303
+ attr_accessor :controller_name
304
+
305
+ def initialize
306
+ @request = DummyRequest.new
307
+ @url = ActionController::UrlRewriter.new(@request, @request.params)
308
+ end
309
+
310
+ def params
311
+ @request.params
312
+ end
313
+
314
+ def url_for(params)
315
+ @url.rewrite(params)
316
+ end
317
+ end
318
+
319
+ class DummyRequest
320
+ attr_accessor :symbolized_path_parameters
321
+
322
+ def initialize
323
+ @get = true
324
+ @params = {}
325
+ @symbolized_path_parameters = { :controller => 'foo', :action => 'bar' }
326
+ end
327
+
328
+ def get?
329
+ @get
330
+ end
331
+
332
+ def post
333
+ @get = false
334
+ end
335
+
336
+ def relative_url_root
337
+ ''
338
+ end
339
+
340
+ def params(more = nil)
341
+ @params.update(more) if more
342
+ @params
343
+ end
344
+ end