nimboids-shoulda 2.11.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (258) hide show
  1. data/CONTRIBUTION_GUIDELINES.rdoc +10 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.rdoc +154 -0
  4. data/Rakefile +74 -0
  5. data/bin/convert_to_should_syntax +42 -0
  6. data/lib/shoulda/action_controller/macros.rb +221 -0
  7. data/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +114 -0
  8. data/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +74 -0
  9. data/lib/shoulda/action_controller/matchers/redirect_to_matcher.rb +62 -0
  10. data/lib/shoulda/action_controller/matchers/render_template_matcher.rb +54 -0
  11. data/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +99 -0
  12. data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +74 -0
  13. data/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +85 -0
  14. data/lib/shoulda/action_controller/matchers/route_matcher.rb +93 -0
  15. data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +98 -0
  16. data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +100 -0
  17. data/lib/shoulda/action_controller/matchers.rb +39 -0
  18. data/lib/shoulda/action_controller.rb +34 -0
  19. data/lib/shoulda/action_mailer/assertions.rb +42 -0
  20. data/lib/shoulda/action_mailer/matchers/have_sent_email.rb +110 -0
  21. data/lib/shoulda/action_mailer/matchers.rb +22 -0
  22. data/lib/shoulda/action_mailer.rb +13 -0
  23. data/lib/shoulda/active_record/assertions.rb +69 -0
  24. data/lib/shoulda/active_record/helpers.rb +32 -0
  25. data/lib/shoulda/active_record/macros.rb +457 -0
  26. data/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +83 -0
  27. data/lib/shoulda/active_record/matchers/allow_value_matcher.rb +110 -0
  28. data/lib/shoulda/active_record/matchers/association_matcher.rb +275 -0
  29. data/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +87 -0
  30. data/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +141 -0
  31. data/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +169 -0
  32. data/lib/shoulda/active_record/matchers/have_db_index_matcher.rb +112 -0
  33. data/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +59 -0
  34. data/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +41 -0
  35. data/lib/shoulda/active_record/matchers/validate_format_of_matcher.rb +65 -0
  36. data/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +39 -0
  37. data/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +60 -0
  38. data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +148 -0
  39. data/lib/shoulda/active_record/matchers/validation_matcher.rb +56 -0
  40. data/lib/shoulda/active_record/matchers.rb +42 -0
  41. data/lib/shoulda/active_record.rb +16 -0
  42. data/lib/shoulda/assertions.rb +79 -0
  43. data/lib/shoulda/autoload_macros.rb +46 -0
  44. data/lib/shoulda/context.rb +441 -0
  45. data/lib/shoulda/helpers.rb +8 -0
  46. data/lib/shoulda/integrations/rspec.rb +13 -0
  47. data/lib/shoulda/integrations/rspec2.rb +22 -0
  48. data/lib/shoulda/integrations/test_unit.rb +22 -0
  49. data/lib/shoulda/macros.rb +161 -0
  50. data/lib/shoulda/private_helpers.rb +13 -0
  51. data/lib/shoulda/proc_extensions.rb +14 -0
  52. data/lib/shoulda/rails.rb +8 -0
  53. data/lib/shoulda/tasks/list_tests.rake +29 -0
  54. data/lib/shoulda/tasks/yaml_to_shoulda.rake +28 -0
  55. data/lib/shoulda/tasks.rb +3 -0
  56. data/lib/shoulda/version.rb +4 -0
  57. data/lib/shoulda.rb +9 -0
  58. data/rails/init.rb +8 -0
  59. data/test/README +36 -0
  60. data/test/fail_macros.rb +55 -0
  61. data/test/fixtures/addresses.yml +3 -0
  62. data/test/fixtures/friendships.yml +0 -0
  63. data/test/fixtures/posts.yml +5 -0
  64. data/test/fixtures/products.yml +0 -0
  65. data/test/fixtures/taggings.yml +0 -0
  66. data/test/fixtures/tags.yml +9 -0
  67. data/test/fixtures/users.yml +6 -0
  68. data/test/functional/posts_controller_test.rb +121 -0
  69. data/test/functional/users_controller_test.rb +19 -0
  70. data/test/matchers/action_mailer/have_sent_email_test.rb +76 -0
  71. data/test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb +74 -0
  72. data/test/matchers/active_record/allow_value_matcher_test.rb +64 -0
  73. data/test/matchers/active_record/association_matcher_test.rb +462 -0
  74. data/test/matchers/active_record/ensure_inclusion_of_matcher_test.rb +81 -0
  75. data/test/matchers/active_record/ensure_length_of_matcher_test.rb +158 -0
  76. data/test/matchers/active_record/have_db_column_matcher_test.rb +169 -0
  77. data/test/matchers/active_record/have_db_index_matcher_test.rb +91 -0
  78. data/test/matchers/active_record/have_readonly_attributes_matcher_test.rb +29 -0
  79. data/test/matchers/active_record/validate_acceptance_of_matcher_test.rb +44 -0
  80. data/test/matchers/active_record/validate_format_of_matcher_test.rb +39 -0
  81. data/test/matchers/active_record/validate_numericality_of_matcher_test.rb +52 -0
  82. data/test/matchers/active_record/validate_presence_of_matcher_test.rb +86 -0
  83. data/test/matchers/active_record/validate_uniqueness_of_matcher_test.rb +147 -0
  84. data/test/matchers/controller/assign_to_matcher_test.rb +55 -0
  85. data/test/matchers/controller/filter_param_matcher_test.rb +40 -0
  86. data/test/matchers/controller/redirect_to_matcher_test.rb +37 -0
  87. data/test/matchers/controller/render_template_matcher_test.rb +37 -0
  88. data/test/matchers/controller/render_with_layout_matcher_test.rb +47 -0
  89. data/test/matchers/controller/respond_with_content_type_matcher_test.rb +32 -0
  90. data/test/matchers/controller/respond_with_matcher_test.rb +96 -0
  91. data/test/matchers/controller/route_matcher_test.rb +75 -0
  92. data/test/matchers/controller/set_session_matcher_test.rb +48 -0
  93. data/test/matchers/controller/set_the_flash_matcher.rb +95 -0
  94. data/test/other/autoload_macro_test.rb +18 -0
  95. data/test/other/context_test.rb +372 -0
  96. data/test/other/convert_to_should_syntax_test.rb +63 -0
  97. data/test/other/helpers_test.rb +317 -0
  98. data/test/other/private_helpers_test.rb +32 -0
  99. data/test/other/should_test.rb +271 -0
  100. data/test/rails2_model_builder.rb +130 -0
  101. data/test/rails2_root/app/controllers/application_controller.rb +22 -0
  102. data/test/rails2_root/app/controllers/posts_controller.rb +87 -0
  103. data/test/rails2_root/app/controllers/users_controller.rb +84 -0
  104. data/test/rails2_root/app/helpers/application_helper.rb +3 -0
  105. data/test/rails2_root/app/helpers/posts_helper.rb +2 -0
  106. data/test/rails2_root/app/helpers/users_helper.rb +2 -0
  107. data/test/rails2_root/app/models/address.rb +7 -0
  108. data/test/rails2_root/app/models/flea.rb +11 -0
  109. data/test/rails2_root/app/models/friendship.rb +4 -0
  110. data/test/rails2_root/app/models/notifier.rb +8 -0
  111. data/test/rails2_root/app/models/pets/cat.rb +7 -0
  112. data/test/rails2_root/app/models/pets/dog.rb +10 -0
  113. data/test/rails2_root/app/models/post.rb +12 -0
  114. data/test/rails2_root/app/models/product.rb +12 -0
  115. data/test/rails2_root/app/models/profile.rb +2 -0
  116. data/test/rails2_root/app/models/registration.rb +2 -0
  117. data/test/rails2_root/app/models/tag.rb +8 -0
  118. data/test/rails2_root/app/models/tagging.rb +4 -0
  119. data/test/rails2_root/app/models/treat.rb +3 -0
  120. data/test/rails2_root/app/models/user.rb +32 -0
  121. data/test/rails2_root/app/views/layouts/posts.rhtml +19 -0
  122. data/test/rails2_root/app/views/layouts/users.rhtml +17 -0
  123. data/test/rails2_root/app/views/layouts/wide.html.erb +1 -0
  124. data/test/rails2_root/app/views/notifier/the_email.html.erb +1 -0
  125. data/test/rails2_root/app/views/posts/edit.rhtml +27 -0
  126. data/test/rails2_root/app/views/posts/index.rhtml +25 -0
  127. data/test/rails2_root/app/views/posts/new.rhtml +26 -0
  128. data/test/rails2_root/app/views/posts/show.rhtml +18 -0
  129. data/test/rails2_root/app/views/users/edit.rhtml +22 -0
  130. data/test/rails2_root/app/views/users/index.rhtml +22 -0
  131. data/test/rails2_root/app/views/users/new.rhtml +21 -0
  132. data/test/rails2_root/app/views/users/show.rhtml +13 -0
  133. data/test/rails2_root/config/boot.rb +110 -0
  134. data/test/rails2_root/config/database.yml +4 -0
  135. data/test/rails2_root/config/environment.rb +17 -0
  136. data/test/rails2_root/config/environments/test.rb +23 -0
  137. data/test/rails2_root/config/initializers/new_rails_defaults.rb +15 -0
  138. data/test/rails2_root/config/initializers/shoulda.rb +8 -0
  139. data/test/rails2_root/config/routes.rb +6 -0
  140. data/test/rails2_root/db/migrate/001_create_users.rb +19 -0
  141. data/test/rails2_root/db/migrate/002_create_posts.rb +13 -0
  142. data/test/rails2_root/db/migrate/003_create_taggings.rb +12 -0
  143. data/test/rails2_root/db/migrate/004_create_tags.rb +11 -0
  144. data/test/rails2_root/db/migrate/005_create_dogs.rb +12 -0
  145. data/test/rails2_root/db/migrate/006_create_addresses.rb +14 -0
  146. data/test/rails2_root/db/migrate/007_create_fleas.rb +11 -0
  147. data/test/rails2_root/db/migrate/008_create_dogs_fleas.rb +12 -0
  148. data/test/rails2_root/db/migrate/009_create_products.rb +17 -0
  149. data/test/rails2_root/db/migrate/010_create_friendships.rb +14 -0
  150. data/test/rails2_root/db/migrate/011_create_treats.rb +12 -0
  151. data/test/rails2_root/db/migrate/20090506203502_create_profiles.rb +12 -0
  152. data/test/rails2_root/db/migrate/20090506203536_create_registrations.rb +14 -0
  153. data/test/rails2_root/db/migrate/20090513104502_create_cats.rb +12 -0
  154. data/test/rails2_root/db/schema.rb +0 -0
  155. data/test/rails2_root/public/404.html +30 -0
  156. data/test/rails2_root/public/422.html +30 -0
  157. data/test/rails2_root/public/500.html +30 -0
  158. data/test/rails2_root/script/console +3 -0
  159. data/test/rails2_root/script/generate +3 -0
  160. data/test/rails2_root/test/shoulda_macros/custom_macro.rb +6 -0
  161. data/test/rails2_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +6 -0
  162. data/test/rails2_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +6 -0
  163. data/test/rails2_test_helper.rb +6 -0
  164. data/test/rails3_model_builder.rb +118 -0
  165. data/test/rails3_root/Gemfile +28 -0
  166. data/test/rails3_root/README +244 -0
  167. data/test/rails3_root/Rakefile +10 -0
  168. data/test/rails3_root/app/controllers/application_controller.rb +22 -0
  169. data/test/rails3_root/app/controllers/posts_controller.rb +87 -0
  170. data/test/rails3_root/app/controllers/users_controller.rb +82 -0
  171. data/test/rails3_root/app/helpers/application_helper.rb +2 -0
  172. data/test/rails3_root/app/models/address.rb +7 -0
  173. data/test/rails3_root/app/models/flea.rb +11 -0
  174. data/test/rails3_root/app/models/friendship.rb +4 -0
  175. data/test/rails3_root/app/models/notifier.rb +8 -0
  176. data/test/rails3_root/app/models/pets/cat.rb +7 -0
  177. data/test/rails3_root/app/models/pets/dog.rb +10 -0
  178. data/test/rails3_root/app/models/post.rb +12 -0
  179. data/test/rails3_root/app/models/product.rb +12 -0
  180. data/test/rails3_root/app/models/profile.rb +2 -0
  181. data/test/rails3_root/app/models/registration.rb +2 -0
  182. data/test/rails3_root/app/models/tag.rb +8 -0
  183. data/test/rails3_root/app/models/tagging.rb +4 -0
  184. data/test/rails3_root/app/models/treat.rb +3 -0
  185. data/test/rails3_root/app/models/user.rb +32 -0
  186. data/test/rails3_root/app/views/layouts/application.html.erb +14 -0
  187. data/test/rails3_root/app/views/layouts/posts.rhtml +19 -0
  188. data/test/rails3_root/app/views/layouts/users.rhtml +17 -0
  189. data/test/rails3_root/app/views/layouts/wide.html.erb +1 -0
  190. data/test/rails3_root/app/views/notifier/the_email.html.erb +1 -0
  191. data/test/rails3_root/app/views/posts/edit.rhtml +27 -0
  192. data/test/rails3_root/app/views/posts/index.rhtml +25 -0
  193. data/test/rails3_root/app/views/posts/new.rhtml +24 -0
  194. data/test/rails3_root/app/views/posts/show.rhtml +18 -0
  195. data/test/rails3_root/app/views/users/edit.rhtml +22 -0
  196. data/test/rails3_root/app/views/users/index.rhtml +22 -0
  197. data/test/rails3_root/app/views/users/new.rhtml +21 -0
  198. data/test/rails3_root/app/views/users/show.rhtml +13 -0
  199. data/test/rails3_root/config/application.rb +46 -0
  200. data/test/rails3_root/config/boot.rb +6 -0
  201. data/test/rails3_root/config/database.yml +22 -0
  202. data/test/rails3_root/config/environment.rb +5 -0
  203. data/test/rails3_root/config/environments/development.rb +19 -0
  204. data/test/rails3_root/config/environments/production.rb +42 -0
  205. data/test/rails3_root/config/environments/test.rb +32 -0
  206. data/test/rails3_root/config/initializers/backtrace_silencers.rb +7 -0
  207. data/test/rails3_root/config/initializers/inflections.rb +10 -0
  208. data/test/rails3_root/config/initializers/mime_types.rb +5 -0
  209. data/test/rails3_root/config/initializers/secret_token.rb +7 -0
  210. data/test/rails3_root/config/initializers/session_store.rb +8 -0
  211. data/test/rails3_root/config/locales/en.yml +5 -0
  212. data/test/rails3_root/config/routes.rb +4 -0
  213. data/test/rails3_root/config.ru +4 -0
  214. data/test/rails3_root/db/migrate/001_create_users.rb +19 -0
  215. data/test/rails3_root/db/migrate/002_create_posts.rb +13 -0
  216. data/test/rails3_root/db/migrate/003_create_taggings.rb +12 -0
  217. data/test/rails3_root/db/migrate/004_create_tags.rb +11 -0
  218. data/test/rails3_root/db/migrate/005_create_dogs.rb +12 -0
  219. data/test/rails3_root/db/migrate/006_create_addresses.rb +14 -0
  220. data/test/rails3_root/db/migrate/007_create_fleas.rb +11 -0
  221. data/test/rails3_root/db/migrate/008_create_dogs_fleas.rb +12 -0
  222. data/test/rails3_root/db/migrate/009_create_products.rb +17 -0
  223. data/test/rails3_root/db/migrate/010_create_friendships.rb +14 -0
  224. data/test/rails3_root/db/migrate/011_create_treats.rb +12 -0
  225. data/test/rails3_root/db/migrate/20090506203502_create_profiles.rb +12 -0
  226. data/test/rails3_root/db/migrate/20090506203536_create_registrations.rb +14 -0
  227. data/test/rails3_root/db/migrate/20090513104502_create_cats.rb +12 -0
  228. data/test/rails3_root/db/seeds.rb +7 -0
  229. data/test/rails3_root/public/404.html +26 -0
  230. data/test/rails3_root/public/422.html +26 -0
  231. data/test/rails3_root/public/500.html +26 -0
  232. data/test/rails3_root/public/favicon.ico +0 -0
  233. data/test/rails3_root/public/images/rails.png +0 -0
  234. data/test/rails3_root/public/index.html +279 -0
  235. data/test/rails3_root/public/javascripts/application.js +2 -0
  236. data/test/rails3_root/public/javascripts/controls.js +965 -0
  237. data/test/rails3_root/public/javascripts/dragdrop.js +974 -0
  238. data/test/rails3_root/public/javascripts/effects.js +1123 -0
  239. data/test/rails3_root/public/javascripts/prototype.js +4874 -0
  240. data/test/rails3_root/public/javascripts/rails.js +118 -0
  241. data/test/rails3_root/public/robots.txt +5 -0
  242. data/test/rails3_root/script/rails +9 -0
  243. data/test/rails3_root/test/performance/browsing_test.rb +9 -0
  244. data/test/rails3_root/test/test_helper.rb +13 -0
  245. data/test/rails3_test_helper.rb +6 -0
  246. data/test/rspec_test.rb +207 -0
  247. data/test/test_helper.rb +36 -0
  248. data/test/unit/address_test.rb +10 -0
  249. data/test/unit/cat_test.rb +7 -0
  250. data/test/unit/dog_test.rb +9 -0
  251. data/test/unit/flea_test.rb +14 -0
  252. data/test/unit/friendship_test.rb +6 -0
  253. data/test/unit/post_test.rb +15 -0
  254. data/test/unit/product_test.rb +23 -0
  255. data/test/unit/tag_test.rb +11 -0
  256. data/test/unit/tagging_test.rb +6 -0
  257. data/test/unit/user_test.rb +46 -0
  258. metadata +330 -0
@@ -0,0 +1,457 @@
1
+ module Shoulda # :nodoc:
2
+ module ActiveRecord # :nodoc:
3
+ # = Macro test helpers for your active record models
4
+ #
5
+ # These helpers will test most of the validations and associations for your ActiveRecord models.
6
+ #
7
+ # class UserTest < Test::Unit::TestCase
8
+ # should_validate_presence_of :name, :phone_number
9
+ # should_not_allow_values_for :phone_number, "abcd", "1234"
10
+ # should_allow_values_for :phone_number, "(123) 456-7890"
11
+ #
12
+ # should_not_allow_mass_assignment_of :password
13
+ #
14
+ # should_have_one :profile
15
+ # should_have_many :dogs
16
+ # should_have_many :messes, :through => :dogs
17
+ # should_belong_to :lover
18
+ # end
19
+ #
20
+ # For all of these helpers, the last parameter may be a hash of options.
21
+ #
22
+ module Macros
23
+ include Helpers
24
+ include Matchers
25
+
26
+ # Deprecated: use ActiveRecord::Matchers#validate_presence_of instead.
27
+ #
28
+ # Ensures that the model cannot be saved if one of the attributes listed is not present.
29
+ #
30
+ # Options:
31
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
32
+ # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.blank')</tt>
33
+ #
34
+ # Example:
35
+ # should_validate_presence_of :name, :phone_number
36
+ #
37
+ def should_validate_presence_of(*attributes)
38
+ ::ActiveSupport::Deprecation.warn("use: should validate_presence_of")
39
+ message = get_options!(attributes, :message)
40
+
41
+ attributes.each do |attribute|
42
+ should validate_presence_of(attribute).with_message(message)
43
+ end
44
+ end
45
+
46
+ # Deprecated: use ActiveRecord::Matchers#validate_uniqueness_of instead.
47
+ #
48
+ # Ensures that the model cannot be saved if one of the attributes listed is not unique.
49
+ # Requires an existing record
50
+ #
51
+ # Options:
52
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
53
+ # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.taken')</tt>
54
+ # * <tt>:scoped_to</tt> - field(s) to scope the uniqueness to.
55
+ # * <tt>:case_sensitive</tt> - whether or not uniqueness is defined by an
56
+ # exact match. Ignored by non-text attributes. Default = <tt>true</tt>
57
+ #
58
+ # Examples:
59
+ # should_validate_uniqueness_of :keyword, :username
60
+ # should_validate_uniqueness_of :name, :message => "O NOES! SOMEONE STOELED YER NAME!"
61
+ # should_validate_uniqueness_of :email, :scoped_to => :name
62
+ # should_validate_uniqueness_of :address, :scoped_to => [:first_name, :last_name]
63
+ # should_validate_uniqueness_of :email, :case_sensitive => false
64
+ #
65
+ def should_validate_uniqueness_of(*attributes)
66
+ ::ActiveSupport::Deprecation.warn("use: should validate_uniqueness_of")
67
+ message, scope, case_sensitive = get_options!(attributes, :message, :scoped_to, :case_sensitive)
68
+ scope = [*scope].compact
69
+ case_sensitive = true if case_sensitive.nil?
70
+
71
+ attributes.each do |attribute|
72
+ matcher = validate_uniqueness_of(attribute).
73
+ with_message(message).scoped_to(scope)
74
+ matcher = matcher.case_insensitive unless case_sensitive
75
+ should matcher
76
+ end
77
+ end
78
+
79
+ # Deprecated: use ActiveRecord::Matchers#allow_mass_assignment_of instead.
80
+ #
81
+ # Ensures that the attribute can be set on mass update.
82
+ #
83
+ # should_allow_mass_assignment_of :first_name, :last_name
84
+ #
85
+ def should_allow_mass_assignment_of(*attributes)
86
+ ::ActiveSupport::Deprecation.warn("use: should allow_mass_assignment_of")
87
+ get_options!(attributes)
88
+
89
+ attributes.each do |attribute|
90
+ should allow_mass_assignment_of(attribute)
91
+ end
92
+ end
93
+
94
+ # Deprecated: use ActiveRecord::Matchers#allow_mass_assignment_of instead.
95
+ #
96
+ # Ensures that the attribute cannot be set on mass update.
97
+ #
98
+ # should_not_allow_mass_assignment_of :password, :admin_flag
99
+ #
100
+ def should_not_allow_mass_assignment_of(*attributes)
101
+ ::ActiveSupport::Deprecation.warn("use: should_not allow_mass_assignment_of")
102
+ get_options!(attributes)
103
+
104
+ attributes.each do |attribute|
105
+ should_not allow_mass_assignment_of(attribute)
106
+ end
107
+ end
108
+
109
+ # Deprecated: use ActiveRecord::Matchers#have_readonly_attribute instead.
110
+ #
111
+ # Ensures that the attribute cannot be changed once the record has been created.
112
+ #
113
+ # should_have_readonly_attributes :password, :admin_flag
114
+ #
115
+ def should_have_readonly_attributes(*attributes)
116
+ ::ActiveSupport::Deprecation.warn("use: should have_readonly_attribute")
117
+ get_options!(attributes)
118
+
119
+ attributes.each do |attribute|
120
+ should have_readonly_attribute(attribute)
121
+ end
122
+ end
123
+
124
+ # Deprecated: use ActiveRecord::Matchers#allow_value instead.
125
+ #
126
+ # Ensures that the attribute cannot be set to the given values
127
+ #
128
+ # Options:
129
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
130
+ # Regexp or string. If omitted, the test will pass if there is ANY error in
131
+ # <tt>errors.on(:attribute)</tt>.
132
+ #
133
+ # Example:
134
+ # should_not_allow_values_for :isbn, "bad 1", "bad 2"
135
+ #
136
+ def should_not_allow_values_for(attribute, *bad_values)
137
+ ::ActiveSupport::Deprecation.warn("use: should_not allow_value")
138
+ message = get_options!(bad_values, :message)
139
+ bad_values.each do |value|
140
+ should_not allow_value(value).for(attribute).with_message(message)
141
+ end
142
+ end
143
+
144
+ # Deprecated: use ActiveRecord::Matchers#allow_value instead.
145
+ #
146
+ # Ensures that the attribute can be set to the given values.
147
+ #
148
+ # Example:
149
+ # should_allow_values_for :isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0"
150
+ #
151
+ def should_allow_values_for(attribute, *good_values)
152
+ ::ActiveSupport::Deprecation.warn("use: should allow_value")
153
+ get_options!(good_values)
154
+ good_values.each do |value|
155
+ should allow_value(value).for(attribute)
156
+ end
157
+ end
158
+
159
+ # Deprecated: use ActiveRecord::Matchers#ensure_length_of instead.
160
+ #
161
+ # Ensures that the length of the attribute is in the given range
162
+ #
163
+ # Options:
164
+ # * <tt>:short_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
165
+ # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.too_short') % range.first</tt>
166
+ # * <tt>:long_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
167
+ # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.too_long') % range.last</tt>
168
+ #
169
+ # Example:
170
+ # should_ensure_length_in_range :password, (6..20)
171
+ #
172
+ def should_ensure_length_in_range(attribute, range, opts = {})
173
+ ::ActiveSupport::Deprecation.warn("use: should ensure_length_of.is_at_least.is_at_most")
174
+ short_message, long_message = get_options!([opts],
175
+ :short_message,
176
+ :long_message)
177
+ should ensure_length_of(attribute).
178
+ is_at_least(range.first).
179
+ with_short_message(short_message).
180
+ is_at_most(range.last).
181
+ with_long_message(long_message)
182
+ end
183
+
184
+ # Deprecated: use ActiveRecord::Matchers#ensure_length_of instead.
185
+ #
186
+ # Ensures that the length of the attribute is at least a certain length
187
+ #
188
+ # Options:
189
+ # * <tt>:short_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
190
+ # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.too_short') % min_length</tt>
191
+ #
192
+ # Example:
193
+ # should_ensure_length_at_least :name, 3
194
+ #
195
+ def should_ensure_length_at_least(attribute, min_length, opts = {})
196
+ ::ActiveSupport::Deprecation.warn("use: should ensure_length_of.is_at_least")
197
+ short_message = get_options!([opts], :short_message)
198
+
199
+ should ensure_length_of(attribute).
200
+ is_at_least(min_length).
201
+ with_short_message(short_message)
202
+ end
203
+
204
+ # Deprecated: use ActiveRecord::Matchers#ensure_length_of instead.
205
+ #
206
+ # Ensures that the length of the attribute is exactly a certain length
207
+ #
208
+ # Options:
209
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
210
+ # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.wrong_length') % length</tt>
211
+ #
212
+ # Example:
213
+ # should_ensure_length_is :ssn, 9
214
+ #
215
+ def should_ensure_length_is(attribute, length, opts = {})
216
+ ::ActiveSupport::Deprecation.warn("use: should ensure_length_of.is_equal_to")
217
+ message = get_options!([opts], :message)
218
+ should ensure_length_of(attribute).
219
+ is_equal_to(length).
220
+ with_message(message)
221
+ end
222
+
223
+ # Deprecated: use ActiveRecord::Matchers#ensure_inclusion_of instead.
224
+ #
225
+ # Ensure that the attribute is in the range specified
226
+ #
227
+ # Options:
228
+ # * <tt>:low_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
229
+ # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.inclusion')</tt>
230
+ # * <tt>:high_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
231
+ # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.inclusion')</tt>
232
+ #
233
+ # Example:
234
+ # should_ensure_value_in_range :age, (0..100)
235
+ #
236
+ def should_ensure_value_in_range(attribute, range, opts = {})
237
+ ::ActiveSupport::Deprecation.warn("use: should ensure_inclusion_of.in_range")
238
+ message, low_message, high_message = get_options!([opts],
239
+ :message,
240
+ :low_message,
241
+ :high_message)
242
+ should ensure_inclusion_of(attribute).
243
+ in_range(range).
244
+ with_message(message).
245
+ with_low_message(low_message).
246
+ with_high_message(high_message)
247
+ end
248
+
249
+ # Deprecated: use ActiveRecord::Matchers#validate_numericality_of instead.
250
+ #
251
+ # Ensure that the attribute is numeric
252
+ #
253
+ # Options:
254
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
255
+ # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.not_a_number')</tt>
256
+ #
257
+ # Example:
258
+ # should_validate_numericality_of :age
259
+ #
260
+ def should_validate_numericality_of(*attributes)
261
+ ::ActiveSupport::Deprecation.warn("use: should validate_numericality_of")
262
+ message = get_options!(attributes, :message)
263
+ attributes.each do |attribute|
264
+ should validate_numericality_of(attribute).
265
+ with_message(message)
266
+ end
267
+ end
268
+
269
+ # Deprecated: use ActiveRecord::Matchers#have_many instead.
270
+ #
271
+ # Ensures that the has_many relationship exists. Will also test that the
272
+ # associated table has the required columns. Works with polymorphic
273
+ # associations.
274
+ #
275
+ # Options:
276
+ # * <tt>:through</tt> - association name for <tt>has_many :through</tt>
277
+ # * <tt>:dependent</tt> - tests that the association makes use of the dependent option.
278
+ #
279
+ # Example:
280
+ # should_have_many :friends
281
+ # should_have_many :enemies, :through => :friends
282
+ # should_have_many :enemies, :dependent => :destroy
283
+ #
284
+ def should_have_many(*associations)
285
+ ::ActiveSupport::Deprecation.warn("use: should have_many")
286
+ through, dependent = get_options!(associations, :through, :dependent)
287
+ associations.each do |association|
288
+ should have_many(association).through(through).dependent(dependent)
289
+ end
290
+ end
291
+
292
+ # Deprecated: use ActiveRecord::Matchers#have_one instead.
293
+ #
294
+ # Ensure that the has_one relationship exists. Will also test that the
295
+ # associated table has the required columns. Works with polymorphic
296
+ # associations.
297
+ #
298
+ # Options:
299
+ # * <tt>:dependent</tt> - tests that the association makes use of the dependent option.
300
+ #
301
+ # Example:
302
+ # should_have_one :god # unless hindu
303
+ #
304
+ def should_have_one(*associations)
305
+ ::ActiveSupport::Deprecation.warn("use: should have_one")
306
+ dependent, through = get_options!(associations, :dependent, :through)
307
+ associations.each do |association|
308
+ should have_one(association).dependent(dependent).through(through)
309
+ end
310
+ end
311
+
312
+ # Deprecated: use ActiveRecord::Matchers#have_and_belong_to_many instead.
313
+ #
314
+ # Ensures that the has_and_belongs_to_many relationship exists, and that the join
315
+ # table is in place.
316
+ #
317
+ # should_have_and_belong_to_many :posts, :cars
318
+ #
319
+ def should_have_and_belong_to_many(*associations)
320
+ ::ActiveSupport::Deprecation.warn("use: should have_and_belong_to_many")
321
+ get_options!(associations)
322
+
323
+ associations.each do |association|
324
+ should have_and_belong_to_many(association)
325
+ end
326
+ end
327
+
328
+ # Deprecated: use ActiveRecord::Matchers#belong_to instead.
329
+ #
330
+ # Ensure that the belongs_to relationship exists.
331
+ #
332
+ # should_belong_to :parent
333
+ #
334
+ def should_belong_to(*associations)
335
+ ::ActiveSupport::Deprecation.warn("use: should belong_to")
336
+ dependent = get_options!(associations, :dependent)
337
+ associations.each do |association|
338
+ should belong_to(association).dependent(dependent)
339
+ end
340
+ end
341
+
342
+ # Deprecated.
343
+ #
344
+ # Ensure that the given class methods are defined on the model.
345
+ #
346
+ # should_have_class_methods :find, :destroy
347
+ #
348
+ def should_have_class_methods(*methods)
349
+ ::ActiveSupport::Deprecation.warn
350
+ get_options!(methods)
351
+ klass = described_type
352
+ methods.each do |method|
353
+ should "respond to class method ##{method}" do
354
+ assert_respond_to klass, method, "#{klass.name} does not have class method #{method}"
355
+ end
356
+ end
357
+ end
358
+
359
+ # Deprecated.
360
+ #
361
+ # Ensure that the given instance methods are defined on the model.
362
+ #
363
+ # should_have_instance_methods :email, :name, :name=
364
+ #
365
+ def should_have_instance_methods(*methods)
366
+ ::ActiveSupport::Deprecation.warn
367
+ get_options!(methods)
368
+ klass = described_type
369
+ methods.each do |method|
370
+ should "respond to instance method ##{method}" do
371
+ assert_respond_to klass.new, method, "#{klass.name} does not have instance method #{method}"
372
+ end
373
+ end
374
+ end
375
+
376
+ # Deprecated: use ActiveRecord::Matchers#have_db_column instead.
377
+ #
378
+ # Ensure that the given columns are defined on the models backing SQL table.
379
+ # Also aliased to should_have_db_column for readability.
380
+ # Takes the same options available in migrations:
381
+ # :type, :precision, :limit, :default, :null, and :scale
382
+ #
383
+ # Examples:
384
+ #
385
+ # should_have_db_columns :id, :email, :name, :created_at
386
+ #
387
+ # should_have_db_column :email, :type => "string", :limit => 255
388
+ # should_have_db_column :salary, :decimal, :precision => 15, :scale => 2
389
+ # should_have_db_column :admin, :default => false, :null => false
390
+ #
391
+ def should_have_db_columns(*columns)
392
+ ::ActiveSupport::Deprecation.warn("use: should have_db_column")
393
+ column_type, precision, limit, default, null, scale, sql_type =
394
+ get_options!(columns, :type, :precision, :limit,
395
+ :default, :null, :scale, :sql_type)
396
+ columns.each do |name|
397
+ should have_db_column(name).
398
+ of_type(column_type).
399
+ with_options(:precision => precision, :limit => limit,
400
+ :default => default, :null => null,
401
+ :scale => scale, :sql_type => sql_type)
402
+ end
403
+ end
404
+
405
+ alias_method :should_have_db_column, :should_have_db_columns
406
+
407
+ # Deprecated: use ActiveRecord::Matchers#have_db_index instead.
408
+ #
409
+ # Ensures that there are DB indices on the given columns or tuples of columns.
410
+ # Also aliased to should_have_db_index for readability
411
+ #
412
+ # Options:
413
+ # * <tt>:unique</tt> - whether or not the index has a unique
414
+ # constraint. Use <tt>true</tt> to explicitly test for a unique
415
+ # constraint. Use <tt>false</tt> to explicitly test for a non-unique
416
+ # constraint. Use <tt>nil</tt> if you don't care whether the index is
417
+ # unique or not. Default = <tt>nil</tt>
418
+ #
419
+ # Examples:
420
+ #
421
+ # should_have_db_indices :email, :name, [:commentable_type, :commentable_id]
422
+ # should_have_db_index :age
423
+ # should_have_db_index :ssn, :unique => true
424
+ #
425
+ def should_have_db_indices(*columns)
426
+ ::ActiveSupport::Deprecation.warn("use: should have_db_index")
427
+ unique = get_options!(columns, :unique)
428
+
429
+ columns.each do |column|
430
+ should have_db_index(column).unique(unique)
431
+ end
432
+ end
433
+
434
+ alias_method :should_have_db_index, :should_have_db_indices
435
+
436
+ # Deprecated: use ActiveRecord::Matchers#validate_acceptance_of instead.
437
+ #
438
+ # Ensures that the model cannot be saved if one of the attributes listed is not accepted.
439
+ #
440
+ # Options:
441
+ # * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
442
+ # Regexp or string. Default = <tt>I18n.translate('activerecord.errors.messages.accepted')</tt>
443
+ #
444
+ # Example:
445
+ # should_validate_acceptance_of :eula
446
+ #
447
+ def should_validate_acceptance_of(*attributes)
448
+ ::ActiveSupport::Deprecation.warn("use: should validate_acceptance_of")
449
+ message = get_options!(attributes, :message)
450
+
451
+ attributes.each do |attribute|
452
+ should validate_acceptance_of(attribute).with_message(message)
453
+ end
454
+ end
455
+ end
456
+ end
457
+ end
@@ -0,0 +1,83 @@
1
+ module Shoulda # :nodoc:
2
+ module ActiveRecord # :nodoc:
3
+ module Matchers
4
+
5
+ # Ensures that the attribute can be set on mass update.
6
+ #
7
+ # it { should_not allow_mass_assignment_of(:password) }
8
+ # it { should allow_mass_assignment_of(:first_name) }
9
+ #
10
+ def allow_mass_assignment_of(value)
11
+ AllowMassAssignmentOfMatcher.new(value)
12
+ end
13
+
14
+ class AllowMassAssignmentOfMatcher # :nodoc:
15
+
16
+ def initialize(attribute)
17
+ @attribute = attribute.to_s
18
+ end
19
+
20
+ def matches?(subject)
21
+ @subject = subject
22
+ if attr_mass_assignable?
23
+ if whitelisting?
24
+ @failure_message = "#{@attribute} was made accessible"
25
+ else
26
+ if protected_attributes.empty?
27
+ @negative_failure_message = "no attributes were protected"
28
+ else
29
+ @failure_message = "#{class_name} is protecting " <<
30
+ "#{protected_attributes.to_a.to_sentence}, " <<
31
+ "but not #{@attribute}."
32
+ end
33
+ end
34
+ true
35
+ else
36
+ if whitelisting?
37
+ @negative_failure_message =
38
+ "Expected #{@attribute} to be accessible"
39
+ else
40
+ @negative_failure_message =
41
+ "Did not expect #{@attribute} to be protected"
42
+ end
43
+ false
44
+ end
45
+ end
46
+
47
+ attr_reader :failure_message, :negative_failure_message
48
+
49
+ def description
50
+ "allow mass assignment of #{@attribute}"
51
+ end
52
+
53
+ private
54
+
55
+ def protected_attributes
56
+ @protected_attributes ||= (@subject.class.protected_attributes || [])
57
+ end
58
+
59
+ def accessible_attributes
60
+ @accessible_attributes ||= (@subject.class.accessible_attributes || [])
61
+ end
62
+
63
+ def whitelisting?
64
+ !accessible_attributes.empty?
65
+ end
66
+
67
+ def attr_mass_assignable?
68
+ if whitelisting?
69
+ accessible_attributes.include?(@attribute)
70
+ else
71
+ !protected_attributes.include?(@attribute)
72
+ end
73
+ end
74
+
75
+ def class_name
76
+ @subject.class.name
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,110 @@
1
+ module Shoulda # :nodoc:
2
+ module ActiveRecord # :nodoc:
3
+ module Matchers
4
+
5
+ # Ensures that the attribute can be set to the given value.
6
+ #
7
+ # Options:
8
+ # * <tt>with_message</tt> - value the test expects to find in
9
+ # <tt>errors.on(:attribute)</tt>. Regexp or string. If omitted,
10
+ # the test looks for any errors in <tt>errors.on(:attribute)</tt>.
11
+ #
12
+ # Example:
13
+ # it { should_not allow_value('bad').for(:isbn) }
14
+ # it { should allow_value("isbn 1 2345 6789 0").for(:isbn) }
15
+ #
16
+ def allow_value(value)
17
+ AllowValueMatcher.new(value)
18
+ end
19
+
20
+ class AllowValueMatcher # :nodoc:
21
+ include Helpers
22
+
23
+ def initialize(value)
24
+ @value = value
25
+ end
26
+
27
+ def for(attribute)
28
+ @attribute = attribute
29
+ self
30
+ end
31
+
32
+ def with_message(message)
33
+ @expected_message = message if message
34
+ self
35
+ end
36
+
37
+ def matches?(instance)
38
+ @instance = instance
39
+ if Symbol === @expected_message
40
+ @expected_message = default_error_message(@expected_message)
41
+ end
42
+ @instance.send("#{@attribute}=", @value)
43
+ !errors_match?
44
+ end
45
+
46
+ def failure_message
47
+ "Did not expect #{expectation}, got error: #{@matched_error}"
48
+ end
49
+
50
+ def negative_failure_message
51
+ "Expected #{expectation}, got #{error_description}"
52
+ end
53
+
54
+ def description
55
+ "allow #{@attribute} to be set to #{@value.inspect}"
56
+ end
57
+
58
+ private
59
+
60
+ def errors_match?
61
+ @instance.valid?
62
+ @errors = errors_for_attribute(@instance, @attribute)
63
+ @errors = [@errors] unless @errors.is_a?(Array)
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
73
+ end
74
+
75
+ def errors_match_regexp?
76
+ if Regexp === @expected_message
77
+ @matched_error = @errors.detect { |e| e =~ @expected_message }
78
+ !@matched_error.nil?
79
+ else
80
+ false
81
+ end
82
+ end
83
+
84
+ def errors_match_string?
85
+ if @errors.include?(@expected_message)
86
+ @matched_error = @expected_message
87
+ true
88
+ else
89
+ false
90
+ end
91
+ end
92
+
93
+ def expectation
94
+ "errors " <<
95
+ (@expected_message ? "to include #{@expected_message.inspect} " : "") <<
96
+ "when #{@attribute} is set to #{@value.inspect}"
97
+ end
98
+
99
+ def error_description
100
+ if @instance.errors.empty?
101
+ "no errors"
102
+ else
103
+ "errors: #{pretty_error_messages(@instance)}"
104
+ end
105
+ end
106
+ end
107
+
108
+ end
109
+ end
110
+ end