shoulda 2.10.3 → 2.11.0
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.
- 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
|