shoulda 2.11.3 → 3.0.0.beta1

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 (262) hide show
  1. data/Gemfile +9 -0
  2. data/Gemfile.lock +108 -0
  3. data/README.md +95 -0
  4. data/Rakefile +6 -50
  5. data/lib/shoulda/version.rb +1 -1
  6. metadata +50 -269
  7. data/README.rdoc +0 -154
  8. data/bin/convert_to_should_syntax +0 -42
  9. data/lib/shoulda.rb +0 -9
  10. data/lib/shoulda/action_controller.rb +0 -34
  11. data/lib/shoulda/action_controller/macros.rb +0 -221
  12. data/lib/shoulda/action_controller/matchers.rb +0 -39
  13. data/lib/shoulda/action_controller/matchers/assign_to_matcher.rb +0 -112
  14. data/lib/shoulda/action_controller/matchers/filter_param_matcher.rb +0 -74
  15. data/lib/shoulda/action_controller/matchers/redirect_to_matcher.rb +0 -62
  16. data/lib/shoulda/action_controller/matchers/render_template_matcher.rb +0 -54
  17. data/lib/shoulda/action_controller/matchers/render_with_layout_matcher.rb +0 -99
  18. data/lib/shoulda/action_controller/matchers/respond_with_content_type_matcher.rb +0 -74
  19. data/lib/shoulda/action_controller/matchers/respond_with_matcher.rb +0 -85
  20. data/lib/shoulda/action_controller/matchers/route_matcher.rb +0 -93
  21. data/lib/shoulda/action_controller/matchers/set_session_matcher.rb +0 -98
  22. data/lib/shoulda/action_controller/matchers/set_the_flash_matcher.rb +0 -100
  23. data/lib/shoulda/action_mailer.rb +0 -13
  24. data/lib/shoulda/action_mailer/assertions.rb +0 -42
  25. data/lib/shoulda/action_mailer/matchers.rb +0 -22
  26. data/lib/shoulda/action_mailer/matchers/have_sent_email.rb +0 -110
  27. data/lib/shoulda/active_record.rb +0 -16
  28. data/lib/shoulda/active_record/assertions.rb +0 -69
  29. data/lib/shoulda/active_record/helpers.rb +0 -32
  30. data/lib/shoulda/active_record/macros.rb +0 -457
  31. data/lib/shoulda/active_record/matchers.rb +0 -42
  32. data/lib/shoulda/active_record/matchers/allow_mass_assignment_of_matcher.rb +0 -83
  33. data/lib/shoulda/active_record/matchers/allow_value_matcher.rb +0 -110
  34. data/lib/shoulda/active_record/matchers/association_matcher.rb +0 -226
  35. data/lib/shoulda/active_record/matchers/ensure_inclusion_of_matcher.rb +0 -87
  36. data/lib/shoulda/active_record/matchers/ensure_length_of_matcher.rb +0 -141
  37. data/lib/shoulda/active_record/matchers/have_db_column_matcher.rb +0 -169
  38. data/lib/shoulda/active_record/matchers/have_db_index_matcher.rb +0 -112
  39. data/lib/shoulda/active_record/matchers/have_readonly_attribute_matcher.rb +0 -59
  40. data/lib/shoulda/active_record/matchers/validate_acceptance_of_matcher.rb +0 -41
  41. data/lib/shoulda/active_record/matchers/validate_format_of_matcher.rb +0 -65
  42. data/lib/shoulda/active_record/matchers/validate_numericality_of_matcher.rb +0 -39
  43. data/lib/shoulda/active_record/matchers/validate_presence_of_matcher.rb +0 -60
  44. data/lib/shoulda/active_record/matchers/validate_uniqueness_of_matcher.rb +0 -148
  45. data/lib/shoulda/active_record/matchers/validation_matcher.rb +0 -56
  46. data/lib/shoulda/assertions.rb +0 -79
  47. data/lib/shoulda/autoload_macros.rb +0 -46
  48. data/lib/shoulda/context.rb +0 -433
  49. data/lib/shoulda/helpers.rb +0 -8
  50. data/lib/shoulda/integrations/rspec.rb +0 -13
  51. data/lib/shoulda/integrations/rspec2.rb +0 -22
  52. data/lib/shoulda/integrations/test_unit.rb +0 -22
  53. data/lib/shoulda/macros.rb +0 -161
  54. data/lib/shoulda/private_helpers.rb +0 -13
  55. data/lib/shoulda/proc_extensions.rb +0 -14
  56. data/lib/shoulda/rails.rb +0 -8
  57. data/lib/shoulda/tasks.rb +0 -3
  58. data/lib/shoulda/tasks/list_tests.rake +0 -29
  59. data/lib/shoulda/tasks/yaml_to_shoulda.rake +0 -28
  60. data/rails/init.rb +0 -8
  61. data/test/README +0 -36
  62. data/test/fail_macros.rb +0 -55
  63. data/test/fixtures/addresses.yml +0 -3
  64. data/test/fixtures/friendships.yml +0 -0
  65. data/test/fixtures/posts.yml +0 -5
  66. data/test/fixtures/products.yml +0 -0
  67. data/test/fixtures/taggings.yml +0 -0
  68. data/test/fixtures/tags.yml +0 -9
  69. data/test/fixtures/users.yml +0 -6
  70. data/test/functional/posts_controller_test.rb +0 -121
  71. data/test/functional/users_controller_test.rb +0 -19
  72. data/test/matchers/action_mailer/have_sent_email_test.rb +0 -70
  73. data/test/matchers/active_record/allow_mass_assignment_of_matcher_test.rb +0 -74
  74. data/test/matchers/active_record/allow_value_matcher_test.rb +0 -64
  75. data/test/matchers/active_record/association_matcher_test.rb +0 -263
  76. data/test/matchers/active_record/ensure_inclusion_of_matcher_test.rb +0 -81
  77. data/test/matchers/active_record/ensure_length_of_matcher_test.rb +0 -158
  78. data/test/matchers/active_record/have_db_column_matcher_test.rb +0 -169
  79. data/test/matchers/active_record/have_db_index_matcher_test.rb +0 -91
  80. data/test/matchers/active_record/have_readonly_attributes_matcher_test.rb +0 -29
  81. data/test/matchers/active_record/validate_acceptance_of_matcher_test.rb +0 -44
  82. data/test/matchers/active_record/validate_format_of_matcher_test.rb +0 -39
  83. data/test/matchers/active_record/validate_numericality_of_matcher_test.rb +0 -52
  84. data/test/matchers/active_record/validate_presence_of_matcher_test.rb +0 -86
  85. data/test/matchers/active_record/validate_uniqueness_of_matcher_test.rb +0 -147
  86. data/test/matchers/controller/assign_to_matcher_test.rb +0 -45
  87. data/test/matchers/controller/filter_param_matcher_test.rb +0 -40
  88. data/test/matchers/controller/redirect_to_matcher_test.rb +0 -37
  89. data/test/matchers/controller/render_template_matcher_test.rb +0 -37
  90. data/test/matchers/controller/render_with_layout_matcher_test.rb +0 -47
  91. data/test/matchers/controller/respond_with_content_type_matcher_test.rb +0 -32
  92. data/test/matchers/controller/respond_with_matcher_test.rb +0 -96
  93. data/test/matchers/controller/route_matcher_test.rb +0 -75
  94. data/test/matchers/controller/set_session_matcher_test.rb +0 -48
  95. data/test/matchers/controller/set_the_flash_matcher.rb +0 -95
  96. data/test/other/autoload_macro_test.rb +0 -18
  97. data/test/other/context_test.rb +0 -372
  98. data/test/other/convert_to_should_syntax_test.rb +0 -63
  99. data/test/other/helpers_test.rb +0 -317
  100. data/test/other/private_helpers_test.rb +0 -32
  101. data/test/other/should_test.rb +0 -271
  102. data/test/rails2_model_builder.rb +0 -130
  103. data/test/rails2_root/app/controllers/application_controller.rb +0 -22
  104. data/test/rails2_root/app/controllers/posts_controller.rb +0 -87
  105. data/test/rails2_root/app/controllers/users_controller.rb +0 -84
  106. data/test/rails2_root/app/helpers/application_helper.rb +0 -3
  107. data/test/rails2_root/app/helpers/posts_helper.rb +0 -2
  108. data/test/rails2_root/app/helpers/users_helper.rb +0 -2
  109. data/test/rails2_root/app/models/address.rb +0 -7
  110. data/test/rails2_root/app/models/flea.rb +0 -11
  111. data/test/rails2_root/app/models/friendship.rb +0 -4
  112. data/test/rails2_root/app/models/notifier.rb +0 -8
  113. data/test/rails2_root/app/models/pets/cat.rb +0 -7
  114. data/test/rails2_root/app/models/pets/dog.rb +0 -10
  115. data/test/rails2_root/app/models/post.rb +0 -12
  116. data/test/rails2_root/app/models/product.rb +0 -12
  117. data/test/rails2_root/app/models/profile.rb +0 -2
  118. data/test/rails2_root/app/models/registration.rb +0 -2
  119. data/test/rails2_root/app/models/tag.rb +0 -8
  120. data/test/rails2_root/app/models/tagging.rb +0 -4
  121. data/test/rails2_root/app/models/treat.rb +0 -3
  122. data/test/rails2_root/app/models/user.rb +0 -32
  123. data/test/rails2_root/app/views/layouts/posts.rhtml +0 -19
  124. data/test/rails2_root/app/views/layouts/users.rhtml +0 -17
  125. data/test/rails2_root/app/views/layouts/wide.html.erb +0 -1
  126. data/test/rails2_root/app/views/notifier/the_email.html.erb +0 -1
  127. data/test/rails2_root/app/views/posts/edit.rhtml +0 -27
  128. data/test/rails2_root/app/views/posts/index.rhtml +0 -25
  129. data/test/rails2_root/app/views/posts/new.rhtml +0 -26
  130. data/test/rails2_root/app/views/posts/show.rhtml +0 -18
  131. data/test/rails2_root/app/views/users/edit.rhtml +0 -22
  132. data/test/rails2_root/app/views/users/index.rhtml +0 -22
  133. data/test/rails2_root/app/views/users/new.rhtml +0 -21
  134. data/test/rails2_root/app/views/users/show.rhtml +0 -13
  135. data/test/rails2_root/config/boot.rb +0 -110
  136. data/test/rails2_root/config/database.yml +0 -4
  137. data/test/rails2_root/config/environment.rb +0 -17
  138. data/test/rails2_root/config/environments/test.rb +0 -23
  139. data/test/rails2_root/config/initializers/new_rails_defaults.rb +0 -15
  140. data/test/rails2_root/config/initializers/shoulda.rb +0 -8
  141. data/test/rails2_root/config/routes.rb +0 -6
  142. data/test/rails2_root/db/migrate/001_create_users.rb +0 -19
  143. data/test/rails2_root/db/migrate/002_create_posts.rb +0 -13
  144. data/test/rails2_root/db/migrate/003_create_taggings.rb +0 -12
  145. data/test/rails2_root/db/migrate/004_create_tags.rb +0 -11
  146. data/test/rails2_root/db/migrate/005_create_dogs.rb +0 -12
  147. data/test/rails2_root/db/migrate/006_create_addresses.rb +0 -14
  148. data/test/rails2_root/db/migrate/007_create_fleas.rb +0 -11
  149. data/test/rails2_root/db/migrate/008_create_dogs_fleas.rb +0 -12
  150. data/test/rails2_root/db/migrate/009_create_products.rb +0 -17
  151. data/test/rails2_root/db/migrate/010_create_friendships.rb +0 -14
  152. data/test/rails2_root/db/migrate/011_create_treats.rb +0 -12
  153. data/test/rails2_root/db/migrate/20090506203502_create_profiles.rb +0 -12
  154. data/test/rails2_root/db/migrate/20090506203536_create_registrations.rb +0 -14
  155. data/test/rails2_root/db/migrate/20090513104502_create_cats.rb +0 -12
  156. data/test/rails2_root/db/schema.rb +0 -0
  157. data/test/rails2_root/log/test.log +0 -50381
  158. data/test/rails2_root/public/404.html +0 -30
  159. data/test/rails2_root/public/422.html +0 -30
  160. data/test/rails2_root/public/500.html +0 -30
  161. data/test/rails2_root/script/console +0 -3
  162. data/test/rails2_root/script/generate +0 -3
  163. data/test/rails2_root/test/shoulda_macros/custom_macro.rb +0 -6
  164. data/test/rails2_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +0 -6
  165. data/test/rails2_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +0 -6
  166. data/test/rails2_test_helper.rb +0 -6
  167. data/test/rails3_model_builder.rb +0 -118
  168. data/test/rails3_root/Gemfile +0 -28
  169. data/test/rails3_root/README +0 -244
  170. data/test/rails3_root/Rakefile +0 -10
  171. data/test/rails3_root/app/controllers/application_controller.rb +0 -22
  172. data/test/rails3_root/app/controllers/posts_controller.rb +0 -87
  173. data/test/rails3_root/app/controllers/users_controller.rb +0 -82
  174. data/test/rails3_root/app/helpers/application_helper.rb +0 -2
  175. data/test/rails3_root/app/models/address.rb +0 -7
  176. data/test/rails3_root/app/models/flea.rb +0 -11
  177. data/test/rails3_root/app/models/friendship.rb +0 -4
  178. data/test/rails3_root/app/models/notifier.rb +0 -8
  179. data/test/rails3_root/app/models/pets/cat.rb +0 -7
  180. data/test/rails3_root/app/models/pets/dog.rb +0 -10
  181. data/test/rails3_root/app/models/post.rb +0 -12
  182. data/test/rails3_root/app/models/product.rb +0 -12
  183. data/test/rails3_root/app/models/profile.rb +0 -2
  184. data/test/rails3_root/app/models/registration.rb +0 -2
  185. data/test/rails3_root/app/models/tag.rb +0 -8
  186. data/test/rails3_root/app/models/tagging.rb +0 -4
  187. data/test/rails3_root/app/models/treat.rb +0 -3
  188. data/test/rails3_root/app/models/user.rb +0 -32
  189. data/test/rails3_root/app/views/layouts/application.html.erb +0 -14
  190. data/test/rails3_root/app/views/layouts/posts.rhtml +0 -19
  191. data/test/rails3_root/app/views/layouts/users.rhtml +0 -17
  192. data/test/rails3_root/app/views/layouts/wide.html.erb +0 -1
  193. data/test/rails3_root/app/views/notifier/the_email.html.erb +0 -1
  194. data/test/rails3_root/app/views/posts/edit.rhtml +0 -27
  195. data/test/rails3_root/app/views/posts/index.rhtml +0 -25
  196. data/test/rails3_root/app/views/posts/new.rhtml +0 -24
  197. data/test/rails3_root/app/views/posts/show.rhtml +0 -18
  198. data/test/rails3_root/app/views/users/edit.rhtml +0 -22
  199. data/test/rails3_root/app/views/users/index.rhtml +0 -22
  200. data/test/rails3_root/app/views/users/new.rhtml +0 -21
  201. data/test/rails3_root/app/views/users/show.rhtml +0 -13
  202. data/test/rails3_root/config.ru +0 -4
  203. data/test/rails3_root/config/application.rb +0 -46
  204. data/test/rails3_root/config/boot.rb +0 -6
  205. data/test/rails3_root/config/database.yml +0 -22
  206. data/test/rails3_root/config/environment.rb +0 -5
  207. data/test/rails3_root/config/environments/development.rb +0 -19
  208. data/test/rails3_root/config/environments/production.rb +0 -42
  209. data/test/rails3_root/config/environments/test.rb +0 -32
  210. data/test/rails3_root/config/initializers/backtrace_silencers.rb +0 -7
  211. data/test/rails3_root/config/initializers/inflections.rb +0 -10
  212. data/test/rails3_root/config/initializers/mime_types.rb +0 -5
  213. data/test/rails3_root/config/initializers/secret_token.rb +0 -7
  214. data/test/rails3_root/config/initializers/session_store.rb +0 -8
  215. data/test/rails3_root/config/locales/en.yml +0 -5
  216. data/test/rails3_root/config/routes.rb +0 -4
  217. data/test/rails3_root/db/migrate/001_create_users.rb +0 -19
  218. data/test/rails3_root/db/migrate/002_create_posts.rb +0 -13
  219. data/test/rails3_root/db/migrate/003_create_taggings.rb +0 -12
  220. data/test/rails3_root/db/migrate/004_create_tags.rb +0 -11
  221. data/test/rails3_root/db/migrate/005_create_dogs.rb +0 -12
  222. data/test/rails3_root/db/migrate/006_create_addresses.rb +0 -14
  223. data/test/rails3_root/db/migrate/007_create_fleas.rb +0 -11
  224. data/test/rails3_root/db/migrate/008_create_dogs_fleas.rb +0 -12
  225. data/test/rails3_root/db/migrate/009_create_products.rb +0 -17
  226. data/test/rails3_root/db/migrate/010_create_friendships.rb +0 -14
  227. data/test/rails3_root/db/migrate/011_create_treats.rb +0 -12
  228. data/test/rails3_root/db/migrate/20090506203502_create_profiles.rb +0 -12
  229. data/test/rails3_root/db/migrate/20090506203536_create_registrations.rb +0 -14
  230. data/test/rails3_root/db/migrate/20090513104502_create_cats.rb +0 -12
  231. data/test/rails3_root/db/seeds.rb +0 -7
  232. data/test/rails3_root/db/test.sqlite3 +0 -0
  233. data/test/rails3_root/log/test.log +0 -10834
  234. data/test/rails3_root/public/404.html +0 -26
  235. data/test/rails3_root/public/422.html +0 -26
  236. data/test/rails3_root/public/500.html +0 -26
  237. data/test/rails3_root/public/favicon.ico +0 -0
  238. data/test/rails3_root/public/images/rails.png +0 -0
  239. data/test/rails3_root/public/index.html +0 -279
  240. data/test/rails3_root/public/javascripts/application.js +0 -2
  241. data/test/rails3_root/public/javascripts/controls.js +0 -965
  242. data/test/rails3_root/public/javascripts/dragdrop.js +0 -974
  243. data/test/rails3_root/public/javascripts/effects.js +0 -1123
  244. data/test/rails3_root/public/javascripts/prototype.js +0 -4874
  245. data/test/rails3_root/public/javascripts/rails.js +0 -118
  246. data/test/rails3_root/public/robots.txt +0 -5
  247. data/test/rails3_root/script/rails +0 -9
  248. data/test/rails3_root/test/performance/browsing_test.rb +0 -9
  249. data/test/rails3_root/test/test_helper.rb +0 -13
  250. data/test/rails3_test_helper.rb +0 -6
  251. data/test/rspec_test.rb +0 -207
  252. data/test/test_helper.rb +0 -36
  253. data/test/unit/address_test.rb +0 -10
  254. data/test/unit/cat_test.rb +0 -7
  255. data/test/unit/dog_test.rb +0 -9
  256. data/test/unit/flea_test.rb +0 -14
  257. data/test/unit/friendship_test.rb +0 -6
  258. data/test/unit/post_test.rb +0 -15
  259. data/test/unit/product_test.rb +0 -23
  260. data/test/unit/tag_test.rb +0 -11
  261. data/test/unit/tagging_test.rb +0 -6
  262. data/test/unit/user_test.rb +0 -46
@@ -1,59 +0,0 @@
1
- module Shoulda # :nodoc:
2
- module ActiveRecord # :nodoc:
3
- module Matchers
4
-
5
- # Ensures that the attribute cannot be changed once the record has been
6
- # created.
7
- #
8
- # it { should have_readonly_attributes(:password) }
9
- #
10
- def have_readonly_attribute(value)
11
- HaveReadonlyAttributeMatcher.new(value)
12
- end
13
-
14
- class HaveReadonlyAttributeMatcher # :nodoc:
15
-
16
- def initialize(attribute)
17
- @attribute = attribute.to_s
18
- end
19
-
20
- def matches?(subject)
21
- @subject = subject
22
- if readonly_attributes.include?(@attribute)
23
- @negative_failure_message =
24
- "Did not expect #{@attribute} to be read-only"
25
- true
26
- else
27
- if readonly_attributes.empty?
28
- @failure_message = "#{class_name} attribute #{@attribute} " <<
29
- "is not read-only"
30
- else
31
- @failure_message = "#{class_name} is making " <<
32
- "#{readonly_attributes.to_sentence} " <<
33
- "read-only, but not #{@attribute}."
34
- end
35
- false
36
- end
37
- end
38
-
39
- attr_reader :failure_message, :negative_failure_message
40
-
41
- def description
42
- "make #{@attribute} read-only"
43
- end
44
-
45
- private
46
-
47
- def readonly_attributes
48
- @readonly_attributes ||= (@subject.class.readonly_attributes || [])
49
- end
50
-
51
- def class_name
52
- @subject.class.name
53
- end
54
-
55
- end
56
-
57
- end
58
- end
59
- end
@@ -1,41 +0,0 @@
1
- module Shoulda # :nodoc:
2
- module ActiveRecord # :nodoc:
3
- module Matchers
4
-
5
- # Ensures that the model cannot be saved the given attribute is not
6
- # accepted.
7
- #
8
- # Options:
9
- # * <tt>with_message</tt> - value the test expects to find in
10
- # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
11
- # translation for <tt>:accepted</tt>.
12
- #
13
- # Example:
14
- # it { should validate_acceptance_of(:eula) }
15
- #
16
- def validate_acceptance_of(attr)
17
- ValidateAcceptanceOfMatcher.new(attr)
18
- end
19
-
20
- class ValidateAcceptanceOfMatcher < ValidationMatcher # :nodoc:
21
-
22
- def with_message(message)
23
- @expected_message = message if message
24
- self
25
- end
26
-
27
- def matches?(subject)
28
- super(subject)
29
- @expected_message ||= :accepted
30
- disallows_value_of(false, @expected_message)
31
- end
32
-
33
- def description
34
- "require #{@attribute} to be accepted"
35
- end
36
-
37
- end
38
-
39
- end
40
- end
41
- end
@@ -1,65 +0,0 @@
1
- module Shoulda # :nodoc:
2
- module ActiveRecord # :nodoc:
3
- module Matchers
4
-
5
- # Ensures that the model is not valid if the given attribute is not
6
- # formatted correctly.
7
- #
8
- # Options:
9
- # * <tt>with_message</tt> - value the test expects to find in
10
- # <tt>errors.on(:attribute)</tt>. <tt>Regexp</tt> or <tt>String</tt>.
11
- # Defaults to the translation for <tt>:blank</tt>.
12
- # * <tt>with(string to test against)</tt>
13
- # * <tt>not_with(string to test against)</tt>
14
- #
15
- # Examples:
16
- # it { should validate_format_of(:name).
17
- # with('12345').
18
- # with_message(/is not optional/) }
19
- # it { should validate_format_of(:name).
20
- # not_with('12D45').
21
- # with_message(/is not optional/) }
22
- #
23
- def validate_format_of(attr)
24
- ValidateFormatOfMatcher.new(attr)
25
- end
26
-
27
- class ValidateFormatOfMatcher < ValidationMatcher # :nodoc:
28
-
29
- def initialize(attribute)
30
- super
31
- end
32
-
33
- def with_message(message)
34
- @expected_message = message if message
35
- self
36
- end
37
-
38
- def with(value)
39
- raise "You may not call both with and not_with" if @value_to_fail
40
- @value_to_pass = value
41
- self
42
- end
43
-
44
- def not_with(value)
45
- raise "You may not call both with and not_with" if @value_to_pass
46
- @value_to_fail = value
47
- self
48
- end
49
-
50
- def matches?(subject)
51
- super(subject)
52
- @expected_message ||= :blank
53
- return disallows_value_of(@value_to_fail, @expected_message) if @value_to_fail
54
- allows_value_of(@value_to_pass, @expected_message) if @value_to_pass
55
- end
56
-
57
- def description
58
- "#{@attribute} have a valid format"
59
- end
60
-
61
- end
62
-
63
- end
64
- end
65
- end
@@ -1,39 +0,0 @@
1
- module Shoulda # :nodoc:
2
- module ActiveRecord # :nodoc:
3
- module Matchers
4
-
5
- # Ensure that the attribute is numeric
6
- #
7
- # Options:
8
- # * <tt>with_message</tt> - value the test expects to find in
9
- # <tt>errors.on(:attribute)</tt>. Regexp or string. Defaults to the
10
- # translation for <tt>:not_a_number</tt>.
11
- #
12
- # Example:
13
- # it { should validate_numericality_of(:age) }
14
- #
15
- def validate_numericality_of(attr)
16
- ValidateNumericalityOfMatcher.new(attr)
17
- end
18
-
19
- class ValidateNumericalityOfMatcher < ValidationMatcher # :nodoc:
20
-
21
- def with_message(message)
22
- @expected_message = message if message
23
- self
24
- end
25
-
26
- def matches?(subject)
27
- super(subject)
28
- @expected_message ||= :not_a_number
29
- disallows_value_of('abcd', @expected_message)
30
- end
31
-
32
- def description
33
- "only allow numeric values for #{@attribute}"
34
- end
35
- end
36
-
37
- end
38
- end
39
- end
@@ -1,60 +0,0 @@
1
- module Shoulda # :nodoc:
2
- module ActiveRecord # :nodoc:
3
- module Matchers
4
-
5
- # Ensures that the model is not valid if the given attribute is not
6
- # present.
7
- #
8
- # Options:
9
- # * <tt>with_message</tt> - value the test expects to find in
10
- # <tt>errors.on(:attribute)</tt>. <tt>Regexp</tt> or <tt>String</tt>.
11
- # Defaults to the translation for <tt>:blank</tt>.
12
- #
13
- # Examples:
14
- # it { should validate_presence_of(:name) }
15
- # it { should validate_presence_of(:name).
16
- # with_message(/is not optional/) }
17
- #
18
- def validate_presence_of(attr)
19
- ValidatePresenceOfMatcher.new(attr)
20
- end
21
-
22
- class ValidatePresenceOfMatcher < ValidationMatcher # :nodoc:
23
-
24
- def with_message(message)
25
- @expected_message = message if message
26
- self
27
- end
28
-
29
- def matches?(subject)
30
- super(subject)
31
- @expected_message ||= :blank
32
- disallows_value_of(blank_value, @expected_message)
33
- end
34
-
35
- def description
36
- "require #{@attribute} to be set"
37
- end
38
-
39
- private
40
-
41
- def blank_value
42
- if collection?
43
- []
44
- else
45
- nil
46
- end
47
- end
48
-
49
- def collection?
50
- if reflection = @subject.class.reflect_on_association(@attribute)
51
- [:has_many, :has_and_belongs_to_many].include?(reflection.macro)
52
- else
53
- false
54
- end
55
- end
56
- end
57
-
58
- end
59
- end
60
- end
@@ -1,148 +0,0 @@
1
- module Shoulda # :nodoc:
2
- module ActiveRecord # :nodoc:
3
- module Matchers
4
-
5
- # Ensures that the model is invalid if the given attribute is not unique.
6
- #
7
- # Internally, this uses values from existing records to test validations,
8
- # so this will always fail if you have not saved at least one record for
9
- # the model being tested, like so:
10
- #
11
- # describe User do
12
- # before(:each) { User.create!(:email => 'address@example.com') }
13
- # it { should validate_uniqueness_of(:email) }
14
- # end
15
- #
16
- # Options:
17
- #
18
- # * <tt>with_message</tt> - value the test expects to find in
19
- # <tt>errors.on(:attribute)</tt>. <tt>Regexp</tt> or <tt>String</tt>.
20
- # Defaults to the translation for <tt>:taken</tt>.
21
- # * <tt>scoped_to</tt> - field(s) to scope the uniqueness to.
22
- # * <tt>case_insensitive</tt> - ensures that the validation does not
23
- # check case. Off by default. Ignored by non-text attributes.
24
- #
25
- # Examples:
26
- # it { should validate_uniqueness_of(:keyword) }
27
- # it { should validate_uniqueness_of(:keyword).with_message(/dup/) }
28
- # it { should validate_uniqueness_of(:email).scoped_to(:name) }
29
- # it { should validate_uniqueness_of(:email).
30
- # scoped_to(:first_name, :last_name) }
31
- # it { should validate_uniqueness_of(:keyword).case_insensitive }
32
- #
33
- def validate_uniqueness_of(attr)
34
- ValidateUniquenessOfMatcher.new(attr)
35
- end
36
-
37
- class ValidateUniquenessOfMatcher < ValidationMatcher # :nodoc:
38
- include Helpers
39
-
40
- def initialize(attribute)
41
- @attribute = attribute
42
- end
43
-
44
- def scoped_to(*scopes)
45
- @scopes = [*scopes].flatten
46
- self
47
- end
48
-
49
- def with_message(message)
50
- @expected_message = message
51
- self
52
- end
53
-
54
- def case_insensitive
55
- @case_insensitive = true
56
- self
57
- end
58
-
59
- def description
60
- result = "require "
61
- result << "case sensitive " unless @case_insensitive
62
- result << "unique value for #{@attribute}"
63
- result << " scoped to #{@scopes.join(', ')}" unless @scopes.blank?
64
- result
65
- end
66
-
67
- def matches?(subject)
68
- @subject = subject.class.new
69
- @expected_message ||= :taken
70
- find_existing &&
71
- set_scoped_attributes &&
72
- validate_attribute &&
73
- validate_after_scope_change
74
- end
75
-
76
- private
77
-
78
- def find_existing
79
- if @existing = @subject.class.find(:first)
80
- true
81
- else
82
- @failure_message = "Can't find first #{class_name}"
83
- false
84
- end
85
- end
86
-
87
- def set_scoped_attributes
88
- unless @scopes.blank?
89
- @scopes.each do |scope|
90
- setter = :"#{scope}="
91
- unless @subject.respond_to?(setter)
92
- @failure_message =
93
- "#{class_name} doesn't seem to have a #{scope} attribute."
94
- return false
95
- end
96
- @subject.send("#{scope}=", @existing.send(scope))
97
- end
98
- end
99
- true
100
- end
101
-
102
- def validate_attribute
103
- disallows_value_of(existing_value, @expected_message)
104
- end
105
-
106
- # TODO: There is a chance that we could change the scoped field
107
- # to a value that's already taken. An alternative implementation
108
- # could actually find all values for scope and create a unique
109
- def validate_after_scope_change
110
- if @scopes.blank?
111
- true
112
- else
113
- @scopes.all? do |scope|
114
- previous_value = @existing.send(scope)
115
-
116
- # Assume the scope is a foreign key if the field is nil
117
- previous_value ||= 0
118
-
119
- next_value = previous_value.next
120
-
121
- @subject.send("#{scope}=", next_value)
122
-
123
- if allows_value_of(existing_value, @expected_message)
124
- @negative_failure_message <<
125
- " (with different value of #{scope})"
126
- true
127
- else
128
- @failure_message << " (with different value of #{scope})"
129
- false
130
- end
131
- end
132
- end
133
- end
134
-
135
- def class_name
136
- @subject.class.name
137
- end
138
-
139
- def existing_value
140
- value = @existing.send(@attribute)
141
- value.swapcase! if @case_insensitive && value.respond_to?(:swapcase!)
142
- value
143
- end
144
- end
145
-
146
- end
147
- end
148
- end
@@ -1,56 +0,0 @@
1
- module Shoulda # :nodoc:
2
- module ActiveRecord # :nodoc:
3
- module Matchers
4
-
5
- class ValidationMatcher # :nodoc:
6
-
7
- attr_reader :failure_message
8
-
9
- def initialize(attribute)
10
- @attribute = attribute
11
- end
12
-
13
- def negative_failure_message
14
- @negative_failure_message || @failure_message
15
- end
16
-
17
- def matches?(subject)
18
- @subject = subject
19
- false
20
- end
21
-
22
- private
23
-
24
- def allows_value_of(value, message = nil)
25
- allow = AllowValueMatcher.
26
- new(value).
27
- for(@attribute).
28
- with_message(message)
29
- if allow.matches?(@subject)
30
- @negative_failure_message = allow.failure_message
31
- true
32
- else
33
- @failure_message = allow.negative_failure_message
34
- false
35
- end
36
- end
37
-
38
- def disallows_value_of(value, message = nil)
39
- disallow = AllowValueMatcher.
40
- new(value).
41
- for(@attribute).
42
- with_message(message)
43
- if disallow.matches?(@subject)
44
- @failure_message = disallow.negative_failure_message
45
- false
46
- else
47
- @negative_failure_message = disallow.failure_message
48
- true
49
- end
50
- end
51
- end
52
-
53
- end
54
- end
55
- end
56
-