richzhou-rspec-rails 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. data/.document +7 -0
  2. data/.gitignore +8 -0
  3. data/Contribute.rdoc +4 -0
  4. data/Gemfile +4 -0
  5. data/History.rdoc +321 -0
  6. data/License.txt +33 -0
  7. data/Manifest.txt +165 -0
  8. data/README.rdoc +48 -0
  9. data/Rakefile +12 -0
  10. data/TODO.txt +17 -0
  11. data/Upgrade.rdoc +148 -0
  12. data/generators/integration_spec/integration_spec_generator.rb +10 -0
  13. data/generators/integration_spec/templates/integration_spec.rb +4 -0
  14. data/generators/rspec/CHANGES +1 -0
  15. data/generators/rspec/rspec_generator.rb +72 -0
  16. data/generators/rspec/templates/previous_failures.txt +0 -0
  17. data/generators/rspec/templates/rcov.opts +2 -0
  18. data/generators/rspec/templates/rspec.rake +146 -0
  19. data/generators/rspec/templates/script/autospec +6 -0
  20. data/generators/rspec/templates/script/spec +10 -0
  21. data/generators/rspec/templates/spec.opts +4 -0
  22. data/generators/rspec/templates/spec_helper.rb +54 -0
  23. data/generators/rspec_controller/USAGE +33 -0
  24. data/generators/rspec_controller/rspec_controller_generator.rb +47 -0
  25. data/generators/rspec_controller/templates/controller_spec.rb +25 -0
  26. data/generators/rspec_controller/templates/helper_spec.rb +11 -0
  27. data/generators/rspec_controller/templates/view_spec.rb +12 -0
  28. data/generators/rspec_default_values.rb +28 -0
  29. data/generators/rspec_model/USAGE +18 -0
  30. data/generators/rspec_model/rspec_model_generator.rb +35 -0
  31. data/generators/rspec_model/templates/model_spec.rb +13 -0
  32. data/generators/rspec_scaffold/rspec_scaffold_generator.rb +154 -0
  33. data/generators/rspec_scaffold/templates/controller_spec.rb +131 -0
  34. data/generators/rspec_scaffold/templates/edit_erb_spec.rb +25 -0
  35. data/generators/rspec_scaffold/templates/helper_spec.rb +11 -0
  36. data/generators/rspec_scaffold/templates/index_erb_spec.rb +27 -0
  37. data/generators/rspec_scaffold/templates/new_erb_spec.rb +25 -0
  38. data/generators/rspec_scaffold/templates/routing_spec.rb +33 -0
  39. data/generators/rspec_scaffold/templates/show_erb_spec.rb +22 -0
  40. data/init.rb +9 -0
  41. data/lib/autotest/discover.rb +5 -0
  42. data/lib/autotest/rails_rspec.rb +76 -0
  43. data/lib/spec/rails.rb +26 -0
  44. data/lib/spec/rails/example.rb +48 -0
  45. data/lib/spec/rails/example/assigns_hash_proxy.rb +39 -0
  46. data/lib/spec/rails/example/controller_example_group.rb +285 -0
  47. data/lib/spec/rails/example/cookies_proxy.rb +29 -0
  48. data/lib/spec/rails/example/functional_example_group.rb +106 -0
  49. data/lib/spec/rails/example/helper_example_group.rb +153 -0
  50. data/lib/spec/rails/example/integration_example_group.rb +16 -0
  51. data/lib/spec/rails/example/model_example_group.rb +15 -0
  52. data/lib/spec/rails/example/render_observer.rb +82 -0
  53. data/lib/spec/rails/example/routing_example_group.rb +16 -0
  54. data/lib/spec/rails/example/routing_helpers.rb +66 -0
  55. data/lib/spec/rails/example/view_example_group.rb +203 -0
  56. data/lib/spec/rails/extensions.rb +11 -0
  57. data/lib/spec/rails/extensions/action_controller/rescue.rb +42 -0
  58. data/lib/spec/rails/extensions/action_controller/test_case.rb +16 -0
  59. data/lib/spec/rails/extensions/action_controller/test_response.rb +21 -0
  60. data/lib/spec/rails/extensions/action_view/base.rb +35 -0
  61. data/lib/spec/rails/extensions/active_record/base.rb +45 -0
  62. data/lib/spec/rails/extensions/active_support/test_case.rb +7 -0
  63. data/lib/spec/rails/extensions/spec/matchers/have.rb +23 -0
  64. data/lib/spec/rails/extensions/spec/runner/configuration.rb +45 -0
  65. data/lib/spec/rails/interop/testcase.rb +14 -0
  66. data/lib/spec/rails/matchers.rb +32 -0
  67. data/lib/spec/rails/matchers/ar_be_valid.rb +27 -0
  68. data/lib/spec/rails/matchers/assert_select.rb +180 -0
  69. data/lib/spec/rails/matchers/change.rb +13 -0
  70. data/lib/spec/rails/matchers/have_text.rb +57 -0
  71. data/lib/spec/rails/matchers/include_text.rb +54 -0
  72. data/lib/spec/rails/matchers/redirect_to.rb +126 -0
  73. data/lib/spec/rails/matchers/render_template.rb +129 -0
  74. data/lib/spec/rails/matchers/route_to.rb +149 -0
  75. data/lib/spec/rails/mocks.rb +140 -0
  76. data/lib/spec/rails/version.rb +16 -0
  77. data/rspec-rails.gemspec +25 -0
  78. data/spec/autotest/mappings_spec.rb +86 -0
  79. data/spec/rails_suite.rb +7 -0
  80. data/spec/resources/controllers/action_view_base_spec_controller.rb +2 -0
  81. data/spec/resources/controllers/application.rb +9 -0
  82. data/spec/resources/controllers/controller_spec_controller.rb +127 -0
  83. data/spec/resources/controllers/example.txt +1 -0
  84. data/spec/resources/controllers/redirect_spec_controller.rb +70 -0
  85. data/spec/resources/controllers/render_spec_controller.rb +34 -0
  86. data/spec/resources/controllers/rjs_spec_controller.rb +58 -0
  87. data/spec/resources/helpers/addition_helper.rb +5 -0
  88. data/spec/resources/helpers/explicit_helper.rb +46 -0
  89. data/spec/resources/helpers/more_explicit_helper.rb +5 -0
  90. data/spec/resources/helpers/plugin_application_helper.rb +6 -0
  91. data/spec/resources/helpers/view_spec_helper.rb +13 -0
  92. data/spec/resources/models/animal.rb +4 -0
  93. data/spec/resources/models/person.rb +18 -0
  94. data/spec/resources/models/thing.rb +3 -0
  95. data/spec/resources/views/controller_spec/_partial.html.erb +0 -0
  96. data/spec/resources/views/controller_spec/action_setting_flash_after_session_reset.html.erb +1 -0
  97. data/spec/resources/views/controller_spec/action_setting_flash_before_session_reset.html.erb +1 -0
  98. data/spec/resources/views/controller_spec/action_setting_the_assigns_hash.html.erb +0 -0
  99. data/spec/resources/views/controller_spec/action_with_errors_in_template.html.erb +1 -0
  100. data/spec/resources/views/controller_spec/action_with_template.html.erb +1 -0
  101. data/spec/resources/views/controller_spec/non_existent_action_with_existent_template.html.erb +1 -0
  102. data/spec/resources/views/layouts/application.html.erb +0 -0
  103. data/spec/resources/views/layouts/simple.html.erb +0 -0
  104. data/spec/resources/views/objects/_object.html.erb +1 -0
  105. data/spec/resources/views/render_spec/_a_partial.html.erb +0 -0
  106. data/spec/resources/views/render_spec/action_with_alternate_layout.html.erb +0 -0
  107. data/spec/resources/views/render_spec/some_action.html.erb +0 -0
  108. data/spec/resources/views/render_spec/some_action.js.rjs +1 -0
  109. data/spec/resources/views/rjs_spec/_replacement_partial.html.erb +1 -0
  110. data/spec/resources/views/rjs_spec/hide_div.js.rjs +1 -0
  111. data/spec/resources/views/rjs_spec/hide_page_element.js.rjs +1 -0
  112. data/spec/resources/views/rjs_spec/insert_html.js.rjs +1 -0
  113. data/spec/resources/views/rjs_spec/replace.js.rjs +1 -0
  114. data/spec/resources/views/rjs_spec/replace_html.js.rjs +1 -0
  115. data/spec/resources/views/rjs_spec/replace_html_with_partial.js.rjs +1 -0
  116. data/spec/resources/views/rjs_spec/visual_effect.js.rjs +1 -0
  117. data/spec/resources/views/rjs_spec/visual_toggle_effect.js.rjs +1 -0
  118. data/spec/resources/views/tag_spec/no_tags.html.erb +1 -0
  119. data/spec/resources/views/tag_spec/single_div_with_no_attributes.html.erb +1 -0
  120. data/spec/resources/views/tag_spec/single_div_with_one_attribute.html.erb +1 -0
  121. data/spec/resources/views/view_spec/_partial.html.erb +2 -0
  122. data/spec/resources/views/view_spec/_partial_used_twice.html.erb +0 -0
  123. data/spec/resources/views/view_spec/_partial_with_local_variable.html.erb +1 -0
  124. data/spec/resources/views/view_spec/_partial_with_sub_partial.html.erb +1 -0
  125. data/spec/resources/views/view_spec/_spacer.html.erb +1 -0
  126. data/spec/resources/views/view_spec/accessor.html.erb +6 -0
  127. data/spec/resources/views/view_spec/block_helper.html.erb +3 -0
  128. data/spec/resources/views/view_spec/entry_form.html.erb +2 -0
  129. data/spec/resources/views/view_spec/explicit_helper.html.erb +2 -0
  130. data/spec/resources/views/view_spec/foo/show.html.erb +1 -0
  131. data/spec/resources/views/view_spec/implicit_helper.html.erb +2 -0
  132. data/spec/resources/views/view_spec/multiple_helpers.html.erb +3 -0
  133. data/spec/resources/views/view_spec/path_params.html.erb +1 -0
  134. data/spec/resources/views/view_spec/should_not_receive.html.erb +3 -0
  135. data/spec/resources/views/view_spec/template_with_partial.html.erb +5 -0
  136. data/spec/resources/views/view_spec/template_with_partial_using_collection.html.erb +3 -0
  137. data/spec/resources/views/view_spec/template_with_partial_with_array.html.erb +1 -0
  138. data/spec/resources/views/view_spec/view_helpers.html.erb +1 -0
  139. data/spec/spec/rails/example/assigns_hash_proxy_spec.rb +109 -0
  140. data/spec/spec/rails/example/configuration_spec.rb +67 -0
  141. data/spec/spec/rails/example/controller_example_group_spec.rb +307 -0
  142. data/spec/spec/rails/example/controller_isolation_spec.rb +75 -0
  143. data/spec/spec/rails/example/cookies_proxy_spec.rb +87 -0
  144. data/spec/spec/rails/example/error_handling_spec.rb +90 -0
  145. data/spec/spec/rails/example/example_group_factory_spec.rb +112 -0
  146. data/spec/spec/rails/example/helper_example_group_spec.rb +247 -0
  147. data/spec/spec/rails/example/model_example_group_spec.rb +32 -0
  148. data/spec/spec/rails/example/routing_example_group_spec.rb +9 -0
  149. data/spec/spec/rails/example/shared_routing_example_group_examples.rb +241 -0
  150. data/spec/spec/rails/example/test_unit_assertion_accessibility_spec.rb +33 -0
  151. data/spec/spec/rails/example/view_example_group_spec.rb +346 -0
  152. data/spec/spec/rails/extensions/action_view_base_spec.rb +79 -0
  153. data/spec/spec/rails/extensions/active_record_spec.rb +14 -0
  154. data/spec/spec/rails/interop/testcase_spec.rb +70 -0
  155. data/spec/spec/rails/matchers/ar_be_valid_spec.rb +19 -0
  156. data/spec/spec/rails/matchers/assert_select_spec.rb +835 -0
  157. data/spec/spec/rails/matchers/errors_on_spec.rb +37 -0
  158. data/spec/spec/rails/matchers/have_text_spec.rb +69 -0
  159. data/spec/spec/rails/matchers/include_text_spec.rb +62 -0
  160. data/spec/spec/rails/matchers/redirect_to_spec.rb +253 -0
  161. data/spec/spec/rails/matchers/render_template_spec.rb +208 -0
  162. data/spec/spec/rails/matchers/should_change_spec.rb +15 -0
  163. data/spec/spec/rails/mocks/ar_classes.rb +10 -0
  164. data/spec/spec/rails/mocks/mock_model_spec.rb +112 -0
  165. data/spec/spec/rails/mocks/stub_model_spec.rb +80 -0
  166. data/spec/spec/rails/sample_modified_fixture.rb +8 -0
  167. data/spec/spec/rails/sample_spec.rb +8 -0
  168. data/spec/spec/rails/spec_spec.rb +11 -0
  169. data/spec/spec_helper.rb +78 -0
  170. metadata +363 -0
@@ -0,0 +1,11 @@
1
+ require 'spec'
2
+
3
+ require 'spec/rails/extensions/spec/runner/configuration'
4
+ require 'spec/rails/extensions/spec/matchers/have'
5
+
6
+ require 'spec/rails/extensions/active_support/test_case'
7
+ require 'spec/rails/extensions/active_record/base'
8
+ require 'spec/rails/extensions/action_controller/rescue'
9
+ require 'spec/rails/extensions/action_controller/test_case'
10
+ require 'spec/rails/extensions/action_controller/test_response'
11
+ require 'spec/rails/extensions/action_view/base'
@@ -0,0 +1,42 @@
1
+ module ActionController
2
+ module Rescue
3
+ def use_rails_error_handling!
4
+ Kernel.warn <<-WARNING
5
+ DEPRECATION NOTICE: controller.use_rails_error_handling! is
6
+ deprecated and will be removed from a future version of
7
+ rspec-rails.
8
+
9
+ Use rescue_action_in_public!, which is defined directly in
10
+ rails' testing framework, instead.
11
+ WARNING
12
+ if ::Rails::VERSION::STRING =~ /^2\.0/
13
+ @use_rails_error_handling = true
14
+ else
15
+ # anything but 0.0.0.0 - borrowed from rails own rescue_action_in_public!
16
+ request.remote_addr = '208.77.188.166'
17
+ end
18
+ end
19
+
20
+ def use_rails_error_handling?
21
+ @use_rails_error_handling ||= false
22
+ end
23
+
24
+ protected
25
+
26
+ if ::Rails::VERSION::STRING =~ /^2\.0/
27
+ def rescue_action_in_public?
28
+ request.respond_to?(:rescue_action_in_public?) and request.rescue_action_in_public?
29
+ end
30
+
31
+ def rescue_action_with_handler_with_fast_errors(exception)
32
+ if (use_rails_error_handling? || rescue_action_in_public?) & !handler_for_rescue(exception)
33
+ rescue_action_in_public(exception)
34
+ else
35
+ rescue_action_with_handler_without_fast_errors(exception)
36
+ end
37
+ end
38
+ alias_method_chain :rescue_action_with_handler, :fast_errors
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,16 @@
1
+ module ActionController
2
+ class TestCase
3
+ include ::Spec::Rails::Example::RoutingHelpers
4
+
5
+ if ::Rails::VERSION::STRING =~ /2\.0/
6
+ # Introduced in Rails 2.1, but we need it for 2.0
7
+ def rescue_action_in_public!
8
+ # See rescue.rb in this same directory
9
+ def request.rescue_action_in_public?
10
+ true
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
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
+
9
+ if ::Rails::VERSION::STRING < "2.3"
10
+ def [](name)
11
+ Kernel.warn <<-WARNING
12
+ DEPRECATION NOTICE: [](name) as an alias for capture(name) (TestResponse
13
+ extension in rspec-rails) is deprecated and will not be defined by rspec-rails
14
+ when working with rails >= 2.3.0. It will also be removed entirely from
15
+ a future version of rspec-rails.
16
+ WARNING
17
+ capture(name)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ module ActionView #:nodoc:
2
+ class Base #:nodoc:
3
+ include Spec::Rails::Example::RenderObserver
4
+ cattr_accessor :base_view_path
5
+
6
+ def render_partial_with_base_view_path_handling(partial_path, local_assigns = nil, deprecated_local_assigns = nil) #:nodoc:
7
+ if partial_path.is_a?(String)
8
+ unless partial_path.include?("/")
9
+ unless self.class.base_view_path.nil?
10
+ partial_path = "#{self.class.base_view_path}/#{partial_path}"
11
+ end
12
+ end
13
+ end
14
+ begin
15
+ render_partial_without_base_view_path_handling(partial_path, local_assigns, deprecated_local_assigns)
16
+ rescue ArgumentError # edge rails > 2.1 changed render_partial to accept only one arg
17
+ render_partial_without_base_view_path_handling(partial_path)
18
+ end
19
+ end
20
+ alias_method_chain :render_partial, :base_view_path_handling
21
+
22
+ def render_with_mock_proxy(options = {}, old_local_assigns = {}, &block)
23
+ if render_proxy.__send__(:__mock_proxy).__send__(:find_matching_expectation, :render, options, old_local_assigns)
24
+ render_proxy.render(options, old_local_assigns)
25
+ elsif render_proxy.__send__(:__mock_proxy).__send__(:find_matching_expectation, :render, options)
26
+ render_proxy.render(options)
27
+ else
28
+ unless render_proxy.__send__(:__mock_proxy).__send__(:find_matching_method_stub, :render, options)
29
+ render_without_mock_proxy(options, old_local_assigns, &block)
30
+ end
31
+ end
32
+ end
33
+ alias_method_chain :render, :mock_proxy
34
+ end
35
+ end
@@ -0,0 +1,45 @@
1
+ if defined?(ActiveRecord::Base)
2
+ module Spec
3
+ module Rails
4
+ module Extensions
5
+ module ActiveRecord
6
+ module ClassMethods
7
+ # :call-seq:
8
+ # ModelClass.should have(:no).records
9
+ # ModelClass.should have(1).record
10
+ # ModelClass.should have(n).records
11
+ #
12
+ # Extension to enhance <tt>should have</tt> on AR Model classes
13
+ def records
14
+ find(:all)
15
+ end
16
+ alias :record :records
17
+ end
18
+
19
+ module InstanceMethods
20
+ # :call-seq:
21
+ # model.should have(:no).errors_on(:attribute)
22
+ # model.should have(1).error_on(:attribute)
23
+ # model.should have(n).errors_on(:attribute)
24
+ #
25
+ # Extension to enhance <tt>should have</tt> on AR Model instances.
26
+ # Calls model.valid? in order to prepare the object's errors
27
+ # object.
28
+ def errors_on(attribute)
29
+ self.valid?
30
+ [self.errors.on(attribute)].flatten.compact
31
+ end
32
+ alias :error_on :errors_on
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ module ActiveRecord #:nodoc:
40
+ class Base
41
+ extend Spec::Rails::Extensions::ActiveRecord::ClassMethods
42
+ include Spec::Rails::Extensions::ActiveRecord::InstanceMethods
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,7 @@
1
+ module ActiveSupport
2
+ class TestCase
3
+ include ::Spec::Rails::Matchers
4
+ include ::Spec::Rails::Mocks
5
+ end
6
+ end
7
+
@@ -0,0 +1,23 @@
1
+ require 'spec/matchers/have'
2
+
3
+ module Spec #:nodoc:
4
+ module Matchers #:nodoc:
5
+ class Have #:nodoc:
6
+
7
+ def failure_message_for_should_with_errors_on_extensions
8
+ return "expected #{relativities[@relativity]}#{@expected} errors on :#{@args[0]}, got #{@actual}" if @collection_name == :errors_on
9
+ return "expected #{relativities[@relativity]}#{@expected} error on :#{@args[0]}, got #{@actual}" if @collection_name == :error_on
10
+ return failure_message_for_should_without_errors_on_extensions
11
+ end
12
+ alias_method_chain :failure_message_for_should, :errors_on_extensions
13
+
14
+ def description_with_errors_on_extensions
15
+ return "have #{relativities[@relativity]}#{@expected} errors on :#{@args[0]}" if @collection_name == :errors_on
16
+ return "have #{relativities[@relativity]}#{@expected} error on :#{@args[0]}" if @collection_name == :error_on
17
+ return description_without_errors_on_extensions
18
+ end
19
+ alias_method_chain :description, :errors_on_extensions
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec/runner/configuration'
2
+ require 'test_help'
3
+
4
+ if defined?(ActiveRecord::Base)
5
+ module Spec
6
+ module Runner
7
+ class Configuration
8
+
9
+ def initialize
10
+ super
11
+ self.fixture_path = RAILS_ROOT + '/spec/fixtures'
12
+ end
13
+
14
+ def use_transactional_fixtures
15
+ ActiveSupport::TestCase.use_transactional_fixtures
16
+ end
17
+ def use_transactional_fixtures=(value)
18
+ ActiveSupport::TestCase.use_transactional_fixtures = value
19
+ end
20
+
21
+ def use_instantiated_fixtures
22
+ ActiveSupport::TestCase.use_instantiated_fixtures
23
+ end
24
+ def use_instantiated_fixtures=(value)
25
+ ActiveSupport::TestCase.use_instantiated_fixtures = value
26
+ end
27
+
28
+ def fixture_path
29
+ ActiveSupport::TestCase.fixture_path
30
+ end
31
+ def fixture_path=(path)
32
+ ActiveSupport::TestCase.fixture_path = path
33
+ ActionController::IntegrationTest.fixture_path = path
34
+ end
35
+
36
+ def global_fixtures
37
+ ActiveSupport::TestCase.fixture_table_names
38
+ end
39
+ def global_fixtures=(fixtures)
40
+ ActiveSupport::TestCase.fixtures(*fixtures)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,14 @@
1
+ module Test
2
+ module Unit
3
+ class TestCase
4
+ # Edge rails (r8664) introduces class-wide setup & teardown callbacks for Test::Unit::TestCase.
5
+ # Make sure these still get run when running TestCases under rspec:
6
+ prepend_before(:each) do
7
+ run_callbacks :setup if respond_to?(:run_callbacks)
8
+ end
9
+ append_after(:each) do
10
+ run_callbacks :teardown if respond_to?(:run_callbacks)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,32 @@
1
+ module Spec
2
+ module Rails
3
+ # Spec::Rails::Expectations::Matchers provides several expectation matchers
4
+ # intended to work with Rails components like models and responses. For example:
5
+ #
6
+ # response.should redirect_to("some/url") #redirect_to(url) is the matcher.
7
+ #
8
+ # In addition to those you see below, the arbitrary predicate feature of RSpec
9
+ # makes the following available as well:
10
+ #
11
+ # response.should be_success #passes if response.success?
12
+ # response.should be_redirect #passes if response.redirect?
13
+ #
14
+ # Note that many of these matchers are part of a wrapper of <tt>assert_select</tt>, so
15
+ # the documentation comes straight from that with some slight modifications.
16
+ # <tt>assert_select</tt> is a Test::Unit extension originally contributed to the
17
+ # Rails community as a plugin by Assaf Arkin and eventually shipped as part of Rails.
18
+ #
19
+ # For more info on <tt>assert_select</tt>, see the relevant Rails documentation.
20
+ module Matchers
21
+ end
22
+ end
23
+ end
24
+
25
+ require 'spec/rails/matchers/ar_be_valid'
26
+ require 'spec/rails/matchers/assert_select'
27
+ require 'spec/rails/matchers/change'
28
+ require 'spec/rails/matchers/have_text'
29
+ require 'spec/rails/matchers/include_text'
30
+ require 'spec/rails/matchers/redirect_to'
31
+ require 'spec/rails/matchers/route_to'
32
+ require 'spec/rails/matchers/render_template'
@@ -0,0 +1,27 @@
1
+ if defined?(ActiveRecord::Base)
2
+ module Spec
3
+ module Rails
4
+ module Matchers
5
+ # :call-seq:
6
+ # response.should be_valid
7
+ # response.should_not be_valid
8
+ def be_valid
9
+ ::Spec::Matchers::Matcher.new :be_valid do
10
+ match do |actual|
11
+ actual.valid?
12
+ end
13
+
14
+ failure_message_for_should do |actual|
15
+ if actual.respond_to?(:errors) && ActiveRecord::Errors === actual.errors
16
+ "Expected #{actual.inspect} to be valid, but it was not\nErrors: " + actual.errors.full_messages.join(", ")
17
+ else
18
+ "Expected #{actual.inspect} to be valid"
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,180 @@
1
+ # This is a wrapper of assert_select for rspec.
2
+
3
+ module Spec # :nodoc:
4
+ module Rails
5
+ module Matchers
6
+
7
+ class AssertSelect #:nodoc:
8
+ attr_reader :options
9
+
10
+ def initialize(selector_assertion, spec_scope, *args, &block)
11
+ @args, @options = args_and_options(args)
12
+ @spec_scope = spec_scope
13
+ @selector_assertion = selector_assertion
14
+ @block = block
15
+ end
16
+
17
+ def matches?(response_or_text, &block)
18
+ @block = block if block
19
+
20
+ if doc = doc_from(response_or_text)
21
+ @args.unshift(doc)
22
+ end
23
+
24
+ begin
25
+ @spec_scope.__send__(@selector_assertion, *@args, &@block)
26
+ true
27
+ rescue ::Test::Unit::AssertionFailedError => @error
28
+ false
29
+ end
30
+ end
31
+
32
+ def failure_message_for_should; @error.message; end
33
+ def failure_message_for_should_not; "should not #{description}, but did"; end
34
+
35
+ def description
36
+ {
37
+ :assert_select => "have tag#{format_args(*@args)}",
38
+ :assert_select_email => "send email#{format_args(*@args)}",
39
+ }[@selector_assertion]
40
+ end
41
+
42
+ private
43
+
44
+ module TestResponseOrString
45
+ def test_response?
46
+ ActionController::TestResponse === self and
47
+ !self.headers['Content-Type'].blank? and
48
+ self.headers['Content-Type'].to_sym == :xml
49
+ end
50
+
51
+ def string?
52
+ String === self
53
+ end
54
+ end
55
+
56
+ def doc_from(response_or_text)
57
+ response_or_text.extend TestResponseOrString
58
+ if response_or_text.test_response?
59
+ HTML::Document.new(response_or_text.body, @options[:strict], @options[:xml]).root
60
+ elsif response_or_text.string?
61
+ HTML::Document.new(response_or_text, @options[:strict], @options[:xml]).root
62
+ end
63
+ end
64
+
65
+ def format_args(*args)
66
+ args.empty? ? "" : "(#{arg_list(*args)})"
67
+ end
68
+
69
+ def arg_list(*args)
70
+ args.map do |arg|
71
+ arg.respond_to?(:description) ? arg.description : arg.inspect
72
+ end.join(", ")
73
+ end
74
+
75
+ def args_and_options(args)
76
+ opts = {:xml => false, :strict => false}
77
+ if args.last.is_a?(::Hash)
78
+ opts[:strict] = args.last.delete(:strict) unless args.last[:strict].nil?
79
+ opts[:xml] = args.last.delete(:xml) unless args.last[:xml].nil?
80
+ args.pop if args.last.empty?
81
+ end
82
+ return [args, opts]
83
+ end
84
+
85
+ end
86
+
87
+ # :call-seq:
88
+ # response.should have_tag(*args, &block)
89
+ # string.should have_tag(*args, &block)
90
+ #
91
+ # wrapper for assert_select with additional support for using
92
+ # css selectors to set expectation on Strings. Use this in
93
+ # helper specs, for example, to set expectations on the results
94
+ # of helper methods. Also allow specification of how the
95
+ # response is parsed using the options :xml and :strict options.
96
+ # By default, these options are set to false.
97
+ #
98
+ # == Examples
99
+ #
100
+ # # in a controller spec
101
+ # response.should have_tag("div", "some text")
102
+ #
103
+ # # to force xml and/or strict parsing of the response
104
+ # response.should have_tag("div", "some text", :xml => true)
105
+ # response.should have_tag("div", "some text", :strict => true)
106
+ # response.should have_tag("div", "some text", :xml => true, :strict => false)
107
+ #
108
+ # # in a helper spec (person_address_tag is a method in the helper)
109
+ # person_address_tag.should have_tag("input#person_address")
110
+ #
111
+ # see documentation for assert_select at http://api.rubyonrails.org/
112
+ def have_tag(*args, &block)
113
+ @__current_scope_for_assert_select = AssertSelect.new(:assert_select, self, *args, &block)
114
+ end
115
+
116
+ # wrapper for a nested assert_select
117
+ #
118
+ # response.should have_tag("div#form") do
119
+ # with_tag("input#person_name[name=?]", "person[name]")
120
+ # end
121
+ #
122
+ # see documentation for assert_select at http://api.rubyonrails.org/
123
+ def with_tag(*args, &block)
124
+ args = prepare_args(args, @__current_scope_for_assert_select)
125
+ @__current_scope_for_assert_select.should have_tag(*args, &block)
126
+ end
127
+
128
+ # wrapper for a nested assert_select with false
129
+ #
130
+ # response.should have_tag("div#1") do
131
+ # without_tag("span", "some text that shouldn't be there")
132
+ # end
133
+ #
134
+ # see documentation for assert_select at http://api.rubyonrails.org/
135
+ def without_tag(*args, &block)
136
+ args = prepare_args(args, @__current_scope_for_assert_select)
137
+ @__current_scope_for_assert_select.should_not have_tag(*args, &block)
138
+ end
139
+
140
+ # :call-seq:
141
+ # response.should have_rjs(*args, &block)
142
+ #
143
+ # wrapper for assert_select_rjs
144
+ #
145
+ # see documentation for assert_select_rjs at http://api.rubyonrails.org/
146
+ def have_rjs(*args, &block)
147
+ AssertSelect.new(:assert_select_rjs, self, *args, &block)
148
+ end
149
+
150
+ # :call-seq:
151
+ # response.should send_email(*args, &block)
152
+ #
153
+ # wrapper for assert_select_email
154
+ #
155
+ # see documentation for assert_select_email at http://api.rubyonrails.org/
156
+ def send_email(*args, &block)
157
+ AssertSelect.new(:assert_select_email, self, *args, &block)
158
+ end
159
+
160
+ # wrapper for assert_select_encoded
161
+ #
162
+ # see documentation for assert_select_encoded at http://api.rubyonrails.org/
163
+ def with_encoded(*args, &block)
164
+ should AssertSelect.new(:assert_select_encoded, self, *args, &block)
165
+ end
166
+
167
+ private
168
+
169
+ def prepare_args(args, current_scope = nil)
170
+ return args if current_scope.nil?
171
+ defaults = current_scope.options || {:strict => false, :xml => false}
172
+ args << {} unless args.last.is_a?(::Hash)
173
+ args.last[:strict] = defaults[:strict] if args.last[:strict].nil?
174
+ args.last[:xml] = defaults[:xml] if args.last[:xml].nil?
175
+ args
176
+ end
177
+
178
+ end
179
+ end
180
+ end