shoulda 2.10.3 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +8 -27
- data/lib/shoulda.rb +1 -3
- data/lib/shoulda/action_controller.rb +8 -0
- data/lib/shoulda/action_controller/macros.rb +54 -73
- data/lib/shoulda/action_controller/matchers.rb +2 -0
- data/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +9 -6
- data/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +18 -1
- data/lib/shoulda/action_controller/matchers/redirect_to_matcher.rb +62 -0
- data/lib/shoulda/action_controller/matchers/render_template_matcher.rb +54 -0
- data/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +33 -15
- data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +1 -1
- data/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +5 -1
- data/lib/shoulda/action_controller/matchers/route_matcher.rb +1 -1
- data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +13 -2
- data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +1 -1
- data/lib/shoulda/action_mailer.rb +3 -0
- data/lib/shoulda/action_mailer/assertions.rb +4 -0
- data/lib/shoulda/action_mailer/matchers.rb +22 -0
- data/lib/shoulda/action_mailer/matchers/have_sent_email.rb +119 -0
- data/lib/shoulda/active_record/helpers.rb +6 -1
- data/lib/shoulda/active_record/macros.rb +86 -141
- data/lib/shoulda/active_record/matchers.rb +0 -1
- data/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +1 -1
- data/lib/shoulda/active_record/matchers/allow_value_matcher.rb +10 -2
- data/lib/shoulda/assertions.rb +8 -0
- data/lib/shoulda/context.rb +52 -32
- data/lib/shoulda/macros.rb +16 -18
- data/lib/shoulda/rails.rb +0 -5
- data/lib/shoulda/rspec.rb +2 -0
- data/lib/shoulda/version.rb +4 -0
- data/rails/init.rb +1 -0
- data/test/fail_macros.rb +20 -4
- data/test/functional/posts_controller_test.rb +7 -7
- data/test/functional/users_controller_test.rb +1 -1
- data/test/matchers/action_mailer/have_sent_email_test.rb +53 -0
- data/test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb +7 -1
- data/test/matchers/active_record/allow_value_matcher_test.rb +1 -1
- data/test/matchers/active_record/association_matcher_test.rb +16 -16
- data/test/matchers/active_record/ensure_inclusion_of_matcher_test.rb +3 -2
- data/test/matchers/active_record/ensure_length_of_matcher_test.rb +1 -1
- data/test/matchers/active_record/have_db_column_matcher_test.rb +1 -1
- data/test/matchers/active_record/have_db_index_matcher_test.rb +1 -1
- data/test/matchers/active_record/have_readonly_attributes_matcher_test.rb +1 -1
- data/test/matchers/active_record/validate_acceptance_of_matcher_test.rb +1 -1
- data/test/matchers/active_record/validate_format_of_matcher_test.rb +1 -1
- data/test/matchers/active_record/validate_numericality_of_matcher_test.rb +1 -1
- data/test/matchers/active_record/validate_presence_of_matcher_test.rb +1 -1
- data/test/matchers/active_record/validate_uniqueness_of_matcher_test.rb +1 -1
- data/test/matchers/controller/assign_to_matcher_test.rb +11 -1
- data/test/matchers/controller/filter_param_matcher_test.rb +10 -2
- data/test/matchers/controller/redirect_to_matcher_test.rb +37 -0
- data/test/matchers/controller/render_template_matcher_test.rb +37 -0
- data/test/matchers/controller/render_with_layout_matcher_test.rb +15 -1
- data/test/matchers/controller/respond_with_content_type_matcher_test.rb +1 -1
- data/test/matchers/controller/respond_with_matcher_test.rb +1 -11
- data/test/matchers/controller/route_matcher_test.rb +1 -1
- data/test/matchers/controller/set_session_matcher_test.rb +11 -1
- data/test/matchers/controller/set_the_flash_matcher.rb +1 -1
- data/test/other/autoload_macro_test.rb +1 -1
- data/test/other/context_test.rb +177 -8
- data/test/other/helpers_test.rb +13 -36
- data/test/other/private_helpers_test.rb +1 -1
- data/test/other/should_test.rb +1 -1
- data/test/{model_builder.rb → rails2_model_builder.rb} +28 -4
- data/test/{rails_root → rails2_root}/app/controllers/application_controller.rb +0 -3
- data/test/{rails_root → rails2_root}/app/controllers/posts_controller.rb +0 -0
- data/test/{rails_root → rails2_root}/app/controllers/users_controller.rb +0 -0
- data/test/{rails_root → rails2_root}/app/helpers/application_helper.rb +0 -0
- data/test/{rails_root → rails2_root}/app/helpers/posts_helper.rb +0 -0
- data/test/{rails_root → rails2_root}/app/helpers/users_helper.rb +0 -0
- data/test/{rails_root → rails2_root}/app/models/address.rb +0 -0
- data/test/rails2_root/app/models/flea.rb +11 -0
- data/test/{rails_root → rails2_root}/app/models/friendship.rb +0 -0
- data/test/rails2_root/app/models/notifier.rb +8 -0
- data/test/{rails_root → rails2_root}/app/models/pets/cat.rb +0 -0
- data/test/{rails_root → rails2_root}/app/models/pets/dog.rb +0 -0
- data/test/{rails_root → rails2_root}/app/models/post.rb +0 -0
- data/test/{rails_root → rails2_root}/app/models/product.rb +0 -0
- data/test/{rails_root → rails2_root}/app/models/profile.rb +0 -0
- data/test/{rails_root → rails2_root}/app/models/registration.rb +0 -0
- data/test/{rails_root → rails2_root}/app/models/tag.rb +0 -0
- data/test/{rails_root → rails2_root}/app/models/tagging.rb +0 -0
- data/test/{rails_root → rails2_root}/app/models/treat.rb +0 -0
- data/test/{rails_root → rails2_root}/app/models/user.rb +0 -0
- data/test/{rails_root → rails2_root}/app/views/layouts/posts.rhtml +0 -0
- data/test/{rails_root → rails2_root}/app/views/layouts/users.rhtml +0 -0
- data/test/{rails_root → rails2_root}/app/views/layouts/wide.html.erb +0 -0
- data/test/rails2_root/app/views/notifier/the_email.html.erb +1 -0
- data/test/{rails_root → rails2_root}/app/views/posts/edit.rhtml +0 -0
- data/test/{rails_root → rails2_root}/app/views/posts/index.rhtml +0 -0
- data/test/{rails_root → rails2_root}/app/views/posts/new.rhtml +0 -0
- data/test/{rails_root → rails2_root}/app/views/posts/show.rhtml +0 -0
- data/test/{rails_root → rails2_root}/app/views/users/edit.rhtml +0 -0
- data/test/{rails_root → rails2_root}/app/views/users/index.rhtml +0 -0
- data/test/{rails_root → rails2_root}/app/views/users/new.rhtml +0 -0
- data/test/{rails_root → rails2_root}/app/views/users/show.rhtml +0 -0
- data/test/{rails_root → rails2_root}/config/boot.rb +0 -0
- data/test/{rails_root → rails2_root}/config/database.yml +1 -1
- data/test/{rails_root → rails2_root}/config/environment.rb +0 -1
- data/test/rails2_root/config/environments/test.rb +23 -0
- data/test/{rails_root → rails2_root}/config/initializers/new_rails_defaults.rb +0 -0
- data/test/{rails_root → rails2_root}/config/initializers/shoulda.rb +0 -0
- data/test/{rails_root → rails2_root}/config/routes.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/001_create_users.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/002_create_posts.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/003_create_taggings.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/004_create_tags.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/005_create_dogs.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/006_create_addresses.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/007_create_fleas.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/008_create_dogs_fleas.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/009_create_products.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/010_create_friendships.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/011_create_treats.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/20090506203502_create_profiles.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/20090506203536_create_registrations.rb +0 -0
- data/test/{rails_root → rails2_root}/db/migrate/20090513104502_create_cats.rb +0 -0
- data/test/{rails_root → rails2_root}/db/schema.rb +0 -0
- data/test/rails2_root/log/test.log +121771 -0
- data/test/{rails_root → rails2_root}/public/404.html +0 -0
- data/test/{rails_root → rails2_root}/public/422.html +0 -0
- data/test/{rails_root → rails2_root}/public/500.html +0 -0
- data/test/{rails_root → rails2_root}/script/console +0 -0
- data/test/{rails_root → rails2_root}/script/generate +0 -0
- data/test/{rails_root → rails2_root}/test/shoulda_macros/custom_macro.rb +0 -0
- data/test/{rails_root → rails2_root}/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +0 -0
- data/test/{rails_root → rails2_root}/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +0 -0
- data/test/rails2_test_helper.rb +6 -0
- data/test/rails3_model_builder.rb +118 -0
- data/test/rails3_root/Gemfile +28 -0
- data/test/rails3_root/README +244 -0
- data/test/rails3_root/Rakefile +10 -0
- data/test/rails3_root/app/controllers/application_controller.rb +22 -0
- data/test/rails3_root/app/controllers/posts_controller.rb +87 -0
- data/test/rails3_root/app/controllers/users_controller.rb +82 -0
- data/test/rails3_root/app/helpers/application_helper.rb +2 -0
- data/test/rails3_root/app/models/address.rb +7 -0
- data/test/rails3_root/app/models/flea.rb +11 -0
- data/test/rails3_root/app/models/friendship.rb +4 -0
- data/test/rails3_root/app/models/notifier.rb +8 -0
- data/test/rails3_root/app/models/pets/cat.rb +7 -0
- data/test/rails3_root/app/models/pets/dog.rb +10 -0
- data/test/rails3_root/app/models/post.rb +12 -0
- data/test/rails3_root/app/models/product.rb +12 -0
- data/test/rails3_root/app/models/profile.rb +2 -0
- data/test/rails3_root/app/models/registration.rb +2 -0
- data/test/rails3_root/app/models/tag.rb +8 -0
- data/test/rails3_root/app/models/tagging.rb +4 -0
- data/test/rails3_root/app/models/treat.rb +3 -0
- data/test/rails3_root/app/models/user.rb +32 -0
- data/test/rails3_root/app/views/layouts/application.html.erb +14 -0
- data/test/rails3_root/app/views/layouts/posts.rhtml +19 -0
- data/test/rails3_root/app/views/layouts/users.rhtml +17 -0
- data/test/rails3_root/app/views/layouts/wide.html.erb +1 -0
- data/test/rails3_root/app/views/notifier/the_email.html.erb +1 -0
- data/test/rails3_root/app/views/posts/edit.rhtml +27 -0
- data/test/rails3_root/app/views/posts/index.rhtml +25 -0
- data/test/rails3_root/app/views/posts/new.rhtml +24 -0
- data/test/rails3_root/app/views/posts/show.rhtml +18 -0
- data/test/rails3_root/app/views/users/edit.rhtml +22 -0
- data/test/rails3_root/app/views/users/index.rhtml +22 -0
- data/test/rails3_root/app/views/users/new.rhtml +21 -0
- data/test/rails3_root/app/views/users/show.rhtml +13 -0
- data/test/rails3_root/config.ru +4 -0
- data/test/rails3_root/config/application.rb +46 -0
- data/test/rails3_root/config/boot.rb +6 -0
- data/test/rails3_root/config/database.yml +22 -0
- data/test/rails3_root/config/environment.rb +5 -0
- data/test/rails3_root/config/environments/development.rb +19 -0
- data/test/rails3_root/config/environments/production.rb +42 -0
- data/test/rails3_root/config/environments/test.rb +32 -0
- data/test/rails3_root/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails3_root/config/initializers/inflections.rb +10 -0
- data/test/rails3_root/config/initializers/mime_types.rb +5 -0
- data/test/rails3_root/config/initializers/secret_token.rb +7 -0
- data/test/rails3_root/config/initializers/session_store.rb +8 -0
- data/test/rails3_root/config/locales/en.yml +5 -0
- data/test/rails3_root/config/routes.rb +4 -0
- data/test/rails3_root/db/migrate/001_create_users.rb +19 -0
- data/test/rails3_root/db/migrate/002_create_posts.rb +13 -0
- data/test/rails3_root/db/migrate/003_create_taggings.rb +12 -0
- data/test/rails3_root/db/migrate/004_create_tags.rb +11 -0
- data/test/rails3_root/db/migrate/005_create_dogs.rb +12 -0
- data/test/rails3_root/db/migrate/006_create_addresses.rb +14 -0
- data/test/rails3_root/db/migrate/007_create_fleas.rb +11 -0
- data/test/rails3_root/db/migrate/008_create_dogs_fleas.rb +12 -0
- data/test/rails3_root/db/migrate/009_create_products.rb +17 -0
- data/test/rails3_root/db/migrate/010_create_friendships.rb +14 -0
- data/test/rails3_root/db/migrate/011_create_treats.rb +12 -0
- data/test/rails3_root/db/migrate/20090506203502_create_profiles.rb +12 -0
- data/test/rails3_root/db/migrate/20090506203536_create_registrations.rb +14 -0
- data/test/rails3_root/db/migrate/20090513104502_create_cats.rb +12 -0
- data/test/rails3_root/db/seeds.rb +7 -0
- data/test/rails3_root/db/test.sqlite3 +0 -0
- data/test/rails3_root/doc/README_FOR_APP +2 -0
- data/test/{rails_root/config/environments/test.rb → rails3_root/log/development.log} +0 -0
- data/test/rails3_root/log/production.log +0 -0
- data/test/rails3_root/log/server.log +0 -0
- data/test/rails3_root/log/test.log +63274 -0
- data/test/rails3_root/public/404.html +26 -0
- data/test/rails3_root/public/422.html +26 -0
- data/test/rails3_root/public/500.html +26 -0
- data/test/rails3_root/public/favicon.ico +0 -0
- data/test/rails3_root/public/images/rails.png +0 -0
- data/test/rails3_root/public/index.html +279 -0
- data/test/rails3_root/public/javascripts/application.js +2 -0
- data/test/rails3_root/public/javascripts/controls.js +965 -0
- data/test/rails3_root/public/javascripts/dragdrop.js +974 -0
- data/test/rails3_root/public/javascripts/effects.js +1123 -0
- data/test/rails3_root/public/javascripts/prototype.js +4874 -0
- data/test/rails3_root/public/javascripts/rails.js +118 -0
- data/test/rails3_root/public/robots.txt +5 -0
- data/test/rails3_root/script/rails +9 -0
- data/test/rails3_root/test/performance/browsing_test.rb +9 -0
- data/test/rails3_root/test/test_helper.rb +13 -0
- data/test/rails3_test_helper.rb +6 -0
- data/test/test_helper.rb +16 -8
- data/test/unit/address_test.rb +1 -1
- data/test/unit/cat_test.rb +1 -1
- data/test/unit/dog_test.rb +1 -1
- data/test/unit/flea_test.rb +9 -1
- data/test/unit/friendship_test.rb +1 -1
- data/test/unit/post_test.rb +1 -5
- data/test/unit/product_test.rb +1 -1
- data/test/unit/tag_test.rb +1 -5
- data/test/unit/tagging_test.rb +1 -1
- data/test/unit/user_test.rb +3 -37
- metadata +180 -73
- data/lib/shoulda/action_view.rb +0 -10
- data/lib/shoulda/action_view/macros.rb +0 -61
- data/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +0 -128
- data/test/matchers/active_record/have_named_scope_matcher_test.rb +0 -65
- data/test/rails_root/app/models/flea.rb +0 -3
@@ -13,7 +13,6 @@ require 'shoulda/active_record/matchers/have_db_column_matcher'
|
|
13
13
|
require 'shoulda/active_record/matchers/have_db_index_matcher'
|
14
14
|
require 'shoulda/active_record/matchers/have_readonly_attribute_matcher'
|
15
15
|
require 'shoulda/active_record/matchers/allow_mass_assignment_of_matcher'
|
16
|
-
require 'shoulda/active_record/matchers/have_named_scope_matcher'
|
17
16
|
|
18
17
|
|
19
18
|
module Shoulda # :nodoc:
|
@@ -24,7 +24,7 @@ module Shoulda # :nodoc:
|
|
24
24
|
@failure_message = "#{@attribute} was made accessible"
|
25
25
|
else
|
26
26
|
if protected_attributes.empty?
|
27
|
-
@
|
27
|
+
@negative_failure_message = "no attributes were protected"
|
28
28
|
else
|
29
29
|
@failure_message = "#{class_name} is protecting " <<
|
30
30
|
"#{protected_attributes.to_a.to_sentence}, " <<
|
@@ -59,9 +59,17 @@ module Shoulda # :nodoc:
|
|
59
59
|
|
60
60
|
def errors_match?
|
61
61
|
@instance.valid?
|
62
|
-
@errors = @instance
|
62
|
+
@errors = errors_for_attribute(@instance, @attribute)
|
63
63
|
@errors = [@errors] unless @errors.is_a?(Array)
|
64
|
-
@expected_message ? (errors_match_regexp? || errors_match_string?) : (@errors
|
64
|
+
@expected_message ? (errors_match_regexp? || errors_match_string?) : (@errors.compact.any?)
|
65
|
+
end
|
66
|
+
|
67
|
+
def errors_for_attribute(instance, attribute)
|
68
|
+
if instance.errors.respond_to?(:[])
|
69
|
+
instance.errors[attribute]
|
70
|
+
else
|
71
|
+
instance.errors.on(attribute)
|
72
|
+
end
|
65
73
|
end
|
66
74
|
|
67
75
|
def errors_match_regexp?
|
data/lib/shoulda/assertions.rb
CHANGED
@@ -46,6 +46,10 @@ module Shoulda # :nodoc:
|
|
46
46
|
|
47
47
|
# Asserts that the given matcher returns true when +target+ is passed to #matches?
|
48
48
|
def assert_accepts(matcher, target, options = {})
|
49
|
+
if matcher.respond_to?(:in_context)
|
50
|
+
matcher.in_context(self)
|
51
|
+
end
|
52
|
+
|
49
53
|
if matcher.matches?(target)
|
50
54
|
assert_block { true }
|
51
55
|
if options[:message]
|
@@ -58,6 +62,10 @@ module Shoulda # :nodoc:
|
|
58
62
|
|
59
63
|
# Asserts that the given matcher returns false when +target+ is passed to #matches?
|
60
64
|
def assert_rejects(matcher, target, options = {})
|
65
|
+
if matcher.respond_to?(:in_context)
|
66
|
+
matcher.in_context(self)
|
67
|
+
end
|
68
|
+
|
61
69
|
unless matcher.matches?(target)
|
62
70
|
assert_block { true }
|
63
71
|
if options[:message]
|
data/lib/shoulda/context.rb
CHANGED
@@ -21,9 +21,10 @@ module Shoulda
|
|
21
21
|
module ClassMethods
|
22
22
|
# == Should statements
|
23
23
|
#
|
24
|
-
# Should statements are just syntactic sugar over normal Test::Unit test
|
25
|
-
# contains all the normal code and assertions
|
26
|
-
#
|
24
|
+
# Should statements are just syntactic sugar over normal Test::Unit test
|
25
|
+
# methods. A should block contains all the normal code and assertions
|
26
|
+
# you're used to seeing, with the added benefit that they can be wrapped
|
27
|
+
# inside context blocks (see below).
|
27
28
|
#
|
28
29
|
# === Example:
|
29
30
|
#
|
@@ -56,14 +57,43 @@ module Shoulda
|
|
56
57
|
# assert true
|
57
58
|
# end
|
58
59
|
# end
|
60
|
+
#
|
61
|
+
# Should statements can also wrap matchers, making virtually any matcher
|
62
|
+
# usable in a macro style. The matcher's description is used to generate a
|
63
|
+
# test name and failure message, and the test will pass if the matcher
|
64
|
+
# matches the subject.
|
65
|
+
#
|
66
|
+
# === Example:
|
67
|
+
#
|
68
|
+
# should validate_presence_of(:first_name).with_message(/gotta be there/)
|
69
|
+
#
|
70
|
+
|
71
|
+
def should(name_or_matcher, options = {}, &blk)
|
72
|
+
if Shoulda.current_context
|
73
|
+
Shoulda.current_context.should(name_or_matcher, options, &blk)
|
74
|
+
else
|
75
|
+
context_name = self.name.gsub(/Test/, "")
|
76
|
+
context = Shoulda::Context.new(context_name, self) do
|
77
|
+
should(name_or_matcher, options, &blk)
|
78
|
+
end
|
79
|
+
context.build
|
80
|
+
end
|
81
|
+
end
|
59
82
|
|
60
|
-
|
83
|
+
# Allows negative tests using matchers. The matcher's description is used
|
84
|
+
# to generate a test name and negative failure message, and the test will
|
85
|
+
# pass unless the matcher matches the subject.
|
86
|
+
#
|
87
|
+
# === Example:
|
88
|
+
#
|
89
|
+
# should_not set_the_flash
|
90
|
+
def should_not(matcher)
|
61
91
|
if Shoulda.current_context
|
62
|
-
|
92
|
+
Shoulda.current_context.should_not(matcher)
|
63
93
|
else
|
64
94
|
context_name = self.name.gsub(/Test/, "")
|
65
95
|
context = Shoulda::Context.new(context_name, self) do
|
66
|
-
|
96
|
+
should_not(matcher)
|
67
97
|
end
|
68
98
|
context.build
|
69
99
|
end
|
@@ -214,19 +244,6 @@ module Shoulda
|
|
214
244
|
# end
|
215
245
|
# end
|
216
246
|
#
|
217
|
-
# If an instance variable exists named after the described class, that
|
218
|
-
# instance variable will be used as the subject. This behavior is
|
219
|
-
# deprecated, and will be removed in a future version of Shoulda. The
|
220
|
-
# recommended approach for using a different subject is to use the subject
|
221
|
-
# class method.
|
222
|
-
#
|
223
|
-
# class UserTest
|
224
|
-
# should "be the existing user" do
|
225
|
-
# @user = User.new
|
226
|
-
# assert_equal @user, subject # passes
|
227
|
-
# end
|
228
|
-
# end
|
229
|
-
#
|
230
247
|
# The subject is used by all macros that require an instance of the class
|
231
248
|
# being tested.
|
232
249
|
def subject
|
@@ -239,17 +256,7 @@ module Shoulda
|
|
239
256
|
|
240
257
|
def get_instance_of(object_or_klass) # :nodoc:
|
241
258
|
if object_or_klass.is_a?(Class)
|
242
|
-
|
243
|
-
ivar = "@#{instance_variable_name_for(klass)}"
|
244
|
-
if instance = instance_variable_get(ivar)
|
245
|
-
warn "[WARNING] Using #{ivar} as the subject. Future versions " <<
|
246
|
-
"of Shoulda will require an explicit subject using the " <<
|
247
|
-
"subject class method. Add this after your setup to avoid " <<
|
248
|
-
"this warning: subject { #{ivar} }"
|
249
|
-
instance
|
250
|
-
else
|
251
|
-
klass.new
|
252
|
-
end
|
259
|
+
object_or_klass.new
|
253
260
|
else
|
254
261
|
object_or_klass
|
255
262
|
end
|
@@ -311,14 +318,27 @@ module Shoulda
|
|
311
318
|
self.teardown_blocks << blk
|
312
319
|
end
|
313
320
|
|
314
|
-
def should(
|
315
|
-
if
|
321
|
+
def should(name_or_matcher, options = {}, &blk)
|
322
|
+
if name_or_matcher.respond_to?(:description) && name_or_matcher.respond_to?(:matches?)
|
323
|
+
name = name_or_matcher.description
|
324
|
+
blk = lambda { assert_accepts name_or_matcher, subject }
|
325
|
+
else
|
326
|
+
name = name_or_matcher
|
327
|
+
end
|
328
|
+
|
329
|
+
if blk
|
316
330
|
self.shoulds << { :name => name, :before => options[:before], :block => blk }
|
317
331
|
else
|
318
332
|
self.should_eventuallys << { :name => name }
|
319
333
|
end
|
320
334
|
end
|
321
335
|
|
336
|
+
def should_not(matcher)
|
337
|
+
name = matcher.description
|
338
|
+
blk = lambda { assert_rejects matcher, subject }
|
339
|
+
self.shoulds << { :name => "not #{name}", :block => blk }
|
340
|
+
end
|
341
|
+
|
322
342
|
def should_eventually(name, &blk)
|
323
343
|
self.should_eventuallys << { :name => name, :block => blk }
|
324
344
|
end
|
data/lib/shoulda/macros.rb
CHANGED
@@ -2,6 +2,8 @@ require 'shoulda/private_helpers'
|
|
2
2
|
|
3
3
|
module Shoulda # :nodoc:
|
4
4
|
module Macros
|
5
|
+
# Deprecated.
|
6
|
+
#
|
5
7
|
# Macro that creates a test asserting a change between the return value
|
6
8
|
# of a block that is run before and after the current setup block
|
7
9
|
# is run. This is similar to Active Support's <tt>assert_difference</tt>
|
@@ -35,23 +37,17 @@ module Shoulda # :nodoc:
|
|
35
37
|
# # Assert the value changed to "new:"
|
36
38
|
# should_change("the post title", :to => "new") { @post.title }
|
37
39
|
def should_change(description, options = {}, &block)
|
40
|
+
::ActiveSupport::Deprecation.warn
|
38
41
|
by, from, to = get_options!([options], :by, :from, :to)
|
39
42
|
stmt = "change #{description}"
|
40
43
|
stmt << " from #{from.inspect}" if from
|
41
44
|
stmt << " to #{to.inspect}" if to
|
42
45
|
stmt << " by #{by.inspect}" if by
|
43
46
|
|
44
|
-
|
45
|
-
code = block
|
46
|
-
else
|
47
|
-
warn "[DEPRECATION] should_change(expression, options) is deprecated. " <<
|
48
|
-
"Use should_change(description, options) { code } instead."
|
49
|
-
code = lambda { eval(description) }
|
50
|
-
end
|
51
|
-
before = lambda { @_before_should_change = code.bind(self).call }
|
47
|
+
before = lambda { @_before_should_change = block.bind(self).call }
|
52
48
|
should stmt, :before => before do
|
53
49
|
old_value = @_before_should_change
|
54
|
-
new_value =
|
50
|
+
new_value = block.bind(self).call
|
55
51
|
assert_operator from, :===, old_value, "#{description} did not originally match #{from.inspect}" if from
|
56
52
|
assert_not_equal old_value, new_value, "#{description} did not change" unless by == 0
|
57
53
|
assert_operator to, :===, new_value, "#{description} was not changed to match #{to.inspect}" if to
|
@@ -59,6 +55,8 @@ module Shoulda # :nodoc:
|
|
59
55
|
end
|
60
56
|
end
|
61
57
|
|
58
|
+
# Deprecated.
|
59
|
+
#
|
62
60
|
# Macro that creates a test asserting no change between the return value
|
63
61
|
# of a block that is run before and after the current setup block
|
64
62
|
# is run. This is the logical opposite of should_change.
|
@@ -72,20 +70,16 @@ module Shoulda # :nodoc:
|
|
72
70
|
# should_not_change("the number of posts") { Post.count }
|
73
71
|
# end
|
74
72
|
def should_not_change(description, &block)
|
75
|
-
|
76
|
-
|
77
|
-
else
|
78
|
-
warn "[DEPRECATION] should_not_change(expression) is deprecated. " <<
|
79
|
-
"Use should_not_change(description) { code } instead."
|
80
|
-
code = lambda { eval(description) }
|
81
|
-
end
|
82
|
-
before = lambda { @_before_should_not_change = code.bind(self).call }
|
73
|
+
::ActiveSupport::Deprecation.warn
|
74
|
+
before = lambda { @_before_should_not_change = block.bind(self).call }
|
83
75
|
should "not change #{description}", :before => before do
|
84
|
-
new_value =
|
76
|
+
new_value = block.bind(self).call
|
85
77
|
assert_equal @_before_should_not_change, new_value, "#{description} changed"
|
86
78
|
end
|
87
79
|
end
|
88
80
|
|
81
|
+
# Deprecated.
|
82
|
+
#
|
89
83
|
# Macro that creates a test asserting that a record of the given class was
|
90
84
|
# created.
|
91
85
|
#
|
@@ -96,9 +90,12 @@ module Shoulda # :nodoc:
|
|
96
90
|
# should_create :post
|
97
91
|
# end
|
98
92
|
def should_create(class_name)
|
93
|
+
::ActiveSupport::Deprecation.warn
|
99
94
|
should_change_record_count_of(class_name, 1, 'create')
|
100
95
|
end
|
101
96
|
|
97
|
+
# Deprecated.
|
98
|
+
#
|
102
99
|
# Macro that creates a test asserting that a record of the given class was
|
103
100
|
# destroyed.
|
104
101
|
#
|
@@ -109,6 +106,7 @@ module Shoulda # :nodoc:
|
|
109
106
|
# should_destroy :post
|
110
107
|
# end
|
111
108
|
def should_destroy(class_name)
|
109
|
+
::ActiveSupport::Deprecation.warn
|
112
110
|
should_change_record_count_of(class_name, -1, 'destroy')
|
113
111
|
end
|
114
112
|
|
data/lib/shoulda/rails.rb
CHANGED
@@ -4,10 +4,5 @@ require 'shoulda'
|
|
4
4
|
|
5
5
|
require 'shoulda/active_record' if defined? ActiveRecord::Base
|
6
6
|
require 'shoulda/action_controller' if defined? ActionController::Base
|
7
|
-
require 'shoulda/action_view' if defined? ActionView::Base
|
8
7
|
require 'shoulda/action_mailer' if defined? ActionMailer::Base
|
9
8
|
|
10
|
-
if defined?(RAILS_ROOT)
|
11
|
-
# load in the 3rd party macros from vendorized plugins and gems
|
12
|
-
Shoulda.autoload_macros RAILS_ROOT, File.join("vendor", "{plugins,gems}", "*")
|
13
|
-
end
|
data/lib/shoulda/rspec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'shoulda/active_record/matchers'
|
2
2
|
require 'shoulda/action_controller/matchers'
|
3
|
+
require 'shoulda/action_mailer/matchers'
|
3
4
|
require 'active_support/test_case'
|
4
5
|
|
5
6
|
# :enddoc:
|
@@ -7,5 +8,6 @@ module ActiveSupport
|
|
7
8
|
class TestCase
|
8
9
|
include Shoulda::ActiveRecord::Matchers
|
9
10
|
include Shoulda::ActionController::Matchers
|
11
|
+
include Shoulda::ActionMailer::Matchers
|
10
12
|
end
|
11
13
|
end
|
data/rails/init.rb
CHANGED
data/test/fail_macros.rb
CHANGED
@@ -27,13 +27,29 @@ module Shoulda
|
|
27
27
|
|
28
28
|
class Context
|
29
29
|
# alias_method_chain hack to allow the should_fail macro to work
|
30
|
-
def should_with_failure_scenario(
|
30
|
+
def should_with_failure_scenario(*args, &block)
|
31
|
+
should_without_failure_scenario(*args, &block)
|
32
|
+
wrap_last_should_with_failure_expectation
|
33
|
+
end
|
34
|
+
alias_method_chain :should, :failure_scenario
|
35
|
+
|
36
|
+
# alias_method_chain hack to allow the should_fail macro to work
|
37
|
+
def should_not_with_failure_scenario(*args, &block)
|
38
|
+
should_not_without_failure_scenario(*args, &block)
|
39
|
+
wrap_last_should_with_failure_expectation
|
40
|
+
end
|
41
|
+
alias_method_chain :should_not, :failure_scenario
|
42
|
+
|
43
|
+
def wrap_last_should_with_failure_expectation
|
31
44
|
if Shoulda.expected_exceptions
|
32
45
|
expected_exceptions = Shoulda.expected_exceptions
|
33
|
-
|
46
|
+
should = self.shoulds.last
|
47
|
+
assertion_block = should[:block]
|
48
|
+
failure_block = lambda do
|
49
|
+
assert_raise(*expected_exceptions, &assertion_block.bind(self))
|
50
|
+
end
|
51
|
+
should[:block] = failure_block
|
34
52
|
end
|
35
|
-
should_without_failure_scenario(name, options, &(failure_block || block))
|
36
53
|
end
|
37
|
-
alias_method_chain :should, :failure_scenario
|
38
54
|
end
|
39
55
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'test_helper'
|
2
2
|
require 'posts_controller'
|
3
3
|
|
4
4
|
# Re-raise errors caught by the controller.
|
@@ -54,8 +54,6 @@ class PostsControllerTest < ActionController::TestCase
|
|
54
54
|
end
|
55
55
|
should_assign_to :posts
|
56
56
|
should_not_assign_to :foo, :bar
|
57
|
-
should_render_page_with_metadata :description => /Posts/, :title => /index/
|
58
|
-
should_render_page_with_metadata :keywords => "posts"
|
59
57
|
end
|
60
58
|
|
61
59
|
context "viewing posts for a user with rss format" do
|
@@ -65,8 +63,12 @@ class PostsControllerTest < ActionController::TestCase
|
|
65
63
|
end
|
66
64
|
should_respond_with :success
|
67
65
|
should_respond_with_content_type 'application/rss+xml'
|
68
|
-
|
69
|
-
|
66
|
+
context "with a symbol" do
|
67
|
+
should_respond_with_content_type :rss
|
68
|
+
end
|
69
|
+
context "with a regexp" do
|
70
|
+
should_respond_with_content_type /rss/
|
71
|
+
end
|
70
72
|
should_set_session(:mischief) { nil }
|
71
73
|
should_set_session(:special) { '$2 off your next purchase' }
|
72
74
|
should_set_session(:special_user_id) { @user.id }
|
@@ -85,7 +87,6 @@ class PostsControllerTest < ActionController::TestCase
|
|
85
87
|
should_render_with_layout :wide
|
86
88
|
end
|
87
89
|
should_assign_to :false_flag
|
88
|
-
should_set_the_flash_to nil
|
89
90
|
should_fail do
|
90
91
|
should_set_the_flash_to /.*/
|
91
92
|
end
|
@@ -95,7 +96,6 @@ class PostsControllerTest < ActionController::TestCase
|
|
95
96
|
setup { get :new, :user_id => users(:first) }
|
96
97
|
should_render_without_layout
|
97
98
|
should_not_set_the_flash
|
98
|
-
should_render_a_form
|
99
99
|
end
|
100
100
|
|
101
101
|
context "on POST to #create" do
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class HaveSentEmailTest < ActiveSupport::TestCase # :nodoc:
|
4
|
+
context "an email" do
|
5
|
+
setup do
|
6
|
+
define_mailer :mailer, [:the_email] do
|
7
|
+
def the_email
|
8
|
+
if defined?(AbstractController::Rendering)
|
9
|
+
mail :from => "do-not-reply@example.com",
|
10
|
+
:to => "myself@me.com",
|
11
|
+
:subject => "This is spam",
|
12
|
+
:body => "Every email is spam."
|
13
|
+
else
|
14
|
+
from "do-not-reply@example.com"
|
15
|
+
recipients "myself@me.com"
|
16
|
+
subject "This is spam"
|
17
|
+
body "Every email is spam."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
if defined?(AbstractController::Rendering)
|
22
|
+
::ActionMailer::Base.deliveries << Mailer.the_email
|
23
|
+
else
|
24
|
+
::ActionMailer::Base.deliveries << Mailer.create_the_email
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
should "accept based on the subject" do
|
29
|
+
assert_accepts have_sent_email.with_subject(/is spam$/), nil
|
30
|
+
assert_rejects have_sent_email.with_subject(/totally safe/), nil
|
31
|
+
end
|
32
|
+
|
33
|
+
should "accept based on the sender" do
|
34
|
+
assert_accepts have_sent_email.from('do-not-reply@example.com'), nil
|
35
|
+
assert_rejects have_sent_email.from('you@example.com'), nil
|
36
|
+
end
|
37
|
+
|
38
|
+
should "accept based on the body" do
|
39
|
+
assert_accepts have_sent_email.with_body(/is spam\./), nil
|
40
|
+
assert_rejects have_sent_email.with_body(/totally safe/), nil
|
41
|
+
end
|
42
|
+
|
43
|
+
should "accept baed on the recipienct" do
|
44
|
+
assert_accepts have_sent_email.to('myself@me.com'), nil
|
45
|
+
assert_rejects have_sent_email.to('you@example.com'), nil
|
46
|
+
end
|
47
|
+
|
48
|
+
should "chain" do
|
49
|
+
assert_accepts have_sent_email.with_subject(/spam/).from('do-not-reply@example.com').with_body(/spam/).to('myself@me.com'), nil
|
50
|
+
assert_rejects have_sent_email.with_subject(/ham/).from('you@example.com').with_body(/ham/).to('them@example.com'), nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|