ryanbriones-ZenTest 3.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/History.txt +523 -0
  2. data/Manifest.txt +69 -0
  3. data/README.txt +110 -0
  4. data/Rakefile +68 -0
  5. data/articles/Article.css +721 -0
  6. data/articles/getting_started_with_autotest.html +532 -0
  7. data/articles/how_to_use_zentest.txt +393 -0
  8. data/bin/autotest +55 -0
  9. data/bin/multiruby +40 -0
  10. data/bin/multiruby_setup +68 -0
  11. data/bin/rails_test_audit +80 -0
  12. data/bin/unit_diff +38 -0
  13. data/bin/zentest +28 -0
  14. data/example.txt +42 -0
  15. data/example1.rb +7 -0
  16. data/example2.rb +15 -0
  17. data/example_dot_autotest.rb +45 -0
  18. data/lib/autotest.rb +654 -0
  19. data/lib/autotest/autoupdate.rb +26 -0
  20. data/lib/autotest/camping.rb +37 -0
  21. data/lib/autotest/cctray.rb +57 -0
  22. data/lib/autotest/discover.rb +6 -0
  23. data/lib/autotest/emacs.rb +35 -0
  24. data/lib/autotest/email_notify.rb +66 -0
  25. data/lib/autotest/fixtures.rb +12 -0
  26. data/lib/autotest/growl.rb +28 -0
  27. data/lib/autotest/heckle.rb +14 -0
  28. data/lib/autotest/html_report.rb +31 -0
  29. data/lib/autotest/jabber_notify.rb +111 -0
  30. data/lib/autotest/kdenotify.rb +14 -0
  31. data/lib/autotest/menu.rb +51 -0
  32. data/lib/autotest/migrate.rb +7 -0
  33. data/lib/autotest/notify.rb +34 -0
  34. data/lib/autotest/once.rb +9 -0
  35. data/lib/autotest/pretty.rb +83 -0
  36. data/lib/autotest/rails.rb +81 -0
  37. data/lib/autotest/rcov.rb +22 -0
  38. data/lib/autotest/redgreen.rb +21 -0
  39. data/lib/autotest/restart.rb +11 -0
  40. data/lib/autotest/screen.rb +73 -0
  41. data/lib/autotest/shame.rb +45 -0
  42. data/lib/autotest/snarl.rb +51 -0
  43. data/lib/autotest/timestamp.rb +9 -0
  44. data/lib/functional_test_matrix.rb +92 -0
  45. data/lib/multiruby.rb +401 -0
  46. data/lib/test/rails.rb +295 -0
  47. data/lib/test/rails/controller_test_case.rb +382 -0
  48. data/lib/test/rails/functional_test_case.rb +79 -0
  49. data/lib/test/rails/helper_test_case.rb +64 -0
  50. data/lib/test/rails/ivar_proxy.rb +31 -0
  51. data/lib/test/rails/pp_html_document.rb +74 -0
  52. data/lib/test/rails/rake_tasks.rb +50 -0
  53. data/lib/test/rails/render_tree.rb +93 -0
  54. data/lib/test/rails/test_case.rb +28 -0
  55. data/lib/test/rails/view_test_case.rb +597 -0
  56. data/lib/test/zentest_assertions.rb +134 -0
  57. data/lib/unit_diff.rb +259 -0
  58. data/lib/zentest.rb +566 -0
  59. data/lib/zentest_mapping.rb +99 -0
  60. data/test/test_autotest.rb +449 -0
  61. data/test/test_help.rb +36 -0
  62. data/test/test_rails_autotest.rb +229 -0
  63. data/test/test_rails_controller_test_case.rb +58 -0
  64. data/test/test_rails_helper_test_case.rb +48 -0
  65. data/test/test_rails_view_test_case.rb +275 -0
  66. data/test/test_unit_diff.rb +319 -0
  67. data/test/test_zentest.rb +566 -0
  68. data/test/test_zentest_assertions.rb +128 -0
  69. data/test/test_zentest_mapping.rb +222 -0
  70. metadata +151 -0
@@ -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
+
@@ -0,0 +1,74 @@
1
+ class HTML::Document
2
+ def pretty_print(q)
3
+ q.object_address_group self do
4
+ q.breakable
5
+ q.seplist @root.children_without_newlines do |v| q.pp v end
6
+ end
7
+ end
8
+ end
9
+
10
+ class HTML::Node
11
+ def children_without_newlines
12
+ @children.reject do |c|
13
+ HTML::Text == c.class and c.content_without_whitespace == "\n"
14
+ end
15
+ end
16
+
17
+ def pretty_print(q)
18
+ q.group 1, '[NODE ', ']' do
19
+ q.breakable
20
+ q.seplist children_without_newlines do |v| q.pp v end
21
+ end
22
+ end
23
+ end
24
+
25
+ class HTML::Tag
26
+ def pretty_print(q)
27
+ case @closing
28
+ when :close then
29
+ q.text "[close #{@name}]"
30
+ when :self then
31
+ pretty_print_tag 'empty', q
32
+ when nil then
33
+ pretty_print_tag 'open ', q
34
+ else
35
+ raise "Unknown closing #{@closing.inspect}"
36
+ end
37
+ end
38
+
39
+ def pretty_print_tag(type, q)
40
+ q.group 1, "(#{type} #{@name.inspect}", ')' do
41
+ unless @attributes.empty? then
42
+ q.breakable
43
+ q.pp @attributes
44
+ end
45
+ unless children_without_newlines.empty? then
46
+ q.breakable
47
+ q.group 1, '[', ']' do
48
+ q.seplist children_without_newlines do |v|
49
+ q.pp v
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ class HTML::Text
58
+ def content_without_whitespace
59
+ @content.gsub(/^[ ]+/, '').sub(/[ ]+\Z/, '')
60
+ end
61
+
62
+ def pretty_print(q)
63
+ q.pp content_without_whitespace
64
+ end
65
+ end
66
+
67
+ class HTML::CDATA
68
+ def pretty_print(q)
69
+ q.group 1, '[', ']' do
70
+ q.pp @content
71
+ end
72
+ end
73
+ end
74
+
@@ -0,0 +1,50 @@
1
+ require 'code_statistics'
2
+
3
+ def define_test_task(test_type)
4
+ desc "Run the #{test_type} tests in test/#{test_type}s"
5
+ Rake::TestTask.new "#{test_type}s" => [ 'db:test:prepare' ] do |t|
6
+ t.libs << 'test'
7
+ t.pattern = "test/#{test_type}s/**/*_test.rb"
8
+ t.verbose = true
9
+ end
10
+ end
11
+
12
+ namespace :test do
13
+ define_test_task 'helper'
14
+ define_test_task 'view'
15
+ define_test_task 'controller'
16
+ end
17
+
18
+ desc 'Run all tests'
19
+ task :test => %w[
20
+ test:units
21
+ test:controllers
22
+ test:helpers
23
+ test:views
24
+ test:functionals
25
+ test:integration
26
+ ]
27
+
28
+ dirs = [
29
+ %w[Libraries lib/],
30
+ %w[Models app/models],
31
+ %w[Unit\ tests test/unit],
32
+ %w[Helpers app/helpers],
33
+ %w[Helper\ tests test/helpers],
34
+ %w[Components components],
35
+ %w[Controllers app/controllers],
36
+ %w[Controller\ tests test/controllers],
37
+ %w[View\ tests test/views],
38
+ %w[Functional\ tests test/functional],
39
+ %w[Integration\ tests test/integration],
40
+ %w[APIs app/apis],
41
+ ]
42
+
43
+ dirs = dirs.map { |name, dir| [name, File.join(RAILS_ROOT, dir)] }
44
+ dirs = dirs.select { |name, dir| File.directory? dir }
45
+
46
+ STATS_DIRECTORIES.replace dirs
47
+
48
+ new_test_types = ['Controller tests', 'Helper tests', 'View tests']
49
+ CodeStatistics::TEST_TYPES.push(*new_test_types)
50
+
@@ -0,0 +1,93 @@
1
+ ##
2
+ # test/rails/render_tree.rb adds debug rendering to ActionView::Base#render.
3
+ #
4
+ # Debug rendering prints out a tree of calls to render allowing you to easily
5
+ # visualize where rendering occurs in unfamiliar code.
6
+
7
+ class ActionView::Base
8
+
9
+ alias plain_render render # :nodoc:
10
+
11
+ ##
12
+ # List of render types for ActionView::Base#render
13
+
14
+ RENDERS = [:partial, :template, :file, :action, :text, :inline, :nothing,
15
+ :update]
16
+
17
+ ##
18
+ # Add debug output to rendering.
19
+ #
20
+ # When you include lib/rails/render_tree a tree of renders will be displayed
21
+ # in the console. This is especially useful when writing tests.
22
+ #
23
+ # This test:
24
+ #
25
+ # require 'test/test_helper'
26
+ # require 'test/rails/render_tree'
27
+ #
28
+ # class ThingsViewTest < Test::Rails::ViewTestCase
29
+ #
30
+ # fixtures :goals
31
+ #
32
+ # def test_body
33
+ # assigns[:goal] = goals(:first)
34
+ # assigns[:related_goals_moved] = []
35
+ # assigns[:related_goals_instead] = []
36
+ #
37
+ # render :partial => 'things/body'
38
+ #
39
+ # assert_tag :tag => 'div', :attributes => { :id => 'entriesbucket' }
40
+ # end
41
+ #
42
+ # end
43
+ #
44
+ # Will give this output when run:
45
+ #
46
+ # $ ruby test/views/things_view_test.rb -n test_body
47
+ # Loaded suite test/views/things_view_test
48
+ # Started
49
+ # "things/_body"
50
+ # :partial => "widgets/goals_gallery_teaser"
51
+ # "widgets/_goals_gallery_teaser"
52
+ # :partial => "entries_bucket"
53
+ # "things/_entries_bucket"
54
+ # :partial => "things/ask_a_question"
55
+ # "things/_ask_a_question"
56
+ # "widgets/forms/related_goals"
57
+ # .
58
+ # Finished in 1.293523 seconds.
59
+ #
60
+ # 1 tests, 1 assertions, 0 failures, 0 errors
61
+
62
+ def render(*args)
63
+ @level ||= 0
64
+
65
+ print ' ' * @level
66
+
67
+ case args.first
68
+ when String then
69
+ p args.first
70
+ when Hash then
71
+ hash = args.first
72
+ if hash.include? :collection and hash.include? :partial then
73
+ puts "%p => %p" % [:collection, hash[:partial]]
74
+ else
75
+ found = hash.keys & RENDERS
76
+ if found.length == 1 then
77
+ puts "%p => %p" % [found.first, hash[found.first]]
78
+ else
79
+ raise "Dunno: %p" % [hash]
80
+ end
81
+ end
82
+ else
83
+ raise "Dunno: %p" % [args]
84
+ end
85
+
86
+ @level += 1
87
+ result = plain_render(*args)
88
+ @level -= 1
89
+ result
90
+ end
91
+
92
+ end
93
+
@@ -0,0 +1,28 @@
1
+ ##
2
+ # Test::Rails::TestCase is an abstract test case for Test::Rails test cases.
3
+ #--
4
+ # Eventually this will hold the fixture setup stuff.
5
+
6
+ class Test::Rails::TestCase < Test::Unit::TestCase
7
+
8
+ undef_method :default_test
9
+
10
+ # Set defaults because Rails has poor ones (and these don't inherit properly)
11
+ self.use_transactional_fixtures = true
12
+ self.use_instantiated_fixtures = false
13
+
14
+ end
15
+
16
+ module Test::Unit::Assertions
17
+ ##
18
+ # TODO: should this go in this file?
19
+ # Asserts that model indeed has a given callback
20
+ #
21
+ # assert_callback(Model, :before_save, :something)
22
+
23
+ def assert_callback(model_class, callback, method_name, message=nil)
24
+ vars = model_class.instance_variable_get(:@inheritable_attributes)
25
+ assert vars.has_key?(callback), message
26
+ assert_include vars[callback], method_name, message
27
+ end
28
+ end
@@ -0,0 +1,597 @@
1
+ ##
2
+ # ViewTestCase allows views to be tested independent of their controllers.
3
+ # Testcase implementors must set up the instance variables the view needs to
4
+ # render itself.
5
+ #
6
+ # = Features
7
+ #
8
+ # * Allows testing of individual AJAX templates.
9
+ # * Allows testing of individual partials.
10
+ # * Large library of helpful assertions.
11
+ #
12
+ # = Naming
13
+ #
14
+ # The test class must be named after your controller class name, so if you're
15
+ # testing views for the +RouteController+ you would name your test case
16
+ # +RouteViewTest+. The test case will expect to find your view files in
17
+ # <tt>app/views/route</tt>.
18
+ #
19
+ # The test names should be in the form of +test_view_edgecase+ where 'view'
20
+ # corresponds to the name of the view file, and 'edgecase' describes the
21
+ # scenario you are testing.
22
+ #
23
+ # If you are testing a view file named 'show.rhtml' your test should be named
24
+ # +test_show+. If your view is behaves differently depending upon its
25
+ # parameters then you can make the test name descriptive like
26
+ # +test_show_photos+ and +test_show_no_photos+.
27
+ #
28
+ # = Examples
29
+ #
30
+ # == Typical View Test
31
+ #
32
+ # class RouteViewTest < Test::Rails::ViewTestCase
33
+ #
34
+ # fixtures :users, :routes, :points, :photos
35
+ #
36
+ # def test_delete
37
+ # # Set up instance variables for template
38
+ # assigns[:loggedin_user] = users(:herbert)
39
+ # assigns[:route] = routes(:work)
40
+ #
41
+ # # render template for the delete action in RouteController
42
+ # render
43
+ #
44
+ # # assert that there's a form with an action of "/route/destroy"
45
+ # assert_form form_url, :post do
46
+ # # with a hidden id field
47
+ # assert_input :hidden, :id
48
+ # # And a submit button that says 'Delete!'
49
+ # assert_submit 'Delete!'
50
+ # end
51
+ #
52
+ # # And a link back to the route so you don't delete it
53
+ # assert_links_to "/route/show/#{routes(:work).id}", 'No, I do not!'
54
+ # end
55
+ #
56
+ # end
57
+ #
58
+ # == Typical Layout Test
59
+ #
60
+ # require 'test/test_helper'
61
+ #
62
+ # # Create a dummy controller for layout views. This lets the setup use the
63
+ # # right path with minimum fuss.
64
+ # class LayoutsController < ApplicationController; end
65
+ #
66
+ # class LayoutsViewTest < Test::Rails::ViewTestCase
67
+ #
68
+ # fixtures :users, :routes, :points, :photos
69
+ #
70
+ # def test_default
71
+ # # Template set-up
72
+ # @request.request_uri = '/foo'
73
+ # assigns[:action_title] = 'Hello & Goodbye'
74
+ #
75
+ # # Render an empty string with the 'application' layout.
76
+ # render :text => '', :layout => 'application'
77
+ #
78
+ # # Assert content just like a regular view test.
79
+ # assert_links_to '/', 'Home'
80
+ # assert_links_to '/user', 'Login'
81
+ # deny_links_to '/user/logout', 'Logout'
82
+ # assert_title 'Hello &amp; Goodbye'
83
+ # assert_h 1, 'Hello &amp; Goodbye'
84
+ # end
85
+ #
86
+ # end
87
+ #
88
+ # = Deprecated Features
89
+ #
90
+ # Form assertions are now using assert_select, so you don't need to pass URLs
91
+ # around everywhere and can instead use a block. (See above example).
92
+ #
93
+ # The form assertions will still work using the old syntax, but in a future
94
+ # release they will give warnings, then will be removed.
95
+
96
+ class Test::Rails::ViewTestCase < Test::Rails::FunctionalTestCase
97
+
98
+ self.use_transactional_fixtures = true
99
+ self.use_instantiated_fixtures = false
100
+
101
+ ##
102
+ # Sets up the test case.
103
+
104
+ def setup
105
+ return if self.class == Test::Rails::ViewTestCase
106
+
107
+ @path_parameters ||= {}
108
+
109
+ klass_name = self.class.name.sub(/View/, 'Controller')
110
+ @controller_class_name ||= klass_name.sub 'Test', ''
111
+
112
+ super
113
+
114
+ @ivar_proxy = Test::Rails::IvarProxy.new @controller
115
+
116
+ # these go here so that flash and session work as they should.
117
+ @controller.send :initialize_template_class, @response
118
+ @controller.send :assign_shortcuts, @request, @response
119
+
120
+ assigns[:session] = @controller.session
121
+ @controller.class.send :public, :flash # make flash accessible to the test
122
+ end
123
+
124
+ ##
125
+ # Allows the view instance variables to be set like flash:
126
+ #
127
+ # test:
128
+ # def test_show
129
+ # assigns[:route] = routes(:work)
130
+
131
+ def assigns
132
+ @ivar_proxy
133
+ end
134
+
135
+ ##
136
+ # Renders the template. The template is determined from the test name. If
137
+ # you have multiple tests for the same view render will try to Do The Right
138
+ # Thing and remove parts of the name looking for the template file.
139
+ #
140
+ # By default, render has the added option <tt>:layout => false</tt>,
141
+ # so if want to test behavior in your layout add <tt>:layout => true</tt>.
142
+ #
143
+ # The action can be forced by using the options:
144
+ #
145
+ # render :action => 'new'
146
+ #
147
+ # render :template => 'profile/index'
148
+ #
149
+ # A test's path parameters may be overridden, allowing routes with
150
+ # additional parameters to work.
151
+ #
152
+ # == Working with Routes
153
+ #
154
+ # By default, a view tests sets the controller and action of a test to the
155
+ # controller name and action name for the test. This may be overriden.
156
+ #
157
+ # A test involving routes like:
158
+ #
159
+ # map.workspace '/users/:owner/workspace/:action',
160
+ # :controller => 'workspace', :action => 'workspace'
161
+ #
162
+ # Can be invoked by setting @path_parameters like this:
163
+ #
164
+ # def test__app_entry
165
+ # @path_parameters[:owner] = 'bob'
166
+ # @path_parameters[:action] = 'apps'
167
+ #
168
+ # render :partial => 'apps/app_entry'
169
+ #
170
+ # # ...
171
+ # end
172
+ #
173
+ # == View Lookup
174
+ #
175
+ # render strips off words trailing an _ in the test name one at a time until
176
+ # it finds a matching action. It tries the extensions 'rhtml', 'rxml',
177
+ # 'rjs', and 'mab' in order for each action until a view is found.
178
+ #
179
+ # With this test case:
180
+ #
181
+ # class RouteViewTest < Test::Rails::ViewTestCase
182
+ # def test_show_photos
183
+ # render
184
+ # end
185
+ # def test_show_no_photos
186
+ # render
187
+ # end
188
+ # end
189
+ #
190
+ # In test_show_photos, render will look for:
191
+ # * app/views/route/show_photos.rhtml
192
+ # * app/views/route/show_photos.rxml
193
+ # * app/views/route/show_photos.rjs
194
+ # * app/views/route/show_photos.mab
195
+ # * app/views/route/show.[...]
196
+ #
197
+ # And in test_show_no_photos, render will look for:
198
+ # * app/views/route/show_no_photos.rhtml
199
+ # * app/views/route/show_no_photos.rxml
200
+ # * app/views/route/show_no_photos.rjs
201
+ # * app/views/route/show_no_photos.mab
202
+ # * app/views/route/show_no.[...]
203
+ # * app/views/route/show.[...]
204
+ #
205
+ # If a view cannot be found the test will flunk.
206
+
207
+ def render(options = {}, deprecated_status = nil)
208
+ @action_name = action_name caller[0] if options.empty?
209
+ assigns[:action_name] = @action_name
210
+
211
+ default_path_parameters = {
212
+ :controller => @controller.controller_name,
213
+ :action => @action_name
214
+ }
215
+
216
+ path_parameters = default_path_parameters.merge(@path_parameters)
217
+
218
+ @request.path_parameters = path_parameters
219
+
220
+ defaults = { :layout => false }
221
+ options = defaults.merge options
222
+
223
+ if Test::Rails.rails_version >= Test::Rails.v1_2 then
224
+ @controller.send :params=, @request.parameters
225
+ else
226
+ @controller.instance_variable_set :@params, @request.parameters
227
+ end
228
+ @controller.send :initialize_current_url
229
+ current_url = URI.parse @controller.url_for
230
+ @request.request_uri = current_url.request_uri
231
+
232
+ # Rails 1.0
233
+ @controller.send :assign_names rescue nil
234
+ @controller.send :fire_flash rescue nil
235
+
236
+ # Rails 1.1
237
+ @controller.send :forget_variables_added_to_assigns rescue nil
238
+
239
+ # Do the render
240
+ options[:TR_force] = true
241
+ @controller.render options, deprecated_status
242
+
243
+ # Rails 1.1
244
+ @controller.send :process_cleanup rescue nil
245
+ end
246
+
247
+ ##
248
+ # Asserts that there is an error on +field+ of type +type+.
249
+
250
+ def assert_error_on(field, type)
251
+ error_message = ActiveRecord::Errors.default_error_messages[type]
252
+ assert_select "div.errorExplanation li",
253
+ :text => /^#{field} #{error_message}/i
254
+ end
255
+
256
+ ##
257
+ # A wrapper assert that calls both assert_input and assert_label.
258
+ #
259
+ # view:
260
+ # <%= start_form_tag :controller => 'game', :action => 'save' %>
261
+ # <label for="game_amount">Amount:</label>
262
+ # <% text_field 'game', 'amount' %>
263
+ #
264
+ # test:
265
+ # assert_field '/game/save', :text, :game, :amount
266
+
267
+ def assert_field(*args)
268
+ form_action, type, model, column, value =
269
+ Symbol === args.first ? [nil, *args] : args
270
+
271
+ if form_action then # HACK deprecate
272
+ assert_input form_action, type, "#{model}[#{column}]", value
273
+ assert_label form_action, "#{model}_#{column}"
274
+ else
275
+ assert_input type, "#{model}[#{column}]", value
276
+ assert_label "#{model}_#{column}"
277
+ end
278
+ end
279
+
280
+ ##
281
+ # Asserts that there is a form whose action is +form_action+. Optionally,
282
+ # +method+ and +enctype+ may be specified. If a block is given, assert_form
283
+ # behaves like assert_select, so assert_input and friends may be scoped to
284
+ # the selected form.
285
+ #
286
+ # view:
287
+ # <%= start_form_tag :action => 'create_file' %>
288
+ # # ...
289
+ #
290
+ # test:
291
+ # assert_form '/game/save'
292
+ #
293
+ # or:
294
+ # assert_form '/game/save' do
295
+ # # ...
296
+ # end
297
+
298
+ def assert_form(form_action, method = nil, enctype = nil, &block)
299
+ selector = "form[action='#{form_action}']"
300
+ selector << "[method='#{method}']" if method
301
+ selector << "[enctype='#{enctype}']" if enctype
302
+ assert_select selector, &block
303
+ end
304
+
305
+ ##
306
+ # Asserts a hN tag of level +level+ exists and contains +content+.
307
+ #
308
+ # view:
309
+ # <h3>Recent Builds</h3>
310
+ #
311
+ # test:
312
+ # assert_h 3, 'Recent Builds'
313
+
314
+ def assert_h(level, content)
315
+ assert_select "h#{level}", :text => content
316
+ end
317
+
318
+ ##
319
+ # Asserts that an image exists with a src of +src+.
320
+ #
321
+ # view:
322
+ # <img src="/images/bucket.jpg" alt="Bucket">
323
+ #
324
+ # test:
325
+ # assert_image '/images/bucket.jpg'
326
+
327
+ def assert_image(src)
328
+ assert_select "img[src='#{src}']"
329
+ end
330
+
331
+ ##
332
+ # Asserts that an input element of +type+ with a name of +name+, and
333
+ # optionally a value of +value+ exists.
334
+ #
335
+ # view:
336
+ # <%= text_field 'game', 'amount' %>
337
+ #
338
+ # test:
339
+ # assert_input :text, "game[amount]"
340
+
341
+ def assert_input(*args)
342
+ action, type, name, value = Symbol === args.first ? [nil, *args] : args
343
+
344
+ raise ArgumentError, 'supply type and name' if type.nil? or name.nil?
345
+
346
+ input_selector = "input[type='#{type}'][name='#{name}']"
347
+ input_selector << "[value='#{value}']" if value
348
+
349
+ assert_select_in_form action do assert_select input_selector end
350
+ end
351
+
352
+ ##
353
+ # Asserts that a label with a for attribute of +for_attribute+ exists.
354
+ #
355
+ # view:
356
+ # <%= start_form_tag :controller => 'game', :action => 'save' %>
357
+ # <label for="game_amount">Amount:</label>
358
+ #
359
+ # test:
360
+ # assert_label 'game_amount'
361
+
362
+ def assert_label(*args)
363
+ action, for_attribute = args.length == 1 ? [nil, *args] : args
364
+
365
+ raise ArgumentError, 'supply for_attribute' if for_attribute.nil?
366
+
367
+ label_selector = "label[for='#{for_attribute}']"
368
+
369
+ assert_select_in_form action do assert_select label_selector end
370
+ end
371
+
372
+ ##
373
+ # Asserts that there is an anchor tag with an href of +href+ that optionally
374
+ # has +content+.
375
+ #
376
+ # view:
377
+ # <%= link_to 'drbrain', :model => user %>
378
+ #
379
+ # test:
380
+ # assert_links_to '/players/show/1', 'drbrain'
381
+
382
+ def assert_links_to(href, content = nil)
383
+ assert_select(*links_to_options_for(href, content))
384
+ end
385
+
386
+ ##
387
+ # Denies the existence of an anchor tag with an href of +href+ and
388
+ # optionally +content+.
389
+ #
390
+ # view (for /players/show/1):
391
+ # <%= link_to_unless_current 'drbrain', :model => user %>
392
+ #
393
+ # test:
394
+ # deny_links_to '/players/show/1'
395
+
396
+ def deny_links_to(href, content = nil)
397
+ selector, options = links_to_options_for(href, content)
398
+ options[:count] = 0
399
+
400
+ assert_select selector, options
401
+ end
402
+
403
+ ##
404
+ # Asserts that there is a form using the 'POST' method whose action is
405
+ # +form_action+ and uses the multipart content type. If passed a block,
406
+ # works like assert_form.
407
+ #
408
+ # view:
409
+ # <%= start_form_tag({ :action => 'create_file' }, :multipart => true) %>
410
+ #
411
+ # test:
412
+ # assert_multipart_form '/game/save'
413
+
414
+ def assert_multipart_form(form_action, &block)
415
+ assert_form(form_action, :post, 'multipart/form-data', &block)
416
+ end
417
+
418
+ ##
419
+ # Asserts that there is a form using the 'POST' method whose action is
420
+ # +form_action+. If passed a block, works like assert_form.
421
+ #
422
+ # view:
423
+ # <%= start_form_tag :action => 'create_file' %>
424
+ #
425
+ # test:
426
+ # assert_post_form '/game/save'
427
+
428
+ def assert_post_form(form_action, &block)
429
+ assert_form(form_action, :post, &block)
430
+ end
431
+
432
+ ##
433
+ # Asserts that a select element with a name of "+model+[+column+]" and
434
+ # +options+ with specified names and values exists.
435
+ #
436
+ # view:
437
+ # <%= collection_select :game, :location_id, @locations, :id, :name %>
438
+ #
439
+ # test:
440
+ # assert_select_tag :game, :location_id, 'Ballet' => 1, 'Guaymas' => 2
441
+
442
+ def assert_select_tag(*args)
443
+ action, model, column, options = Symbol === args.first ? [nil, *args] : args
444
+
445
+ assert_kind_of Hash, options, "options needs to be a Hash"
446
+ deny options.empty?, "options must not be empty"
447
+
448
+ select_selector = "select[name='#{model}[#{column}]']"
449
+
450
+ options.each do |option_name, option_value|
451
+ option_selector = "option[value='#{option_value}']"
452
+ selector = "#{select_selector} #{option_selector}"
453
+
454
+ assert_select_in_form action do
455
+ assert_select selector, :text => option_name
456
+ end
457
+ end
458
+ end
459
+
460
+ ##
461
+ # Asserts that a submit element with a value of +value+ exists.
462
+ #
463
+ # view:
464
+ # <input type="submit" value="Create!" %>
465
+ #
466
+ # test:
467
+ # assert_submit 'Create!'
468
+
469
+ def assert_submit(*args)
470
+ action, value = args.length == 1 ? [nil, *args] : args
471
+
472
+ submit_selector = "input[type='submit'][value='#{value}']"
473
+
474
+ assert_select_in_form action do assert_select submit_selector end
475
+ end
476
+
477
+ ##
478
+ # Asserts that a form with +form_action+ has a descendent that matches
479
+ # +options+ exists.
480
+ #
481
+ # Typically this is not used directly in tests. Instead use it to build
482
+ # expressive tests that assert which fields are in what form.
483
+ #
484
+ # view:
485
+ # <%= start_form_tag :action => 'save' %>
486
+ # [...]
487
+ #
488
+ # test:
489
+ # assert_tag_in_form '/route/save', :tag => 'table'
490
+
491
+ def assert_tag_in_form(form_action, options)
492
+ assert_tag :tag => 'form', :attributes => { :action => form_action },
493
+ :descendant => options
494
+ end
495
+
496
+ ##
497
+ # Asserts that a textarea with name +name+ and optionally +value+ exists.
498
+ #
499
+ # view:
500
+ # <%= text_area 'post', 'body' %>
501
+ #
502
+ # test:
503
+ # assert_text_area 'post[body]'
504
+ #
505
+ # view:
506
+ # <textarea id="post_body" name="post[body]">
507
+ # <%= @post.body %>
508
+ # </textarea>
509
+ #
510
+ # test:
511
+ # assert_text_area 'post[body]', posts(:post).body
512
+
513
+ def assert_text_area(*args)
514
+ action, name, value = args.first !~ /\A\// ? [nil, *args] : args
515
+
516
+ raise ArgumentError, 'supply name' if name.nil?
517
+
518
+ text_area_selector = ["textarea[name='#{name}']"]
519
+ text_area_selector << { :text => value } if value
520
+
521
+ assert_select_in_form action do assert_select(*text_area_selector) end
522
+ end
523
+
524
+ alias assert_textarea assert_text_area
525
+
526
+ ##
527
+ # Asserts that a title with +title+ exists.
528
+ #
529
+ # view:
530
+ # <title>some content</title>
531
+ #
532
+ # test:
533
+ # assert_title 'some content'
534
+
535
+ def assert_title(title)
536
+ assert_select 'title', :text => title
537
+ end
538
+
539
+ ##
540
+ # Opposite of assert_select.
541
+
542
+ def deny_select(selector)
543
+ assert_select selector, false
544
+ end
545
+
546
+ ##
547
+ # Creates a new Paginator that uses the current controller. +item_count+,
548
+ # +items_per_page+ and +page_number+ are passed straight through.
549
+
550
+ def util_make_paginator(item_count, items_per_page, page_number)
551
+ ActionController::Pagination::Paginator.new(@controller, item_count,
552
+ items_per_page, page_number)
553
+ end
554
+
555
+ ##
556
+ # Utility method for compatibility with old-style assert_tag form
557
+ # assertions.
558
+
559
+ def assert_select_in_form(action, &block) # :nodoc:
560
+ if action then
561
+ assert_form(action, &block)
562
+ else
563
+ block.call
564
+ end
565
+ end
566
+
567
+ ##
568
+ # Creates an assertion options hash for +href+ and +content+.
569
+
570
+ def links_to_options_for(href, content = nil)
571
+ selector = "a[href='#{href}']"
572
+ equality = content ? { :text => content } : {}
573
+ return selector, equality
574
+ end
575
+
576
+ ##
577
+ # Returns the action_name based on a backtrace line passed in as +test+.
578
+
579
+ def action_name(test)
580
+ orig_name = test = test.sub(/.*in `test_(.*)'/, '\1')
581
+ controller = @controller.class.name.sub('Controller', '').underscore
582
+
583
+ extensions = %w[rhtml rxml rjs mab]
584
+
585
+ while test =~ /_/ do
586
+ return test if extensions.any? { |ext| File.file? "app/views/#{controller}/#{test}.#{ext}" }
587
+
588
+ test = test.sub(/_[^_]+$/, '')
589
+ end
590
+
591
+ return test if extensions.any? { |ext| File.file? "app/views/#{controller}/#{test}.#{ext}" }
592
+
593
+ flunk "Couldn't find view for test_#{orig_name}"
594
+ end
595
+
596
+ end
597
+