mcmire-rspec-rails 1.1.99.9

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 (164) hide show
  1. data/History.txt +174 -0
  2. data/License.txt +33 -0
  3. data/Manifest.txt +164 -0
  4. data/README.txt +45 -0
  5. data/Rakefile +63 -0
  6. data/TODO.txt +1 -0
  7. data/Upgrade.markdown +52 -0
  8. data/features/step_definitions/people.rb +6 -0
  9. data/features/support/env.rb +13 -0
  10. data/features/transactions/transactions_should_rollback.feature +16 -0
  11. data/generators/rspec/CHANGES +1 -0
  12. data/generators/rspec/rspec_generator.rb +37 -0
  13. data/generators/rspec/templates/previous_failures.txt +0 -0
  14. data/generators/rspec/templates/rcov.opts +2 -0
  15. data/generators/rspec/templates/rspec.rake +177 -0
  16. data/generators/rspec/templates/script/autospec +5 -0
  17. data/generators/rspec/templates/script/spec +4 -0
  18. data/generators/rspec/templates/script/spec_server +37 -0
  19. data/generators/rspec/templates/spec.opts +4 -0
  20. data/generators/rspec/templates/spec_helper.rb +47 -0
  21. data/generators/rspec_controller/USAGE +33 -0
  22. data/generators/rspec_controller/rspec_controller_generator.rb +45 -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 +19 -0
  27. data/generators/rspec_model/USAGE +18 -0
  28. data/generators/rspec_model/rspec_model_generator.rb +35 -0
  29. data/generators/rspec_model/templates/model_spec.rb +15 -0
  30. data/generators/rspec_scaffold/rspec_scaffold_generator.rb +150 -0
  31. data/generators/rspec_scaffold/templates/controller_spec.rb +171 -0
  32. data/generators/rspec_scaffold/templates/edit_erb_spec.rb +27 -0
  33. data/generators/rspec_scaffold/templates/helper_spec.rb +11 -0
  34. data/generators/rspec_scaffold/templates/index_erb_spec.rb +28 -0
  35. data/generators/rspec_scaffold/templates/new_erb_spec.rb +27 -0
  36. data/generators/rspec_scaffold/templates/routing_spec.rb +63 -0
  37. data/generators/rspec_scaffold/templates/show_erb_spec.rb +23 -0
  38. data/init.rb +9 -0
  39. data/lib/autotest/discover.rb +1 -0
  40. data/lib/autotest/rails_rspec.rb +76 -0
  41. data/lib/spec/rails.rb +37 -0
  42. data/lib/spec/rails/example.rb +53 -0
  43. data/lib/spec/rails/example/assigns_hash_proxy.rb +39 -0
  44. data/lib/spec/rails/example/controller_example_group.rb +242 -0
  45. data/lib/spec/rails/example/cookies_proxy.rb +29 -0
  46. data/lib/spec/rails/example/functional_example_group.rb +84 -0
  47. data/lib/spec/rails/example/helper_example_group.rb +167 -0
  48. data/lib/spec/rails/example/model_example_group.rb +14 -0
  49. data/lib/spec/rails/example/render_observer.rb +67 -0
  50. data/lib/spec/rails/example/routing_helpers.rb +68 -0
  51. data/lib/spec/rails/example/view_example_group.rb +186 -0
  52. data/lib/spec/rails/extensions.rb +15 -0
  53. data/lib/spec/rails/extensions/action_controller/rescue.rb +42 -0
  54. data/lib/spec/rails/extensions/action_controller/test_case.rb +16 -0
  55. data/lib/spec/rails/extensions/action_controller/test_response.rb +21 -0
  56. data/lib/spec/rails/extensions/action_view/base.rb +33 -0
  57. data/lib/spec/rails/extensions/active_record/base.rb +43 -0
  58. data/lib/spec/rails/extensions/active_support/test_case.rb +7 -0
  59. data/lib/spec/rails/extensions/spec/matchers/have.rb +23 -0
  60. data/lib/spec/rails/extensions/spec/runner/configuration.rb +48 -0
  61. data/lib/spec/rails/interop/testcase.rb +14 -0
  62. data/lib/spec/rails/matchers.rb +40 -0
  63. data/lib/spec/rails/matchers/ar_be_valid.rb +44 -0
  64. data/lib/spec/rails/matchers/assert_select.rb +131 -0
  65. data/lib/spec/rails/matchers/change.rb +11 -0
  66. data/lib/spec/rails/matchers/have_text.rb +57 -0
  67. data/lib/spec/rails/matchers/include_text.rb +54 -0
  68. data/lib/spec/rails/matchers/redirect_to.rb +126 -0
  69. data/lib/spec/rails/matchers/render_template.rb +114 -0
  70. data/lib/spec/rails/mocks.rb +135 -0
  71. data/lib/spec/rails/spec_server.rb +97 -0
  72. data/lib/spec/rails/story_adapter.rb +79 -0
  73. data/lib/spec/rails/version.rb +16 -0
  74. data/rspec-rails.gemspec +39 -0
  75. data/spec/autotest/mappings_spec.rb +36 -0
  76. data/spec/rails_suite.rb +7 -0
  77. data/spec/resources/controllers/action_view_base_spec_controller.rb +2 -0
  78. data/spec/resources/controllers/application.rb +9 -0
  79. data/spec/resources/controllers/controller_spec_controller.rb +116 -0
  80. data/spec/resources/controllers/redirect_spec_controller.rb +70 -0
  81. data/spec/resources/controllers/render_spec_controller.rb +30 -0
  82. data/spec/resources/controllers/rjs_spec_controller.rb +58 -0
  83. data/spec/resources/helpers/addition_helper.rb +5 -0
  84. data/spec/resources/helpers/explicit_helper.rb +46 -0
  85. data/spec/resources/helpers/more_explicit_helper.rb +5 -0
  86. data/spec/resources/helpers/plugin_application_helper.rb +6 -0
  87. data/spec/resources/helpers/view_spec_helper.rb +13 -0
  88. data/spec/resources/models/animal.rb +4 -0
  89. data/spec/resources/models/person.rb +18 -0
  90. data/spec/resources/models/thing.rb +3 -0
  91. data/spec/resources/views/controller_spec/_partial.rhtml +0 -0
  92. data/spec/resources/views/controller_spec/action_setting_flash_after_session_reset.rhtml +1 -0
  93. data/spec/resources/views/controller_spec/action_setting_flash_before_session_reset.rhtml +1 -0
  94. data/spec/resources/views/controller_spec/action_setting_the_assigns_hash.rhtml +0 -0
  95. data/spec/resources/views/controller_spec/action_with_errors_in_template.rhtml +1 -0
  96. data/spec/resources/views/controller_spec/action_with_template.rhtml +1 -0
  97. data/spec/resources/views/layouts/application.rhtml +0 -0
  98. data/spec/resources/views/layouts/simple.rhtml +0 -0
  99. data/spec/resources/views/objects/_object.html.erb +1 -0
  100. data/spec/resources/views/render_spec/_a_partial.rhtml +0 -0
  101. data/spec/resources/views/render_spec/action_with_alternate_layout.rhtml +0 -0
  102. data/spec/resources/views/render_spec/some_action.html.erb +0 -0
  103. data/spec/resources/views/render_spec/some_action.js.rjs +1 -0
  104. data/spec/resources/views/render_spec/some_action.rjs +1 -0
  105. data/spec/resources/views/rjs_spec/_replacement_partial.rhtml +1 -0
  106. data/spec/resources/views/rjs_spec/hide_div.rjs +1 -0
  107. data/spec/resources/views/rjs_spec/hide_page_element.rjs +1 -0
  108. data/spec/resources/views/rjs_spec/insert_html.rjs +1 -0
  109. data/spec/resources/views/rjs_spec/replace.rjs +1 -0
  110. data/spec/resources/views/rjs_spec/replace_html.rjs +1 -0
  111. data/spec/resources/views/rjs_spec/replace_html_with_partial.rjs +1 -0
  112. data/spec/resources/views/rjs_spec/visual_effect.rjs +1 -0
  113. data/spec/resources/views/rjs_spec/visual_toggle_effect.rjs +1 -0
  114. data/spec/resources/views/tag_spec/no_tags.rhtml +1 -0
  115. data/spec/resources/views/tag_spec/single_div_with_no_attributes.rhtml +1 -0
  116. data/spec/resources/views/tag_spec/single_div_with_one_attribute.rhtml +1 -0
  117. data/spec/resources/views/view_spec/_partial.rhtml +2 -0
  118. data/spec/resources/views/view_spec/_partial_used_twice.rhtml +0 -0
  119. data/spec/resources/views/view_spec/_partial_with_local_variable.rhtml +1 -0
  120. data/spec/resources/views/view_spec/_partial_with_sub_partial.rhtml +1 -0
  121. data/spec/resources/views/view_spec/_spacer.rhtml +1 -0
  122. data/spec/resources/views/view_spec/accessor.rhtml +5 -0
  123. data/spec/resources/views/view_spec/block_helper.rhtml +3 -0
  124. data/spec/resources/views/view_spec/entry_form.rhtml +2 -0
  125. data/spec/resources/views/view_spec/explicit_helper.rhtml +2 -0
  126. data/spec/resources/views/view_spec/foo/show.rhtml +1 -0
  127. data/spec/resources/views/view_spec/implicit_helper.rhtml +2 -0
  128. data/spec/resources/views/view_spec/multiple_helpers.rhtml +3 -0
  129. data/spec/resources/views/view_spec/path_params.html.erb +1 -0
  130. data/spec/resources/views/view_spec/should_not_receive.rhtml +3 -0
  131. data/spec/resources/views/view_spec/template_with_partial.rhtml +5 -0
  132. data/spec/resources/views/view_spec/template_with_partial_using_collection.rhtml +3 -0
  133. data/spec/resources/views/view_spec/template_with_partial_with_array.rhtml +1 -0
  134. data/spec/spec/rails/example/assigns_hash_proxy_spec.rb +109 -0
  135. data/spec/spec/rails/example/configuration_spec.rb +65 -0
  136. data/spec/spec/rails/example/controller_example_group_spec.rb +275 -0
  137. data/spec/spec/rails/example/controller_isolation_spec.rb +56 -0
  138. data/spec/spec/rails/example/cookies_proxy_spec.rb +87 -0
  139. data/spec/spec/rails/example/error_handling_spec.rb +90 -0
  140. data/spec/spec/rails/example/example_group_factory_spec.rb +112 -0
  141. data/spec/spec/rails/example/helper_example_group_spec.rb +206 -0
  142. data/spec/spec/rails/example/model_example_group_spec.rb +20 -0
  143. data/spec/spec/rails/example/test_unit_assertion_accessibility_spec.rb +33 -0
  144. data/spec/spec/rails/example/view_example_group_spec.rb +335 -0
  145. data/spec/spec/rails/extensions/action_view_base_spec.rb +48 -0
  146. data/spec/spec/rails/extensions/active_record_spec.rb +14 -0
  147. data/spec/spec/rails/interop/testcase_spec.rb +70 -0
  148. data/spec/spec/rails/matchers/ar_be_valid_spec.rb +45 -0
  149. data/spec/spec/rails/matchers/assert_select_spec.rb +811 -0
  150. data/spec/spec/rails/matchers/errors_on_spec.rb +25 -0
  151. data/spec/spec/rails/matchers/have_text_spec.rb +70 -0
  152. data/spec/spec/rails/matchers/include_text_spec.rb +62 -0
  153. data/spec/spec/rails/matchers/redirect_to_spec.rb +253 -0
  154. data/spec/spec/rails/matchers/render_template_spec.rb +183 -0
  155. data/spec/spec/rails/matchers/should_change_spec.rb +15 -0
  156. data/spec/spec/rails/mocks/ar_classes.rb +10 -0
  157. data/spec/spec/rails/mocks/mock_model_spec.rb +106 -0
  158. data/spec/spec/rails/mocks/stub_model_spec.rb +80 -0
  159. data/spec/spec/rails/sample_modified_fixture.rb +8 -0
  160. data/spec/spec/rails/sample_spec.rb +8 -0
  161. data/spec/spec/rails/spec_server_spec.rb +107 -0
  162. data/spec/spec/rails/spec_spec.rb +11 -0
  163. data/spec/spec_helper.rb +78 -0
  164. metadata +262 -0
@@ -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,84 @@
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
+ def params
14
+ request.parameters
15
+ end
16
+
17
+ def flash
18
+ @controller.__send__ :flash
19
+ end
20
+
21
+ def session
22
+ request.session
23
+ end
24
+
25
+ # Overrides the <tt>cookies()</tt> method in
26
+ # ActionController::TestResponseBehaviour, returning a proxy that
27
+ # accesses the requests cookies when setting a cookie and the
28
+ # responses cookies when reading one. This allows you to set and read
29
+ # cookies in examples using the same API with which you set and read
30
+ # them in controllers.
31
+ #
32
+ # == Examples (Rails 2.0 > 2.2)
33
+ #
34
+ # cookies[:user_id] = {:value => '1234', :expires => 1.minute.ago}
35
+ # get :index
36
+ # response.should be_redirect
37
+ #
38
+ # == Examples (Rails 2.3)
39
+ #
40
+ # Rails 2.3 changes the way cookies are made available to functional
41
+ # tests (and therefore rspec controller specs), only making single
42
+ # values available with no access to other aspects of the cookie. This
43
+ # is backwards-incompatible, so you have to change your examples to
44
+ # look like this:
45
+ #
46
+ # cookies[:foo] = 'bar'
47
+ # get :index
48
+ # cookies[:foo].should == 'bar'
49
+ def cookies
50
+ @cookies ||= Spec::Rails::Example::CookiesProxy.new(self)
51
+ end
52
+
53
+ alias_method :orig_assigns, :assigns
54
+
55
+ # :call-seq:
56
+ # assigns()
57
+ #
58
+ # Hash of instance variables to values that are made available to
59
+ # views. == Examples
60
+ #
61
+ # #in thing_controller.rb
62
+ # def new
63
+ # @thing = Thing.new
64
+ # end
65
+ #
66
+ # #in thing_controller_spec
67
+ # get 'new'
68
+ # assigns[:registration].should == Thing.new
69
+ #--
70
+ # NOTE - Even though docs only use assigns[:key] format, this supports
71
+ # assigns(:key) for backwards compatibility.
72
+ #++
73
+ def assigns(key = nil)
74
+ if key.nil?
75
+ _assigns_hash_proxy
76
+ else
77
+ _assigns_hash_proxy[key]
78
+ end
79
+ end
80
+
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,167 @@
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 protect_against_forgery?
38
+ false
39
+ end
40
+
41
+ def session=(session)
42
+ @session = session
43
+ end
44
+
45
+ def request=(request)
46
+ @request = request
47
+ end
48
+
49
+ def flash=(flash)
50
+ @flash = flash
51
+ end
52
+
53
+ def params=(params)
54
+ @params = params
55
+ end
56
+
57
+ def controller=(controller)
58
+ @controller = controller
59
+ end
60
+
61
+ private
62
+ attr_reader :session, :request, :flash, :params, :controller
63
+ end
64
+
65
+ class << self
66
+ # The helper name....
67
+ def helper_name(name=nil)
68
+ @helper_being_described = "#{name}_helper".camelize.constantize
69
+ send :include, @helper_being_described
70
+ end
71
+
72
+ def helper
73
+ @helper_object ||= returning HelperObject.new do |helper_object|
74
+ if @helper_being_described.nil?
75
+ if described_type.class == Module
76
+ helper_object.extend described_type
77
+ end
78
+ else
79
+ helper_object.extend @helper_being_described
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ # Returns an instance of ActionView::Base with the helper being spec'd
86
+ # included.
87
+ #
88
+ # == Example
89
+ #
90
+ # describe PersonHelper do
91
+ # it "should write a link to person with the name" do
92
+ # assigns[:person] = mock_model(Person, :full_name => "Full Name", :id => 37, :new_record? => false)
93
+ # helper.link_to_person.should == %{<a href="/people/37">Full Name</a>}
94
+ # end
95
+ # end
96
+ #
97
+ # module PersonHelper
98
+ # def link_to_person
99
+ # link_to person.full_name, url_for(person)
100
+ # end
101
+ # end
102
+ #
103
+ def helper
104
+ self.class.helper
105
+ end
106
+
107
+ def orig_assigns
108
+ helper.assigns
109
+ end
110
+
111
+ # Reverse the load order so that custom helpers which are defined last
112
+ # are also loaded last.
113
+ ActionView::Base.included_modules.reverse.each do |mod|
114
+ include mod if mod.parents.include?(ActionView::Helpers)
115
+ end
116
+
117
+ before(:each) do
118
+ @controller.request = @request
119
+ @controller.url = ActionController::UrlRewriter.new @request, {} # url_for
120
+
121
+ @flash = ActionController::Flash::FlashHash.new
122
+ session['flash'] = @flash
123
+
124
+ @output_buffer = ""
125
+ @template = helper
126
+ ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
127
+
128
+ helper.session = session
129
+ helper.request = @request
130
+ helper.flash = flash
131
+ helper.params = params
132
+ helper.controller = @controller
133
+ end
134
+
135
+ def flash
136
+ @flash
137
+ end
138
+
139
+ def eval_erb(text)
140
+ erb_args = [text]
141
+ if helper.respond_to?(:output_buffer)
142
+ erb_args += [nil, nil, '@output_buffer']
143
+ end
144
+
145
+ helper.instance_eval do
146
+ ERB.new(*erb_args).result(binding)
147
+ end
148
+ end
149
+
150
+ # TODO: BT - Helper Examples should proxy method_missing to a Rails View instance.
151
+ # When that is done, remove this method
152
+ def protect_against_forgery?
153
+ false
154
+ end
155
+
156
+ Spec::Example::ExampleGroupFactory.register(:helper, self)
157
+
158
+ protected
159
+
160
+ def _assigns_hash_proxy
161
+ @_assigns_hash_proxy ||= AssignsHashProxy.new(self) {helper}
162
+ end
163
+
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,14 @@
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
+ class ModelExampleGroup < ActiveSupport::TestCase
10
+ Spec::Example::ExampleGroupFactory.register(:model, self)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,67 @@
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!(:render, :expected_from => caller(1)[0])
42
+ else
43
+ super
44
+ end
45
+ end
46
+
47
+ def verify_rendered_proc #:nodoc:
48
+ template = self
49
+ @verify_rendered_proc ||= Proc.new do
50
+ template.verify_rendered
51
+ template.unregister_verify_after_each
52
+ end
53
+ end
54
+
55
+ def register_verify_after_each #:nodoc:
56
+ proc = verify_rendered_proc
57
+ Spec::Example::ExampleGroup.after(:each, &proc)
58
+ end
59
+
60
+ def render_proxy #:nodoc:
61
+ @render_proxy ||= Spec::Mocks::Mock.new("render_proxy")
62
+ end
63
+
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,68 @@
1
+ module Spec
2
+ module Rails
3
+ module Example
4
+ module RoutingHelpers
5
+
6
+ module ParamsFromQueryString # :nodoc:
7
+ def params_from_querystring(querystring) # :nodoc:
8
+ params = {}
9
+ querystring.split('&').each do |piece|
10
+ key, value = piece.split('=')
11
+ params[key.to_sym] = value
12
+ end
13
+ params
14
+ end
15
+ end
16
+
17
+ class RouteFor
18
+ include ::Spec::Rails::Example::RoutingHelpers::ParamsFromQueryString
19
+ def initialize(example, options)
20
+ @example, @options = example, options
21
+ end
22
+
23
+ def ==(expected)
24
+ if Hash === expected
25
+ path, querystring = expected[:path].split('?')
26
+ path = expected.merge(:path => path)
27
+ else
28
+ path, querystring = expected.split('?')
29
+ end
30
+ params = querystring.blank? ? {} : @example.params_from_querystring(querystring)
31
+ @example.assert_recognizes(@options, path, params)
32
+ true
33
+ end
34
+ end
35
+
36
+ # Uses ActionController::Routing::Routes to generate
37
+ # the correct route for a given set of options.
38
+ # == Example
39
+ # route_for(:controller => 'registrations', :action => 'edit', :id => 1)
40
+ # => '/registrations/1;edit'
41
+ def route_for(options)
42
+ RouteFor.new(self, options)
43
+ end
44
+
45
+ # Uses ActionController::Routing::Routes to parse
46
+ # an incoming path so the parameters it generates can be checked
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(params_from_querystring(querystring))
55
+ end
56
+
57
+ private
58
+
59
+ include ParamsFromQueryString
60
+
61
+ def ensure_that_routes_are_loaded
62
+ ActionController::Routing::Routes.reload if ActionController::Routing::Routes.empty?
63
+ end
64
+
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,186 @@
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
+ tests ViewExampleGroupController
51
+ class << self
52
+ def inherited(klass) # :nodoc:
53
+ klass.subject { template }
54
+ super
55
+ end
56
+ end
57
+
58
+ before {ensure_that_flash_and_session_work_properly}
59
+ after {ensure_that_base_view_path_is_not_set_across_example_groups}
60
+
61
+ def ensure_that_flash_and_session_work_properly #:nodoc:
62
+ @controller.class.__send__ :public, :flash
63
+ @controller.__send__ :initialize_template_class, @response
64
+ @controller.__send__ :assign_shortcuts, @request, @response
65
+ @controller.__send__ :initialize_current_url
66
+ @session = @controller.session
67
+ end
68
+
69
+ def ensure_that_base_view_path_is_not_set_across_example_groups #:nodoc:
70
+ ActionView::Base.base_view_path = nil
71
+ end
72
+
73
+ def set_base_view_path(options) #:nodoc:
74
+ ActionView::Base.base_view_path = base_view_path(options)
75
+ end
76
+
77
+ def base_view_path(options) #:nodoc:
78
+ "/#{derived_controller_name(options)}/"
79
+ end
80
+
81
+ def derived_controller_name(options) #:nodoc:
82
+ parts = subject_of_render(options).split('/').reject { |part| part.empty? }
83
+ "#{parts[0..-2].join('/')}"
84
+ end
85
+
86
+ def derived_action_name(options) #:nodoc:
87
+ parts = subject_of_render(options).split('/').reject { |part| part.empty? }
88
+ "#{parts.last}".split('.').first
89
+ end
90
+
91
+ def subject_of_render(options) #:nodoc:
92
+ [:template, :partial, :file].each do |render_type|
93
+ if options.has_key?(render_type)
94
+ return options[render_type]
95
+ end
96
+ end
97
+ return ""
98
+ end
99
+
100
+ def add_helpers(options) #:nodoc:
101
+ @controller.add_helper("application")
102
+ @controller.add_helper(derived_controller_name(options))
103
+ @controller.add_helper(options[:helper]) if options[:helper]
104
+ options[:helpers].each { |helper| @controller.add_helper(helper) } if options[:helpers]
105
+ end
106
+
107
+ # Renders a template for a View Spec, which then provides access to the result
108
+ # through the +response+. Also supports render with :inline, which you can
109
+ # use to spec custom form builders, helpers, etc, in the context of a view.
110
+ #
111
+ # == Examples
112
+ #
113
+ # render('/people/list')
114
+ # render('/people/list', :helper => MyHelper)
115
+ # render('/people/list', :helpers => [MyHelper, MyOtherHelper])
116
+ # render(:partial => '/people/_address')
117
+ # render(:inline => "<% custom_helper 'argument', 'another argument' %>")
118
+ #
119
+ # See Spec::Rails::Example::ViewExampleGroup for more information.
120
+ def render(*args)
121
+ options = Hash === args.last ? args.pop : {}
122
+
123
+ if args.empty?
124
+ unless [:partial, :inline, :file, :template, :xml, :json, :update].any? {|k| options.has_key? k}
125
+ args << self.class.description_parts.first
126
+ end
127
+ end
128
+
129
+ options[:template] = args.first.to_s.sub(/^\//,'') unless args.empty?
130
+
131
+ set_base_view_path(options)
132
+ add_helpers(options)
133
+
134
+ assigns[:action_name] = @action_name
135
+
136
+ @request.path_parameters = @request.path_parameters.merge(
137
+ :controller => derived_controller_name(options),
138
+ :action => derived_action_name(options)
139
+ ).merge(options[:path_parameters] || {})
140
+
141
+ defaults = { :layout => false }
142
+ options = defaults.merge options
143
+
144
+ @controller.__send__(:params).reverse_merge! @request.parameters
145
+
146
+ @controller.class.instance_eval %{
147
+ def controller_path
148
+ "#{derived_controller_name(options)}"
149
+ end
150
+
151
+ def controller_name
152
+ "#{derived_controller_name(options).split('/').last}"
153
+ end
154
+ }
155
+
156
+ @controller.__send__ :forget_variables_added_to_assigns
157
+ @controller.__send__ :render, options
158
+ @controller.__send__ :process_cleanup
159
+ end
160
+
161
+ # This provides the template. Use this to set mock
162
+ # expectations for dealing with partials
163
+ #
164
+ # == Example
165
+ #
166
+ # describe "/person/new" do
167
+ # it "should use the form partial" do
168
+ # template.should_receive(:render).with(:partial => 'form')
169
+ # render "/person/new"
170
+ # end
171
+ # end
172
+ def template
173
+ @controller.template
174
+ end
175
+
176
+ Spec::Example::ExampleGroupFactory.register(:view, self)
177
+
178
+ protected
179
+ def _assigns_hash_proxy
180
+ @_assigns_hash_proxy ||= AssignsHashProxy.new(self) {@response.template}
181
+ end
182
+ end
183
+
184
+ end
185
+ end
186
+ end