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,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper')
2
+
3
+ <% output_attributes = attributes.reject{|attribute| [:datetime, :timestamp, :time, :date].index(attribute.type) } -%>
4
+ describe "/<%= table_name %>/edit.<%= default_file_extension %>" do
5
+ include <%= controller_class_name %>Helper
6
+
7
+ before(:each) do
8
+ assigns[:<%= file_name %>] = @<%= file_name %> = stub_model(<%= class_name %>,
9
+ :new_record? => false<%= output_attributes.empty? ? '' : ',' %>
10
+ <% output_attributes.each_with_index do |attribute, attribute_index| -%>
11
+ :<%= attribute.name %> => <%= attribute.default_value %><%= attribute_index == output_attributes.length - 1 ? '' : ','%>
12
+ <% end -%>
13
+ )
14
+ end
15
+
16
+ it "renders the edit <%= file_name %> form" do
17
+ render
18
+
19
+ response.should have_tag("form[action=#{<%= file_name %>_path(@<%= file_name %>)}][method=post]") do
20
+ <% for attribute in output_attributes -%>
21
+ with_tag('<%= attribute.input_type -%>#<%= file_name %>_<%= attribute.name %>[name=?]', "<%= file_name %>[<%= attribute.name %>]")
22
+ <% end -%>
23
+ end
24
+ end
25
+ end
26
+
27
+
@@ -0,0 +1,11 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper')
2
+
3
+ describe <%= controller_class_name %>Helper do
4
+
5
+ #Delete this example and add some real ones or delete this file
6
+ it "is included in the helper object" do
7
+ included_modules = (class << helper; self; end).send :included_modules
8
+ included_modules.should include(<%= controller_class_name %>Helper)
9
+ end
10
+
11
+ end
@@ -0,0 +1,28 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper')
2
+
3
+ <% output_attributes = attributes.reject{|attribute| [:datetime, :timestamp, :time, :date].index(attribute.type) } -%>
4
+ describe "/<%= table_name %>/index.<%= default_file_extension %>" do
5
+ include <%= controller_class_name %>Helper
6
+
7
+ before(:each) do
8
+ assigns[:<%= table_name %>] = [
9
+ <% [1,2].each_with_index do |id, model_index| -%>
10
+ stub_model(<%= class_name %><%= output_attributes.empty? ? (model_index == 1 ? ')' : '),') : ',' %>
11
+ <% output_attributes.each_with_index do |attribute, attribute_index| -%>
12
+ :<%= attribute.name %> => <%= attribute.default_value %><%= attribute_index == output_attributes.length - 1 ? '' : ','%>
13
+ <% end -%>
14
+ <% if !output_attributes.empty? -%>
15
+ <%= model_index == 1 ? ')' : '),' %>
16
+ <% end -%>
17
+ <% end -%>
18
+ ]
19
+ end
20
+
21
+ it "renders a list of <%= table_name %>" do
22
+ render
23
+ <% for attribute in output_attributes -%>
24
+ response.should have_tag("tr>td", <%= attribute.default_value %>.to_s, 2)
25
+ <% end -%>
26
+ end
27
+ end
28
+
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper')
2
+
3
+ <% output_attributes = attributes.reject{|attribute| [:datetime, :timestamp, :time, :date].index(attribute.type) } -%>
4
+ describe "/<%= table_name %>/new.<%= default_file_extension %>" do
5
+ include <%= controller_class_name %>Helper
6
+
7
+ before(:each) do
8
+ assigns[:<%= file_name %>] = stub_model(<%= class_name %>,
9
+ :new_record? => true<%= output_attributes.empty? ? '' : ',' %>
10
+ <% output_attributes.each_with_index do |attribute, attribute_index| -%>
11
+ :<%= attribute.name %> => <%= attribute.default_value %><%= attribute_index == output_attributes.length - 1 ? '' : ','%>
12
+ <% end -%>
13
+ )
14
+ end
15
+
16
+ it "renders new <%= file_name %> form" do
17
+ render
18
+
19
+ response.should have_tag("form[action=?][method=post]", <%= table_name %>_path) do
20
+ <% for attribute in output_attributes -%>
21
+ with_tag("<%= attribute.input_type -%>#<%= file_name %>_<%= attribute.name %>[name=?]", "<%= file_name %>[<%= attribute.name %>]")
22
+ <% end -%>
23
+ end
24
+ end
25
+ end
26
+
27
+
@@ -0,0 +1,63 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../spec_helper')
2
+
3
+ describe <%= controller_class_name %>Controller do
4
+ describe "route generation" do
5
+ it "maps #index" do
6
+ route_for(:controller => "<%= table_name %>", :action => "index").should == "/<%= table_name %>"
7
+ end
8
+
9
+ it "maps #new" do
10
+ route_for(:controller => "<%= table_name %>", :action => "new").should == "/<%= table_name %>/new"
11
+ end
12
+
13
+ it "maps #show" do
14
+ route_for(:controller => "<%= table_name %>", :action => "show", :id => "1").should == "/<%= table_name %>/1"
15
+ end
16
+
17
+ it "maps #edit" do
18
+ route_for(:controller => "<%= table_name %>", :action => "edit", :id => "1").should == "/<%= table_name %>/1/edit"
19
+ end
20
+
21
+ it "maps #create" do
22
+ route_for(:controller => "<%= table_name %>", :action => "create").should == {:path => "/<%= table_name %>", :method => :post}
23
+ end
24
+
25
+ it "maps #update" do
26
+ route_for(:controller => "<%= table_name %>", :action => "update", :id => "1").should == {:path =>"/<%= table_name %>/1", :method => :put}
27
+ end
28
+
29
+ it "maps #destroy" do
30
+ route_for(:controller => "<%= table_name %>", :action => "destroy", :id => "1").should == {:path =>"/<%= table_name %>/1", :method => :delete}
31
+ end
32
+ end
33
+
34
+ describe "route recognition" do
35
+ it "generates params for #index" do
36
+ params_from(:get, "/<%= table_name %>").should == {:controller => "<%= table_name %>", :action => "index"}
37
+ end
38
+
39
+ it "generates params for #new" do
40
+ params_from(:get, "/<%= table_name %>/new").should == {:controller => "<%= table_name %>", :action => "new"}
41
+ end
42
+
43
+ it "generates params for #create" do
44
+ params_from(:post, "/<%= table_name %>").should == {:controller => "<%= table_name %>", :action => "create"}
45
+ end
46
+
47
+ it "generates params for #show" do
48
+ params_from(:get, "/<%= table_name %>/1").should == {:controller => "<%= table_name %>", :action => "show", :id => "1"}
49
+ end
50
+
51
+ it "generates params for #edit" do
52
+ params_from(:get, "/<%= table_name %>/1/edit").should == {:controller => "<%= table_name %>", :action => "edit", :id => "1"}
53
+ end
54
+
55
+ it "generates params for #update" do
56
+ params_from(:put, "/<%= table_name %>/1").should == {:controller => "<%= table_name %>", :action => "update", :id => "1"}
57
+ end
58
+
59
+ it "generates params for #destroy" do
60
+ params_from(:delete, "/<%= table_name %>/1").should == {:controller => "<%= table_name %>", :action => "destroy", :id => "1"}
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../../spec_helper')
2
+
3
+ <% output_attributes = attributes.reject{|attribute| [:datetime, :timestamp, :time, :date].index(attribute.type) } -%>
4
+ describe "/<%= table_name %>/show.<%= default_file_extension %>" do
5
+ include <%= controller_class_name %>Helper
6
+ before(:each) do
7
+ assigns[:<%= file_name %>] = @<%= file_name %> = stub_model(<%= class_name %><%= output_attributes.empty? ? ')' : ',' %>
8
+ <% output_attributes.each_with_index do |attribute, attribute_index| -%>
9
+ :<%= attribute.name %> => <%= attribute.default_value %><%= attribute_index == output_attributes.length - 1 ? '' : ','%>
10
+ <% end -%>
11
+ <% if !output_attributes.empty? -%>
12
+ )
13
+ <% end -%>
14
+ end
15
+
16
+ it "renders attributes in <p>" do
17
+ render
18
+ <% for attribute in output_attributes -%>
19
+ response.should have_text(/<%= Regexp.escape(attribute.default_value).gsub(/^"|"$/, '')%>/)
20
+ <% end -%>
21
+ end
22
+ end
23
+
data/init.rb ADDED
@@ -0,0 +1,9 @@
1
+ # Placeholder to satisfy Rails.
2
+ #
3
+ # Do NOT add any require statements to this file. Doing
4
+ # so will cause Rails to load this plugin all of the time.
5
+ #
6
+ # Running 'ruby script/generate rspec' will
7
+ # generate spec/spec_helper.rb, which includes the necessary
8
+ # require statements and configuration. This file should
9
+ # be required by all of your spec files.
@@ -0,0 +1 @@
1
+ # This needs to be here for >= ZenTest-3.9.0 to add this directory to the load path.
@@ -0,0 +1,76 @@
1
+ # (c) Copyright 2006 Nick Sieger <nicksieger@gmail.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person
4
+ # obtaining a copy of this software and associated documentation files
5
+ # (the "Software"), to deal in the Software without restriction,
6
+ # including without limitation the rights to use, copy, modify, merge,
7
+ # publish, distribute, sublicense, and/or sell copies of the Software,
8
+ # and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18
+ # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19
+ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ $:.push(*Dir["vendor/rails/*/lib"])
24
+
25
+ require 'active_support'
26
+ require 'autotest/rspec'
27
+
28
+ Autotest.add_hook :initialize do |at|
29
+ %w{config/ coverage/ db/ doc/ log/ public/ script/ tmp/ vendor/rails vendor/plugins previous_failures.txt}.each do |exception|
30
+ at.add_exception(exception)
31
+ end
32
+
33
+ at.clear_mappings
34
+
35
+ at.add_mapping(%r%^(test|spec)/fixtures/(.*).yml$%) { |_, m|
36
+ ["spec/models/#{m[2].singularize}_spec.rb"] + at.files_matching(%r%^spec\/views\/#{m[2]}/.*_spec\.rb$%)
37
+ }
38
+ at.add_mapping(%r%^spec/(models|controllers|views|helpers|lib)/.*rb$%) { |filename, _|
39
+ filename
40
+ }
41
+ at.add_mapping(%r%^app/models/(.*)\.rb$%) { |_, m|
42
+ ["spec/models/#{m[1]}_spec.rb"]
43
+ }
44
+ at.add_mapping(%r%^app/views/(.*)$%) { |_, m|
45
+ at.files_matching %r%^spec/views/#{m[1]}_spec.rb$%
46
+ }
47
+ at.add_mapping(%r%^app/controllers/(.*)\.rb$%) { |_, m|
48
+ if m[1] == "application"
49
+ at.files_matching %r%^spec/controllers/.*_spec\.rb$%
50
+ else
51
+ ["spec/controllers/#{m[1]}_spec.rb"]
52
+ end
53
+ }
54
+ at.add_mapping(%r%^app/helpers/(.*)_helper\.rb$%) { |_, m|
55
+ if m[1] == "application" then
56
+ at.files_matching(%r%^spec/(views|helpers)/.*_spec\.rb$%)
57
+ else
58
+ ["spec/helpers/#{m[1]}_helper_spec.rb"] + at.files_matching(%r%^spec\/views\/#{m[1]}/.*_spec\.rb$%)
59
+ end
60
+ }
61
+ at.add_mapping(%r%^config/routes\.rb$%) {
62
+ at.files_matching %r%^spec/(controllers|views|helpers)/.*_spec\.rb$%
63
+ }
64
+ at.add_mapping(%r%^config/database\.yml$%) { |_, m|
65
+ at.files_matching %r%^spec/models/.*_spec\.rb$%
66
+ }
67
+ at.add_mapping(%r%^(spec/(spec_helper|shared/.*)|config/(boot|environment(s/test)?))\.rb$%) {
68
+ at.files_matching %r%^spec/(models|controllers|views|helpers)/.*_spec\.rb$%
69
+ }
70
+ at.add_mapping(%r%^lib/(.*)\.rb$%) { |_, m|
71
+ ["spec/lib/#{m[1]}_spec.rb"]
72
+ }
73
+ end
74
+
75
+ class Autotest::RailsRspec < Autotest::Rspec
76
+ end
@@ -0,0 +1,37 @@
1
+ RAILS_ENV ||= "test"
2
+
3
+ begin
4
+ require_dependency 'application_controller'
5
+ rescue MissingSourceFile
6
+ begin
7
+ require_dependency 'application'
8
+ rescue MissingSourceFile, NameError
9
+ # ok, ActionController is not defined
10
+ end
11
+ end
12
+ require 'rack/utils'
13
+
14
+ if Object.const_defined?(:ActionController) && ActionController.const_defined?(:Base)
15
+ require 'action_controller/test_process'
16
+ require 'action_controller/integration'
17
+ end
18
+ require 'active_support/test_case'
19
+ if Object.const_defined?(:ActiveRecord) && ActiveRecord.const_defined?(:Base)
20
+ require 'active_record/fixtures'
21
+ end
22
+
23
+ require 'spec/test/unit'
24
+
25
+ require 'spec/rails/matchers'
26
+ require 'spec/rails/mocks'
27
+ require 'spec/rails/example'
28
+ require 'spec/rails/extensions'
29
+ require 'spec/rails/interop/testcase'
30
+
31
+ Spec::Example::ExampleGroupFactory.default(ActiveSupport::TestCase)
32
+
33
+ if Object.const_defined?(:ActionView) && ActionView.const_defined?(:Base) && \
34
+ ActionView::Base.respond_to?(:cache_template_extensions)
35
+ ActionView::Base.cache_template_extensions = false
36
+ end
37
+
@@ -0,0 +1,53 @@
1
+ dir = File.dirname(__FILE__)
2
+
3
+ if Object.const_defined?(:ActionController) && ActionController.const_defined?(:Base)
4
+ require 'spec/rails/example/routing_helpers'
5
+ require 'spec/rails/example/assigns_hash_proxy'
6
+ require "spec/rails/example/render_observer"
7
+ end
8
+ if Object.const_defined?(:ActiveRecord) && ActiveRecord.const_defined?(:Base)
9
+ require "spec/rails/example/model_example_group"
10
+ end
11
+ if Object.const_defined?(:ActionController) && ActionController.const_defined?(:Base)
12
+ require "spec/rails/example/functional_example_group"
13
+ require "spec/rails/example/controller_example_group"
14
+ require "spec/rails/example/helper_example_group"
15
+ require "spec/rails/example/view_example_group"
16
+ require "spec/rails/example/routing_example_group"
17
+ require "spec/rails/example/cookies_proxy"
18
+ end
19
+
20
+ module Spec
21
+ module Rails
22
+ # Spec::Rails::Example extends Spec::Example (RSpec's core Example module) to provide
23
+ # Rails-specific contexts for describing Rails Models, Views, Controllers and Helpers.
24
+ #
25
+ # == Model Examples
26
+ #
27
+ # 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.
28
+ #
29
+ # See Spec::Rails::Example::ModelExampleGroup
30
+ #
31
+ # == Controller Examples
32
+ #
33
+ # 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.
34
+ #
35
+ # See Spec::Rails::Example::ControllerExampleGroup
36
+ #
37
+ # == View Examples
38
+ #
39
+ # This is the other half of Rails functional testing. View specs allow you to set up assigns and render
40
+ # a template. By assigning mock model data, you can specify view behaviour with no dependency on a database
41
+ # or your real models.
42
+ #
43
+ # See Spec::Rails::Example::ViewExampleGroup
44
+ #
45
+ # == Helper Examples
46
+ #
47
+ # These let you specify directly methods that live in your helpers.
48
+ #
49
+ # See Spec::Rails::Example::HelperExampleGroup
50
+ module Example
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,39 @@
1
+ module Spec
2
+ module Rails
3
+ module Example
4
+ class AssignsHashProxy #:nodoc:
5
+ def initialize(example_group, &block)
6
+ @target = block.call
7
+ @example_group = example_group
8
+ end
9
+
10
+ def [](key)
11
+ return false if false == assigns[key] || false == assigns[key.to_s]
12
+ assigns[key] || assigns[key.to_s] || @target.instance_variable_get("@#{key}")
13
+ end
14
+
15
+ def []=(key, val)
16
+ @target.instance_variable_set("@#{key}", val)
17
+ end
18
+
19
+ def delete(key)
20
+ assigns.delete(key.to_s)
21
+ @target.instance_variable_set("@#{key}", nil)
22
+ end
23
+
24
+ def each(&block)
25
+ assigns.each &block
26
+ end
27
+
28
+ def has_key?(key)
29
+ assigns.key?(key.to_s)
30
+ end
31
+
32
+ protected
33
+ def assigns
34
+ @example_group.orig_assigns
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,242 @@
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
+ tests described_class
74
+ end
75
+ end
76
+
77
+ # When you don't pass a controller to describe, like this:
78
+ #
79
+ # describe ThingsController do
80
+ #
81
+ # ... then you must provide a controller_name within the context of
82
+ # your controller specs:
83
+ #
84
+ # describe "ThingController" do
85
+ # controller_name :thing
86
+ # ...
87
+ def controller_name(name)
88
+ tests "#{name}_controller".camelize.constantize
89
+ end
90
+ end
91
+
92
+ before(:each) do
93
+ # Some Rails apps explicitly disable ActionMailer in environment.rb
94
+ if Object.const_defined?(:ActionMailer)
95
+ @deliveries = []
96
+ ActionMailer::Base.deliveries = @deliveries
97
+ end
98
+
99
+ unless @controller.class.ancestors.include?(ActionController::Base)
100
+ Spec::Expectations.fail_with <<-MESSAGE
101
+ Controller specs need to know what controller is being specified. You can
102
+ indicate this by passing the controller to describe():
103
+
104
+ describe MyController do
105
+
106
+ or by declaring the controller's name
107
+
108
+ describe "a MyController" do
109
+ controller_name :my #invokes the MyController
110
+ end
111
+ MESSAGE
112
+ end
113
+ @controller.extend ControllerInstanceMethods
114
+ @controller.integrate_views! if @integrate_views
115
+ @controller.session = session
116
+ end
117
+
118
+ attr_reader :response, :request, :controller
119
+
120
+ def initialize(defined_description, options={}, &implementation) #:nodoc:
121
+ super
122
+ @integrate_views = self.class.integrate_views?
123
+ end
124
+
125
+ # Bypasses any error rescues defined with rescue_from. Useful
126
+ # in cases in which you want to specify errors coming out of
127
+ # actions that might be caught by a rescue_from clause that is
128
+ # specified separately.
129
+ #
130
+ # Note that this will override the effect of rescue_action_in_public
131
+ def bypass_rescue
132
+ if ::Rails::VERSION::STRING >= '2.2'
133
+ def controller.rescue_action(exception)
134
+ raise exception
135
+ end
136
+ else
137
+ def controller.rescue_action_with_handler(exception)
138
+ raise exception
139
+ end
140
+ end
141
+ end
142
+
143
+ protected
144
+
145
+ def _assigns_hash_proxy
146
+ @_assigns_hash_proxy ||= AssignsHashProxy.new(self) {@response.template}
147
+ end
148
+
149
+ private
150
+
151
+ module TemplateIsolationExtensions
152
+ def file_exists?(ignore); true; end
153
+
154
+ def render_file(*args)
155
+ @first_render ||= args[0] unless args[0] =~ /^layouts/
156
+ end
157
+
158
+ # Rails 2.2
159
+ def _pick_template(*args)
160
+ @_first_render ||= args[0] unless args[0] =~ /^layouts/
161
+ PickedTemplate.new
162
+ end
163
+
164
+ def render(*args)
165
+ @_rendered ? record_render(args[0]) : super
166
+ end
167
+
168
+ private
169
+
170
+ def record_render(opts)
171
+ (@_rendered[:template] ||= opts[:file]) if opts[:file]
172
+ (@_rendered[:partials][opts[:partial]] += 1) if opts[:partial]
173
+ end
174
+
175
+ # Returned by _pick_template when running controller examples in isolation mode.
176
+ class PickedTemplate
177
+ # Do nothing when running controller examples in isolation mode.
178
+ def render_template(*ignore_args); end
179
+ # Do nothing when running controller examples in isolation mode.
180
+ def render_partial(*ignore_args); end
181
+ end
182
+ end
183
+
184
+ module ControllerInstanceMethods # :nodoc:
185
+ include Spec::Rails::Example::RenderObserver
186
+
187
+ # === render(options = nil, extra_options={}, &block)
188
+ #
189
+ # This gets added to the controller's singleton meta class,
190
+ # allowing Controller Examples to run in two modes, freely switching
191
+ # from example group to example group.
192
+ def render(options=nil, extra_options={}, &block)
193
+ unless block_given?
194
+ unless integrate_views?
195
+ @template.extend TemplateIsolationExtensions
196
+ end
197
+ end
198
+
199
+ if matching_message_expectation_exists(options)
200
+ render_proxy.render(options, &block)
201
+ @performed_render = true
202
+ else
203
+ if matching_stub_exists(options)
204
+ @performed_render = true
205
+ else
206
+ super
207
+ end
208
+ end
209
+ end
210
+
211
+ def response(&block)
212
+ # NOTE - we're setting @update for the assert_select_spec - kinda weird, huh?
213
+ @update = block
214
+ @_response || @response
215
+ end
216
+
217
+ def integrate_views!
218
+ @integrate_views = true
219
+ end
220
+
221
+ private
222
+
223
+ def integrate_views?
224
+ @integrate_views
225
+ end
226
+
227
+ def matching_message_expectation_exists(options)
228
+ render_proxy.__send__(:__mock_proxy).__send__(:find_matching_expectation, :render, options)
229
+ end
230
+
231
+ def matching_stub_exists(options)
232
+ render_proxy.__send__(:__mock_proxy).__send__(:find_matching_method_stub, :render, options)
233
+ end
234
+
235
+ end
236
+
237
+ Spec::Example::ExampleGroupFactory.register(:controller, self)
238
+
239
+ end
240
+ end
241
+ end
242
+ end