rspec-rails-w-factory_girl 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. data/.document +7 -0
  2. data/Contribute.rdoc +4 -0
  3. data/History.rdoc +310 -0
  4. data/License.txt +33 -0
  5. data/Manifest.txt +166 -0
  6. data/README.rdoc +45 -0
  7. data/Rakefile +72 -0
  8. data/TODO.txt +17 -0
  9. data/Upgrade.rdoc +148 -0
  10. data/generators/integration_spec/integration_spec_generator.rb +10 -0
  11. data/generators/integration_spec/templates/integration_spec.rb +4 -0
  12. data/generators/rspec/CHANGES +1 -0
  13. data/generators/rspec/rspec_generator.rb +73 -0
  14. data/generators/rspec/templates/previous_failures.txt +0 -0
  15. data/generators/rspec/templates/rcov.opts +2 -0
  16. data/generators/rspec/templates/rspec.rake +144 -0
  17. data/generators/rspec/templates/script/autospec +6 -0
  18. data/generators/rspec/templates/script/spec +10 -0
  19. data/generators/rspec/templates/spec.opts +4 -0
  20. data/generators/rspec/templates/spec_helper.rb +54 -0
  21. data/generators/rspec_controller/USAGE +33 -0
  22. data/generators/rspec_controller/rspec_controller_generator.rb +47 -0
  23. data/generators/rspec_controller/templates/controller_spec.rb +25 -0
  24. data/generators/rspec_controller/templates/helper_spec.rb +11 -0
  25. data/generators/rspec_controller/templates/view_spec.rb +12 -0
  26. data/generators/rspec_default_values.rb +28 -0
  27. data/generators/rspec_model/USAGE +18 -0
  28. data/generators/rspec_model/rspec_model_generator.rb +34 -0
  29. data/generators/rspec_model/templates/factories.rb +8 -0
  30. data/generators/rspec_model/templates/model_spec.rb +13 -0
  31. data/generators/rspec_scaffold/rspec_scaffold_generator.rb +154 -0
  32. data/generators/rspec_scaffold/templates/controller_spec.rb +131 -0
  33. data/generators/rspec_scaffold/templates/edit_erb_spec.rb +25 -0
  34. data/generators/rspec_scaffold/templates/helper_spec.rb +11 -0
  35. data/generators/rspec_scaffold/templates/index_erb_spec.rb +27 -0
  36. data/generators/rspec_scaffold/templates/new_erb_spec.rb +25 -0
  37. data/generators/rspec_scaffold/templates/routing_spec.rb +33 -0
  38. data/generators/rspec_scaffold/templates/show_erb_spec.rb +22 -0
  39. data/init.rb +9 -0
  40. data/lib/autotest/discover.rb +5 -0
  41. data/lib/autotest/rails_rspec.rb +76 -0
  42. data/lib/spec/rails/example/assigns_hash_proxy.rb +39 -0
  43. data/lib/spec/rails/example/controller_example_group.rb +285 -0
  44. data/lib/spec/rails/example/cookies_proxy.rb +29 -0
  45. data/lib/spec/rails/example/functional_example_group.rb +106 -0
  46. data/lib/spec/rails/example/helper_example_group.rb +153 -0
  47. data/lib/spec/rails/example/integration_example_group.rb +16 -0
  48. data/lib/spec/rails/example/model_example_group.rb +15 -0
  49. data/lib/spec/rails/example/render_observer.rb +80 -0
  50. data/lib/spec/rails/example/routing_example_group.rb +13 -0
  51. data/lib/spec/rails/example/routing_helpers.rb +66 -0
  52. data/lib/spec/rails/example/view_example_group.rb +199 -0
  53. data/lib/spec/rails/example.rb +48 -0
  54. data/lib/spec/rails/extensions/action_controller/rescue.rb +42 -0
  55. data/lib/spec/rails/extensions/action_controller/test_case.rb +16 -0
  56. data/lib/spec/rails/extensions/action_controller/test_response.rb +21 -0
  57. data/lib/spec/rails/extensions/action_view/base.rb +35 -0
  58. data/lib/spec/rails/extensions/active_record/base.rb +45 -0
  59. data/lib/spec/rails/extensions/active_support/test_case.rb +7 -0
  60. data/lib/spec/rails/extensions/spec/matchers/have.rb +23 -0
  61. data/lib/spec/rails/extensions/spec/runner/configuration.rb +44 -0
  62. data/lib/spec/rails/extensions.rb +11 -0
  63. data/lib/spec/rails/interop/testcase.rb +14 -0
  64. data/lib/spec/rails/matchers/ar_be_valid.rb +27 -0
  65. data/lib/spec/rails/matchers/assert_select.rb +180 -0
  66. data/lib/spec/rails/matchers/change.rb +13 -0
  67. data/lib/spec/rails/matchers/have_text.rb +57 -0
  68. data/lib/spec/rails/matchers/include_text.rb +54 -0
  69. data/lib/spec/rails/matchers/redirect_to.rb +126 -0
  70. data/lib/spec/rails/matchers/render_template.rb +129 -0
  71. data/lib/spec/rails/matchers/route_to.rb +149 -0
  72. data/lib/spec/rails/matchers.rb +32 -0
  73. data/lib/spec/rails/mocks.rb +136 -0
  74. data/lib/spec/rails/version.rb +16 -0
  75. data/lib/spec/rails.rb +26 -0
  76. data/spec/autotest/mappings_spec.rb +86 -0
  77. data/spec/rails_suite.rb +7 -0
  78. data/spec/resources/controllers/action_view_base_spec_controller.rb +2 -0
  79. data/spec/resources/controllers/application.rb +9 -0
  80. data/spec/resources/controllers/controller_spec_controller.rb +127 -0
  81. data/spec/resources/controllers/example.txt +1 -0
  82. data/spec/resources/controllers/redirect_spec_controller.rb +70 -0
  83. data/spec/resources/controllers/render_spec_controller.rb +34 -0
  84. data/spec/resources/controllers/rjs_spec_controller.rb +58 -0
  85. data/spec/resources/helpers/addition_helper.rb +5 -0
  86. data/spec/resources/helpers/explicit_helper.rb +46 -0
  87. data/spec/resources/helpers/more_explicit_helper.rb +5 -0
  88. data/spec/resources/helpers/plugin_application_helper.rb +6 -0
  89. data/spec/resources/helpers/view_spec_helper.rb +13 -0
  90. data/spec/resources/models/animal.rb +4 -0
  91. data/spec/resources/models/person.rb +18 -0
  92. data/spec/resources/models/thing.rb +3 -0
  93. data/spec/resources/views/controller_spec/_partial.html.erb +0 -0
  94. data/spec/resources/views/controller_spec/action_setting_flash_after_session_reset.html.erb +1 -0
  95. data/spec/resources/views/controller_spec/action_setting_flash_before_session_reset.html.erb +1 -0
  96. data/spec/resources/views/controller_spec/action_setting_the_assigns_hash.html.erb +0 -0
  97. data/spec/resources/views/controller_spec/action_with_errors_in_template.html.erb +1 -0
  98. data/spec/resources/views/controller_spec/action_with_template.html.erb +1 -0
  99. data/spec/resources/views/layouts/application.html.erb +0 -0
  100. data/spec/resources/views/layouts/simple.html.erb +0 -0
  101. data/spec/resources/views/objects/_object.html.erb +1 -0
  102. data/spec/resources/views/render_spec/_a_partial.html.erb +0 -0
  103. data/spec/resources/views/render_spec/action_with_alternate_layout.html.erb +0 -0
  104. data/spec/resources/views/render_spec/some_action.html.erb +0 -0
  105. data/spec/resources/views/render_spec/some_action.js.rjs +1 -0
  106. data/spec/resources/views/rjs_spec/_replacement_partial.html.erb +1 -0
  107. data/spec/resources/views/rjs_spec/hide_div.js.rjs +1 -0
  108. data/spec/resources/views/rjs_spec/hide_page_element.js.rjs +1 -0
  109. data/spec/resources/views/rjs_spec/insert_html.js.rjs +1 -0
  110. data/spec/resources/views/rjs_spec/replace.js.rjs +1 -0
  111. data/spec/resources/views/rjs_spec/replace_html.js.rjs +1 -0
  112. data/spec/resources/views/rjs_spec/replace_html_with_partial.js.rjs +1 -0
  113. data/spec/resources/views/rjs_spec/visual_effect.js.rjs +1 -0
  114. data/spec/resources/views/rjs_spec/visual_toggle_effect.js.rjs +1 -0
  115. data/spec/resources/views/tag_spec/no_tags.html.erb +1 -0
  116. data/spec/resources/views/tag_spec/single_div_with_no_attributes.html.erb +1 -0
  117. data/spec/resources/views/tag_spec/single_div_with_one_attribute.html.erb +1 -0
  118. data/spec/resources/views/view_spec/_partial.html.erb +2 -0
  119. data/spec/resources/views/view_spec/_partial_used_twice.html.erb +0 -0
  120. data/spec/resources/views/view_spec/_partial_with_local_variable.html.erb +1 -0
  121. data/spec/resources/views/view_spec/_partial_with_sub_partial.html.erb +1 -0
  122. data/spec/resources/views/view_spec/_spacer.html.erb +1 -0
  123. data/spec/resources/views/view_spec/accessor.html.erb +6 -0
  124. data/spec/resources/views/view_spec/block_helper.html.erb +3 -0
  125. data/spec/resources/views/view_spec/entry_form.html.erb +2 -0
  126. data/spec/resources/views/view_spec/explicit_helper.html.erb +2 -0
  127. data/spec/resources/views/view_spec/foo/show.html.erb +1 -0
  128. data/spec/resources/views/view_spec/implicit_helper.html.erb +2 -0
  129. data/spec/resources/views/view_spec/multiple_helpers.html.erb +3 -0
  130. data/spec/resources/views/view_spec/path_params.html.erb +1 -0
  131. data/spec/resources/views/view_spec/should_not_receive.html.erb +3 -0
  132. data/spec/resources/views/view_spec/template_with_partial.html.erb +5 -0
  133. data/spec/resources/views/view_spec/template_with_partial_using_collection.html.erb +3 -0
  134. data/spec/resources/views/view_spec/template_with_partial_with_array.html.erb +1 -0
  135. data/spec/resources/views/view_spec/view_helpers.html.erb +1 -0
  136. data/spec/spec/rails/example/assigns_hash_proxy_spec.rb +109 -0
  137. data/spec/spec/rails/example/configuration_spec.rb +65 -0
  138. data/spec/spec/rails/example/controller_example_group_spec.rb +307 -0
  139. data/spec/spec/rails/example/controller_isolation_spec.rb +75 -0
  140. data/spec/spec/rails/example/cookies_proxy_spec.rb +87 -0
  141. data/spec/spec/rails/example/error_handling_spec.rb +90 -0
  142. data/spec/spec/rails/example/example_group_factory_spec.rb +112 -0
  143. data/spec/spec/rails/example/helper_example_group_spec.rb +247 -0
  144. data/spec/spec/rails/example/model_example_group_spec.rb +32 -0
  145. data/spec/spec/rails/example/routing_example_group_spec.rb +10 -0
  146. data/spec/spec/rails/example/shared_routing_example_group_examples.rb +237 -0
  147. data/spec/spec/rails/example/test_unit_assertion_accessibility_spec.rb +33 -0
  148. data/spec/spec/rails/example/view_example_group_spec.rb +346 -0
  149. data/spec/spec/rails/extensions/action_view_base_spec.rb +79 -0
  150. data/spec/spec/rails/extensions/active_record_spec.rb +14 -0
  151. data/spec/spec/rails/interop/testcase_spec.rb +70 -0
  152. data/spec/spec/rails/matchers/ar_be_valid_spec.rb +19 -0
  153. data/spec/spec/rails/matchers/assert_select_spec.rb +835 -0
  154. data/spec/spec/rails/matchers/errors_on_spec.rb +37 -0
  155. data/spec/spec/rails/matchers/have_text_spec.rb +69 -0
  156. data/spec/spec/rails/matchers/include_text_spec.rb +62 -0
  157. data/spec/spec/rails/matchers/redirect_to_spec.rb +253 -0
  158. data/spec/spec/rails/matchers/render_template_spec.rb +208 -0
  159. data/spec/spec/rails/matchers/should_change_spec.rb +15 -0
  160. data/spec/spec/rails/mocks/ar_classes.rb +10 -0
  161. data/spec/spec/rails/mocks/mock_model_spec.rb +109 -0
  162. data/spec/spec/rails/mocks/stub_model_spec.rb +80 -0
  163. data/spec/spec/rails/sample_modified_fixture.rb +8 -0
  164. data/spec/spec/rails/sample_spec.rb +8 -0
  165. data/spec/spec/rails/spec_spec.rb +11 -0
  166. data/spec/spec_helper.rb +78 -0
  167. metadata +301 -0
@@ -0,0 +1,285 @@
1
+ module Spec
2
+ module Rails
3
+ module Example
4
+ # Controller Examples live in $RAILS_ROOT/spec/controllers/.
5
+ #
6
+ # Controller Examples use Spec::Rails::Example::ControllerExampleGroup,
7
+ # which supports running specs for Controllers in two modes, which
8
+ # represent the tension between the more granular testing common in TDD
9
+ # and the more high level testing built into rails. BDD sits somewhere
10
+ # in between: we want to a balance between specs that are close enough
11
+ # to the code to enable quick fault isolation and far enough away from
12
+ # the code to enable refactoring with minimal changes to the existing
13
+ # specs.
14
+ #
15
+ # == Isolation mode (default)
16
+ #
17
+ # No dependencies on views because none are ever rendered. The benefit
18
+ # of this mode is that can spec the controller completely independent of
19
+ # the view, allowing that responsibility to be handled later, or by
20
+ # somebody else. Combined w/ separate view specs, this also provides
21
+ # better fault isolation.
22
+ #
23
+ # == Integration mode
24
+ #
25
+ # To run in this mode, include the +integrate_views+ declaration
26
+ # in your controller context:
27
+ #
28
+ # describe ThingController do
29
+ # integrate_views
30
+ # ...
31
+ #
32
+ # In this mode, controller specs are run in the same way that rails
33
+ # functional tests run - one set of tests for both the controllers and
34
+ # the views. The benefit of this approach is that you get wider coverage
35
+ # from each spec. Experienced rails developers may find this an easier
36
+ # approach to begin with, however we encourage you to explore using the
37
+ # isolation mode and revel in its benefits.
38
+ #
39
+ # == Expecting Errors
40
+ #
41
+ # Rspec on Rails will raise errors that occur in controller actions and
42
+ # are not rescued or handeled with rescue_from.
43
+ #
44
+ class ControllerExampleGroup < FunctionalExampleGroup
45
+ class << self
46
+
47
+ # Use integrate_views to instruct RSpec to render views in
48
+ # your controller examples in Integration mode.
49
+ #
50
+ # describe ThingController do
51
+ # integrate_views
52
+ # ...
53
+ #
54
+ # See Spec::Rails::Example::ControllerExampleGroup for more
55
+ # information about Integration and Isolation modes.
56
+ def integrate_views(integrate_views = true)
57
+ @integrate_views = integrate_views
58
+ end
59
+
60
+ def integrate_views? # :nodoc:
61
+ @integrate_views
62
+ end
63
+
64
+ def inherited(klass) # :nodoc:
65
+ klass.integrate_views(integrate_views?)
66
+ klass.subject { controller }
67
+ super
68
+ end
69
+
70
+ def set_description(*args) # :nodoc:
71
+ super
72
+ if described_class && described_class.ancestors.include?(ActionController::Base)
73
+ controller_klass = if superclass.controller_class.ancestors.include?(ActionController::Base)
74
+ superclass.controller_class
75
+ else
76
+ described_class
77
+ end
78
+ tests controller_klass
79
+ end
80
+ end
81
+
82
+ # When you don't pass a controller to describe, like this:
83
+ #
84
+ # describe ThingsController do
85
+ #
86
+ # ... then you must provide a controller_name within the context of
87
+ # your controller specs:
88
+ #
89
+ # describe "ThingController" do
90
+ # controller_name :thing
91
+ # ...
92
+ def controller_name(name)
93
+ tests "#{name}_controller".camelize.constantize
94
+ end
95
+ end
96
+
97
+ before(:each) do
98
+ # Some Rails apps explicitly disable ActionMailer in environment.rb
99
+ if defined?(ActionMailer)
100
+ @deliveries = []
101
+ ActionMailer::Base.deliveries = @deliveries
102
+ end
103
+
104
+ unless @controller.class.ancestors.include?(ActionController::Base)
105
+ Spec::Expectations.fail_with <<-MESSAGE
106
+ Controller specs need to know what controller is being specified. You can
107
+ indicate this by passing the controller to describe():
108
+
109
+ describe MyController do
110
+
111
+ or by declaring the controller's name
112
+
113
+ describe "a MyController" do
114
+ controller_name :my #invokes the MyController
115
+ end
116
+ MESSAGE
117
+ end
118
+ @controller.extend ControllerInstanceMethods
119
+ @controller.integrate_views! if integrate_views?
120
+ @controller.session = session
121
+ end
122
+
123
+ attr_reader :response, :request, :controller
124
+
125
+ def integrate_views?
126
+ @integrate_views || self.class.integrate_views?
127
+ end
128
+
129
+ # Bypasses any error rescues defined with rescue_from. Useful
130
+ # in cases in which you want to specify errors coming out of
131
+ # actions that might be caught by a rescue_from clause that is
132
+ # specified separately.
133
+ #
134
+ # Note that this will override the effect of rescue_action_in_public
135
+ def bypass_rescue
136
+ if ::Rails::VERSION::STRING >= '2.2'
137
+ def controller.rescue_action(exception)
138
+ raise exception
139
+ end
140
+ else
141
+ def controller.rescue_action_with_handler(exception)
142
+ raise exception
143
+ end
144
+ end
145
+ end
146
+
147
+ protected
148
+
149
+ def _assigns_hash_proxy
150
+ @_assigns_hash_proxy ||= AssignsHashProxy.new(self) {@response.template}
151
+ end
152
+
153
+ private
154
+
155
+ module TemplateIsolationExtensions
156
+ def file_exists?(ignore); true; end
157
+
158
+ def render_file(*args)
159
+ @first_render ||= args[0] unless args[0] =~ /^layouts/
160
+ end
161
+
162
+ # Rails 2.2
163
+ def _pick_template(*args)
164
+ @_first_render ||= args[0] unless args[0] =~ /^layouts/
165
+ PickedTemplate.new
166
+ end
167
+
168
+ def __action_exists?(params)
169
+ controller.respond_to? params[:action]
170
+ end
171
+
172
+ def __template_exists?(args)
173
+ self.view_paths.respond_to?(:find_template) ?
174
+ self.view_paths.find_template(args[0][:file], template_format) :
175
+ false
176
+ end
177
+
178
+ def render(*args)
179
+ if ::Rails::VERSION::STRING >= "2.1"
180
+ return super unless __action_exists?(params) || __template_exists?(args)
181
+ end
182
+ if file = args.last[:file].instance_eval{@template_path}
183
+ record_render :file => file
184
+ elsif args.last[:inline]
185
+ super
186
+ elsif @_rendered
187
+ record_render(args[0])
188
+ else
189
+ super
190
+ end
191
+ end
192
+
193
+ private
194
+
195
+ def record_render(opts)
196
+ return unless @_rendered
197
+ @_rendered[:template] ||= opts[:file] if opts[:file]
198
+ @_rendered[:partials][opts[:partial]] += 1 if opts[:partial]
199
+ end
200
+
201
+ # Returned by _pick_template when running controller examples in isolation mode.
202
+ class PickedTemplate
203
+ # Do nothing when running controller examples in isolation mode.
204
+ def render_template(*ignore_args); end
205
+ # Do nothing when running controller examples in isolation mode.
206
+ def render_partial(*ignore_args); end
207
+ end
208
+ end
209
+
210
+ module ControllerInstanceMethods # :nodoc:
211
+ include Spec::Rails::Example::RenderObserver
212
+
213
+ # === render(options = nil, extra_options={}, &block)
214
+ #
215
+ # This gets added to the controller's singleton meta class,
216
+ # allowing Controller Examples to run in two modes, freely switching
217
+ # from example group to example group.
218
+ def render(options=nil, extra_options={}, &block)
219
+ unless block_given?
220
+ unless integrate_views?
221
+ @template.extend TemplateIsolationExtensions
222
+ end
223
+ end
224
+
225
+ if matching_message_expectation_exists(options)
226
+ render_proxy.render(options, &block)
227
+ @performed_render = true
228
+ else
229
+ if matching_stub_exists(options)
230
+ @performed_render = true
231
+ else
232
+ if ::Rails::VERSION::STRING > '2.1'
233
+ super(options, extra_options, &block)
234
+ else
235
+ super(options, &block)
236
+ end
237
+ end
238
+ end
239
+ end
240
+
241
+ # Rails 2.3
242
+ def default_template(action_name = self.action_name)
243
+ if integrate_views?
244
+ super
245
+ else
246
+ begin
247
+ super
248
+ rescue ActionView::MissingTemplate
249
+ "#{self.class.name.sub(/Controller$/,'').underscore}/#{action_name}"
250
+ end
251
+ end
252
+ end
253
+
254
+ def response(&block)
255
+ # NOTE - we're setting @update for the assert_select_spec - kinda weird, huh?
256
+ @update = block
257
+ super
258
+ end
259
+
260
+ def integrate_views!
261
+ @integrate_views = true
262
+ end
263
+
264
+ private
265
+
266
+ def integrate_views?
267
+ @integrate_views
268
+ end
269
+
270
+ def matching_message_expectation_exists(options)
271
+ render_proxy.__send__(:__mock_proxy).__send__(:find_matching_expectation, :render, options)
272
+ end
273
+
274
+ def matching_stub_exists(options)
275
+ render_proxy.__send__(:__mock_proxy).__send__(:find_matching_method_stub, :render, options)
276
+ end
277
+
278
+ end
279
+
280
+ Spec::Example::ExampleGroupFactory.register(:controller, self)
281
+
282
+ end
283
+ end
284
+ end
285
+ end
@@ -0,0 +1,29 @@
1
+ require 'action_controller/cookies'
2
+
3
+ module Spec
4
+ module Rails
5
+ module Example
6
+ class CookiesProxy
7
+ def initialize(example)
8
+ @example = example
9
+ end
10
+
11
+ def[]=(name, value)
12
+ if ::Rails::VERSION::STRING >= '2.3'
13
+ @example.request.cookies[name.to_s] = value
14
+ else
15
+ @example.request.cookies[name.to_s] = CGI::Cookie.new(name.to_s, value)
16
+ end
17
+ end
18
+
19
+ def [](name)
20
+ @example.response.cookies[name.to_s]
21
+ end
22
+
23
+ def delete(name)
24
+ @example.response.cookies.delete(name.to_s)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,106 @@
1
+ require 'action_controller/test_case'
2
+
3
+ module Spec
4
+ module Rails
5
+ module Example
6
+ class FunctionalExampleGroup < ActionController::TestCase
7
+ def setup
8
+ # no-op to override AC::TC's setup w/ conflicts with the before(:each) below
9
+ end
10
+
11
+ attr_reader :request, :response
12
+
13
+ # The params hash accessed within a view or helper. Use this before
14
+ # rendering a view or calling a helper to provide data used by the
15
+ # view or helper.
16
+ #
17
+ # == Examples
18
+ # # in a view spec
19
+ # params[:name] = "David"
20
+ # render
21
+ # response.should have_tag("div.name","David")
22
+ #
23
+ # # in a helper spec
24
+ # params[:first_name] = "David"
25
+ # params[:last_name] = "Chelimsky"
26
+ # helper.full_name.should == "David Chelimsky"
27
+ def params
28
+ request.parameters
29
+ end
30
+
31
+ # Provides access to the flash hash. Use this after rendering a
32
+ # view, calling a helper or calling a controller action.
33
+ #
34
+ # == Examples
35
+ # post :create
36
+ # flash[:notice].should == "Success!"
37
+ def flash
38
+ @controller.__send__ :flash
39
+ end
40
+
41
+ # Provides access to the session hash. Use this before or after
42
+ # rendering a view, calling a helper or calling a controller action.
43
+ def session
44
+ request.session
45
+ end
46
+
47
+ # Overrides the <tt>cookies()</tt> method in
48
+ # ActionController::TestResponseBehaviour, returning a proxy that
49
+ # accesses the requests cookies when setting a cookie and the
50
+ # responses cookies when reading one. This allows you to set and read
51
+ # cookies in examples using the same API with which you set and read
52
+ # them in controllers.
53
+ #
54
+ # == Examples (Rails 2.0 > 2.2)
55
+ #
56
+ # cookies[:user_id] = {:value => '1234', :expires => 1.minute.ago}
57
+ # get :index
58
+ # response.should be_redirect
59
+ #
60
+ # == Examples (Rails 2.3)
61
+ #
62
+ # Rails 2.3 changes the way cookies are made available to functional
63
+ # tests (and therefore rspec controller specs), only making single
64
+ # values available with no access to other aspects of the cookie. This
65
+ # is backwards-incompatible, so you have to change your examples to
66
+ # look like this:
67
+ #
68
+ # cookies[:foo] = 'bar'
69
+ # get :index
70
+ # cookies[:foo].should == 'bar'
71
+ def cookies
72
+ @cookies ||= Spec::Rails::Example::CookiesProxy.new(self)
73
+ end
74
+
75
+ alias_method :orig_assigns, :assigns
76
+
77
+ # :call-seq:
78
+ # assigns()
79
+ #
80
+ # Hash of instance variables to values that are made available to
81
+ # views. == Examples
82
+ #
83
+ # #in thing_controller.rb
84
+ # def new
85
+ # @thing = Thing.new
86
+ # end
87
+ #
88
+ # #in thing_controller_spec
89
+ # get 'new'
90
+ # assigns[:registration].should == Thing.new
91
+ #--
92
+ # NOTE - Even though docs only use assigns[:key] format, this supports
93
+ # assigns(:key) for backwards compatibility.
94
+ #++
95
+ def assigns(key = nil)
96
+ if key.nil?
97
+ _assigns_hash_proxy
98
+ else
99
+ _assigns_hash_proxy[key]
100
+ end
101
+ end
102
+
103
+ end
104
+ end
105
+ end
106
+ end
@@ -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
+ returning HelperObject.new 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,80 @@
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
+ Spec::Example::ExampleGroup.remove_after(:each, &proc)
18
+ end
19
+
20
+ def should_receive(*args)
21
+ if args[0] == :render
22
+ register_verify_after_each
23
+ render_proxy.should_receive(:render, :expected_from => caller(1)[0])
24
+ else
25
+ super
26
+ end
27
+ end
28
+
29
+ def should_not_receive(*args)
30
+ if args[0] == :render
31
+ register_verify_after_each
32
+ render_proxy.should_not_receive(:render)
33
+ else
34
+ super
35
+ end
36
+ end
37
+
38
+ def stub(*args)
39
+ if args[0] == :render
40
+ register_verify_after_each
41
+ render_proxy.stub(args.first, :expected_from => caller(1)[0])
42
+ else
43
+ super
44
+ end
45
+ end
46
+
47
+ # FIXME - for some reason, neither alias nor alias_method are working
48
+ # as expected in the else branch, so this is a duplicate of stub()
49
+ # above. Could delegate, but then we'd run into craziness handling
50
+ # :expected_from. This will have to do for the moment.
51
+ def stub!(*args)
52
+ if args[0] == :render
53
+ register_verify_after_each
54
+ render_proxy.stub!(args.first, :expected_from => caller(1)[0])
55
+ else
56
+ super
57
+ end
58
+ end
59
+
60
+ def verify_rendered_proc #:nodoc:
61
+ template = self
62
+ @verify_rendered_proc ||= Proc.new do
63
+ template.verify_rendered
64
+ template.unregister_verify_after_each
65
+ end
66
+ end
67
+
68
+ def register_verify_after_each #:nodoc:
69
+ proc = verify_rendered_proc
70
+ Spec::Example::ExampleGroup.after(:each, &proc)
71
+ end
72
+
73
+ def render_proxy #:nodoc:
74
+ @render_proxy ||= Spec::Mocks::Mock.new("render_proxy")
75
+ end
76
+
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,13 @@
1
+ module Spec
2
+ module Rails
3
+ module Example
4
+
5
+ class RoutingExampleGroup < ActionController::TestCase
6
+ tests Class.new(ActionController::Base)
7
+
8
+ Spec::Example::ExampleGroupFactory.register(:routing, self)
9
+ end
10
+
11
+ end
12
+ end
13
+ end