dchelimsky-rspec-rails 1.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. data/History.txt +63 -0
  2. data/Manifest.txt +158 -0
  3. data/README.txt +81 -0
  4. data/Rakefile +38 -0
  5. data/UPGRADE +7 -0
  6. data/generators/rspec/CHANGES +1 -0
  7. data/generators/rspec/rspec_generator.rb +40 -0
  8. data/generators/rspec/templates/all_stories.rb +4 -0
  9. data/generators/rspec/templates/previous_failures.txt +0 -0
  10. data/generators/rspec/templates/rcov.opts +2 -0
  11. data/generators/rspec/templates/rspec.rake +132 -0
  12. data/generators/rspec/templates/script/autospec +3 -0
  13. data/generators/rspec/templates/script/spec +4 -0
  14. data/generators/rspec/templates/script/spec_server +116 -0
  15. data/generators/rspec/templates/spec.opts +4 -0
  16. data/generators/rspec/templates/spec_helper.rb +47 -0
  17. data/generators/rspec/templates/stories_helper.rb +3 -0
  18. data/generators/rspec_controller/USAGE +33 -0
  19. data/generators/rspec_controller/rspec_controller_generator.rb +49 -0
  20. data/generators/rspec_controller/templates/controller_spec.rb +25 -0
  21. data/generators/rspec_controller/templates/helper_spec.rb +11 -0
  22. data/generators/rspec_controller/templates/view_spec.rb +12 -0
  23. data/generators/rspec_default_values.rb +19 -0
  24. data/generators/rspec_model/USAGE +18 -0
  25. data/generators/rspec_model/rspec_model_generator.rb +35 -0
  26. data/generators/rspec_model/templates/model_spec.rb +15 -0
  27. data/generators/rspec_scaffold/rspec_scaffold_generator.rb +154 -0
  28. data/generators/rspec_scaffold/templates/controller_spec.rb +173 -0
  29. data/generators/rspec_scaffold/templates/edit_erb_spec.rb +26 -0
  30. data/generators/rspec_scaffold/templates/helper_spec.rb +11 -0
  31. data/generators/rspec_scaffold/templates/index_erb_spec.rb +27 -0
  32. data/generators/rspec_scaffold/templates/new_erb_spec.rb +26 -0
  33. data/generators/rspec_scaffold/templates/routing_spec.rb +59 -0
  34. data/generators/rspec_scaffold/templates/show_erb_spec.rb +23 -0
  35. data/init.rb +9 -0
  36. data/lib/autotest/discover.rb +1 -0
  37. data/lib/autotest/rails_rspec.rb +76 -0
  38. data/lib/spec/rails/example/assigns_hash_proxy.rb +37 -0
  39. data/lib/spec/rails/example/controller_example_group.rb +256 -0
  40. data/lib/spec/rails/example/cookies_proxy.rb +25 -0
  41. data/lib/spec/rails/example/functional_example_group.rb +87 -0
  42. data/lib/spec/rails/example/helper_example_group.rb +166 -0
  43. data/lib/spec/rails/example/model_example_group.rb +14 -0
  44. data/lib/spec/rails/example/rails_example_group.rb +33 -0
  45. data/lib/spec/rails/example/render_observer.rb +93 -0
  46. data/lib/spec/rails/example/view_example_group.rb +183 -0
  47. data/lib/spec/rails/example.rb +47 -0
  48. data/lib/spec/rails/extensions/action_controller/base.rb +14 -0
  49. data/lib/spec/rails/extensions/action_controller/rescue.rb +21 -0
  50. data/lib/spec/rails/extensions/action_controller/test_response.rb +11 -0
  51. data/lib/spec/rails/extensions/action_view/base.rb +31 -0
  52. data/lib/spec/rails/extensions/active_record/base.rb +30 -0
  53. data/lib/spec/rails/extensions/object.rb +5 -0
  54. data/lib/spec/rails/extensions/spec/example/configuration.rb +71 -0
  55. data/lib/spec/rails/extensions/spec/matchers/have.rb +21 -0
  56. data/lib/spec/rails/extensions.rb +12 -0
  57. data/lib/spec/rails/interop/testcase.rb +14 -0
  58. data/lib/spec/rails/matchers/assert_select.rb +131 -0
  59. data/lib/spec/rails/matchers/change.rb +11 -0
  60. data/lib/spec/rails/matchers/have_text.rb +57 -0
  61. data/lib/spec/rails/matchers/include_text.rb +54 -0
  62. data/lib/spec/rails/matchers/redirect_to.rb +113 -0
  63. data/lib/spec/rails/matchers/render_template.rb +90 -0
  64. data/lib/spec/rails/matchers.rb +31 -0
  65. data/lib/spec/rails/mocks.rb +132 -0
  66. data/lib/spec/rails/story_adapter.rb +79 -0
  67. data/lib/spec/rails/version.rb +15 -0
  68. data/lib/spec/rails.rb +15 -0
  69. data/spec/rails/autotest/mappings_spec.rb +36 -0
  70. data/spec/rails/example/assigns_hash_proxy_spec.rb +70 -0
  71. data/spec/rails/example/configuration_spec.rb +83 -0
  72. data/spec/rails/example/controller_isolation_spec.rb +62 -0
  73. data/spec/rails/example/controller_spec_spec.rb +272 -0
  74. data/spec/rails/example/cookies_proxy_spec.rb +74 -0
  75. data/spec/rails/example/example_group_factory_spec.rb +112 -0
  76. data/spec/rails/example/helper_spec_spec.rb +161 -0
  77. data/spec/rails/example/model_spec_spec.rb +18 -0
  78. data/spec/rails/example/shared_behaviour_spec.rb +16 -0
  79. data/spec/rails/example/test_unit_assertion_accessibility_spec.rb +33 -0
  80. data/spec/rails/example/view_spec_spec.rb +280 -0
  81. data/spec/rails/extensions/action_controller_rescue_action_spec.rb +54 -0
  82. data/spec/rails/extensions/action_view_base_spec.rb +48 -0
  83. data/spec/rails/extensions/active_record_spec.rb +14 -0
  84. data/spec/rails/interop/testcase_spec.rb +66 -0
  85. data/spec/rails/matchers/assert_select_spec.rb +814 -0
  86. data/spec/rails/matchers/description_generation_spec.rb +37 -0
  87. data/spec/rails/matchers/errors_on_spec.rb +13 -0
  88. data/spec/rails/matchers/have_text_spec.rb +62 -0
  89. data/spec/rails/matchers/include_text_spec.rb +64 -0
  90. data/spec/rails/matchers/redirect_to_spec.rb +209 -0
  91. data/spec/rails/matchers/render_template_spec.rb +176 -0
  92. data/spec/rails/matchers/should_change_spec.rb +15 -0
  93. data/spec/rails/mocks/ar_classes.rb +10 -0
  94. data/spec/rails/mocks/mock_model_spec.rb +106 -0
  95. data/spec/rails/mocks/stub_model_spec.rb +80 -0
  96. data/spec/rails/sample_modified_fixture.rb +8 -0
  97. data/spec/rails/sample_spec.rb +8 -0
  98. data/spec/rails/spec_server_spec.rb +96 -0
  99. data/spec/rails/spec_spec.rb +11 -0
  100. data/spec/rails_suite.rb +7 -0
  101. data/spec/spec_helper.rb +57 -0
  102. data/spec_resources/controllers/action_view_base_spec_controller.rb +2 -0
  103. data/spec_resources/controllers/controller_spec_controller.rb +94 -0
  104. data/spec_resources/controllers/redirect_spec_controller.rb +59 -0
  105. data/spec_resources/controllers/render_spec_controller.rb +30 -0
  106. data/spec_resources/controllers/rjs_spec_controller.rb +58 -0
  107. data/spec_resources/helpers/explicit_helper.rb +38 -0
  108. data/spec_resources/helpers/more_explicit_helper.rb +5 -0
  109. data/spec_resources/helpers/plugin_application_helper.rb +6 -0
  110. data/spec_resources/helpers/view_spec_helper.rb +13 -0
  111. data/spec_resources/views/controller_spec/_partial.rhtml +0 -0
  112. data/spec_resources/views/controller_spec/action_setting_flash_after_session_reset.rhtml +1 -0
  113. data/spec_resources/views/controller_spec/action_setting_flash_before_session_reset.rhtml +1 -0
  114. data/spec_resources/views/controller_spec/action_setting_the_assigns_hash.rhtml +0 -0
  115. data/spec_resources/views/controller_spec/action_with_errors_in_template.rhtml +1 -0
  116. data/spec_resources/views/controller_spec/action_with_template.rhtml +1 -0
  117. data/spec_resources/views/layouts/application.rhtml +0 -0
  118. data/spec_resources/views/layouts/simple.rhtml +0 -0
  119. data/spec_resources/views/objects/_object.html.erb +1 -0
  120. data/spec_resources/views/render_spec/_a_partial.rhtml +0 -0
  121. data/spec_resources/views/render_spec/action_with_alternate_layout.rhtml +0 -0
  122. data/spec_resources/views/render_spec/some_action.js.rjs +1 -0
  123. data/spec_resources/views/render_spec/some_action.rhtml +0 -0
  124. data/spec_resources/views/render_spec/some_action.rjs +1 -0
  125. data/spec_resources/views/rjs_spec/_replacement_partial.rhtml +1 -0
  126. data/spec_resources/views/rjs_spec/hide_div.rjs +1 -0
  127. data/spec_resources/views/rjs_spec/hide_page_element.rjs +1 -0
  128. data/spec_resources/views/rjs_spec/insert_html.rjs +1 -0
  129. data/spec_resources/views/rjs_spec/replace.rjs +1 -0
  130. data/spec_resources/views/rjs_spec/replace_html.rjs +1 -0
  131. data/spec_resources/views/rjs_spec/replace_html_with_partial.rjs +1 -0
  132. data/spec_resources/views/rjs_spec/visual_effect.rjs +1 -0
  133. data/spec_resources/views/rjs_spec/visual_toggle_effect.rjs +1 -0
  134. data/spec_resources/views/tag_spec/no_tags.rhtml +1 -0
  135. data/spec_resources/views/tag_spec/single_div_with_no_attributes.rhtml +1 -0
  136. data/spec_resources/views/tag_spec/single_div_with_one_attribute.rhtml +1 -0
  137. data/spec_resources/views/view_spec/_partial.rhtml +2 -0
  138. data/spec_resources/views/view_spec/_partial_used_twice.rhtml +0 -0
  139. data/spec_resources/views/view_spec/_partial_with_local_variable.rhtml +1 -0
  140. data/spec_resources/views/view_spec/_partial_with_sub_partial.rhtml +1 -0
  141. data/spec_resources/views/view_spec/_spacer.rhtml +1 -0
  142. data/spec_resources/views/view_spec/accessor.rhtml +5 -0
  143. data/spec_resources/views/view_spec/block_helper.rhtml +3 -0
  144. data/spec_resources/views/view_spec/entry_form.rhtml +2 -0
  145. data/spec_resources/views/view_spec/explicit_helper.rhtml +2 -0
  146. data/spec_resources/views/view_spec/foo/show.rhtml +1 -0
  147. data/spec_resources/views/view_spec/implicit_helper.rhtml +2 -0
  148. data/spec_resources/views/view_spec/multiple_helpers.rhtml +3 -0
  149. data/spec_resources/views/view_spec/should_not_receive.rhtml +3 -0
  150. data/spec_resources/views/view_spec/template_with_partial.rhtml +5 -0
  151. data/spec_resources/views/view_spec/template_with_partial_using_collection.rhtml +3 -0
  152. data/spec_resources/views/view_spec/template_with_partial_with_array.rhtml +1 -0
  153. data/stories/all.rb +10 -0
  154. data/stories/configuration/stories.rb +5 -0
  155. data/stories/helper.rb +6 -0
  156. data/stories/steps/people.rb +8 -0
  157. data/stories/transactions_should_rollback +15 -0
  158. data/stories/transactions_should_rollback.rb +25 -0
  159. metadata +232 -0
@@ -0,0 +1,166 @@
1
+ module Spec
2
+ module Rails
3
+ module Example
4
+ # Helper Specs live in $RAILS_ROOT/spec/helpers/.
5
+ #
6
+ # Helper Specs use Spec::Rails::Example::HelperExampleGroup, which allows you to
7
+ # include your Helper directly in the context and write specs directly
8
+ # against its methods.
9
+ #
10
+ # HelperExampleGroup also includes the standard lot of ActionView::Helpers in case your
11
+ # helpers rely on any of those.
12
+ #
13
+ # == Example
14
+ #
15
+ # class ThingHelper
16
+ # def number_of_things
17
+ # Thing.count
18
+ # end
19
+ # end
20
+ #
21
+ # describe "ThingHelper example_group" do
22
+ # include ThingHelper
23
+ # it "should tell you the number of things" do
24
+ # Thing.should_receive(:count).and_return(37)
25
+ # number_of_things.should == 37
26
+ # end
27
+ # end
28
+ class HelperExampleGroup < FunctionalExampleGroup
29
+ class HelperObject < ActionView::Base
30
+ def protect_against_forgery?
31
+ false
32
+ end
33
+
34
+ def session=(session)
35
+ @session = session
36
+ end
37
+
38
+ def request=(request)
39
+ @request = request
40
+ end
41
+
42
+ def flash=(flash)
43
+ @flash = flash
44
+ end
45
+
46
+ def params=(params)
47
+ @params = params
48
+ end
49
+
50
+ def controller=(controller)
51
+ @controller = controller
52
+ end
53
+
54
+ private
55
+ attr_reader :session, :request, :flash, :params, :controller
56
+ end
57
+
58
+ class << self
59
+ # The helper name....
60
+ def helper_name(name=nil)
61
+ @helper_being_described = "#{name}_helper".camelize.constantize
62
+ send :include, @helper_being_described
63
+ end
64
+
65
+ def helper
66
+ @helper_object ||= returning HelperObject.new do |helper_object|
67
+ if @helper_being_described.nil?
68
+ if described_type.class == Module
69
+ helper_object.extend described_type
70
+ end
71
+ else
72
+ helper_object.extend @helper_being_described
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ # Returns an instance of ActionView::Base with the helper being spec'd
79
+ # included.
80
+ #
81
+ # == Example
82
+ #
83
+ # describe PersonHelper do
84
+ # it "should write a link to person with the name" do
85
+ # assigns[:person] = mock_model(Person, :full_name => "Full Name", :id => 37, :new_record? => false)
86
+ # helper.link_to_person.should == %{<a href="/people/37">Full Name</a>}
87
+ # end
88
+ # end
89
+ #
90
+ # module PersonHelper
91
+ # def link_to_person
92
+ # link_to person.full_name, url_for(person)
93
+ # end
94
+ # end
95
+ #
96
+ def helper
97
+ self.class.helper
98
+ end
99
+
100
+ # Reverse the load order so that custom helpers which are defined last
101
+ # are also loaded last.
102
+ ActionView::Base.included_modules.reverse.each do |mod|
103
+ include mod if mod.parents.include?(ActionView::Helpers)
104
+ end
105
+
106
+ before(:all) do
107
+ @controller_class_name = 'Spec::Rails::Example::HelperExampleGroupController'
108
+ end
109
+
110
+ before(:each) do
111
+ @controller.request = @request
112
+ @controller.url = ActionController::UrlRewriter.new @request, {} # url_for
113
+
114
+ @flash = ActionController::Flash::FlashHash.new
115
+ session['flash'] = @flash
116
+
117
+ ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
118
+
119
+ helper.session = session
120
+ helper.request = @request
121
+ helper.flash = flash
122
+ helper.params = params
123
+ helper.controller = @controller
124
+ end
125
+
126
+ def flash
127
+ @flash
128
+ end
129
+
130
+ def eval_erb(text)
131
+ erb_args = [text]
132
+ if helper.respond_to?(:output_buffer)
133
+ erb_args += [nil, nil, '@output_buffer']
134
+ end
135
+
136
+ helper.instance_eval do
137
+ ERB.new(*erb_args).result(binding)
138
+ end
139
+ end
140
+
141
+ # TODO: BT - Helper Examples should proxy method_missing to a Rails View instance.
142
+ # When that is done, remove this method
143
+ def protect_against_forgery?
144
+ false
145
+ end
146
+
147
+ Spec::Example::ExampleGroupFactory.register(:helper, self)
148
+
149
+ protected
150
+ def _assigns_hash_proxy
151
+ @_assigns_hash_proxy ||= AssignsHashProxy.new self do
152
+ helper
153
+ end
154
+ end
155
+
156
+ end
157
+
158
+ class HelperExampleGroupController < ApplicationController #:nodoc:
159
+ attr_accessor :request, :url
160
+
161
+ # Re-raise errors
162
+ def rescue_action(e); raise e; end
163
+ end
164
+ end
165
+ end
166
+ 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 < RailsExampleGroup
10
+ Spec::Example::ExampleGroupFactory.register(:model, self)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec/interop/test'
2
+
3
+ if ActionView::Base.respond_to?(:cache_template_extension)
4
+ ActionView::Base.cache_template_extensions = false
5
+ end
6
+
7
+ module Spec
8
+ module Rails
9
+
10
+ module Example
11
+ class RailsExampleGroup < Test::Unit::TestCase
12
+
13
+ # Rails >= r8570 uses setup/teardown_fixtures explicitly
14
+ # However, Rails >= r8664 extracted these out to use ActiveSupport::Callbacks.
15
+ # The latter case is handled at the TestCase level, in interop/testcase.rb
16
+ unless ActiveSupport.const_defined?(:Callbacks) and self.include?(ActiveSupport::Callbacks)
17
+ before(:each) do
18
+ setup_fixtures if self.respond_to?(:setup_fixtures)
19
+ end
20
+ after(:each) do
21
+ teardown_fixtures if self.respond_to?(:teardown_fixtures)
22
+ end
23
+ end
24
+
25
+ include Spec::Rails::Matchers
26
+ include Spec::Rails::Mocks
27
+
28
+ Spec::Example::ExampleGroupFactory.default(self)
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,93 @@
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
+ # DEPRECATED
12
+ #
13
+ # Use should_receive(:render).with(opts) instead
14
+ def expect_render(opts={})
15
+ warn_deprecation("expect_render", "should_receive")
16
+ register_verify_after_each
17
+ render_proxy.should_receive(:render, :expected_from => caller(1)[0]).with(opts)
18
+ end
19
+
20
+ # DEPRECATED
21
+ #
22
+ # Use stub!(:render).with(opts) instead
23
+ def stub_render(opts={})
24
+ warn_deprecation("stub_render", "stub!")
25
+ register_verify_after_each
26
+ render_proxy.stub!(:render, :expected_from => caller(1)[0]).with(opts)
27
+ end
28
+
29
+ def warn_deprecation(deprecated_method, new_method)
30
+ Kernel.warn <<-WARNING
31
+ #{deprecated_method} is deprecated and will be removed from a future version of rspec-rails.
32
+
33
+ Please just use object.#{new_method} instead.
34
+ WARNING
35
+ end
36
+
37
+ def verify_rendered # :nodoc:
38
+ render_proxy.rspec_verify
39
+ end
40
+
41
+ def unregister_verify_after_each #:nodoc:
42
+ proc = verify_rendered_proc
43
+ Spec::Example::ExampleGroup.remove_after(:each, &proc)
44
+ end
45
+
46
+ def should_receive(*args)
47
+ if args[0] == :render
48
+ register_verify_after_each
49
+ render_proxy.should_receive(:render, :expected_from => caller(1)[0])
50
+ else
51
+ super
52
+ end
53
+ end
54
+
55
+ def should_not_receive(*args)
56
+ if args[0] == :render
57
+ register_verify_after_each
58
+ render_proxy.should_not_receive(:render)
59
+ else
60
+ super
61
+ end
62
+ end
63
+
64
+ def stub!(*args)
65
+ if args[0] == :render
66
+ register_verify_after_each
67
+ render_proxy.stub!(:render, :expected_from => caller(1)[0])
68
+ else
69
+ super
70
+ end
71
+ end
72
+
73
+ def verify_rendered_proc #:nodoc:
74
+ template = self
75
+ @verify_rendered_proc ||= Proc.new do
76
+ template.verify_rendered
77
+ template.unregister_verify_after_each
78
+ end
79
+ end
80
+
81
+ def register_verify_after_each #:nodoc:
82
+ proc = verify_rendered_proc
83
+ Spec::Example::ExampleGroup.after(:each, &proc)
84
+ end
85
+
86
+ def render_proxy #:nodoc:
87
+ @render_proxy ||= Spec::Mocks::Mock.new("render_proxy")
88
+ end
89
+
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,183 @@
1
+ module Spec
2
+ module Rails
3
+ module Example
4
+ # View Examples live in $RAILS_ROOT/spec/views/.
5
+ #
6
+ # View Specs use Spec::Rails::Example::ViewExampleGroup,
7
+ # which provides access to views without invoking any of your controllers.
8
+ # See Spec::Rails::Expectations::Matchers for information about specific
9
+ # expectations that you can set on views.
10
+ #
11
+ # == Example
12
+ #
13
+ # describe "login/login" do
14
+ # before do
15
+ # render 'login/login'
16
+ # end
17
+ #
18
+ # it "should display login form" do
19
+ # response.should have_tag("form[action=/login]") do
20
+ # with_tag("input[type=text][name=email]")
21
+ # with_tag("input[type=password][name=password]")
22
+ # with_tag("input[type=submit][value=Login]")
23
+ # end
24
+ # end
25
+ # end
26
+ class ViewExampleGroup < FunctionalExampleGroup
27
+ before(:each) do
28
+ ensure_that_flash_and_session_work_properly
29
+ end
30
+
31
+ after(:each) do
32
+ ensure_that_base_view_path_is_not_set_across_example_groups
33
+ end
34
+
35
+ def initialize(defined_description, &implementation) #:nodoc:
36
+ super
37
+ @controller_class_name = "Spec::Rails::Example::ViewExampleGroupController"
38
+ end
39
+
40
+ def ensure_that_flash_and_session_work_properly #:nodoc:
41
+ @controller.send :initialize_template_class, @response
42
+ @controller.send :assign_shortcuts, @request, @response
43
+ @session = @controller.session
44
+ @controller.class.send :public, :flash
45
+ end
46
+
47
+ def ensure_that_base_view_path_is_not_set_across_example_groups #:nodoc:
48
+ ActionView::Base.base_view_path = nil
49
+ end
50
+
51
+ def set_base_view_path(options) #:nodoc:
52
+ ActionView::Base.base_view_path = base_view_path(options)
53
+ end
54
+
55
+ def base_view_path(options) #:nodoc:
56
+ "/#{derived_controller_name(options)}/"
57
+ end
58
+
59
+ def derived_controller_name(options) #:nodoc:
60
+ parts = subject_of_render(options).split('/').reject { |part| part.empty? }
61
+ "#{parts[0..-2].join('/')}"
62
+ end
63
+
64
+ def derived_action_name(options) #:nodoc:
65
+ parts = subject_of_render(options).split('/').reject { |part| part.empty? }
66
+ "#{parts.last}"
67
+ end
68
+
69
+ def subject_of_render(options) #:nodoc:
70
+ [:template, :partial, :file].each do |render_type|
71
+ if options.has_key?(render_type)
72
+ return options[render_type]
73
+ end
74
+ end
75
+ return ""
76
+ end
77
+
78
+ def add_helpers(options) #:nodoc:
79
+ @controller.add_helper("application")
80
+ @controller.add_helper(derived_controller_name(options))
81
+ @controller.add_helper(options[:helper]) if options[:helper]
82
+ options[:helpers].each { |helper| @controller.add_helper(helper) } if options[:helpers]
83
+ end
84
+
85
+ # Renders a template for a View Spec, which then provides access to the result
86
+ # through the +response+. Also supports render with :inline, which you can
87
+ # use to spec custom form builders, helpers, etc, in the context of a view.
88
+ #
89
+ # == Examples
90
+ #
91
+ # render('/people/list')
92
+ # render('/people/list', :helper => MyHelper)
93
+ # render('/people/list', :helpers => [MyHelper, MyOtherHelper])
94
+ # render(:partial => '/people/_address')
95
+ # render(:inline => "<% custom_helper 'argument', 'another argument' %>")
96
+ #
97
+ # See Spec::Rails::Example::ViewExampleGroup for more information.
98
+ def render(*args)
99
+ options = Hash === args.last ? args.pop : {}
100
+ options[:template] = args.first.to_s unless args.empty?
101
+
102
+ set_base_view_path(options)
103
+ add_helpers(options)
104
+
105
+ assigns[:action_name] = @action_name
106
+
107
+ @request.path_parameters = {
108
+ :controller => derived_controller_name(options),
109
+ :action => derived_action_name(options)
110
+ }
111
+
112
+ defaults = { :layout => false }
113
+ options = defaults.merge options
114
+
115
+ @controller.send(:params).reverse_merge! @request.parameters
116
+
117
+ @controller.send :initialize_current_url
118
+
119
+ @controller.class.instance_eval %{
120
+ def controller_path
121
+ "#{derived_controller_name(options)}"
122
+ end
123
+
124
+ def controller_name
125
+ "#{derived_controller_name(options).split('/').last}"
126
+ end
127
+ }
128
+
129
+ @controller.send :forget_variables_added_to_assigns
130
+ @controller.send :render, options
131
+ @controller.send :process_cleanup
132
+ end
133
+
134
+ # This provides the template. Use this to set mock
135
+ # expectations for dealing with partials
136
+ #
137
+ # == Example
138
+ #
139
+ # describe "/person/new" do
140
+ # it "should use the form partial" do
141
+ # template.should_receive(:render).with(:partial => 'form')
142
+ # render "/person/new"
143
+ # end
144
+ # end
145
+ def template
146
+ @controller.template
147
+ end
148
+
149
+ Spec::Example::ExampleGroupFactory.register(:view, self)
150
+
151
+ protected
152
+ def _assigns_hash_proxy
153
+ @_assigns_hash_proxy ||= AssignsHashProxy.new self do
154
+ @response.template
155
+ end
156
+ end
157
+ end
158
+
159
+ class ViewExampleGroupController < ApplicationController #:nodoc:
160
+ include Spec::Rails::Example::RenderObserver
161
+ attr_reader :template
162
+
163
+ def add_helper_for(template_path)
164
+ add_helper(template_path.split('/')[0])
165
+ end
166
+
167
+ def add_helper(name)
168
+ begin
169
+ helper_module = "#{name}_helper".camelize.constantize
170
+ rescue
171
+ return
172
+ end
173
+ (class << template; self; end).class_eval do
174
+ include helper_module
175
+ end
176
+ end
177
+
178
+ def forget_variables_added_to_assigns
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,47 @@
1
+ dir = File.dirname(__FILE__)
2
+
3
+ require 'spec/rails/example/assigns_hash_proxy'
4
+
5
+ require "spec/rails/example/render_observer"
6
+ require "spec/rails/example/rails_example_group"
7
+ require "spec/rails/example/model_example_group"
8
+ require "spec/rails/example/functional_example_group"
9
+ require "spec/rails/example/controller_example_group"
10
+ require "spec/rails/example/helper_example_group"
11
+ require "spec/rails/example/view_example_group"
12
+ require "spec/rails/example/cookies_proxy"
13
+
14
+ module Spec
15
+ module Rails
16
+ # Spec::Rails::Example extends Spec::Example (RSpec's core Example module) to provide
17
+ # Rails-specific contexts for describing Rails Models, Views, Controllers and Helpers.
18
+ #
19
+ # == Model Examples
20
+ #
21
+ # These are the equivalent of unit tests in Rails' built in testing. Ironically (for the traditional TDD'er) these are the only specs that we feel should actually interact with the database.
22
+ #
23
+ # See Spec::Rails::Example::ModelExampleGroup
24
+ #
25
+ # == Controller Examples
26
+ #
27
+ # These align somewhat with functional tests in rails, except that they do not actually render views (though you can force rendering of views if you prefer). Instead of setting expectations about what goes on a page, you set expectations about what templates get rendered.
28
+ #
29
+ # See Spec::Rails::Example::ControllerExampleGroup
30
+ #
31
+ # == View Examples
32
+ #
33
+ # This is the other half of Rails functional testing. View specs allow you to set up assigns and render
34
+ # a template. By assigning mock model data, you can specify view behaviour with no dependency on a database
35
+ # or your real models.
36
+ #
37
+ # See Spec::Rails::Example::ViewExampleGroup
38
+ #
39
+ # == Helper Examples
40
+ #
41
+ # These let you specify directly methods that live in your helpers.
42
+ #
43
+ # See Spec::Rails::Example::HelperExampleGroup
44
+ module Example
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,14 @@
1
+ module ActionController
2
+ class Base
3
+ class << self
4
+ def set_view_path(path)
5
+ [:append_view_path, :view_paths=, :template_root=].each do |method|
6
+ if respond_to?(method)
7
+ return send(method, path)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,21 @@
1
+ module ActionController
2
+ module Rescue
3
+ def use_rails_error_handling!
4
+ @use_rails_error_handling = true
5
+ end
6
+
7
+ def use_rails_error_handling?
8
+ @use_rails_error_handling ||= false
9
+ end
10
+
11
+ protected
12
+ def rescue_action_with_fast_errors(exception)
13
+ if use_rails_error_handling?
14
+ rescue_action_without_fast_errors exception
15
+ else
16
+ raise exception
17
+ end
18
+ end
19
+ alias_method_chain :rescue_action, :fast_errors
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ module ActionController #:nodoc:
2
+ class TestResponse #:nodoc:
3
+ attr_writer :controller_path
4
+
5
+ def capture(name)
6
+ template.instance_variable_get "@content_for_#{name.to_s}"
7
+ end
8
+ alias [] capture
9
+
10
+ end
11
+ end
@@ -0,0 +1,31 @@
1
+ module ActionView #:nodoc:
2
+ class Base #:nodoc:
3
+ include Spec::Rails::Example::RenderObserver
4
+ cattr_accessor :base_view_path
5
+ def render_partial(partial_path, local_assigns = nil, deprecated_local_assigns = nil) #:nodoc:
6
+ if partial_path.is_a?(String)
7
+ unless partial_path.include?("/")
8
+ unless self.class.base_view_path.nil?
9
+ partial_path = "#{self.class.base_view_path}/#{partial_path}"
10
+ end
11
+ end
12
+ end
13
+ begin
14
+ super(partial_path, local_assigns, deprecated_local_assigns)
15
+ rescue ArgumentError # edge rails > 2.1 changed render_partial to accept only one arg
16
+ super(partial_path)
17
+ end
18
+ end
19
+
20
+ alias_method :orig_render, :render
21
+ def render(options = {}, old_local_assigns = {}, &block)
22
+ if render_proxy.send(:__mock_proxy).send(:find_matching_expectation, :render, options)
23
+ render_proxy.render(options)
24
+ else
25
+ unless render_proxy.send(:__mock_proxy).send(:find_matching_method_stub, :render, options)
26
+ orig_render(options, old_local_assigns, &block)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ if defined?(ActiveRecord::Base)
2
+ module ActiveRecord #:nodoc:
3
+ class Base
4
+
5
+ (class << self; self; end).class_eval do
6
+ # Extension for <tt>should have</tt> on AR Model classes
7
+ #
8
+ # ModelClass.should have(:no).records
9
+ # ModelClass.should have(1).record
10
+ # ModelClass.should have(n).records
11
+ def records
12
+ find(:all)
13
+ end
14
+ alias :record :records
15
+ end
16
+
17
+ # Extension for <tt>should have</tt> on AR Model instances
18
+ #
19
+ # model.should have(:no).errors_on(:attribute)
20
+ # model.should have(1).error_on(:attribute)
21
+ # model.should have(n).errors_on(:attribute)
22
+ def errors_on(attribute)
23
+ self.valid?
24
+ [self.errors.on(attribute)].flatten.compact
25
+ end
26
+ alias :error_on :errors_on
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ class Object # :nodoc:
2
+ def self.path2class(klassname)
3
+ klassname.split('::').inject(Object) { |k,n| k.const_get n }
4
+ end
5
+ end