thoughtbot-shoulda 2.10.2 → 2.11.1

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 (241) hide show
  1. data/CONTRIBUTION_GUIDELINES.rdoc +5 -5
  2. data/README.rdoc +72 -89
  3. data/Rakefile +31 -33
  4. data/lib/shoulda.rb +6 -6
  5. data/lib/shoulda/action_controller.rb +8 -0
  6. data/lib/shoulda/action_controller/macros.rb +54 -73
  7. data/lib/shoulda/action_controller/matchers.rb +7 -5
  8. data/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +10 -7
  9. data/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +18 -1
  10. data/lib/shoulda/action_controller/matchers/redirect_to_matcher.rb +62 -0
  11. data/lib/shoulda/action_controller/matchers/render_template_matcher.rb +54 -0
  12. data/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +33 -15
  13. data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +10 -10
  14. data/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +17 -13
  15. data/lib/shoulda/action_controller/matchers/route_matcher.rb +3 -3
  16. data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +13 -2
  17. data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +1 -1
  18. data/lib/shoulda/action_mailer.rb +3 -0
  19. data/lib/shoulda/action_mailer/assertions.rb +4 -0
  20. data/lib/shoulda/action_mailer/matchers.rb +22 -0
  21. data/lib/shoulda/action_mailer/matchers/have_sent_email.rb +110 -0
  22. data/lib/shoulda/active_record/helpers.rb +8 -3
  23. data/lib/shoulda/active_record/macros.rb +88 -143
  24. data/lib/shoulda/active_record/matchers.rb +0 -1
  25. data/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +1 -1
  26. data/lib/shoulda/active_record/matchers/allow_value_matcher.rb +10 -2
  27. data/lib/shoulda/active_record/matchers/association_matcher.rb +8 -8
  28. data/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +1 -1
  29. data/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +2 -2
  30. data/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +11 -11
  31. data/lib/shoulda/active_record/matchers/have_db_index_matcher.rb +8 -8
  32. data/lib/shoulda/active_record/matchers/validate_format_of_matcher.rb +2 -4
  33. data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +3 -3
  34. data/lib/shoulda/active_record/matchers/validation_matcher.rb +0 -1
  35. data/lib/shoulda/assertions.rb +10 -2
  36. data/lib/shoulda/autoload_macros.rb +20 -20
  37. data/lib/shoulda/context.rb +70 -39
  38. data/lib/shoulda/{rspec.rb → integrations/rspec.rb} +2 -0
  39. data/lib/shoulda/integrations/rspec2.rb +22 -0
  40. data/lib/shoulda/{test_unit.rb → integrations/test_unit.rb} +0 -0
  41. data/lib/shoulda/macros.rb +46 -18
  42. data/lib/shoulda/rails.rb +0 -5
  43. data/lib/shoulda/tasks/yaml_to_shoulda.rake +11 -11
  44. data/lib/shoulda/version.rb +4 -0
  45. data/rails/init.rb +3 -2
  46. data/test/fail_macros.rb +20 -4
  47. data/test/functional/posts_controller_test.rb +7 -7
  48. data/test/functional/users_controller_test.rb +1 -1
  49. data/test/matchers/action_mailer/have_sent_email_test.rb +70 -0
  50. data/test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb +7 -1
  51. data/test/matchers/active_record/allow_value_matcher_test.rb +1 -1
  52. data/test/matchers/active_record/association_matcher_test.rb +16 -16
  53. data/test/matchers/active_record/ensure_inclusion_of_matcher_test.rb +3 -2
  54. data/test/matchers/active_record/ensure_length_of_matcher_test.rb +1 -1
  55. data/test/matchers/active_record/have_db_column_matcher_test.rb +1 -1
  56. data/test/matchers/active_record/have_db_index_matcher_test.rb +1 -1
  57. data/test/matchers/active_record/have_readonly_attributes_matcher_test.rb +1 -1
  58. data/test/matchers/active_record/validate_acceptance_of_matcher_test.rb +1 -1
  59. data/test/matchers/active_record/validate_format_of_matcher_test.rb +1 -1
  60. data/test/matchers/active_record/validate_numericality_of_matcher_test.rb +1 -1
  61. data/test/matchers/active_record/validate_presence_of_matcher_test.rb +1 -1
  62. data/test/matchers/active_record/validate_uniqueness_of_matcher_test.rb +1 -1
  63. data/test/matchers/controller/assign_to_matcher_test.rb +11 -1
  64. data/test/matchers/controller/filter_param_matcher_test.rb +10 -2
  65. data/test/matchers/controller/redirect_to_matcher_test.rb +37 -0
  66. data/test/matchers/controller/render_template_matcher_test.rb +37 -0
  67. data/test/matchers/controller/render_with_layout_matcher_test.rb +15 -1
  68. data/test/matchers/controller/respond_with_content_type_matcher_test.rb +1 -1
  69. data/test/matchers/controller/respond_with_matcher_test.rb +1 -11
  70. data/test/matchers/controller/route_matcher_test.rb +18 -1
  71. data/test/matchers/controller/set_session_matcher_test.rb +11 -1
  72. data/test/matchers/controller/set_the_flash_matcher.rb +1 -1
  73. data/test/other/autoload_macro_test.rb +1 -1
  74. data/test/other/context_test.rb +210 -27
  75. data/test/other/convert_to_should_syntax_test.rb +1 -1
  76. data/test/other/helpers_test.rb +13 -36
  77. data/test/other/private_helpers_test.rb +2 -2
  78. data/test/other/should_test.rb +13 -13
  79. data/test/{model_builder.rb → rails2_model_builder.rb} +32 -8
  80. data/test/{rails_root → rails2_root}/app/controllers/application_controller.rb +0 -3
  81. data/test/{rails_root → rails2_root}/app/controllers/posts_controller.rb +0 -0
  82. data/test/{rails_root → rails2_root}/app/controllers/users_controller.rb +0 -0
  83. data/test/{rails_root → rails2_root}/app/helpers/application_helper.rb +0 -0
  84. data/test/{rails_root → rails2_root}/app/helpers/posts_helper.rb +0 -0
  85. data/test/{rails_root → rails2_root}/app/helpers/users_helper.rb +0 -0
  86. data/test/{rails_root → rails2_root}/app/models/address.rb +0 -0
  87. data/test/rails2_root/app/models/flea.rb +11 -0
  88. data/test/{rails_root → rails2_root}/app/models/friendship.rb +0 -0
  89. data/test/rails2_root/app/models/notifier.rb +8 -0
  90. data/test/{rails_root → rails2_root}/app/models/pets/cat.rb +0 -0
  91. data/test/{rails_root → rails2_root}/app/models/pets/dog.rb +0 -0
  92. data/test/{rails_root → rails2_root}/app/models/post.rb +1 -1
  93. data/test/{rails_root → rails2_root}/app/models/product.rb +0 -0
  94. data/test/{rails_root → rails2_root}/app/models/profile.rb +0 -0
  95. data/test/{rails_root → rails2_root}/app/models/registration.rb +0 -0
  96. data/test/{rails_root → rails2_root}/app/models/tag.rb +0 -0
  97. data/test/{rails_root → rails2_root}/app/models/tagging.rb +0 -0
  98. data/test/{rails_root → rails2_root}/app/models/treat.rb +0 -0
  99. data/test/{rails_root → rails2_root}/app/models/user.rb +0 -0
  100. data/test/{rails_root → rails2_root}/app/views/layouts/posts.rhtml +0 -0
  101. data/test/{rails_root → rails2_root}/app/views/layouts/users.rhtml +0 -0
  102. data/test/{rails_root → rails2_root}/app/views/layouts/wide.html.erb +0 -0
  103. data/test/rails2_root/app/views/notifier/the_email.html.erb +1 -0
  104. data/test/{rails_root → rails2_root}/app/views/posts/edit.rhtml +0 -0
  105. data/test/{rails_root → rails2_root}/app/views/posts/index.rhtml +0 -0
  106. data/test/{rails_root → rails2_root}/app/views/posts/new.rhtml +0 -0
  107. data/test/{rails_root → rails2_root}/app/views/posts/show.rhtml +0 -0
  108. data/test/{rails_root → rails2_root}/app/views/users/edit.rhtml +0 -0
  109. data/test/{rails_root → rails2_root}/app/views/users/index.rhtml +0 -0
  110. data/test/{rails_root → rails2_root}/app/views/users/new.rhtml +0 -0
  111. data/test/{rails_root → rails2_root}/app/views/users/show.rhtml +0 -0
  112. data/test/{rails_root → rails2_root}/config/boot.rb +0 -0
  113. data/test/{rails_root → rails2_root}/config/database.yml +1 -1
  114. data/test/{rails_root → rails2_root}/config/environment.rb +0 -1
  115. data/test/rails2_root/config/environments/test.rb +23 -0
  116. data/test/{rails_root → rails2_root}/config/initializers/new_rails_defaults.rb +0 -0
  117. data/test/{rails_root → rails2_root}/config/initializers/shoulda.rb +0 -0
  118. data/test/{rails_root → rails2_root}/config/routes.rb +0 -0
  119. data/test/{rails_root → rails2_root}/db/migrate/001_create_users.rb +0 -0
  120. data/test/{rails_root → rails2_root}/db/migrate/002_create_posts.rb +0 -0
  121. data/test/{rails_root → rails2_root}/db/migrate/003_create_taggings.rb +0 -0
  122. data/test/{rails_root → rails2_root}/db/migrate/004_create_tags.rb +0 -0
  123. data/test/{rails_root → rails2_root}/db/migrate/005_create_dogs.rb +0 -0
  124. data/test/{rails_root → rails2_root}/db/migrate/006_create_addresses.rb +0 -0
  125. data/test/{rails_root → rails2_root}/db/migrate/007_create_fleas.rb +0 -0
  126. data/test/{rails_root → rails2_root}/db/migrate/008_create_dogs_fleas.rb +0 -0
  127. data/test/{rails_root → rails2_root}/db/migrate/009_create_products.rb +0 -0
  128. data/test/{rails_root → rails2_root}/db/migrate/010_create_friendships.rb +0 -0
  129. data/test/{rails_root → rails2_root}/db/migrate/011_create_treats.rb +0 -0
  130. data/test/{rails_root → rails2_root}/db/migrate/20090506203502_create_profiles.rb +0 -0
  131. data/test/{rails_root → rails2_root}/db/migrate/20090506203536_create_registrations.rb +0 -0
  132. data/test/{rails_root → rails2_root}/db/migrate/20090513104502_create_cats.rb +0 -0
  133. data/test/{rails_root → rails2_root}/db/schema.rb +0 -0
  134. data/test/{rails_root → rails2_root}/public/404.html +0 -0
  135. data/test/{rails_root → rails2_root}/public/422.html +0 -0
  136. data/test/{rails_root → rails2_root}/public/500.html +0 -0
  137. data/test/{rails_root → rails2_root}/script/console +0 -0
  138. data/test/{rails_root → rails2_root}/script/generate +0 -0
  139. data/test/{rails_root → rails2_root}/test/shoulda_macros/custom_macro.rb +0 -0
  140. data/test/{rails_root → rails2_root}/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +0 -0
  141. data/test/{rails_root → rails2_root}/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +0 -0
  142. data/test/rails2_test_helper.rb +6 -0
  143. data/test/rails3_model_builder.rb +118 -0
  144. data/test/rails3_root/Gemfile +28 -0
  145. data/test/rails3_root/README +244 -0
  146. data/test/rails3_root/Rakefile +10 -0
  147. data/test/rails3_root/app/controllers/application_controller.rb +22 -0
  148. data/test/rails3_root/app/controllers/posts_controller.rb +87 -0
  149. data/test/rails3_root/app/controllers/users_controller.rb +82 -0
  150. data/test/rails3_root/app/helpers/application_helper.rb +2 -0
  151. data/test/rails3_root/app/models/address.rb +7 -0
  152. data/test/rails3_root/app/models/flea.rb +11 -0
  153. data/test/rails3_root/app/models/friendship.rb +4 -0
  154. data/test/rails3_root/app/models/notifier.rb +8 -0
  155. data/test/rails3_root/app/models/pets/cat.rb +7 -0
  156. data/test/rails3_root/app/models/pets/dog.rb +10 -0
  157. data/test/rails3_root/app/models/post.rb +12 -0
  158. data/test/rails3_root/app/models/product.rb +12 -0
  159. data/test/rails3_root/app/models/profile.rb +2 -0
  160. data/test/rails3_root/app/models/registration.rb +2 -0
  161. data/test/rails3_root/app/models/tag.rb +8 -0
  162. data/test/rails3_root/app/models/tagging.rb +4 -0
  163. data/test/rails3_root/app/models/treat.rb +3 -0
  164. data/test/rails3_root/app/models/user.rb +32 -0
  165. data/test/rails3_root/app/views/layouts/application.html.erb +14 -0
  166. data/test/rails3_root/app/views/layouts/posts.rhtml +19 -0
  167. data/test/rails3_root/app/views/layouts/users.rhtml +17 -0
  168. data/test/rails3_root/app/views/layouts/wide.html.erb +1 -0
  169. data/test/rails3_root/app/views/notifier/the_email.html.erb +1 -0
  170. data/test/rails3_root/app/views/posts/edit.rhtml +27 -0
  171. data/test/rails3_root/app/views/posts/index.rhtml +25 -0
  172. data/test/rails3_root/app/views/posts/new.rhtml +24 -0
  173. data/test/rails3_root/app/views/posts/show.rhtml +18 -0
  174. data/test/rails3_root/app/views/users/edit.rhtml +22 -0
  175. data/test/rails3_root/app/views/users/index.rhtml +22 -0
  176. data/test/rails3_root/app/views/users/new.rhtml +21 -0
  177. data/test/rails3_root/app/views/users/show.rhtml +13 -0
  178. data/test/rails3_root/config.ru +4 -0
  179. data/test/rails3_root/config/application.rb +46 -0
  180. data/test/rails3_root/config/boot.rb +6 -0
  181. data/test/rails3_root/config/database.yml +22 -0
  182. data/test/rails3_root/config/environment.rb +5 -0
  183. data/test/rails3_root/config/environments/development.rb +19 -0
  184. data/test/rails3_root/config/environments/production.rb +42 -0
  185. data/test/rails3_root/config/environments/test.rb +32 -0
  186. data/test/rails3_root/config/initializers/backtrace_silencers.rb +7 -0
  187. data/test/rails3_root/config/initializers/inflections.rb +10 -0
  188. data/test/rails3_root/config/initializers/mime_types.rb +5 -0
  189. data/test/rails3_root/config/initializers/secret_token.rb +7 -0
  190. data/test/rails3_root/config/initializers/session_store.rb +8 -0
  191. data/test/rails3_root/config/locales/en.yml +5 -0
  192. data/test/rails3_root/config/routes.rb +4 -0
  193. data/test/rails3_root/db/migrate/001_create_users.rb +19 -0
  194. data/test/rails3_root/db/migrate/002_create_posts.rb +13 -0
  195. data/test/rails3_root/db/migrate/003_create_taggings.rb +12 -0
  196. data/test/rails3_root/db/migrate/004_create_tags.rb +11 -0
  197. data/test/rails3_root/db/migrate/005_create_dogs.rb +12 -0
  198. data/test/rails3_root/db/migrate/006_create_addresses.rb +14 -0
  199. data/test/rails3_root/db/migrate/007_create_fleas.rb +11 -0
  200. data/test/rails3_root/db/migrate/008_create_dogs_fleas.rb +12 -0
  201. data/test/rails3_root/db/migrate/009_create_products.rb +17 -0
  202. data/test/rails3_root/db/migrate/010_create_friendships.rb +14 -0
  203. data/test/rails3_root/db/migrate/011_create_treats.rb +12 -0
  204. data/test/rails3_root/db/migrate/20090506203502_create_profiles.rb +12 -0
  205. data/test/rails3_root/db/migrate/20090506203536_create_registrations.rb +14 -0
  206. data/test/rails3_root/db/migrate/20090513104502_create_cats.rb +12 -0
  207. data/test/rails3_root/db/seeds.rb +7 -0
  208. data/test/rails3_root/public/404.html +26 -0
  209. data/test/rails3_root/public/422.html +26 -0
  210. data/test/rails3_root/public/500.html +26 -0
  211. data/test/{rails_root/config/environments/test.rb → rails3_root/public/favicon.ico} +0 -0
  212. data/test/rails3_root/public/images/rails.png +0 -0
  213. data/test/rails3_root/public/index.html +279 -0
  214. data/test/rails3_root/public/javascripts/application.js +2 -0
  215. data/test/rails3_root/public/javascripts/controls.js +965 -0
  216. data/test/rails3_root/public/javascripts/dragdrop.js +974 -0
  217. data/test/rails3_root/public/javascripts/effects.js +1123 -0
  218. data/test/rails3_root/public/javascripts/prototype.js +4874 -0
  219. data/test/rails3_root/public/javascripts/rails.js +118 -0
  220. data/test/rails3_root/public/robots.txt +5 -0
  221. data/test/rails3_root/script/rails +9 -0
  222. data/test/rails3_root/test/performance/browsing_test.rb +9 -0
  223. data/test/rails3_root/test/test_helper.rb +13 -0
  224. data/test/rails3_test_helper.rb +6 -0
  225. data/test/test_helper.rb +16 -8
  226. data/test/unit/address_test.rb +1 -1
  227. data/test/unit/cat_test.rb +1 -1
  228. data/test/unit/dog_test.rb +1 -1
  229. data/test/unit/flea_test.rb +9 -1
  230. data/test/unit/friendship_test.rb +1 -1
  231. data/test/unit/post_test.rb +1 -5
  232. data/test/unit/product_test.rb +1 -1
  233. data/test/unit/tag_test.rb +1 -5
  234. data/test/unit/tagging_test.rb +1 -1
  235. data/test/unit/user_test.rb +3 -37
  236. metadata +184 -118
  237. data/lib/shoulda/action_view.rb +0 -10
  238. data/lib/shoulda/action_view/macros.rb +0 -61
  239. data/lib/shoulda/active_record/matchers/have_named_scope_matcher.rb +0 -128
  240. data/test/matchers/active_record/have_named_scope_matcher_test.rb +0 -65
  241. data/test/rails_root/app/models/flea.rb +0 -3
@@ -36,6 +36,7 @@ module Shoulda # :nodoc:
36
36
 
37
37
  def to(params)
38
38
  @params = params
39
+ stringify_params!
39
40
  self
40
41
  end
41
42
 
@@ -47,7 +48,6 @@ module Shoulda # :nodoc:
47
48
  def matches?(controller)
48
49
  @controller = controller
49
50
  guess_controller!
50
- stringify_params!
51
51
  route_recognized?
52
52
  end
53
53
 
@@ -65,13 +65,13 @@ module Shoulda # :nodoc:
65
65
 
66
66
  def stringify_params!
67
67
  @params.each do |key, value|
68
- @params[key] = value.to_param
68
+ @params[key] = value.is_a?(Array) ? value.collect {|v| v.to_param } : value.to_param
69
69
  end
70
70
  end
71
71
 
72
72
  def route_recognized?
73
73
  begin
74
- @context.send(:assert_routing,
74
+ @context.send(:assert_routing,
75
75
  { :method => @method, :path => @path },
76
76
  @params)
77
77
 
@@ -19,13 +19,15 @@ module Shoulda # :nodoc:
19
19
  @key = key.to_s
20
20
  end
21
21
 
22
- def to(value)
22
+ def to(value = nil, &block)
23
23
  @value = value
24
+ @value_block = block
24
25
  self
25
26
  end
26
27
 
27
28
  def matches?(controller)
28
29
  @controller = controller
30
+ @value = @context.instance_eval(&@value_block) if @value_block
29
31
  (assigned_value? && assigned_correct_value?) || cleared_value?
30
32
  end
31
33
 
@@ -43,6 +45,11 @@ module Shoulda # :nodoc:
43
45
  description
44
46
  end
45
47
 
48
+ def in_context(context)
49
+ @context = context
50
+ self
51
+ end
52
+
46
53
  private
47
54
 
48
55
  def assigned_value?
@@ -63,7 +70,11 @@ module Shoulda # :nodoc:
63
70
  end
64
71
 
65
72
  def session
66
- @controller.response.session.data
73
+ if @controller.request.respond_to?(:session)
74
+ @controller.request.session.to_hash
75
+ else
76
+ @controller.response.session.data
77
+ end
67
78
  end
68
79
 
69
80
  def expectation
@@ -60,7 +60,7 @@ module Shoulda # :nodoc:
60
60
  end
61
61
 
62
62
  def flash
63
- @controller.response.session['flash']
63
+ @controller.send(:flash)
64
64
  end
65
65
 
66
66
  def expectation
@@ -1,10 +1,13 @@
1
1
  require 'shoulda'
2
2
  require 'shoulda/action_mailer/assertions'
3
+ require 'shoulda/action_mailer/matchers'
3
4
 
4
5
  module Test # :nodoc: all
5
6
  module Unit
6
7
  class TestCase
7
8
  include Shoulda::ActionMailer::Assertions
9
+ include Shoulda::ActionMailer::Matchers
10
+ extend Shoulda::ActionMailer::Matchers
8
11
  end
9
12
  end
10
13
  end
@@ -16,6 +16,7 @@ module Shoulda # :nodoc:
16
16
  # 'none@none.com' as one of the recipients.
17
17
  #
18
18
  def assert_sent_email
19
+ ::ActiveSupport::Deprecation.warn("use: should have_sent_email")
19
20
  emails = ::ActionMailer::Base.deliveries
20
21
  assert !emails.empty?, "No emails were sent"
21
22
  if block_given?
@@ -24,10 +25,13 @@ module Shoulda # :nodoc:
24
25
  end
25
26
  end
26
27
 
28
+ # should have_sent_email.with_subject(/hi there/).to('none@none.com').from('noreply@example.com').with_body(/reach out/)
29
+
27
30
  # Asserts that no ActionMailer mails were delivered
28
31
  #
29
32
  # assert_did_not_send_email
30
33
  def assert_did_not_send_email
34
+ ::ActiveSupport::Deprecation.warn("use: should_not have_sent_email")
31
35
  msg = "Sent #{::ActionMailer::Base.deliveries.size} emails.\n"
32
36
  ::ActionMailer::Base.deliveries.each { |m| msg << " '#{m.subject}' sent to #{m.to.to_sentence}\n" }
33
37
  assert ::ActionMailer::Base.deliveries.empty?, msg
@@ -0,0 +1,22 @@
1
+ require 'shoulda/action_mailer/matchers/have_sent_email'
2
+
3
+ module Shoulda # :nodoc:
4
+ module ActionMailer # :nodoc:
5
+ # = Matchers for your mailers
6
+ #
7
+ # This matcher will test that email is sent properly
8
+ #
9
+ # describe User do
10
+ # it { should have_sent_email.with_subject(/is spam$/) }
11
+ # it { should have_sent_email.from('do-not-reply@example.com') }
12
+ # it { should have_sent_email.with_body(/is spam\./) }
13
+ # it { should have_sent_email.to('myself@me.com') }
14
+ # it { should have_sent_email.with_subject(/spam/).
15
+ # from('do-not-reply@example.com').
16
+ # with_body(/spam/).
17
+ # to('myself@me.com') }
18
+ # end
19
+ module Matchers
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,110 @@
1
+ module Shoulda # :nodoc:
2
+ module ActionMailer # :nodoc:
3
+ module Matchers
4
+
5
+ # The right email is sent.
6
+ #
7
+ # it { should have_sent_email.with_subject(/is spam$/) }
8
+ # it { should have_sent_email.from('do-not-reply@example.com') }
9
+ # it { should have_sent_email.with_body(/is spam\./) }
10
+ # it { should have_sent_email.to('myself@me.com') }
11
+ # it { should have_sent_email.with_subject(/spam/).
12
+ # from('do-not-reply@example.com').
13
+ # with_body(/spam/).
14
+ # to('myself@me.com') }
15
+ def have_sent_email
16
+ HaveSentEmailMatcher.new
17
+ end
18
+
19
+ class HaveSentEmailMatcher # :nodoc:
20
+
21
+ def initialize
22
+ end
23
+
24
+ def with_subject(email_subject)
25
+ @email_subject = email_subject
26
+ self
27
+ end
28
+
29
+ def from(sender)
30
+ @sender = sender
31
+ self
32
+ end
33
+
34
+ def with_body(body)
35
+ @body = body
36
+ self
37
+ end
38
+
39
+ def to(recipient)
40
+ @recipient = recipient
41
+ self
42
+ end
43
+
44
+ def matches?(subject)
45
+ ::ActionMailer::Base.deliveries.each do |mail|
46
+ @subject_failed = !regexp_or_string_match(mail.subject, @email_subject) if @email_subject
47
+ @body_failed = !regexp_or_string_match(mail.body, @body) if @body
48
+ @sender_failed = !regexp_or_string_match_in_array(mail.from, @sender) if @sender
49
+ @recipient_failed = !regexp_or_string_match_in_array(mail.to, @recipient) if @recipient
50
+ return true unless anything_failed?
51
+ end
52
+
53
+ false
54
+ end
55
+
56
+ def failure_message
57
+ "Expected #{expectation}"
58
+ end
59
+
60
+ def negative_failure_message
61
+ "Did not expect #{expectation}"
62
+ end
63
+
64
+ def description
65
+ "send an email"
66
+ end
67
+
68
+ private
69
+
70
+ def expectation
71
+ expectation = "sent email"
72
+ expectation << " with subject #{@email_subject.inspect}" if @subject_failed
73
+ expectation << " with body #{@body.inspect}" if @body_failed
74
+ expectation << " from #{@sender.inspect}" if @sender_failed
75
+ expectation << " to #{@recipient.inspect}" if @recipient_failed
76
+ expectation << "\nDeliveries:\n#{inspect_deliveries}"
77
+ end
78
+
79
+ def inspect_deliveries
80
+ ::ActionMailer::Base.deliveries.map do |delivery|
81
+ "#{delivery.subject.inspect} to #{delivery.to.inspect}"
82
+ end.join("\n")
83
+ end
84
+
85
+ def anything_failed?
86
+ @subject_failed || @body_failed || @sender_failed || @recipient_failed
87
+ end
88
+
89
+ def regexp_or_string_match(a_string, a_regexp_or_string)
90
+ case a_regexp_or_string
91
+ when Regexp
92
+ a_string =~ a_regexp_or_string
93
+ when String
94
+ a_string == a_regexp_or_string
95
+ end
96
+ end
97
+
98
+ def regexp_or_string_match_in_array(an_array, a_regexp_or_string)
99
+ case a_regexp_or_string
100
+ when Regexp
101
+ an_array.detect{|e| e =~ a_regexp_or_string}.any?
102
+ when String
103
+ an_array.include?(a_regexp_or_string)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+
@@ -2,8 +2,8 @@ module Shoulda # :nodoc:
2
2
  module ActiveRecord # :nodoc:
3
3
  module Helpers
4
4
  def pretty_error_messages(obj) # :nodoc:
5
- obj.errors.map do |a, m|
6
- msg = "#{a} #{m}"
5
+ obj.errors.map do |a, m|
6
+ msg = "#{a} #{m}"
7
7
  msg << " (#{obj.send(a).inspect})" unless a.to_sym == :base
8
8
  end
9
9
  end
@@ -17,7 +17,12 @@ module Shoulda # :nodoc:
17
17
  # default_error_message(:too_long, :count => 60)
18
18
  def default_error_message(key, values = {})
19
19
  if Object.const_defined?(:I18n) # Rails >= 2.2
20
- I18n.translate("activerecord.errors.messages.#{key}", values)
20
+ result = I18n.translate("activerecord.errors.messages.#{key}", values)
21
+ if result =~ /^translation missing/
22
+ I18n.translate("errors.messages.#{key}", values)
23
+ else
24
+ result
25
+ end
21
26
  else # Rails <= 2.1.x
22
27
  ::ActiveRecord::Errors.default_error_messages[key] % values[:count]
23
28
  end
@@ -23,6 +23,8 @@ module Shoulda # :nodoc:
23
23
  include Helpers
24
24
  include Matchers
25
25
 
26
+ # Deprecated: use ActiveRecord::Matchers#validate_presence_of instead.
27
+ #
26
28
  # Ensures that the model cannot be saved if one of the attributes listed is not present.
27
29
  #
28
30
  # Options:
@@ -33,21 +35,20 @@ module Shoulda # :nodoc:
33
35
  # should_validate_presence_of :name, :phone_number
34
36
  #
35
37
  def should_validate_presence_of(*attributes)
38
+ ::ActiveSupport::Deprecation.warn("use: should validate_presence_of")
36
39
  message = get_options!(attributes, :message)
37
40
 
38
41
  attributes.each do |attribute|
39
- matcher = validate_presence_of(attribute).with_message(message)
40
- should matcher.description do
41
- assert_accepts(matcher, subject)
42
- end
42
+ should validate_presence_of(attribute).with_message(message)
43
43
  end
44
44
  end
45
-
45
+
46
+ # Deprecated: use ActiveRecord::Matchers#validate_uniqueness_of instead.
47
+ #
46
48
  # Ensures that the model cannot be saved if one of the attributes listed is not unique.
47
49
  # Requires an existing record
48
50
  #
49
51
  # Options:
50
-
51
52
  # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
52
53
  # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.taken')</tt>
53
54
  # * <tt>:scoped_to</tt> - field(s) to scope the uniqueness to.
@@ -62,6 +63,7 @@ module Shoulda # :nodoc:
62
63
  # should_validate_uniqueness_of :email, :case_sensitive => false
63
64
  #
64
65
  def should_validate_uniqueness_of(*attributes)
66
+ ::ActiveSupport::Deprecation.warn("use: should validate_uniqueness_of")
65
67
  message, scope, case_sensitive = get_options!(attributes, :message, :scoped_to, :case_sensitive)
66
68
  scope = [*scope].compact
67
69
  case_sensitive = true if case_sensitive.nil?
@@ -70,57 +72,57 @@ module Shoulda # :nodoc:
70
72
  matcher = validate_uniqueness_of(attribute).
71
73
  with_message(message).scoped_to(scope)
72
74
  matcher = matcher.case_insensitive unless case_sensitive
73
- should matcher.description do
74
- assert_accepts(matcher, subject)
75
- end
75
+ should matcher
76
76
  end
77
77
  end
78
78
 
79
+ # Deprecated: use ActiveRecord::Matchers#allow_mass_assignment_of instead.
80
+ #
79
81
  # Ensures that the attribute can be set on mass update.
80
82
  #
81
83
  # should_allow_mass_assignment_of :first_name, :last_name
82
84
  #
83
85
  def should_allow_mass_assignment_of(*attributes)
86
+ ::ActiveSupport::Deprecation.warn("use: should allow_mass_assignment_of")
84
87
  get_options!(attributes)
85
88
 
86
89
  attributes.each do |attribute|
87
- matcher = allow_mass_assignment_of(attribute)
88
- should matcher.description do
89
- assert_accepts matcher, subject
90
- end
90
+ should allow_mass_assignment_of(attribute)
91
91
  end
92
92
  end
93
93
 
94
+ # Deprecated: use ActiveRecord::Matchers#allow_mass_assignment_of instead.
95
+ #
94
96
  # Ensures that the attribute cannot be set on mass update.
95
97
  #
96
98
  # should_not_allow_mass_assignment_of :password, :admin_flag
97
99
  #
98
100
  def should_not_allow_mass_assignment_of(*attributes)
101
+ ::ActiveSupport::Deprecation.warn("use: should_not allow_mass_assignment_of")
99
102
  get_options!(attributes)
100
103
 
101
104
  attributes.each do |attribute|
102
- matcher = allow_mass_assignment_of(attribute)
103
- should "not #{matcher.description}" do
104
- assert_rejects matcher, subject
105
- end
105
+ should_not allow_mass_assignment_of(attribute)
106
106
  end
107
107
  end
108
108
 
109
+ # Deprecated: use ActiveRecord::Matchers#have_readonly_attribute instead.
110
+ #
109
111
  # Ensures that the attribute cannot be changed once the record has been created.
110
112
  #
111
113
  # should_have_readonly_attributes :password, :admin_flag
112
114
  #
113
115
  def should_have_readonly_attributes(*attributes)
116
+ ::ActiveSupport::Deprecation.warn("use: should have_readonly_attribute")
114
117
  get_options!(attributes)
115
118
 
116
119
  attributes.each do |attribute|
117
- matcher = have_readonly_attribute(attribute)
118
- should matcher.description do
119
- assert_accepts matcher, subject
120
- end
120
+ should have_readonly_attribute(attribute)
121
121
  end
122
122
  end
123
123
 
124
+ # Deprecated: use ActiveRecord::Matchers#allow_value instead.
125
+ #
124
126
  # Ensures that the attribute cannot be set to the given values
125
127
  #
126
128
  # Options:
@@ -132,30 +134,30 @@ module Shoulda # :nodoc:
132
134
  # should_not_allow_values_for :isbn, "bad 1", "bad 2"
133
135
  #
134
136
  def should_not_allow_values_for(attribute, *bad_values)
137
+ ::ActiveSupport::Deprecation.warn("use: should_not allow_value")
135
138
  message = get_options!(bad_values, :message)
136
139
  bad_values.each do |value|
137
- matcher = allow_value(value).for(attribute).with_message(message)
138
- should "not #{matcher.description}" do
139
- assert_rejects matcher, subject
140
- end
140
+ should_not allow_value(value).for(attribute).with_message(message)
141
141
  end
142
142
  end
143
143
 
144
+ # Deprecated: use ActiveRecord::Matchers#allow_value instead.
145
+ #
144
146
  # Ensures that the attribute can be set to the given values.
145
147
  #
146
148
  # Example:
147
149
  # should_allow_values_for :isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0"
148
150
  #
149
151
  def should_allow_values_for(attribute, *good_values)
152
+ ::ActiveSupport::Deprecation.warn("use: should allow_value")
150
153
  get_options!(good_values)
151
154
  good_values.each do |value|
152
- matcher = allow_value(value).for(attribute)
153
- should matcher.description do
154
- assert_accepts matcher, subject
155
- end
155
+ should allow_value(value).for(attribute)
156
156
  end
157
157
  end
158
158
 
159
+ # Deprecated: use ActiveRecord::Matchers#ensure_length_of instead.
160
+ #
159
161
  # Ensures that the length of the attribute is in the given range
160
162
  #
161
163
  # Options:
@@ -168,20 +170,19 @@ module Shoulda # :nodoc:
168
170
  # should_ensure_length_in_range :password, (6..20)
169
171
  #
170
172
  def should_ensure_length_in_range(attribute, range, opts = {})
171
- short_message, long_message = get_options!([opts],
173
+ ::ActiveSupport::Deprecation.warn("use: should ensure_length_of.is_at_least.is_at_most")
174
+ short_message, long_message = get_options!([opts],
172
175
  :short_message,
173
176
  :long_message)
174
- matcher = ensure_length_of(attribute).
177
+ should ensure_length_of(attribute).
175
178
  is_at_least(range.first).
176
179
  with_short_message(short_message).
177
180
  is_at_most(range.last).
178
181
  with_long_message(long_message)
179
-
180
- should matcher.description do
181
- assert_accepts matcher, subject
182
- end
183
182
  end
184
183
 
184
+ # Deprecated: use ActiveRecord::Matchers#ensure_length_of instead.
185
+ #
185
186
  # Ensures that the length of the attribute is at least a certain length
186
187
  #
187
188
  # Options:
@@ -192,17 +193,16 @@ module Shoulda # :nodoc:
192
193
  # should_ensure_length_at_least :name, 3
193
194
  #
194
195
  def should_ensure_length_at_least(attribute, min_length, opts = {})
196
+ ::ActiveSupport::Deprecation.warn("use: should ensure_length_of.is_at_least")
195
197
  short_message = get_options!([opts], :short_message)
196
198
 
197
- matcher = ensure_length_of(attribute).
199
+ should ensure_length_of(attribute).
198
200
  is_at_least(min_length).
199
201
  with_short_message(short_message)
200
-
201
- should matcher.description do
202
- assert_accepts matcher, subject
203
- end
204
202
  end
205
203
 
204
+ # Deprecated: use ActiveRecord::Matchers#ensure_length_of instead.
205
+ #
206
206
  # Ensures that the length of the attribute is exactly a certain length
207
207
  #
208
208
  # Options:
@@ -213,16 +213,15 @@ module Shoulda # :nodoc:
213
213
  # should_ensure_length_is :ssn, 9
214
214
  #
215
215
  def should_ensure_length_is(attribute, length, opts = {})
216
+ ::ActiveSupport::Deprecation.warn("use: should ensure_length_of.is_equal_to")
216
217
  message = get_options!([opts], :message)
217
- matcher = ensure_length_of(attribute).
218
+ should ensure_length_of(attribute).
218
219
  is_equal_to(length).
219
220
  with_message(message)
220
-
221
- should matcher.description do
222
- assert_accepts matcher, subject
223
- end
224
221
  end
225
222
 
223
+ # Deprecated: use ActiveRecord::Matchers#ensure_inclusion_of instead.
224
+ #
226
225
  # Ensure that the attribute is in the range specified
227
226
  #
228
227
  # Options:
@@ -235,20 +234,20 @@ module Shoulda # :nodoc:
235
234
  # should_ensure_value_in_range :age, (0..100)
236
235
  #
237
236
  def should_ensure_value_in_range(attribute, range, opts = {})
237
+ ::ActiveSupport::Deprecation.warn("use: should ensure_inclusion_of.in_range")
238
238
  message, low_message, high_message = get_options!([opts],
239
239
  :message,
240
240
  :low_message,
241
241
  :high_message)
242
- matcher = ensure_inclusion_of(attribute).
242
+ should ensure_inclusion_of(attribute).
243
243
  in_range(range).
244
244
  with_message(message).
245
245
  with_low_message(low_message).
246
246
  with_high_message(high_message)
247
- should matcher.description do
248
- assert_accepts matcher, subject
249
- end
250
247
  end
251
248
 
249
+ # Deprecated: use ActiveRecord::Matchers#validate_numericality_of instead.
250
+ #
252
251
  # Ensure that the attribute is numeric
253
252
  #
254
253
  # Options:
@@ -259,16 +258,16 @@ module Shoulda # :nodoc:
259
258
  # should_validate_numericality_of :age
260
259
  #
261
260
  def should_validate_numericality_of(*attributes)
261
+ ::ActiveSupport::Deprecation.warn("use: should validate_numericality_of")
262
262
  message = get_options!(attributes, :message)
263
263
  attributes.each do |attribute|
264
- matcher = validate_numericality_of(attribute).
264
+ should validate_numericality_of(attribute).
265
265
  with_message(message)
266
- should matcher.description do
267
- assert_accepts matcher, subject
268
- end
269
266
  end
270
267
  end
271
268
 
269
+ # Deprecated: use ActiveRecord::Matchers#have_many instead.
270
+ #
272
271
  # Ensures that the has_many relationship exists. Will also test that the
273
272
  # associated table has the required columns. Works with polymorphic
274
273
  # associations.
@@ -283,15 +282,15 @@ module Shoulda # :nodoc:
283
282
  # should_have_many :enemies, :dependent => :destroy
284
283
  #
285
284
  def should_have_many(*associations)
285
+ ::ActiveSupport::Deprecation.warn("use: should have_many")
286
286
  through, dependent = get_options!(associations, :through, :dependent)
287
287
  associations.each do |association|
288
- matcher = have_many(association).through(through).dependent(dependent)
289
- should matcher.description do
290
- assert_accepts(matcher, subject)
291
- end
288
+ should have_many(association).through(through).dependent(dependent)
292
289
  end
293
290
  end
294
291
 
292
+ # Deprecated: use ActiveRecord::Matchers#have_one instead.
293
+ #
295
294
  # Ensure that the has_one relationship exists. Will also test that the
296
295
  # associated table has the required columns. Works with polymorphic
297
296
  # associations.
@@ -303,50 +302,51 @@ module Shoulda # :nodoc:
303
302
  # should_have_one :god # unless hindu
304
303
  #
305
304
  def should_have_one(*associations)
305
+ ::ActiveSupport::Deprecation.warn("use: should have_one")
306
306
  dependent, through = get_options!(associations, :dependent, :through)
307
307
  associations.each do |association|
308
- matcher = have_one(association).dependent(dependent).through(through)
309
- should matcher.description do
310
- assert_accepts(matcher, subject)
311
- end
308
+ should have_one(association).dependent(dependent).through(through)
312
309
  end
313
310
  end
314
311
 
312
+ # Deprecated: use ActiveRecord::Matchers#have_and_belong_to_many instead.
313
+ #
315
314
  # Ensures that the has_and_belongs_to_many relationship exists, and that the join
316
315
  # table is in place.
317
316
  #
318
317
  # should_have_and_belong_to_many :posts, :cars
319
318
  #
320
319
  def should_have_and_belong_to_many(*associations)
320
+ ::ActiveSupport::Deprecation.warn("use: should have_and_belong_to_many")
321
321
  get_options!(associations)
322
322
 
323
323
  associations.each do |association|
324
- matcher = have_and_belong_to_many(association)
325
- should matcher.description do
326
- assert_accepts(matcher, subject)
327
- end
324
+ should have_and_belong_to_many(association)
328
325
  end
329
326
  end
330
327
 
328
+ # Deprecated: use ActiveRecord::Matchers#belong_to instead.
329
+ #
331
330
  # Ensure that the belongs_to relationship exists.
332
331
  #
333
332
  # should_belong_to :parent
334
333
  #
335
334
  def should_belong_to(*associations)
335
+ ::ActiveSupport::Deprecation.warn("use: should belong_to")
336
336
  dependent = get_options!(associations, :dependent)
337
337
  associations.each do |association|
338
- matcher = belong_to(association).dependent(dependent)
339
- should matcher.description do
340
- assert_accepts(matcher, subject)
341
- end
338
+ should belong_to(association).dependent(dependent)
342
339
  end
343
340
  end
344
341
 
342
+ # Deprecated.
343
+ #
345
344
  # Ensure that the given class methods are defined on the model.
346
345
  #
347
346
  # should_have_class_methods :find, :destroy
348
347
  #
349
348
  def should_have_class_methods(*methods)
349
+ ::ActiveSupport::Deprecation.warn
350
350
  get_options!(methods)
351
351
  klass = described_type
352
352
  methods.each do |method|
@@ -356,11 +356,14 @@ module Shoulda # :nodoc:
356
356
  end
357
357
  end
358
358
 
359
+ # Deprecated.
360
+ #
359
361
  # Ensure that the given instance methods are defined on the model.
360
362
  #
361
363
  # should_have_instance_methods :email, :name, :name=
362
364
  #
363
365
  def should_have_instance_methods(*methods)
366
+ ::ActiveSupport::Deprecation.warn
364
367
  get_options!(methods)
365
368
  klass = described_type
366
369
  methods.each do |method|
@@ -370,9 +373,11 @@ module Shoulda # :nodoc:
370
373
  end
371
374
  end
372
375
 
376
+ # Deprecated: use ActiveRecord::Matchers#have_db_column instead.
377
+ #
373
378
  # Ensure that the given columns are defined on the models backing SQL table.
374
379
  # Also aliased to should_have_db_column for readability.
375
- # Takes the same options available in migrations:
380
+ # Takes the same options available in migrations:
376
381
  # :type, :precision, :limit, :default, :null, and :scale
377
382
  #
378
383
  # Examples:
@@ -384,23 +389,23 @@ module Shoulda # :nodoc:
384
389
  # should_have_db_column :admin, :default => false, :null => false
385
390
  #
386
391
  def should_have_db_columns(*columns)
387
- column_type, precision, limit, default, null, scale, sql_type =
392
+ ::ActiveSupport::Deprecation.warn("use: should have_db_column")
393
+ column_type, precision, limit, default, null, scale, sql_type =
388
394
  get_options!(columns, :type, :precision, :limit,
389
395
  :default, :null, :scale, :sql_type)
390
396
  columns.each do |name|
391
- matcher = have_db_column(name).
397
+ should have_db_column(name).
392
398
  of_type(column_type).
393
399
  with_options(:precision => precision, :limit => limit,
394
400
  :default => default, :null => null,
395
401
  :scale => scale, :sql_type => sql_type)
396
- should matcher.description do
397
- assert_accepts(matcher, subject)
398
- end
399
402
  end
400
403
  end
401
-
404
+
402
405
  alias_method :should_have_db_column, :should_have_db_columns
403
406
 
407
+ # Deprecated: use ActiveRecord::Matchers#have_db_index instead.
408
+ #
404
409
  # Ensures that there are DB indices on the given columns or tuples of columns.
405
410
  # Also aliased to should_have_db_index for readability
406
411
  #
@@ -418,32 +423,18 @@ module Shoulda # :nodoc:
418
423
  # should_have_db_index :ssn, :unique => true
419
424
  #
420
425
  def should_have_db_indices(*columns)
426
+ ::ActiveSupport::Deprecation.warn("use: should have_db_index")
421
427
  unique = get_options!(columns, :unique)
422
-
428
+
423
429
  columns.each do |column|
424
- matcher = have_db_index(column).unique(unique)
425
- should matcher.description do
426
- assert_accepts(matcher, subject)
427
- end
430
+ should have_db_index(column).unique(unique)
428
431
  end
429
432
  end
430
433
 
431
434
  alias_method :should_have_db_index, :should_have_db_indices
432
435
 
433
- # Deprecated. See should_have_db_index
434
- def should_have_index(*args)
435
- warn "[DEPRECATION] should_have_index is deprecated. " <<
436
- "Use should_have_db_index instead."
437
- should_have_db_index(*args)
438
- end
439
-
440
- # Deprecated. See should_have_db_indices
441
- def should_have_indices(*args)
442
- warn "[DEPRECATION] should_have_indices is deprecated. " <<
443
- "Use should_have_db_indices instead."
444
- should_have_db_indices(*args)
445
- end
446
-
436
+ # Deprecated: use ActiveRecord::Matchers#validate_acceptance_of instead.
437
+ #
447
438
  # Ensures that the model cannot be saved if one of the attributes listed is not accepted.
448
439
  #
449
440
  # Options:
@@ -454,57 +445,11 @@ module Shoulda # :nodoc:
454
445
  # should_validate_acceptance_of :eula
455
446
  #
456
447
  def should_validate_acceptance_of(*attributes)
448
+ ::ActiveSupport::Deprecation.warn("use: should validate_acceptance_of")
457
449
  message = get_options!(attributes, :message)
458
450
 
459
451
  attributes.each do |attribute|
460
- matcher = validate_acceptance_of(attribute).with_message(message)
461
- should matcher.description do
462
- assert_accepts matcher, subject
463
- end
464
- end
465
- end
466
-
467
- # Deprecated.
468
- #
469
- # Ensures that the model has a method named scope_name that returns a NamedScope object with the
470
- # proxy options set to the options you supply. scope_name can be either a symbol, or a method
471
- # call which will be evaled against the model. The eval'd method call has access to all the same
472
- # instance variables that a should statement would.
473
- #
474
- # Options: Any of the options that the named scope would pass on to find.
475
- #
476
- # Example:
477
- #
478
- # should_have_named_scope :visible, :conditions => {:visible => true}
479
- #
480
- # Passes for
481
- #
482
- # named_scope :visible, :conditions => {:visible => true}
483
- #
484
- # Or for
485
- #
486
- # def self.visible
487
- # scoped(:conditions => {:visible => true})
488
- # end
489
- #
490
- # You can test lambdas or methods that return ActiveRecord#scoped calls:
491
- #
492
- # should_have_named_scope 'recent(5)', :limit => 5
493
- # should_have_named_scope 'recent(1)', :limit => 1
494
- #
495
- # Passes for
496
- # named_scope :recent, lambda {|c| {:limit => c}}
497
- #
498
- # Or for
499
- #
500
- # def self.recent(c)
501
- # scoped(:limit => c)
502
- # end
503
- #
504
- def should_have_named_scope(scope_call, find_options = nil)
505
- matcher = have_named_scope(scope_call).finding(find_options)
506
- should matcher.description do
507
- assert_accepts matcher.in_context(self), subject
452
+ should validate_acceptance_of(attribute).with_message(message)
508
453
  end
509
454
  end
510
455
  end