richzhou-rspec-rails 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. data/.document +7 -0
  2. data/.gitignore +8 -0
  3. data/Contribute.rdoc +4 -0
  4. data/Gemfile +4 -0
  5. data/History.rdoc +321 -0
  6. data/License.txt +33 -0
  7. data/Manifest.txt +165 -0
  8. data/README.rdoc +48 -0
  9. data/Rakefile +12 -0
  10. data/TODO.txt +17 -0
  11. data/Upgrade.rdoc +148 -0
  12. data/generators/integration_spec/integration_spec_generator.rb +10 -0
  13. data/generators/integration_spec/templates/integration_spec.rb +4 -0
  14. data/generators/rspec/CHANGES +1 -0
  15. data/generators/rspec/rspec_generator.rb +72 -0
  16. data/generators/rspec/templates/previous_failures.txt +0 -0
  17. data/generators/rspec/templates/rcov.opts +2 -0
  18. data/generators/rspec/templates/rspec.rake +146 -0
  19. data/generators/rspec/templates/script/autospec +6 -0
  20. data/generators/rspec/templates/script/spec +10 -0
  21. data/generators/rspec/templates/spec.opts +4 -0
  22. data/generators/rspec/templates/spec_helper.rb +54 -0
  23. data/generators/rspec_controller/USAGE +33 -0
  24. data/generators/rspec_controller/rspec_controller_generator.rb +47 -0
  25. data/generators/rspec_controller/templates/controller_spec.rb +25 -0
  26. data/generators/rspec_controller/templates/helper_spec.rb +11 -0
  27. data/generators/rspec_controller/templates/view_spec.rb +12 -0
  28. data/generators/rspec_default_values.rb +28 -0
  29. data/generators/rspec_model/USAGE +18 -0
  30. data/generators/rspec_model/rspec_model_generator.rb +35 -0
  31. data/generators/rspec_model/templates/model_spec.rb +13 -0
  32. data/generators/rspec_scaffold/rspec_scaffold_generator.rb +154 -0
  33. data/generators/rspec_scaffold/templates/controller_spec.rb +131 -0
  34. data/generators/rspec_scaffold/templates/edit_erb_spec.rb +25 -0
  35. data/generators/rspec_scaffold/templates/helper_spec.rb +11 -0
  36. data/generators/rspec_scaffold/templates/index_erb_spec.rb +27 -0
  37. data/generators/rspec_scaffold/templates/new_erb_spec.rb +25 -0
  38. data/generators/rspec_scaffold/templates/routing_spec.rb +33 -0
  39. data/generators/rspec_scaffold/templates/show_erb_spec.rb +22 -0
  40. data/init.rb +9 -0
  41. data/lib/autotest/discover.rb +5 -0
  42. data/lib/autotest/rails_rspec.rb +76 -0
  43. data/lib/spec/rails.rb +26 -0
  44. data/lib/spec/rails/example.rb +48 -0
  45. data/lib/spec/rails/example/assigns_hash_proxy.rb +39 -0
  46. data/lib/spec/rails/example/controller_example_group.rb +285 -0
  47. data/lib/spec/rails/example/cookies_proxy.rb +29 -0
  48. data/lib/spec/rails/example/functional_example_group.rb +106 -0
  49. data/lib/spec/rails/example/helper_example_group.rb +153 -0
  50. data/lib/spec/rails/example/integration_example_group.rb +16 -0
  51. data/lib/spec/rails/example/model_example_group.rb +15 -0
  52. data/lib/spec/rails/example/render_observer.rb +82 -0
  53. data/lib/spec/rails/example/routing_example_group.rb +16 -0
  54. data/lib/spec/rails/example/routing_helpers.rb +66 -0
  55. data/lib/spec/rails/example/view_example_group.rb +203 -0
  56. data/lib/spec/rails/extensions.rb +11 -0
  57. data/lib/spec/rails/extensions/action_controller/rescue.rb +42 -0
  58. data/lib/spec/rails/extensions/action_controller/test_case.rb +16 -0
  59. data/lib/spec/rails/extensions/action_controller/test_response.rb +21 -0
  60. data/lib/spec/rails/extensions/action_view/base.rb +35 -0
  61. data/lib/spec/rails/extensions/active_record/base.rb +45 -0
  62. data/lib/spec/rails/extensions/active_support/test_case.rb +7 -0
  63. data/lib/spec/rails/extensions/spec/matchers/have.rb +23 -0
  64. data/lib/spec/rails/extensions/spec/runner/configuration.rb +45 -0
  65. data/lib/spec/rails/interop/testcase.rb +14 -0
  66. data/lib/spec/rails/matchers.rb +32 -0
  67. data/lib/spec/rails/matchers/ar_be_valid.rb +27 -0
  68. data/lib/spec/rails/matchers/assert_select.rb +180 -0
  69. data/lib/spec/rails/matchers/change.rb +13 -0
  70. data/lib/spec/rails/matchers/have_text.rb +57 -0
  71. data/lib/spec/rails/matchers/include_text.rb +54 -0
  72. data/lib/spec/rails/matchers/redirect_to.rb +126 -0
  73. data/lib/spec/rails/matchers/render_template.rb +129 -0
  74. data/lib/spec/rails/matchers/route_to.rb +149 -0
  75. data/lib/spec/rails/mocks.rb +140 -0
  76. data/lib/spec/rails/version.rb +16 -0
  77. data/rspec-rails.gemspec +25 -0
  78. data/spec/autotest/mappings_spec.rb +86 -0
  79. data/spec/rails_suite.rb +7 -0
  80. data/spec/resources/controllers/action_view_base_spec_controller.rb +2 -0
  81. data/spec/resources/controllers/application.rb +9 -0
  82. data/spec/resources/controllers/controller_spec_controller.rb +127 -0
  83. data/spec/resources/controllers/example.txt +1 -0
  84. data/spec/resources/controllers/redirect_spec_controller.rb +70 -0
  85. data/spec/resources/controllers/render_spec_controller.rb +34 -0
  86. data/spec/resources/controllers/rjs_spec_controller.rb +58 -0
  87. data/spec/resources/helpers/addition_helper.rb +5 -0
  88. data/spec/resources/helpers/explicit_helper.rb +46 -0
  89. data/spec/resources/helpers/more_explicit_helper.rb +5 -0
  90. data/spec/resources/helpers/plugin_application_helper.rb +6 -0
  91. data/spec/resources/helpers/view_spec_helper.rb +13 -0
  92. data/spec/resources/models/animal.rb +4 -0
  93. data/spec/resources/models/person.rb +18 -0
  94. data/spec/resources/models/thing.rb +3 -0
  95. data/spec/resources/views/controller_spec/_partial.html.erb +0 -0
  96. data/spec/resources/views/controller_spec/action_setting_flash_after_session_reset.html.erb +1 -0
  97. data/spec/resources/views/controller_spec/action_setting_flash_before_session_reset.html.erb +1 -0
  98. data/spec/resources/views/controller_spec/action_setting_the_assigns_hash.html.erb +0 -0
  99. data/spec/resources/views/controller_spec/action_with_errors_in_template.html.erb +1 -0
  100. data/spec/resources/views/controller_spec/action_with_template.html.erb +1 -0
  101. data/spec/resources/views/controller_spec/non_existent_action_with_existent_template.html.erb +1 -0
  102. data/spec/resources/views/layouts/application.html.erb +0 -0
  103. data/spec/resources/views/layouts/simple.html.erb +0 -0
  104. data/spec/resources/views/objects/_object.html.erb +1 -0
  105. data/spec/resources/views/render_spec/_a_partial.html.erb +0 -0
  106. data/spec/resources/views/render_spec/action_with_alternate_layout.html.erb +0 -0
  107. data/spec/resources/views/render_spec/some_action.html.erb +0 -0
  108. data/spec/resources/views/render_spec/some_action.js.rjs +1 -0
  109. data/spec/resources/views/rjs_spec/_replacement_partial.html.erb +1 -0
  110. data/spec/resources/views/rjs_spec/hide_div.js.rjs +1 -0
  111. data/spec/resources/views/rjs_spec/hide_page_element.js.rjs +1 -0
  112. data/spec/resources/views/rjs_spec/insert_html.js.rjs +1 -0
  113. data/spec/resources/views/rjs_spec/replace.js.rjs +1 -0
  114. data/spec/resources/views/rjs_spec/replace_html.js.rjs +1 -0
  115. data/spec/resources/views/rjs_spec/replace_html_with_partial.js.rjs +1 -0
  116. data/spec/resources/views/rjs_spec/visual_effect.js.rjs +1 -0
  117. data/spec/resources/views/rjs_spec/visual_toggle_effect.js.rjs +1 -0
  118. data/spec/resources/views/tag_spec/no_tags.html.erb +1 -0
  119. data/spec/resources/views/tag_spec/single_div_with_no_attributes.html.erb +1 -0
  120. data/spec/resources/views/tag_spec/single_div_with_one_attribute.html.erb +1 -0
  121. data/spec/resources/views/view_spec/_partial.html.erb +2 -0
  122. data/spec/resources/views/view_spec/_partial_used_twice.html.erb +0 -0
  123. data/spec/resources/views/view_spec/_partial_with_local_variable.html.erb +1 -0
  124. data/spec/resources/views/view_spec/_partial_with_sub_partial.html.erb +1 -0
  125. data/spec/resources/views/view_spec/_spacer.html.erb +1 -0
  126. data/spec/resources/views/view_spec/accessor.html.erb +6 -0
  127. data/spec/resources/views/view_spec/block_helper.html.erb +3 -0
  128. data/spec/resources/views/view_spec/entry_form.html.erb +2 -0
  129. data/spec/resources/views/view_spec/explicit_helper.html.erb +2 -0
  130. data/spec/resources/views/view_spec/foo/show.html.erb +1 -0
  131. data/spec/resources/views/view_spec/implicit_helper.html.erb +2 -0
  132. data/spec/resources/views/view_spec/multiple_helpers.html.erb +3 -0
  133. data/spec/resources/views/view_spec/path_params.html.erb +1 -0
  134. data/spec/resources/views/view_spec/should_not_receive.html.erb +3 -0
  135. data/spec/resources/views/view_spec/template_with_partial.html.erb +5 -0
  136. data/spec/resources/views/view_spec/template_with_partial_using_collection.html.erb +3 -0
  137. data/spec/resources/views/view_spec/template_with_partial_with_array.html.erb +1 -0
  138. data/spec/resources/views/view_spec/view_helpers.html.erb +1 -0
  139. data/spec/spec/rails/example/assigns_hash_proxy_spec.rb +109 -0
  140. data/spec/spec/rails/example/configuration_spec.rb +67 -0
  141. data/spec/spec/rails/example/controller_example_group_spec.rb +307 -0
  142. data/spec/spec/rails/example/controller_isolation_spec.rb +75 -0
  143. data/spec/spec/rails/example/cookies_proxy_spec.rb +87 -0
  144. data/spec/spec/rails/example/error_handling_spec.rb +90 -0
  145. data/spec/spec/rails/example/example_group_factory_spec.rb +112 -0
  146. data/spec/spec/rails/example/helper_example_group_spec.rb +247 -0
  147. data/spec/spec/rails/example/model_example_group_spec.rb +32 -0
  148. data/spec/spec/rails/example/routing_example_group_spec.rb +9 -0
  149. data/spec/spec/rails/example/shared_routing_example_group_examples.rb +241 -0
  150. data/spec/spec/rails/example/test_unit_assertion_accessibility_spec.rb +33 -0
  151. data/spec/spec/rails/example/view_example_group_spec.rb +346 -0
  152. data/spec/spec/rails/extensions/action_view_base_spec.rb +79 -0
  153. data/spec/spec/rails/extensions/active_record_spec.rb +14 -0
  154. data/spec/spec/rails/interop/testcase_spec.rb +70 -0
  155. data/spec/spec/rails/matchers/ar_be_valid_spec.rb +19 -0
  156. data/spec/spec/rails/matchers/assert_select_spec.rb +835 -0
  157. data/spec/spec/rails/matchers/errors_on_spec.rb +37 -0
  158. data/spec/spec/rails/matchers/have_text_spec.rb +69 -0
  159. data/spec/spec/rails/matchers/include_text_spec.rb +62 -0
  160. data/spec/spec/rails/matchers/redirect_to_spec.rb +253 -0
  161. data/spec/spec/rails/matchers/render_template_spec.rb +208 -0
  162. data/spec/spec/rails/matchers/should_change_spec.rb +15 -0
  163. data/spec/spec/rails/mocks/ar_classes.rb +10 -0
  164. data/spec/spec/rails/mocks/mock_model_spec.rb +112 -0
  165. data/spec/spec/rails/mocks/stub_model_spec.rb +80 -0
  166. data/spec/spec/rails/sample_modified_fixture.rb +8 -0
  167. data/spec/spec/rails/sample_spec.rb +8 -0
  168. data/spec/spec/rails/spec_spec.rb +11 -0
  169. data/spec/spec_helper.rb +78 -0
  170. metadata +363 -0
@@ -0,0 +1,153 @@
1
+ module Spec
2
+ module Rails
3
+ module Example
4
+ class HelperExampleGroupController < ApplicationController #:nodoc:
5
+ attr_accessor :request, :url
6
+ end
7
+
8
+ # Helper Specs live in $RAILS_ROOT/spec/helpers/.
9
+ #
10
+ # Helper Specs use Spec::Rails::Example::HelperExampleGroup, which allows you to
11
+ # include your Helper directly in the context and write specs directly
12
+ # against its methods.
13
+ #
14
+ # HelperExampleGroup also includes the standard lot of ActionView::Helpers in case your
15
+ # helpers rely on any of those.
16
+ #
17
+ # == Example
18
+ #
19
+ # module ThingHelper
20
+ # def number_of_things
21
+ # Thing.count
22
+ # end
23
+ # end
24
+ #
25
+ # describe "ThingHelper example_group" do
26
+ # include ThingHelper
27
+ # it "should tell you the number of things" do
28
+ # Thing.should_receive(:count).and_return(37)
29
+ # number_of_things.should == 37
30
+ # end
31
+ # end
32
+ class HelperExampleGroup < FunctionalExampleGroup
33
+ tests HelperExampleGroupController
34
+ attr_accessor :output_buffer
35
+
36
+ class HelperObject < ActionView::Base
37
+ def initialize(*args)
38
+ @template = self
39
+ super
40
+ end
41
+ def protect_against_forgery?
42
+ false
43
+ end
44
+
45
+ attr_writer :session, :request, :flash, :params, :controller
46
+
47
+ private
48
+ attr_reader :session, :request, :flash, :params, :controller
49
+ end
50
+
51
+ class << self
52
+ # The helper name....
53
+ def helper_name(name=nil)
54
+ @helper_being_described = "#{name}_helper".camelize.constantize
55
+ send :include, @helper_being_described
56
+ end
57
+
58
+ def helper
59
+ HelperObject.new.tap do |helper_object|
60
+ if @helper_being_described.nil?
61
+ if described_type.class == Module
62
+ helper_object.extend described_type
63
+ end
64
+ else
65
+ helper_object.extend @helper_being_described
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ # Returns an instance of ActionView::Base with the helper being spec'd
72
+ # included.
73
+ #
74
+ # == Example
75
+ #
76
+ # describe PersonHelper do
77
+ # it "should write a link to person with the name" do
78
+ # assigns[:person] = mock_model(Person, :full_name => "Full Name", :id => 37, :new_record? => false)
79
+ # helper.link_to_person.should == %{<a href="/people/37">Full Name</a>}
80
+ # end
81
+ # end
82
+ #
83
+ # module PersonHelper
84
+ # def link_to_person
85
+ # link_to person.full_name, url_for(person)
86
+ # end
87
+ # end
88
+ #
89
+ def helper
90
+ @helper ||= self.class.helper
91
+ end
92
+
93
+ def orig_assigns
94
+ helper.assigns
95
+ end
96
+
97
+ # Reverse the load order so that custom helpers which are defined last
98
+ # are also loaded last.
99
+ ActionView::Base.included_modules.reverse.each do |mod|
100
+ include mod if mod.parents.include?(ActionView::Helpers)
101
+ end
102
+
103
+ before(:each) do
104
+ @controller.request = @request
105
+ @controller.url = ActionController::UrlRewriter.new @request, {} # url_for
106
+
107
+ @flash = ActionController::Flash::FlashHash.new
108
+ session['flash'] = @flash
109
+
110
+ @output_buffer = ""
111
+ @template = helper
112
+ ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
113
+
114
+ helper.session = session
115
+ helper.request = @request
116
+ helper.flash = flash
117
+ helper.params = params
118
+ helper.controller = @controller
119
+ end
120
+
121
+ def flash
122
+ @flash
123
+ end
124
+
125
+ def eval_erb(text)
126
+ erb_args = [text]
127
+ if helper.respond_to?(:output_buffer)
128
+ erb_args += [nil, nil, '@output_buffer']
129
+ end
130
+
131
+ helper.instance_eval do
132
+ ERB.new(*erb_args).result(binding)
133
+ end
134
+ end
135
+
136
+ # TODO: BT - Helper Examples should proxy method_missing to a Rails View instance.
137
+ # When that is done, remove this method
138
+ def protect_against_forgery?
139
+ false
140
+ end
141
+
142
+ Spec::Example::ExampleGroupFactory.register(:helper, self)
143
+
144
+ protected
145
+
146
+ def _assigns_hash_proxy
147
+ @_assigns_hash_proxy ||= AssignsHashProxy.new(self) {helper}
148
+ end
149
+
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,16 @@
1
+ class ActionController::IntegrationTest
2
+ alias_method :orig_initialize, :initialize
3
+ def initialize(*args)
4
+ super
5
+ end
6
+ end
7
+
8
+ module Spec
9
+ module Rails
10
+ module Example
11
+ class IntegrationExampleGroup < ActionController::IntegrationTest
12
+ Spec::Example::ExampleGroupFactory.register(:integration, self)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Spec
2
+ module Rails
3
+ module Example
4
+ # Model examples live in $RAILS_ROOT/spec/models/.
5
+ #
6
+ # Model examples use Spec::Rails::Example::ModelExampleGroup, which
7
+ # provides support for fixtures and some custom expectations via extensions
8
+ # to ActiveRecord::Base.
9
+ base = defined?(ActiveRecord::TestCase) ? ActiveRecord::TestCase : ActiveSupport::TestCase
10
+ class ModelExampleGroup < base
11
+ Spec::Example::ExampleGroupFactory.register(:model, self)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec/mocks/framework'
2
+
3
+ module Spec
4
+ module Rails
5
+ module Example
6
+ # Extends the #should_receive, #should_not_receive and #stub! methods in rspec's
7
+ # mocking framework to handle #render calls to controller in controller examples
8
+ # and template and view examples
9
+ module RenderObserver
10
+
11
+ def verify_rendered # :nodoc:
12
+ render_proxy.rspec_verify
13
+ end
14
+
15
+ def unregister_verify_after_each #:nodoc:
16
+ proc = verify_rendered_proc
17
+ #fix exception with undefined method `remove_after' for Spec::Example::ExampleGroup:Class
18
+ Spec::Example::ExampleGroup.after_each_parts.delete(proc)
19
+ #Spec::Example::ExampleGroup.remove_after(:each, &proc)
20
+ end
21
+
22
+ def should_receive(*args)
23
+ if args[0] == :render
24
+ register_verify_after_each
25
+ render_proxy.should_receive(:render, :expected_from => caller(1)[0])
26
+ else
27
+ super
28
+ end
29
+ end
30
+
31
+ def should_not_receive(*args)
32
+ if args[0] == :render
33
+ register_verify_after_each
34
+ render_proxy.should_not_receive(:render)
35
+ else
36
+ super
37
+ end
38
+ end
39
+
40
+ def stub(*args)
41
+ if args[0] == :render
42
+ register_verify_after_each
43
+ render_proxy.stub(args.first, :expected_from => caller(1)[0])
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ # FIXME - for some reason, neither alias nor alias_method are working
50
+ # as expected in the else branch, so this is a duplicate of stub()
51
+ # above. Could delegate, but then we'd run into craziness handling
52
+ # :expected_from. This will have to do for the moment.
53
+ def stub!(*args)
54
+ if args[0] == :render
55
+ register_verify_after_each
56
+ render_proxy.stub!(args.first, :expected_from => caller(1)[0])
57
+ else
58
+ super
59
+ end
60
+ end
61
+
62
+ def verify_rendered_proc #:nodoc:
63
+ template = self
64
+ @verify_rendered_proc ||= Proc.new do
65
+ template.verify_rendered
66
+ template.unregister_verify_after_each
67
+ end
68
+ end
69
+
70
+ def register_verify_after_each #:nodoc:
71
+ proc = verify_rendered_proc
72
+ Spec::Example::ExampleGroup.after(:each, &proc)
73
+ end
74
+
75
+ def render_proxy #:nodoc:
76
+ @render_proxy ||= Spec::Mocks::Mock.new("render_proxy")
77
+ end
78
+
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,16 @@
1
+ module Spec
2
+ module Rails
3
+ module Example
4
+
5
+ class RoutingExampleGroup < ActionController::TestCase
6
+ class RoutingController < ActionController::Base
7
+ end
8
+
9
+ tests RoutingController
10
+
11
+ Spec::Example::ExampleGroupFactory.register(:routing, self)
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,66 @@
1
+ require 'rack/utils'
2
+
3
+ module Spec
4
+ module Rails
5
+ module Example
6
+ module RoutingHelpers
7
+
8
+ class RouteFor
9
+ def initialize(example, options)
10
+ @example, @options = example, options
11
+ end
12
+
13
+ def ==(expected)
14
+ if Hash === expected
15
+ path, querystring = expected[:path].split('?')
16
+ path_string = path
17
+ path = expected.merge(:path => path)
18
+ else
19
+ path, querystring = expected.split('?')
20
+ path_string = path
21
+ path = { :path => path, :method => :get }
22
+ end
23
+ params = querystring.blank? ? {} : Rack::Utils.parse_query(querystring).symbolize_keys!
24
+ begin
25
+ @example.assert_routing(path, @options, {}, params)
26
+ true
27
+ rescue ActionController::RoutingError, ::Test::Unit::AssertionFailedError => e
28
+ raise e.class, "#{e}\nIf you're expecting this failure, we suggest {:#{path[:method]}=>\"#{path[:path]}\"}.should_not be_routable"
29
+ end
30
+ end
31
+ end
32
+ # Uses ActionController::Routing::Routes to generate
33
+ # the correct route for a given set of options.
34
+ # == Examples
35
+ # route_for(:controller => 'registrations', :action => 'edit', :id => '1')
36
+ # => '/registrations/1/edit'
37
+ # route_for(:controller => 'registrations', :action => 'create')
38
+ # => {:path => "/registrations", :method => :post}
39
+ def route_for(options)
40
+ RouteFor.new(self, options)
41
+ end
42
+
43
+ # Uses ActionController::Routing::Routes to parse
44
+ # an incoming path so the parameters it generates can be checked
45
+ #
46
+ # Note that this method is obsoleted by the route_to matcher.
47
+ # == Example
48
+ # params_from(:get, '/registrations/1/edit')
49
+ # => :controller => 'registrations', :action => 'edit', :id => '1'
50
+ def params_from(method, path)
51
+ ensure_that_routes_are_loaded
52
+ path, querystring = path.split('?')
53
+ params = ActionController::Routing::Routes.recognize_path(path, :method => method)
54
+ querystring.blank? ? params : params.merge(Rack::Utils.parse_query(querystring).symbolize_keys!)
55
+ end
56
+
57
+ private
58
+
59
+ def ensure_that_routes_are_loaded
60
+ ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty?
61
+ end
62
+
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,203 @@
1
+ module Spec
2
+ module Rails
3
+ module Example
4
+ class ViewExampleGroupController < ApplicationController #:nodoc:
5
+ include Spec::Rails::Example::RenderObserver
6
+ attr_reader :template
7
+
8
+ def add_helper_for(template_path)
9
+ add_helper(template_path.split('/')[0])
10
+ end
11
+
12
+ def add_helper(name)
13
+ begin
14
+ helper_module = "#{name}_helper".camelize.constantize
15
+ rescue
16
+ return
17
+ end
18
+ (class << template; self; end).class_eval do
19
+ include helper_module
20
+ end
21
+ end
22
+
23
+ def forget_variables_added_to_assigns
24
+ end
25
+ end
26
+
27
+ # View Examples live in $RAILS_ROOT/spec/views/.
28
+ #
29
+ # View Specs use Spec::Rails::Example::ViewExampleGroup,
30
+ # which provides access to views without invoking any of your controllers.
31
+ # See Spec::Rails::Expectations::Matchers for information about specific
32
+ # expectations that you can set on views.
33
+ #
34
+ # == Example
35
+ #
36
+ # describe "login/login" do
37
+ # before do
38
+ # render 'login/login'
39
+ # end
40
+ #
41
+ # it "should display login form" do
42
+ # response.should have_tag("form[action=/login]") do
43
+ # with_tag("input[type=text][name=email]")
44
+ # with_tag("input[type=password][name=password]")
45
+ # with_tag("input[type=submit][value=Login]")
46
+ # end
47
+ # end
48
+ # end
49
+ class ViewExampleGroup < FunctionalExampleGroup
50
+ if ActionView::Base.respond_to?(:load_helpers) # Rails 2.0.x
51
+ ActionView::Helpers.constants.each do |name|
52
+ const = ActionView::Helpers.const_get(name)
53
+ include const if name.include?("Helper") && Module === const
54
+ end
55
+ elsif ActionView::Base.respond_to?(:helper_modules) # Rails 2.1.x
56
+ ActionView::Base.helper_modules.each do |helper_module|
57
+ include helper_module
58
+ end
59
+ else # Rails 2.2.x
60
+ include ActionView::Helpers
61
+ end
62
+
63
+ tests ViewExampleGroupController
64
+ class << self
65
+ def inherited(klass) # :nodoc:
66
+ klass.subject { template }
67
+ super
68
+ end
69
+ end
70
+
71
+ before {ensure_that_flash_and_session_work_properly}
72
+ after {ensure_that_base_view_path_is_not_set_across_example_groups}
73
+
74
+ def ensure_that_flash_and_session_work_properly #:nodoc:
75
+ # For some reason which I do not yet understand, when running
76
+ # examples with rake on ruby-1.9.2, the @controller is not defined.
77
+ @controller ||= ViewExampleGroupController.new
78
+
79
+ @controller.class.__send__ :public, :flash
80
+ @controller.__send__ :initialize_template_class, @response
81
+ @controller.__send__ :assign_shortcuts, @request, @response
82
+ @controller.__send__ :initialize_current_url
83
+ @session = @controller.session
84
+ end
85
+
86
+ def ensure_that_base_view_path_is_not_set_across_example_groups #:nodoc:
87
+ ActionView::Base.base_view_path = nil
88
+ end
89
+
90
+ def set_base_view_path(options) #:nodoc:
91
+ ActionView::Base.base_view_path = base_view_path(options)
92
+ end
93
+
94
+ def base_view_path(options) #:nodoc:
95
+ "/#{derived_controller_name(options)}/"
96
+ end
97
+
98
+ def derived_controller_name(options) #:nodoc:
99
+ parts = subject_of_render(options).split('/').reject { |part| part.empty? }
100
+ "#{parts[0..-2].join('/')}"
101
+ end
102
+
103
+ def derived_action_name(options) #:nodoc:
104
+ parts = subject_of_render(options).split('/').reject { |part| part.empty? }
105
+ "#{parts.last}".split('.').first
106
+ end
107
+
108
+ def subject_of_render(options) #:nodoc:
109
+ [:template, :partial, :file].each do |render_type|
110
+ if options.has_key?(render_type)
111
+ return options[render_type]
112
+ end
113
+ end
114
+ return ""
115
+ end
116
+
117
+ def add_helpers(options) #:nodoc:
118
+ @controller.add_helper("application")
119
+ @controller.add_helper(derived_controller_name(options))
120
+ @controller.add_helper(options[:helper]) if options[:helper]
121
+ options[:helpers].each { |helper| @controller.add_helper(helper) } if options[:helpers]
122
+ end
123
+
124
+ # Renders a template for a View Spec, which then provides access to the result
125
+ # through the +response+. Also supports render with :inline, which you can
126
+ # use to spec custom form builders, helpers, etc, in the context of a view.
127
+ #
128
+ # == Examples
129
+ #
130
+ # render('/people/list')
131
+ # render('/people/list', :helper => My)
132
+ # render('/people/list', :helpers => [My, MyOther])
133
+ # render(:partial => '/people/_address')
134
+ # render(:inline => "<% custom_helper 'argument', 'another argument' %>")
135
+ #
136
+ # See Spec::Rails::Example::ViewExampleGroup for more information.
137
+ def render(*args)
138
+ options = Hash === args.last ? args.pop : {}
139
+
140
+ if args.empty?
141
+ unless [:partial, :inline, :file, :template, :xml, :json, :update].any? {|k| options.has_key? k}
142
+ args << self.class.description_parts.first
143
+ end
144
+ end
145
+
146
+ options[:template] = args.first.to_s.sub(/^\//,'') unless args.empty?
147
+
148
+ set_base_view_path(options)
149
+ add_helpers(options)
150
+
151
+ assigns[:action_name] = @action_name
152
+
153
+ @request.path_parameters = @request.path_parameters.merge(
154
+ :controller => derived_controller_name(options),
155
+ :action => derived_action_name(options)
156
+ ).merge(options[:path_parameters] || {})
157
+
158
+ defaults = { :layout => false }
159
+ options = defaults.merge options
160
+
161
+ @controller.__send__(:params).reverse_merge! @request.parameters
162
+
163
+ @controller.class.instance_eval %{
164
+ def controller_path
165
+ "#{derived_controller_name(options)}"
166
+ end
167
+
168
+ def controller_name
169
+ "#{derived_controller_name(options).split('/').last}"
170
+ end
171
+ }
172
+
173
+ @controller.__send__ :forget_variables_added_to_assigns
174
+ @controller.__send__ :render, options
175
+ @controller.__send__ :process_cleanup
176
+ end
177
+
178
+ # This provides the template. Use this to set mock
179
+ # expectations for dealing with partials
180
+ #
181
+ # == Example
182
+ #
183
+ # describe "/person/new" do
184
+ # it "should use the form partial" do
185
+ # template.should_receive(:render).with(:partial => 'form')
186
+ # render "/person/new"
187
+ # end
188
+ # end
189
+ def template
190
+ @controller.template
191
+ end
192
+
193
+ Spec::Example::ExampleGroupFactory.register(:view, self)
194
+
195
+ protected
196
+ def _assigns_hash_proxy
197
+ @_assigns_hash_proxy ||= AssignsHashProxy.new(self) {@response.template}
198
+ end
199
+ end
200
+
201
+ end
202
+ end
203
+ end