faster_shoulda 2.11.3

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 (259) 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 +226 -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 +537 -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/hello_should.rb +37 -0
  71. data/test/matchers/action_mailer/have_sent_email_test.rb +76 -0
  72. data/test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb +74 -0
  73. data/test/matchers/active_record/allow_value_matcher_test.rb +64 -0
  74. data/test/matchers/active_record/association_matcher_test.rb +263 -0
  75. data/test/matchers/active_record/ensure_inclusion_of_matcher_test.rb +81 -0
  76. data/test/matchers/active_record/ensure_length_of_matcher_test.rb +158 -0
  77. data/test/matchers/active_record/have_db_column_matcher_test.rb +169 -0
  78. data/test/matchers/active_record/have_db_index_matcher_test.rb +91 -0
  79. data/test/matchers/active_record/have_readonly_attributes_matcher_test.rb +29 -0
  80. data/test/matchers/active_record/validate_acceptance_of_matcher_test.rb +44 -0
  81. data/test/matchers/active_record/validate_format_of_matcher_test.rb +39 -0
  82. data/test/matchers/active_record/validate_numericality_of_matcher_test.rb +52 -0
  83. data/test/matchers/active_record/validate_presence_of_matcher_test.rb +86 -0
  84. data/test/matchers/active_record/validate_uniqueness_of_matcher_test.rb +147 -0
  85. data/test/matchers/controller/assign_to_matcher_test.rb +55 -0
  86. data/test/matchers/controller/filter_param_matcher_test.rb +40 -0
  87. data/test/matchers/controller/redirect_to_matcher_test.rb +37 -0
  88. data/test/matchers/controller/render_template_matcher_test.rb +37 -0
  89. data/test/matchers/controller/render_with_layout_matcher_test.rb +47 -0
  90. data/test/matchers/controller/respond_with_content_type_matcher_test.rb +32 -0
  91. data/test/matchers/controller/respond_with_matcher_test.rb +96 -0
  92. data/test/matchers/controller/route_matcher_test.rb +75 -0
  93. data/test/matchers/controller/set_session_matcher_test.rb +48 -0
  94. data/test/matchers/controller/set_the_flash_matcher.rb +95 -0
  95. data/test/other/autoload_macro_test.rb +18 -0
  96. data/test/other/context_test.rb +372 -0
  97. data/test/other/convert_to_should_syntax_test.rb +63 -0
  98. data/test/other/helpers_test.rb +317 -0
  99. data/test/other/private_helpers_test.rb +32 -0
  100. data/test/other/should_test.rb +271 -0
  101. data/test/rails2_model_builder.rb +130 -0
  102. data/test/rails2_root/app/controllers/application_controller.rb +22 -0
  103. data/test/rails2_root/app/controllers/posts_controller.rb +87 -0
  104. data/test/rails2_root/app/controllers/users_controller.rb +84 -0
  105. data/test/rails2_root/app/helpers/application_helper.rb +3 -0
  106. data/test/rails2_root/app/helpers/posts_helper.rb +2 -0
  107. data/test/rails2_root/app/helpers/users_helper.rb +2 -0
  108. data/test/rails2_root/app/models/address.rb +7 -0
  109. data/test/rails2_root/app/models/flea.rb +11 -0
  110. data/test/rails2_root/app/models/friendship.rb +4 -0
  111. data/test/rails2_root/app/models/notifier.rb +8 -0
  112. data/test/rails2_root/app/models/pets/cat.rb +7 -0
  113. data/test/rails2_root/app/models/pets/dog.rb +10 -0
  114. data/test/rails2_root/app/models/post.rb +12 -0
  115. data/test/rails2_root/app/models/product.rb +12 -0
  116. data/test/rails2_root/app/models/profile.rb +2 -0
  117. data/test/rails2_root/app/models/registration.rb +2 -0
  118. data/test/rails2_root/app/models/tag.rb +8 -0
  119. data/test/rails2_root/app/models/tagging.rb +4 -0
  120. data/test/rails2_root/app/models/treat.rb +3 -0
  121. data/test/rails2_root/app/models/user.rb +32 -0
  122. data/test/rails2_root/app/views/layouts/posts.rhtml +19 -0
  123. data/test/rails2_root/app/views/layouts/users.rhtml +17 -0
  124. data/test/rails2_root/app/views/layouts/wide.html.erb +1 -0
  125. data/test/rails2_root/app/views/notifier/the_email.html.erb +1 -0
  126. data/test/rails2_root/app/views/posts/edit.rhtml +27 -0
  127. data/test/rails2_root/app/views/posts/index.rhtml +25 -0
  128. data/test/rails2_root/app/views/posts/new.rhtml +26 -0
  129. data/test/rails2_root/app/views/posts/show.rhtml +18 -0
  130. data/test/rails2_root/app/views/users/edit.rhtml +22 -0
  131. data/test/rails2_root/app/views/users/index.rhtml +22 -0
  132. data/test/rails2_root/app/views/users/new.rhtml +21 -0
  133. data/test/rails2_root/app/views/users/show.rhtml +13 -0
  134. data/test/rails2_root/config/boot.rb +110 -0
  135. data/test/rails2_root/config/database.yml +4 -0
  136. data/test/rails2_root/config/environment.rb +17 -0
  137. data/test/rails2_root/config/environments/test.rb +23 -0
  138. data/test/rails2_root/config/initializers/new_rails_defaults.rb +15 -0
  139. data/test/rails2_root/config/initializers/shoulda.rb +8 -0
  140. data/test/rails2_root/config/routes.rb +6 -0
  141. data/test/rails2_root/db/migrate/001_create_users.rb +19 -0
  142. data/test/rails2_root/db/migrate/002_create_posts.rb +13 -0
  143. data/test/rails2_root/db/migrate/003_create_taggings.rb +12 -0
  144. data/test/rails2_root/db/migrate/004_create_tags.rb +11 -0
  145. data/test/rails2_root/db/migrate/005_create_dogs.rb +12 -0
  146. data/test/rails2_root/db/migrate/006_create_addresses.rb +14 -0
  147. data/test/rails2_root/db/migrate/007_create_fleas.rb +11 -0
  148. data/test/rails2_root/db/migrate/008_create_dogs_fleas.rb +12 -0
  149. data/test/rails2_root/db/migrate/009_create_products.rb +17 -0
  150. data/test/rails2_root/db/migrate/010_create_friendships.rb +14 -0
  151. data/test/rails2_root/db/migrate/011_create_treats.rb +12 -0
  152. data/test/rails2_root/db/migrate/20090506203502_create_profiles.rb +12 -0
  153. data/test/rails2_root/db/migrate/20090506203536_create_registrations.rb +14 -0
  154. data/test/rails2_root/db/migrate/20090513104502_create_cats.rb +12 -0
  155. data/test/rails2_root/db/schema.rb +0 -0
  156. data/test/rails2_root/public/404.html +30 -0
  157. data/test/rails2_root/public/422.html +30 -0
  158. data/test/rails2_root/public/500.html +30 -0
  159. data/test/rails2_root/script/console +3 -0
  160. data/test/rails2_root/script/generate +3 -0
  161. data/test/rails2_root/test/shoulda_macros/custom_macro.rb +6 -0
  162. data/test/rails2_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +6 -0
  163. data/test/rails2_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +6 -0
  164. data/test/rails2_test_helper.rb +6 -0
  165. data/test/rails3_model_builder.rb +118 -0
  166. data/test/rails3_root/Gemfile +28 -0
  167. data/test/rails3_root/README +244 -0
  168. data/test/rails3_root/Rakefile +10 -0
  169. data/test/rails3_root/app/controllers/application_controller.rb +22 -0
  170. data/test/rails3_root/app/controllers/posts_controller.rb +87 -0
  171. data/test/rails3_root/app/controllers/users_controller.rb +82 -0
  172. data/test/rails3_root/app/helpers/application_helper.rb +2 -0
  173. data/test/rails3_root/app/models/address.rb +7 -0
  174. data/test/rails3_root/app/models/flea.rb +11 -0
  175. data/test/rails3_root/app/models/friendship.rb +4 -0
  176. data/test/rails3_root/app/models/notifier.rb +8 -0
  177. data/test/rails3_root/app/models/pets/cat.rb +7 -0
  178. data/test/rails3_root/app/models/pets/dog.rb +10 -0
  179. data/test/rails3_root/app/models/post.rb +12 -0
  180. data/test/rails3_root/app/models/product.rb +12 -0
  181. data/test/rails3_root/app/models/profile.rb +2 -0
  182. data/test/rails3_root/app/models/registration.rb +2 -0
  183. data/test/rails3_root/app/models/tag.rb +8 -0
  184. data/test/rails3_root/app/models/tagging.rb +4 -0
  185. data/test/rails3_root/app/models/treat.rb +3 -0
  186. data/test/rails3_root/app/models/user.rb +32 -0
  187. data/test/rails3_root/app/views/layouts/application.html.erb +14 -0
  188. data/test/rails3_root/app/views/layouts/posts.rhtml +19 -0
  189. data/test/rails3_root/app/views/layouts/users.rhtml +17 -0
  190. data/test/rails3_root/app/views/layouts/wide.html.erb +1 -0
  191. data/test/rails3_root/app/views/notifier/the_email.html.erb +1 -0
  192. data/test/rails3_root/app/views/posts/edit.rhtml +27 -0
  193. data/test/rails3_root/app/views/posts/index.rhtml +25 -0
  194. data/test/rails3_root/app/views/posts/new.rhtml +24 -0
  195. data/test/rails3_root/app/views/posts/show.rhtml +18 -0
  196. data/test/rails3_root/app/views/users/edit.rhtml +22 -0
  197. data/test/rails3_root/app/views/users/index.rhtml +22 -0
  198. data/test/rails3_root/app/views/users/new.rhtml +21 -0
  199. data/test/rails3_root/app/views/users/show.rhtml +13 -0
  200. data/test/rails3_root/config/application.rb +46 -0
  201. data/test/rails3_root/config/boot.rb +6 -0
  202. data/test/rails3_root/config/database.yml +22 -0
  203. data/test/rails3_root/config/environment.rb +5 -0
  204. data/test/rails3_root/config/environments/development.rb +19 -0
  205. data/test/rails3_root/config/environments/production.rb +42 -0
  206. data/test/rails3_root/config/environments/test.rb +32 -0
  207. data/test/rails3_root/config/initializers/backtrace_silencers.rb +7 -0
  208. data/test/rails3_root/config/initializers/inflections.rb +10 -0
  209. data/test/rails3_root/config/initializers/mime_types.rb +5 -0
  210. data/test/rails3_root/config/initializers/secret_token.rb +7 -0
  211. data/test/rails3_root/config/initializers/session_store.rb +8 -0
  212. data/test/rails3_root/config/locales/en.yml +5 -0
  213. data/test/rails3_root/config/routes.rb +4 -0
  214. data/test/rails3_root/config.ru +4 -0
  215. data/test/rails3_root/db/migrate/001_create_users.rb +19 -0
  216. data/test/rails3_root/db/migrate/002_create_posts.rb +13 -0
  217. data/test/rails3_root/db/migrate/003_create_taggings.rb +12 -0
  218. data/test/rails3_root/db/migrate/004_create_tags.rb +11 -0
  219. data/test/rails3_root/db/migrate/005_create_dogs.rb +12 -0
  220. data/test/rails3_root/db/migrate/006_create_addresses.rb +14 -0
  221. data/test/rails3_root/db/migrate/007_create_fleas.rb +11 -0
  222. data/test/rails3_root/db/migrate/008_create_dogs_fleas.rb +12 -0
  223. data/test/rails3_root/db/migrate/009_create_products.rb +17 -0
  224. data/test/rails3_root/db/migrate/010_create_friendships.rb +14 -0
  225. data/test/rails3_root/db/migrate/011_create_treats.rb +12 -0
  226. data/test/rails3_root/db/migrate/20090506203502_create_profiles.rb +12 -0
  227. data/test/rails3_root/db/migrate/20090506203536_create_registrations.rb +14 -0
  228. data/test/rails3_root/db/migrate/20090513104502_create_cats.rb +12 -0
  229. data/test/rails3_root/db/seeds.rb +7 -0
  230. data/test/rails3_root/public/404.html +26 -0
  231. data/test/rails3_root/public/422.html +26 -0
  232. data/test/rails3_root/public/500.html +26 -0
  233. data/test/rails3_root/public/favicon.ico +0 -0
  234. data/test/rails3_root/public/images/rails.png +0 -0
  235. data/test/rails3_root/public/index.html +279 -0
  236. data/test/rails3_root/public/javascripts/application.js +2 -0
  237. data/test/rails3_root/public/javascripts/controls.js +965 -0
  238. data/test/rails3_root/public/javascripts/dragdrop.js +974 -0
  239. data/test/rails3_root/public/javascripts/effects.js +1123 -0
  240. data/test/rails3_root/public/javascripts/prototype.js +4874 -0
  241. data/test/rails3_root/public/javascripts/rails.js +118 -0
  242. data/test/rails3_root/public/robots.txt +5 -0
  243. data/test/rails3_root/script/rails +9 -0
  244. data/test/rails3_root/test/performance/browsing_test.rb +9 -0
  245. data/test/rails3_root/test/test_helper.rb +13 -0
  246. data/test/rails3_test_helper.rb +6 -0
  247. data/test/rspec_test.rb +207 -0
  248. data/test/test_helper.rb +36 -0
  249. data/test/unit/address_test.rb +10 -0
  250. data/test/unit/cat_test.rb +7 -0
  251. data/test/unit/dog_test.rb +9 -0
  252. data/test/unit/flea_test.rb +14 -0
  253. data/test/unit/friendship_test.rb +6 -0
  254. data/test/unit/post_test.rb +15 -0
  255. data/test/unit/product_test.rb +23 -0
  256. data/test/unit/tag_test.rb +11 -0
  257. data/test/unit/tagging_test.rb +6 -0
  258. data/test/unit/user_test.rb +46 -0
  259. metadata +325 -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