omghax-test_rails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/test/rails.rb ADDED
@@ -0,0 +1,295 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'rubygems/version'
4
+ require 'test_help' # hopefully temporary, required for Test::Rails to work
5
+ # until we get rid of test_help so Test::Unit::TestCase
6
+ # is kept virgin.
7
+ require 'rails/version' unless defined? Rails::VERSION
8
+
9
+ $TESTING = true
10
+
11
+ ##
12
+ # = Introduction
13
+ #
14
+ # Test::Rails helps you build industrial-strength Rails code by:
15
+ # * testing views separate from controllers
16
+ # * enhancing the assertion vocabulary, and
17
+ # * auditing your tests for consistency.
18
+ #
19
+ # = Details
20
+ #
21
+ # Test::Rails:
22
+ # * splits Functional test into Controller and View tests.
23
+ # * Splits view assertions away from controller assertions.
24
+ # * Helps decouple views from controllers.
25
+ # * Allows you to test AJAX actions in isolation.
26
+ # * Allows you to test a single partial.
27
+ # * Clearer failures when assert_tag fails.
28
+ # * An auditing script analyzes missing assertions in your controllers and
29
+ # views.
30
+ # * Library of assertions for testing views.
31
+ #
32
+ # = How to Convert to Test::Rails
33
+ #
34
+ # You will need to make three small changes to test/test_helper.rb to set up
35
+ # Test::Rails:
36
+ #
37
+ # First, add the following to 'test/test_helper.rb' before you require
38
+ # +test_help+:
39
+ #
40
+ # require 'test/rails'
41
+ #
42
+ # Next, change the class from "Unit" to "Rails" right after you
43
+ # require +test_help+.
44
+ #
45
+ # Your 'test/test_helper.rb' will end up looking like this:
46
+ #
47
+ # ENV["RAILS_ENV"] = "test"
48
+ # require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
49
+ # require 'test/rails'
50
+ # require 'test_help'
51
+ #
52
+ # class Test::Rails::TestCase
53
+ # ...
54
+ #
55
+ # Finally, you need to add the extra rake tasks Test::Rails provides.
56
+ # Add the following line to your Rakefile after you require
57
+ # 'tasks/rails':
58
+ #
59
+ # require 'test/rails/rake_tasks'
60
+ #
61
+ # *NOTE*:
62
+ #
63
+ # * get/post/etc. no longer have a session or flash argument. Use the session
64
+ # and flash accessor instead.
65
+ # * assert_tag will (eventually) not work in controller tests.
66
+ #
67
+ # == Writing View Tests
68
+ #
69
+ # View tests live in test/views. They are named after the controller that is
70
+ # being tested. For exampe, RouteViewTest will live in the file
71
+ # test/views/route_view_test.rb.
72
+ #
73
+ # === Example View Test Case
74
+ #
75
+ # require 'test/test_helper'
76
+ #
77
+ # # We are testing RouteController's views
78
+ # class RouteViewTest < Test::Rails::ViewTestCase
79
+ #
80
+ # fixtures :users, :routes, :points, :photos
81
+ #
82
+ # # testing the view for the delete action of RouteController
83
+ # def test_delete
84
+ # # Instance variables necessary for this view
85
+ # assigns[:loggedin_user] = users(:herbert)
86
+ # assigns[:route] = routes(:work)
87
+ #
88
+ # # render this view
89
+ # render
90
+ #
91
+ # # assert everything is as it should be
92
+ # assert_links_to "/route/flickr_refresh/#{routes(:work).id}"
93
+ #
94
+ # form_url = '/route/destroy'
95
+ # assert_post_form form_url
96
+ # assert_input form_url, :hidden, :id
97
+ # assert_submit form_url, 'Delete!'
98
+ # assert_links_to "/route/show/#{routes(:work).id}", 'No, I do not!'
99
+ # end
100
+ #
101
+ # # ...
102
+ #
103
+ # end
104
+ #
105
+ # All view tests are a subclass of Test::Rails::ViewTestCase. The name of the
106
+ # subclass must match the controller this view depends upon. ViewTestCase
107
+ # takes care of all the setup necessary for running the tests.
108
+ #
109
+ # The +test_delete+ method is named after the delete method in
110
+ # RouteController. The ViewTestCase#render method looks at the name of the
111
+ # test and tries to figure out which view file to use, so naming tests after
112
+ # actions will save you headaches and typing.
113
+ #
114
+ # Use +assigns+ to set up the variables the view will use when it renders.
115
+ #
116
+ # The call to render is the equivalent to a functional tests' get/post
117
+ # methods. It makes several assumptions, so be sure to read
118
+ # ViewTestCase#render carefully.
119
+ #
120
+ # ViewTestCase has a vastly expanded assertion library to help you out with
121
+ # testing. See ViewTestCase for all the helpful assertions you can use in
122
+ # your view tests.
123
+ #
124
+ # == Writing Controller Tests
125
+ #
126
+ # Controller tests are essentially functional tests without the view assertions.
127
+ #
128
+ # They live in test/controllers, subclass ControllerTestCase, and are
129
+ # named after the controller they are testing. For example,
130
+ # RouteControllerTest will live in the file
131
+ # test/controllers/route_controller_test.rb.
132
+ #
133
+ # === Example Controller Test Case
134
+ #
135
+ # require 'test/test_helper'
136
+ #
137
+ # # We are testing RouteController's actions
138
+ # class RouteControllerTest < Test::Rails::ControllerTestCase
139
+ #
140
+ # fixtures :users, :routes, :points, :photos
141
+ #
142
+ # # Testing the delete method
143
+ # def test_delete
144
+ # # A session accessor is provided instead of passing a hash to get.
145
+ # session[:username] = users(:herbert).username
146
+ #
147
+ # get :delete, :id => routes(:work).id
148
+ #
149
+ # # assert we got a 200
150
+ # assert_success
151
+ #
152
+ # # assert that instance variables are correctly assigned
153
+ # assert_assigned :action_title, "Deleting \"#{routes(:work).name}\""
154
+ # assert_assigned :route, routes(:work)
155
+ # end
156
+ #
157
+ # # ...
158
+ #
159
+ # end
160
+ #
161
+ # == Writing Abstract Test Cases
162
+ #
163
+ # Abstract test cases are a great way to refactor your tests and
164
+ # ensure you do not violate the DRY principal and share code between
165
+ # different test classes. If you have common setup code for your test
166
+ # classes you can create your own subclass of ControllerTestCase or
167
+ # ViewTestCase.
168
+ #
169
+ # === Example Abstract Test Case
170
+ #
171
+ # class RobotControllerTestCase < Test::Rails::ControllerTestCase
172
+ #
173
+ # fixtures :markets, :people
174
+ #
175
+ # def setup
176
+ # super
177
+ #
178
+ # # We're running tests in this class so we don't need to do any more
179
+ # # setup
180
+ # return if self.class == RobotControllerTestCase
181
+ #
182
+ # # Set our current host
183
+ # @host = 'www.test.robotcoop.com'
184
+ # util_set_host @host
185
+ # end
186
+ #
187
+ # ##
188
+ # # Sets the hostname to +host+ for this request.
189
+ #
190
+ # def util_set_host(hoston)
191
+ # @request.host = host
192
+ # end
193
+ #
194
+ # end
195
+ #
196
+ # = How to Audit Your Tests
197
+ #
198
+ # <tt>bin/rails_test_audit</tt> ensures that your view tests'
199
+ # +assign+s are compared against your controller tests'
200
+ # assert_assigned, warning you when you've forgotten to test
201
+ # something.
202
+ #
203
+ # Given:
204
+ #
205
+ # class RouteControllerTest < Test::Rails::ControllerTestCase
206
+ # def test_flickr_refresh
207
+ # get :flickr_refresh, :id => routes(:work).id
208
+ # assert_success
209
+ #
210
+ # assert_assigned :tz_name, 'Pacific Time (US & Canada)'
211
+ # end
212
+ # end
213
+ #
214
+ # And:
215
+ #
216
+ # class RouteViewTest < Test::Rails::ViewTestCase
217
+ # def test_flickr_refresh
218
+ # assigns[:route] = routes(:work)
219
+ # assigns[:tz_name] = 'Pacific Time (US & Canada)'
220
+ #
221
+ # render
222
+ #
223
+ # # ...
224
+ # end
225
+ # end
226
+ #
227
+ # +rails_test_audit+ will see that you don't have an +assert_assigned+
228
+ # for +route+ and will output:
229
+ #
230
+ # require 'test/test_helper'
231
+ #
232
+ # class RouteControllerTest < Test::Rails::ControllerTestCase
233
+ #
234
+ # def test_flickr_refresh
235
+ # assert_assigned :route, routes(:work)
236
+ # end
237
+ #
238
+ # end
239
+ #
240
+ # = How 'rake test' Changed
241
+ #
242
+ # test:views and test:controllers targets get added so you can run just the
243
+ # view or controller tests.
244
+ #
245
+ # The "test" target runs tests in the following order: units, controllers,
246
+ # views, functionals, integration.
247
+ #
248
+ # The test target no longer runs all tests, it stops on the first
249
+ # failure. This way a failure in a unit test doesn't fill your screen
250
+ # with less important errors because the underlying failure also
251
+ # affected your controllers and views.
252
+ #
253
+ # The stats target is updated to account for controller and view tests.
254
+
255
+ module Test::Rails
256
+
257
+ @rails_version = Gem::Version.new Rails::VERSION::STRING
258
+ @v1_2 = Gem::Version.new '1.2'
259
+
260
+ ##
261
+ # The currently loaded rails version. Better than Rails::VERSION::STRING
262
+ # since this one is comparable.
263
+
264
+ def self.rails_version
265
+ @rails_version
266
+ end
267
+
268
+ def self.v1_2 # :nodoc:
269
+ @v1_2
270
+ end
271
+
272
+ end
273
+
274
+ class Object # :nodoc:
275
+ def self.path2class(klassname)
276
+ klassname.split('::').inject(Object) { |k,n| k.const_get n }
277
+ end
278
+ end
279
+
280
+ require 'test/zentest_assertions'
281
+ require 'test/rails/test_case'
282
+ require 'test/rails/functional_test_case'
283
+ require 'test/rails/controller_test_case'
284
+ require 'test/rails/helper_test_case'
285
+ require 'test/rails/ivar_proxy'
286
+ require 'test/rails/view_test_case'
287
+
288
+ ##
289
+ # Use sensible defaults.
290
+
291
+ class Test::Unit::TestCase # :nodoc:
292
+ self.use_transactional_fixtures = true
293
+ self.use_instantiated_fixtures = false
294
+ end
295
+
@@ -0,0 +1,134 @@
1
+ require 'test/unit/assertions'
2
+
3
+ ##
4
+ # Extra assertions for Test::Unit
5
+
6
+ module Test::Unit::Assertions
7
+ has_miniunit = defined? ::Mini
8
+
9
+ if has_miniunit then
10
+ alias :assert_include :assert_includes
11
+ alias :deny :refute
12
+ alias :deny_empty :refute_empty
13
+ alias :deny_equal :refute_equal
14
+ alias :deny_include :refute_includes
15
+ alias :deny_includes :refute_includes
16
+ alias :deny_nil :refute_nil
17
+ alias :util_capture :capture_io
18
+ else
19
+
20
+ alias :refute_nil :assert_not_nil
21
+
22
+ ##
23
+ # Asserts that +obj+ responds to #empty? and #empty? returns true.
24
+
25
+ def assert_empty(obj)
26
+ assert_respond_to obj, :empty?
27
+ assert_block "#{obj.inspect} expected to be empty." do obj.empty? end
28
+ end
29
+
30
+ ##
31
+ # Like assert_in_delta but better dealing with errors proportional
32
+ # to the sizes of +a+ and +b+.
33
+
34
+ def assert_in_epsilon(a, b, epsilon, message = nil)
35
+ return assert(true) if a == b # count assertion
36
+
37
+ error = ((a - b).to_f / ((b.abs > a.abs) ? b : a)).abs
38
+ message ||= "#{a} expected to be within #{epsilon * 100}% of #{b}, was #{error}"
39
+
40
+ assert_block message do error <= epsilon end
41
+ end
42
+
43
+ ##
44
+ # Asserts that +collection+ includes +obj+.
45
+
46
+ def assert_include collection, obj, msg = nil
47
+ assert_respond_to collection, :include?
48
+
49
+ message ||= "#{collection.inspect}\ndoes not include\n#{obj.inspect}."
50
+ assert_block message do collection.include?(obj) end
51
+ end
52
+
53
+ alias assert_includes assert_include
54
+
55
+ ##
56
+ # Asserts that +boolean+ is not false or nil.
57
+
58
+ def deny(boolean, message = nil)
59
+ _wrap_assertion do
60
+ assert_block(build_message(message, "Failed refutation, no message given.")) { not boolean }
61
+ end
62
+ end
63
+
64
+ ##
65
+ # Asserts that +obj+ responds to #empty? and #empty? returns false.
66
+
67
+ def deny_empty(obj)
68
+ assert_respond_to obj, :empty?
69
+ assert_block "#{obj.inspect} expected to have stuff." do !obj.empty? end
70
+ end
71
+
72
+ ##
73
+ # Alias for assert_not_equal
74
+
75
+ alias deny_equal assert_not_equal # rescue nil # rescue for miniunit
76
+
77
+ ##
78
+ # Asserts that +obj+ responds to #include? and that obj does not include
79
+ # +item+.
80
+
81
+ def deny_include(collection, obj, message = nil)
82
+ assert_respond_to collection, :include?
83
+ message ||= "#{collection.inspect} includes #{obj.inspect}."
84
+ assert_block message do !collection.include? obj end
85
+ end
86
+
87
+ alias deny_includes deny_include
88
+
89
+ ##
90
+ # Asserts that +obj+ is not nil.
91
+
92
+ alias deny_nil assert_not_nil
93
+
94
+ ##
95
+ # Captures $stdout and $stderr to StringIO objects and returns them.
96
+ # Restores $stdout and $stderr when done.
97
+ #
98
+ # Usage:
99
+ # def test_puts
100
+ # out, err = capture do
101
+ # puts 'hi'
102
+ # STDERR.puts 'bye!'
103
+ # end
104
+ # assert_equal "hi\n", out.string
105
+ # assert_equal "bye!\n", err.string
106
+ # end
107
+
108
+ def util_capture
109
+ require 'stringio'
110
+ orig_stdout = $stdout.dup
111
+ orig_stderr = $stderr.dup
112
+ captured_stdout = StringIO.new
113
+ captured_stderr = StringIO.new
114
+ $stdout = captured_stdout
115
+ $stderr = captured_stderr
116
+ yield
117
+ captured_stdout.rewind
118
+ captured_stderr.rewind
119
+ return captured_stdout.string, captured_stderr.string
120
+ ensure
121
+ $stdout = orig_stdout
122
+ $stderr = orig_stderr
123
+ end
124
+ end
125
+ end
126
+
127
+ class Object # :nodoc:
128
+ unless respond_to? :path2class then
129
+ def path2class(path) # :nodoc:
130
+ path.split('::').inject(Object) { |k,n| k.const_get n }
131
+ end
132
+ end
133
+ end
134
+
data/test/test_help.rb ADDED
@@ -0,0 +1,36 @@
1
+ # ActionPack
2
+ module ActionController; end
3
+ module ActionController::Flash; end
4
+ class ActionController::Flash::FlashHash < Hash; end
5
+ class ActionController::TestSession < Hash; end
6
+
7
+ class ActionController::TestRequest
8
+ attr_accessor :session
9
+ end
10
+ class ActionController::TestResponse; end
11
+
12
+ class ApplicationController; end
13
+
14
+ module ActionView; end
15
+ module ActionView::Helpers; end
16
+ module ActionView::Helpers::ActiveRecordHelper; end
17
+ module ActionView::Helpers::TagHelper; end
18
+ module ActionView::Helpers::TextHelper; end
19
+ module ActionView::Helpers::FormTagHelper; end
20
+ module ActionView::Helpers::FormOptionsHelper; end
21
+ module ActionView::Helpers::FormHelper; end
22
+ module ActionView::Helpers::UrlHelper; end
23
+ module ActionView::Helpers::AssetTagHelper; end
24
+
25
+ class << Test::Unit::TestCase
26
+ attr_accessor :use_transactional_fixtures
27
+ attr_accessor :use_instantiated_fixtures
28
+ end
29
+
30
+ # ActionMailer
31
+ module ActionMailer; end
32
+ class ActionMailer::Base
33
+ def self.deliveries=(arg); end unless defined? @@defined
34
+ @@defined = true
35
+ end
36
+
@@ -0,0 +1,58 @@
1
+ require 'test/unit'
2
+ require 'test/zentest_assertions'
3
+
4
+ unless defined? $TESTING_RTC then
5
+ $TESTING_RTC = true
6
+
7
+ begin
8
+ require 'test/rails'
9
+ rescue LoadError, NameError
10
+ $TESTING_RTC = false
11
+ end
12
+ end
13
+
14
+ class TRController < ApplicationController
15
+ end if $TESTING_RTC
16
+
17
+ class TestRailsControllerTestCase < Test::Rails::ControllerTestCase
18
+
19
+ def setup
20
+ @controller_class_name = 'TRController'
21
+ super
22
+ end
23
+
24
+ def assigns
25
+ { 'ivar' => 'value' }
26
+ end
27
+
28
+ def test_assert_assigned
29
+ assert_assigned :ivar
30
+ assert_assigned :ivar, 'value'
31
+
32
+ assert_raise Test::Unit::AssertionFailedError do
33
+ assert_assigned :no_ivar
34
+ end
35
+
36
+ e = assert_raise Test::Unit::AssertionFailedError do
37
+ assert_assigned :ivar, 'bad_value'
38
+ end
39
+
40
+ expected = <<-EOF.strip
41
+ assert_assigned :ivar.
42
+ <\"bad_value\"> expected but was
43
+ <\"value\">.
44
+ EOF
45
+
46
+ assert_equal expected, e.message
47
+ end
48
+
49
+ def test_deny_assigned
50
+ deny_assigned :no_ivar
51
+
52
+ assert_raise Test::Unit::AssertionFailedError do
53
+ deny_assigned :ivar
54
+ end
55
+ end
56
+
57
+ end if $TESTING_RTC
58
+
@@ -0,0 +1,48 @@
1
+ require 'test/unit'
2
+ require 'test/zentest_assertions'
3
+
4
+ unless defined? $TESTING_RTC then
5
+ $TESTING_RTC = true
6
+
7
+ begin
8
+ require 'test/rails'
9
+ rescue LoadError, NameError
10
+ $TESTING_RTC = false
11
+ end
12
+ end
13
+
14
+ begin
15
+ module TRHelper
16
+ def tr_helper; end
17
+ end
18
+ class TRHelperTest < Test::Rails::HelperTestCase; end
19
+ rescue RuntimeError
20
+ end if $TESTING_RTC
21
+
22
+ begin
23
+ module Widgets; end
24
+ module Widgets::SomeHelper
25
+ def widgets_some_helper; end
26
+ end
27
+ class Widgets::SomeHelperTest < Test::Rails::HelperTestCase; end
28
+ rescue RuntimeError
29
+ end if $TESTING_RTC
30
+
31
+ class TestRailsHelperTestCase < Test::Unit::TestCase
32
+
33
+ def test_self_inherited
34
+ assert defined? TRHelperTest
35
+
36
+ assert_includes TRHelperTest.instance_methods, 'tr_helper'
37
+ end
38
+
39
+ def test_self_inherited_namespaced
40
+ assert defined? Widgets
41
+ assert defined? Widgets::SomeHelperTest
42
+
43
+ assert_includes(Widgets::SomeHelperTest.instance_methods,
44
+ 'widgets_some_helper')
45
+ end
46
+
47
+ end if $TESTING_RTC
48
+