omghax-test_rails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -0
- data/Manifest.txt +21 -0
- data/README.txt +110 -0
- data/Rakefile +13 -0
- data/lib/test/rails/controller_test_case.rb +382 -0
- data/lib/test/rails/functional_test_case.rb +79 -0
- data/lib/test/rails/helper_test_case.rb +64 -0
- data/lib/test/rails/ivar_proxy.rb +31 -0
- data/lib/test/rails/pp_html_document.rb +74 -0
- data/lib/test/rails/rake_tasks.rb +50 -0
- data/lib/test/rails/render_tree.rb +93 -0
- data/lib/test/rails/test_case.rb +28 -0
- data/lib/test/rails/version.rb +11 -0
- data/lib/test/rails/view_test_case.rb +597 -0
- data/lib/test/rails.rb +295 -0
- data/lib/test/zentest_assertions.rb +134 -0
- data/test/test_help.rb +36 -0
- data/test/test_rails_controller_test_case.rb +58 -0
- data/test/test_rails_helper_test_case.rb +48 -0
- data/test/test_rails_view_test_case.rb +275 -0
- data/test/test_zentest_assertions.rb +128 -0
- metadata +94 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
lib/test/rails.rb
|
6
|
+
lib/test/rails/controller_test_case.rb
|
7
|
+
lib/test/rails/functional_test_case.rb
|
8
|
+
lib/test/rails/helper_test_case.rb
|
9
|
+
lib/test/rails/ivar_proxy.rb
|
10
|
+
lib/test/rails/pp_html_document.rb
|
11
|
+
lib/test/rails/rake_tasks.rb
|
12
|
+
lib/test/rails/render_tree.rb
|
13
|
+
lib/test/rails/test_case.rb
|
14
|
+
lib/test/rails/version.rb
|
15
|
+
lib/test/rails/view_test_case.rb
|
16
|
+
lib/test/zentest_assertions.rb
|
17
|
+
test/test_help.rb
|
18
|
+
test/test_rails_controller_test_case.rb
|
19
|
+
test/test_rails_helper_test_case.rb
|
20
|
+
test/test_rails_view_test_case.rb
|
21
|
+
test/test_zentest_assertions.rb
|
data/README.txt
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
= ZenTest
|
2
|
+
|
3
|
+
* http://www.zenspider.com/ZSS/Products/ZenTest/
|
4
|
+
* http://rubyforge.org/projects/zentest/
|
5
|
+
* mailto:ryand-ruby@zenspider.com
|
6
|
+
|
7
|
+
== DESCRIPTION
|
8
|
+
|
9
|
+
ZenTest provides 4 different tools and 1 library: zentest, unit_diff,
|
10
|
+
autotest, multiruby, and Test::Rails.
|
11
|
+
|
12
|
+
ZenTest scans your target and unit-test code and writes your missing
|
13
|
+
code based on simple naming rules, enabling XP at a much quicker
|
14
|
+
pace. ZenTest only works with Ruby and Test::Unit.
|
15
|
+
|
16
|
+
unit_diff is a command-line filter to diff expected results from
|
17
|
+
actual results and allow you to quickly see exactly what is wrong.
|
18
|
+
|
19
|
+
autotest is a continous testing facility meant to be used during
|
20
|
+
development. As soon as you save a file, autotest will run the
|
21
|
+
corresponding dependent tests.
|
22
|
+
|
23
|
+
multiruby runs anything you want on multiple versions of ruby. Great
|
24
|
+
for compatibility checking! Use multiruby_setup to manage your
|
25
|
+
installed versions.
|
26
|
+
|
27
|
+
Test::Rails helps you build industrial-strength Rails code.
|
28
|
+
|
29
|
+
== STRATEGERY
|
30
|
+
|
31
|
+
There are two strategeries intended for ZenTest: test conformance
|
32
|
+
auditing and rapid XP.
|
33
|
+
|
34
|
+
For auditing, ZenTest provides an excellent means of finding methods
|
35
|
+
that have slipped through the testing process. I've run it against my
|
36
|
+
own software and found I missed a lot in a well tested
|
37
|
+
package. Writing those tests found 4 bugs I had no idea existed.
|
38
|
+
|
39
|
+
ZenTest can also be used to evaluate generated code and execute your
|
40
|
+
tests, allowing for very rapid development of both tests and
|
41
|
+
implementation.
|
42
|
+
|
43
|
+
== FEATURES
|
44
|
+
|
45
|
+
* Scans your ruby code and tests and generates missing methods for you.
|
46
|
+
* Includes a very helpful filter for Test::Unit output called unit_diff.
|
47
|
+
* Continually and intelligently test only those files you change with autotest.
|
48
|
+
* Test against multiple versions with multiruby.
|
49
|
+
* Enhance and automatically audit your rails tests using Test::Rails.
|
50
|
+
* Includes a LinuxJournal article on testing with ZenTest written by Pat Eyler.
|
51
|
+
* See also: http://blog.zenspider.com/archives/zentest/
|
52
|
+
* See also: http://blog.segment7.net/articles/category/zentest
|
53
|
+
|
54
|
+
== SYNOPSYS
|
55
|
+
|
56
|
+
ZenTest MyProject.rb TestMyProject.rb > missing.rb
|
57
|
+
|
58
|
+
./TestMyProject.rb | unit_diff
|
59
|
+
|
60
|
+
autotest
|
61
|
+
|
62
|
+
multiruby_setup mri:svn:current
|
63
|
+
multiruby ./TestMyProject.rb
|
64
|
+
|
65
|
+
(and other stuff for Test::Rails)
|
66
|
+
|
67
|
+
== REQUIREMENTS
|
68
|
+
|
69
|
+
* Ruby 1.6+, JRuby 1.1.2+, or rubinius
|
70
|
+
* Test::Unit or miniunit
|
71
|
+
* Hoe
|
72
|
+
* rubygems
|
73
|
+
* diff.exe on windoze. Try http://gnuwin32.sourceforge.net/packages.html
|
74
|
+
|
75
|
+
== INSTALL
|
76
|
+
|
77
|
+
Using Rubygems:
|
78
|
+
|
79
|
+
* sudo gem install ZenTest
|
80
|
+
|
81
|
+
Using Rake:
|
82
|
+
|
83
|
+
* rake test
|
84
|
+
* sudo rake install
|
85
|
+
|
86
|
+
== LICENSE
|
87
|
+
|
88
|
+
(The MIT License)
|
89
|
+
|
90
|
+
Copyright (c) 2001-2006 Ryan Davis, Eric Hodel, Zen Spider Software
|
91
|
+
|
92
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
93
|
+
a copy of this software and associated documentation files (the
|
94
|
+
"Software"), to deal in the Software without restriction, including
|
95
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
96
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
97
|
+
permit persons to whom the Software is furnished to do so, subject to
|
98
|
+
the following conditions:
|
99
|
+
|
100
|
+
The above copyright notice and this permission notice shall be
|
101
|
+
included in all copies or substantial portions of the Software.
|
102
|
+
|
103
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
104
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
105
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
106
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
107
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
108
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
109
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
110
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/test/rails/version.rb'
|
6
|
+
|
7
|
+
Hoe.new('test_rails', Test::Rails::VERSION::STRING) do |test_rails|
|
8
|
+
test_rails.developer('Ryan Davis', 'ryand-ruby@zenspider.com')
|
9
|
+
test_rails.developer('Eric Hodel', 'drbrain@segment7.net')
|
10
|
+
test_rails.developer('Dray Lacy', 'dray@izea.com')
|
11
|
+
end
|
12
|
+
|
13
|
+
# vim: syntax=Ruby
|
@@ -0,0 +1,382 @@
|
|
1
|
+
##
|
2
|
+
# ControllerTestCase allows controllers to be tested independent of their
|
3
|
+
# views.
|
4
|
+
#
|
5
|
+
# = Features
|
6
|
+
#
|
7
|
+
# * ActionMailer is already set up for you.
|
8
|
+
# * The session and flash accessors work on both sides of get/post/etc.
|
9
|
+
# * Optional automatic auditing for missing assert_assigns. See
|
10
|
+
# util_audit_assert_assigned
|
11
|
+
#
|
12
|
+
# = Naming
|
13
|
+
#
|
14
|
+
# The test class must be named after your controller class name, so if
|
15
|
+
# you're testing actions for the +RouteController+ you would name your
|
16
|
+
# test case +RouteControllerTest+.
|
17
|
+
#
|
18
|
+
# The test names should be in the form of +test_action_edgecase+ where
|
19
|
+
# 'action' corresponds to the name of the controller action, and
|
20
|
+
# 'edgecase' describes the scenario you are testing.
|
21
|
+
#
|
22
|
+
# If you are testing an action named 'show' your test should be named
|
23
|
+
# +test_show+. If your action behaves differently depending upon its
|
24
|
+
# arguments then you can make the test name descriptive like
|
25
|
+
# +test_show_photos+ and +test_show_no_photos+.
|
26
|
+
#
|
27
|
+
# = Examples
|
28
|
+
#
|
29
|
+
# == Typical Controller Test
|
30
|
+
#
|
31
|
+
# class RouteControllerTest < Test::Rails::ControllerTestCase
|
32
|
+
#
|
33
|
+
# fixtures :users, :routes, :points, :photos
|
34
|
+
#
|
35
|
+
# def test_delete
|
36
|
+
# # Store current count
|
37
|
+
# count = Route.count
|
38
|
+
# # Set up our environment
|
39
|
+
# session[:username] = users(:herbert).username
|
40
|
+
#
|
41
|
+
# # perform the delete action
|
42
|
+
# get :delete, :id => routes(:work).id
|
43
|
+
#
|
44
|
+
# # Assert we got a 200
|
45
|
+
# assert_response :success
|
46
|
+
# # Assert controller deleted route
|
47
|
+
# assert_equal count-1, Route.count
|
48
|
+
# # Ensure that @action_title is set properly
|
49
|
+
# assert_assigned :action_title, "Deleting \"#{routes(:work).name}\""
|
50
|
+
# # Ensure that @route is set properly
|
51
|
+
# assert_assigned :route, routes(:work)
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# == ActionMailer Test
|
57
|
+
#
|
58
|
+
# class ApplicationController < ActionController::Base
|
59
|
+
#
|
60
|
+
# ##
|
61
|
+
# # Send an email when we get an unhandled exception.
|
62
|
+
#
|
63
|
+
# def log_error(exception)
|
64
|
+
# case exception
|
65
|
+
# when ::ActionController::RoutingError,
|
66
|
+
# ::ActionController::UnknownAction,
|
67
|
+
# ::ActiveRecord::RecordNotFound then
|
68
|
+
# # ignore
|
69
|
+
# else
|
70
|
+
# unless RAILS_ENV == 'development' then
|
71
|
+
# Email.deliver_error exception, params, session, @request.env
|
72
|
+
# end
|
73
|
+
# end
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# ##
|
79
|
+
# # Dummy Controller just for testing.
|
80
|
+
#
|
81
|
+
# class DummyController < ApplicationController
|
82
|
+
#
|
83
|
+
# def error
|
84
|
+
# # Simulate a bug in our application
|
85
|
+
# raise RuntimeError
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# class DummyControllerTest < Test::Rails::ControllerTestCase
|
91
|
+
#
|
92
|
+
# def test_error_email
|
93
|
+
# # The rescue_action added by ControllerTestCase needs to be removed so
|
94
|
+
# # that exceptions fall through to the real error handler
|
95
|
+
# @controller.class.send :remove_method, :rescue_action
|
96
|
+
#
|
97
|
+
# # Fire off a request
|
98
|
+
# get :error
|
99
|
+
#
|
100
|
+
# # We should get a 500
|
101
|
+
# assert_response 500
|
102
|
+
#
|
103
|
+
# # And one delivered email
|
104
|
+
# assert_equal 1, @deliveries.length, 'error email sent'
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
#--
|
110
|
+
# TODO: Ensure that assert_tag doesn't work
|
111
|
+
# TODO: Cookie input.
|
112
|
+
|
113
|
+
class Test::Rails::ControllerTestCase < Test::Rails::FunctionalTestCase
|
114
|
+
|
115
|
+
self.use_transactional_fixtures = true
|
116
|
+
self.use_instantiated_fixtures = false
|
117
|
+
|
118
|
+
NOTHING = Object.new # :nodoc:
|
119
|
+
|
120
|
+
DEFAULT_ASSIGNS = %w[
|
121
|
+
_cookies _flash _headers _params _request _response _session
|
122
|
+
|
123
|
+
cookies flash headers params request response session
|
124
|
+
|
125
|
+
action_name
|
126
|
+
before_filter_chain_aborted
|
127
|
+
db_rt_after_render
|
128
|
+
db_rt_before_render
|
129
|
+
ignore_missing_templates
|
130
|
+
loggedin_user
|
131
|
+
logger
|
132
|
+
rendering_runtime
|
133
|
+
request_origin
|
134
|
+
template
|
135
|
+
template_class
|
136
|
+
template_root
|
137
|
+
url
|
138
|
+
user
|
139
|
+
variables_added
|
140
|
+
]
|
141
|
+
|
142
|
+
def setup
|
143
|
+
return if self.class == Test::Rails::ControllerTestCase
|
144
|
+
|
145
|
+
@controller_class_name ||= self.class.name.sub 'Test', ''
|
146
|
+
|
147
|
+
super
|
148
|
+
|
149
|
+
@controller_class.send(:define_method, :rescue_action) { |e| raise e }
|
150
|
+
|
151
|
+
@deliveries = []
|
152
|
+
ActionMailer::Base.deliveries = @deliveries
|
153
|
+
|
154
|
+
# used by util_audit_assert_assigns
|
155
|
+
@assigns_asserted = []
|
156
|
+
@assigns_ignored ||= [] # untested assigns to ignore
|
157
|
+
end
|
158
|
+
|
159
|
+
##
|
160
|
+
# Excutes the request +action+ with +params+.
|
161
|
+
#
|
162
|
+
# See also: get, post, put, delete, head, xml_http_request
|
163
|
+
|
164
|
+
def process(action, parameters = nil)
|
165
|
+
parameters ||= {}
|
166
|
+
|
167
|
+
@request.recycle!
|
168
|
+
@request.env['REQUEST_METHOD'] ||= 'GET'
|
169
|
+
@request.action = action.to_s
|
170
|
+
|
171
|
+
@request.assign_parameters @controller_class.controller_path, action.to_s,
|
172
|
+
parameters
|
173
|
+
|
174
|
+
build_request_uri action, parameters
|
175
|
+
|
176
|
+
@controller.process @request, @response
|
177
|
+
end
|
178
|
+
|
179
|
+
##
|
180
|
+
# Performs a GET request on +action+ with +params+.
|
181
|
+
|
182
|
+
def get(action, parameters = nil)
|
183
|
+
@request.env['REQUEST_METHOD'] = 'GET'
|
184
|
+
process action, parameters
|
185
|
+
end
|
186
|
+
|
187
|
+
##
|
188
|
+
# Performs a HEAD request on +action+ with +params+.
|
189
|
+
|
190
|
+
def head(action, parameters = nil)
|
191
|
+
@request.env['REQUEST_METHOD'] = 'HEAD'
|
192
|
+
process action, parameters
|
193
|
+
end
|
194
|
+
|
195
|
+
##
|
196
|
+
# Performs a POST request on +action+ with +params+.
|
197
|
+
|
198
|
+
def post(action, parameters = nil)
|
199
|
+
@request.env['REQUEST_METHOD'] = 'POST'
|
200
|
+
process action, parameters
|
201
|
+
end
|
202
|
+
|
203
|
+
##
|
204
|
+
# Performs a PUT request on +action+ with +params+.
|
205
|
+
|
206
|
+
def put(action, parameters = nil)
|
207
|
+
@request.env['REQUEST_METHOD'] = 'PUT'
|
208
|
+
process action, parameters
|
209
|
+
end
|
210
|
+
|
211
|
+
##
|
212
|
+
# Performs a DELETE request on +action+ with +params+.
|
213
|
+
|
214
|
+
def delete(action, parameters = nil)
|
215
|
+
@request.env['REQUEST_METHOD'] = 'DELETE'
|
216
|
+
process action, parameters
|
217
|
+
end
|
218
|
+
|
219
|
+
##
|
220
|
+
# Performs a XMLHttpRequest request using +request_method+ on +action+ with
|
221
|
+
# +params+.
|
222
|
+
|
223
|
+
def xml_http_request(request_method, action, parameters = nil)
|
224
|
+
@request.env['REQUEST_METHOD'] = request_method.to_s
|
225
|
+
|
226
|
+
@request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
|
227
|
+
@request.env['HTTP_ACCEPT'] = 'text/javascript, text/html, application/xml, text/xml, */*'
|
228
|
+
|
229
|
+
result = process action, parameters
|
230
|
+
|
231
|
+
@request.env.delete 'HTTP_X_REQUESTED_WITH'
|
232
|
+
@request.env.delete 'HTTP_ACCEPT'
|
233
|
+
|
234
|
+
return result
|
235
|
+
end
|
236
|
+
|
237
|
+
##
|
238
|
+
# Friendly alias for xml_http_request
|
239
|
+
|
240
|
+
alias xhr xml_http_request
|
241
|
+
|
242
|
+
##
|
243
|
+
# Asserts that the assigns variable +ivar+ is assigned to +value+. If
|
244
|
+
# +value+ is omitted, asserts that assigns variable +ivar+ exists.
|
245
|
+
|
246
|
+
def assert_assigned(ivar, value = NOTHING)
|
247
|
+
ivar = ivar.to_s
|
248
|
+
@assigns_asserted << ivar
|
249
|
+
assert_includes assigns, ivar, "#{ivar.inspect} missing from assigns"
|
250
|
+
unless value.equal? NOTHING then
|
251
|
+
assert_equal value, assigns[ivar],
|
252
|
+
"assert_assigned #{ivar.intern.inspect}"
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
##
|
257
|
+
# Asserts the response content type matches +type+.
|
258
|
+
|
259
|
+
def assert_content_type(type, message = nil)
|
260
|
+
assert_equal type, @response.headers['Content-Type'], message
|
261
|
+
end
|
262
|
+
|
263
|
+
##
|
264
|
+
# Asserts that +key+ of flash has +content+. If +content+ is a Regexp, then
|
265
|
+
# the assertion will fail if the Regexp does not match.
|
266
|
+
#
|
267
|
+
# controller:
|
268
|
+
# flash[:notice] = 'Please log in'
|
269
|
+
#
|
270
|
+
# test:
|
271
|
+
# assert_flash :notice, 'Please log in'
|
272
|
+
|
273
|
+
def assert_flash(key, content)
|
274
|
+
assert flash.include?(key),
|
275
|
+
"#{key.inspect} missing from flash, has #{flash.keys.inspect}"
|
276
|
+
|
277
|
+
case content
|
278
|
+
when Regexp then
|
279
|
+
assert_match content, flash[key],
|
280
|
+
"Content of flash[#{key.inspect}] did not match"
|
281
|
+
else
|
282
|
+
assert_equal content, flash[key],
|
283
|
+
"Incorrect content in flash[#{key.inspect}]"
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
##
|
288
|
+
# Asserts that the assigns variable +ivar+ is not set.
|
289
|
+
|
290
|
+
def deny_assigned(ivar)
|
291
|
+
ivar = ivar.to_s
|
292
|
+
deny_includes assigns, ivar
|
293
|
+
end
|
294
|
+
|
295
|
+
##
|
296
|
+
# Checks your assert_assigned tests against the instance variables in
|
297
|
+
# assigns. Fails if the two don't match.
|
298
|
+
#
|
299
|
+
# Add util_audit_assert_assigned to your teardown. If you have instance
|
300
|
+
# variables that you don't need to set (for example, were set in a
|
301
|
+
# before_filter in ApplicationController) then add them to the
|
302
|
+
# @assigns_ignored instance variable in your setup.
|
303
|
+
#
|
304
|
+
# = Example
|
305
|
+
#
|
306
|
+
# == Controller method
|
307
|
+
#
|
308
|
+
# class UserController < ApplicationController
|
309
|
+
# def new
|
310
|
+
# # ...
|
311
|
+
#
|
312
|
+
# @login_form = false
|
313
|
+
# end
|
314
|
+
# end
|
315
|
+
#
|
316
|
+
# == Test setup:
|
317
|
+
#
|
318
|
+
# class UserControllerTest < Test::Rails::ControllerTestCase
|
319
|
+
#
|
320
|
+
# def teardown
|
321
|
+
# super
|
322
|
+
# util_audit_assert_assigned
|
323
|
+
# end
|
324
|
+
#
|
325
|
+
# def test_new
|
326
|
+
# get :new
|
327
|
+
#
|
328
|
+
# assert_response :success
|
329
|
+
# # no assert_assigns for @login_form
|
330
|
+
# end
|
331
|
+
#
|
332
|
+
# end
|
333
|
+
#
|
334
|
+
# == Output
|
335
|
+
# 1) Failure:
|
336
|
+
# test_new(UserControllerTest)
|
337
|
+
# [[...]/controller_test_case.rb:331:in `util_audit_assert_assigned'
|
338
|
+
# [...]/user_controller_test.rb:14:in `teardown_without_fixtures'
|
339
|
+
# [...]fixtures.rb:555:in `teardown']:
|
340
|
+
# You are missing these assert_assigned assertions:
|
341
|
+
# assert_assigned :login_form #, some_value
|
342
|
+
# .
|
343
|
+
|
344
|
+
def util_audit_assert_assigned
|
345
|
+
return unless @test_passed
|
346
|
+
return unless @controller.send :performed?
|
347
|
+
all_assigns = assigns.keys.sort
|
348
|
+
|
349
|
+
assigns_ignored = DEFAULT_ASSIGNS | @assigns_ignored
|
350
|
+
assigns_ignored = assigns_ignored.map { |a| a.to_s }
|
351
|
+
|
352
|
+
assigns_created = all_assigns - assigns_ignored
|
353
|
+
assigns_asserted = @assigns_asserted - assigns_ignored
|
354
|
+
|
355
|
+
assigns_missing = assigns_created - assigns_asserted
|
356
|
+
|
357
|
+
return if assigns_missing.empty?
|
358
|
+
|
359
|
+
message = []
|
360
|
+
message << "You are missing these assert_assigned assertions:"
|
361
|
+
assigns_missing.sort.each do |ivar|
|
362
|
+
message << " assert_assigned #{ivar.intern.inspect} #, :some_value"
|
363
|
+
end
|
364
|
+
message << nil # stupid '.'
|
365
|
+
|
366
|
+
flunk message.join("\n")
|
367
|
+
end
|
368
|
+
|
369
|
+
private
|
370
|
+
|
371
|
+
def build_request_uri(action, parameters)
|
372
|
+
return if @request.env['REQUEST_URI']
|
373
|
+
|
374
|
+
options = @controller.send :rewrite_options, parameters
|
375
|
+
options.update :only_path => true, :action => action
|
376
|
+
|
377
|
+
url = ActionController::UrlRewriter.new @request, parameters
|
378
|
+
@request.set_REQUEST_URI url.rewrite(options)
|
379
|
+
end
|
380
|
+
|
381
|
+
end
|
382
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
$TESTING_RTC = defined?($TESTING_RTC) && $TESTING_RTC
|
2
|
+
|
3
|
+
##
|
4
|
+
# FunctionalTestCase is an abstract class that sets up a controller instance
|
5
|
+
# for its subclasses.
|
6
|
+
|
7
|
+
class Test::Rails::FunctionalTestCase < Test::Rails::TestCase
|
8
|
+
|
9
|
+
self.use_transactional_fixtures = true
|
10
|
+
self.use_instantiated_fixtures = false
|
11
|
+
|
12
|
+
##
|
13
|
+
# Sets up instance variables to allow tests depending on a controller work.
|
14
|
+
#
|
15
|
+
# setup uses the instance variable @controller_class_name to determine which
|
16
|
+
# controller class to instantiate.
|
17
|
+
#
|
18
|
+
# setup also instantiates a new @request and @response object.
|
19
|
+
#
|
20
|
+
# If you need to perform extra setup actions, define #setup_extra and
|
21
|
+
# FunctionalTestCase will call it after performing the rest of its setup
|
22
|
+
# actions.
|
23
|
+
|
24
|
+
def setup
|
25
|
+
return if self.class.name =~ /TestCase$/ and not $TESTING_RTC
|
26
|
+
super
|
27
|
+
|
28
|
+
@controller_class = Object.path2class @controller_class_name
|
29
|
+
raise "Can't determine controller class for #{self.class}" if @controller_class.nil?
|
30
|
+
|
31
|
+
@controller = @controller_class.new
|
32
|
+
|
33
|
+
@session = ActionController::TestSession.new
|
34
|
+
|
35
|
+
@flash = ActionController::Flash::FlashHash.new
|
36
|
+
@session['flash'] = @flash
|
37
|
+
|
38
|
+
@request = ActionController::TestRequest.new
|
39
|
+
@request.session = @session
|
40
|
+
|
41
|
+
# HACK There's probably an official way to do this
|
42
|
+
@controller.instance_variable_set :@_session, @request.session
|
43
|
+
|
44
|
+
@response = ActionController::TestResponse.new
|
45
|
+
|
46
|
+
setup_extra if respond_to? :setup_extra
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Flash accessor. The flash can be assigned to before calling process or
|
51
|
+
# render and it will Just Work (yay!)
|
52
|
+
#
|
53
|
+
# view:
|
54
|
+
# <div class="error"><%= flash[:error] %></div>
|
55
|
+
#
|
56
|
+
# test:
|
57
|
+
# flash[:error] = 'You did a bad thing.'
|
58
|
+
# render
|
59
|
+
# assert_tag :tag => 'div', :attributes => { :class => 'error' },
|
60
|
+
# :content => 'You did a bad thing.'
|
61
|
+
|
62
|
+
attr_reader :flash
|
63
|
+
|
64
|
+
##
|
65
|
+
# Session accessor. The session can be assigned to before calling process
|
66
|
+
# or render and it will Just Work (yay!)
|
67
|
+
#
|
68
|
+
# test:
|
69
|
+
#
|
70
|
+
# def test_logout
|
71
|
+
# session[:user] = users(:herbert)
|
72
|
+
# post :logout
|
73
|
+
# assert_equal nil, session[:user]
|
74
|
+
# end
|
75
|
+
|
76
|
+
attr_reader :session
|
77
|
+
|
78
|
+
end
|
79
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
##
|
2
|
+
# Stub controller for testing helpers.
|
3
|
+
|
4
|
+
class HelperTestCaseController < ApplicationController
|
5
|
+
|
6
|
+
attr_accessor :request
|
7
|
+
|
8
|
+
attr_accessor :url
|
9
|
+
|
10
|
+
##
|
11
|
+
# Re-raise errors
|
12
|
+
|
13
|
+
def rescue_action(e)
|
14
|
+
raise e
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# HelperTestCase allows helpers to be easily tested.
|
21
|
+
#
|
22
|
+
# Original concept by Ryan Davis, original implementation by Geoff Grosenbach.
|
23
|
+
|
24
|
+
class Test::Rails::HelperTestCase < Test::Rails::FunctionalTestCase
|
25
|
+
|
26
|
+
self.use_transactional_fixtures = true
|
27
|
+
self.use_instantiated_fixtures = false
|
28
|
+
|
29
|
+
# Are other helpers needed?
|
30
|
+
|
31
|
+
include ActionView::Helpers::ActiveRecordHelper
|
32
|
+
include ActionView::Helpers::TagHelper
|
33
|
+
include ActionView::Helpers::FormTagHelper
|
34
|
+
include ActionView::Helpers::FormOptionsHelper
|
35
|
+
include ActionView::Helpers::FormHelper
|
36
|
+
include ActionView::Helpers::UrlHelper
|
37
|
+
include ActionView::Helpers::AssetTagHelper
|
38
|
+
include ActionView::Helpers::PrototypeHelper rescue nil # Rails 1.0 only
|
39
|
+
include ActionView::Helpers::TextHelper
|
40
|
+
|
41
|
+
##
|
42
|
+
# Automatically includes the helper module into the test sublcass.
|
43
|
+
|
44
|
+
def self.inherited(helper_testcase)
|
45
|
+
super
|
46
|
+
helper_name = helper_testcase.name.sub 'Test', ''
|
47
|
+
helper_module = Object.path2class helper_name
|
48
|
+
helper_testcase.send :include, helper_module
|
49
|
+
rescue NameError
|
50
|
+
raise "Unable to find helper #{helper_name}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def setup
|
54
|
+
return if self.class.name =~ /TestCase$/
|
55
|
+
@controller_class_name = 'HelperTestCaseController'
|
56
|
+
super
|
57
|
+
@controller.request = @request
|
58
|
+
@controller.url = ActionController::UrlRewriter.new @request, {} # url_for
|
59
|
+
|
60
|
+
ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test/rails'
|
2
|
+
|
3
|
+
##
|
4
|
+
# A wrapper that allows instance variables to be manipulated using +[]+ and
|
5
|
+
# +[]=+
|
6
|
+
|
7
|
+
class Test::Rails::IvarProxy
|
8
|
+
|
9
|
+
##
|
10
|
+
# Wraps +object+ allowing its instance variables to be manipulated.
|
11
|
+
|
12
|
+
def initialize(object)
|
13
|
+
@object = object
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Retrieves +ivar+ from the wrapped object.
|
18
|
+
|
19
|
+
def [](ivar)
|
20
|
+
@object.instance_variable_get "@#{ivar}"
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Sets +ivar+ to +val+ on the wrapped object.
|
25
|
+
|
26
|
+
def []=(ivar, val)
|
27
|
+
@object.instance_variable_set "@#{ivar}", val
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|