whyvalidationssuckin96 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/.document +5 -0
  2. data/.gitignore +22 -0
  3. data/LICENSE +20 -0
  4. data/README.md +121 -0
  5. data/Rakefile +45 -0
  6. data/VERSION +1 -0
  7. data/doc/ActiveRecord/RecordInvalid.html +258 -0
  8. data/doc/ActiveRecord.html +93 -0
  9. data/doc/FalseClass.html +87 -0
  10. data/doc/NilClass.html +87 -0
  11. data/doc/Numeric.html +87 -0
  12. data/doc/Object.html +79 -0
  13. data/doc/String.html +87 -0
  14. data/doc/TrueClass.html +87 -0
  15. data/doc/WhyValidationsSuckIn96/ActiveRecord/InstanceMethods.html +156 -0
  16. data/doc/WhyValidationsSuckIn96/ActiveRecord.html +192 -0
  17. data/doc/WhyValidationsSuckIn96/AttributeBasedValidation.html +464 -0
  18. data/doc/WhyValidationsSuckIn96/SkippableValidation.html +194 -0
  19. data/doc/WhyValidationsSuckIn96/ValidatesAcceptance.html +254 -0
  20. data/doc/WhyValidationsSuckIn96/ValidatesAssociated.html +250 -0
  21. data/doc/WhyValidationsSuckIn96/ValidatesConfirmation.html +251 -0
  22. data/doc/WhyValidationsSuckIn96/ValidatesExclusion.html +388 -0
  23. data/doc/WhyValidationsSuckIn96/ValidatesFormat.html +387 -0
  24. data/doc/WhyValidationsSuckIn96/ValidatesInclusion.html +388 -0
  25. data/doc/WhyValidationsSuckIn96/ValidatesLength.html +469 -0
  26. data/doc/WhyValidationsSuckIn96/ValidatesNumericality.html +267 -0
  27. data/doc/WhyValidationsSuckIn96/ValidatesPresence.html +244 -0
  28. data/doc/WhyValidationsSuckIn96/ValidatesUniqueness.html +289 -0
  29. data/doc/WhyValidationsSuckIn96/Validation.html +934 -0
  30. data/doc/WhyValidationsSuckIn96/ValidationBuilder.html +391 -0
  31. data/doc/WhyValidationsSuckIn96/ValidationSupport/ClassMethods.html +249 -0
  32. data/doc/WhyValidationsSuckIn96/ValidationSupport/InstanceMethods.html +484 -0
  33. data/doc/WhyValidationsSuckIn96/ValidationSupport.html +168 -0
  34. data/doc/WhyValidationsSuckIn96.html +97 -0
  35. data/doc/_index.html +346 -0
  36. data/doc/class_list.html +293 -0
  37. data/doc/css/common.css +1 -0
  38. data/doc/css/full_list.css +23 -0
  39. data/doc/css/style.css +263 -0
  40. data/doc/file.README.html +173 -0
  41. data/doc/file_list.html +29 -0
  42. data/doc/index.html +173 -0
  43. data/doc/js/app.js +91 -0
  44. data/doc/js/full_list.js +39 -0
  45. data/doc/js/jquery.js +19 -0
  46. data/doc/method_list.html +462 -0
  47. data/doc/top-level-namespace.html +81 -0
  48. data/lib/whyvalidationssuckin96/attribute_based_validation.rb +46 -0
  49. data/lib/whyvalidationssuckin96/constants.rb +3 -0
  50. data/lib/whyvalidationssuckin96/ext/blank.rb +47 -0
  51. data/lib/whyvalidationssuckin96/macros/validates_acceptance.rb +36 -0
  52. data/lib/whyvalidationssuckin96/macros/validates_associated.rb +33 -0
  53. data/lib/whyvalidationssuckin96/macros/validates_confirmation.rb +40 -0
  54. data/lib/whyvalidationssuckin96/macros/validates_exclusion.rb +38 -0
  55. data/lib/whyvalidationssuckin96/macros/validates_format.rb +38 -0
  56. data/lib/whyvalidationssuckin96/macros/validates_inclusion.rb +38 -0
  57. data/lib/whyvalidationssuckin96/macros/validates_length.rb +98 -0
  58. data/lib/whyvalidationssuckin96/macros/validates_numericality.rb +56 -0
  59. data/lib/whyvalidationssuckin96/macros/validates_presence.rb +30 -0
  60. data/lib/whyvalidationssuckin96/macros.rb +9 -0
  61. data/lib/whyvalidationssuckin96/rails/active_record.rb +94 -0
  62. data/lib/whyvalidationssuckin96/rails/macros/validates_uniqueness.rb +87 -0
  63. data/lib/whyvalidationssuckin96/rails/macros.rb +1 -0
  64. data/lib/whyvalidationssuckin96/skippable_validation.rb +59 -0
  65. data/lib/whyvalidationssuckin96/validation.rb +88 -0
  66. data/lib/whyvalidationssuckin96/validation_builder.rb +56 -0
  67. data/lib/whyvalidationssuckin96/validation_support.rb +74 -0
  68. data/lib/whyvalidationssuckin96.rb +4 -0
  69. data/test/attribute_based_validation_test.rb +58 -0
  70. data/test/macros/validates_acceptance_test.rb +64 -0
  71. data/test/macros/validates_associated_test.rb +60 -0
  72. data/test/macros/validates_confirmation_test.rb +63 -0
  73. data/test/macros/validates_exclusion_test.rb +37 -0
  74. data/test/macros/validates_format_test.rb +43 -0
  75. data/test/macros/validates_inclusion_test.rb +37 -0
  76. data/test/macros/validates_length_test.rb +179 -0
  77. data/test/macros/validates_numericality_test.rb +129 -0
  78. data/test/macros/validates_presence_test.rb +31 -0
  79. data/test/rails/active_record_test.rb +187 -0
  80. data/test/rails/active_record_test_helper.rb +90 -0
  81. data/test/rails/macros/validates_uniqueness_test.rb +153 -0
  82. data/test/skippable_validation_test.rb +102 -0
  83. data/test/teststrap.rb +4 -0
  84. data/test/validation_builder_test.rb +62 -0
  85. data/test/validation_support_test.rb +209 -0
  86. data/test/validation_test.rb +101 -0
  87. data/whyvalidationssuckin96.gemspec +153 -0
  88. metadata +189 -0
@@ -0,0 +1,81 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta name="Content-Type" content="text/html; charset=UTF-8" />
6
+ <title>Top Level Namespace</title>
7
+ <link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8" />
8
+ <link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
9
+
10
+ <script type="text/javascript" charset="utf-8">
11
+ relpath = '';
12
+ if (relpath != '') relpath += '/';
13
+ </script>
14
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
15
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
16
+
17
+ </head>
18
+ <body>
19
+ <div id="header">
20
+ <div id="menu">
21
+
22
+ <a href="_index.html">Index</a> &raquo;
23
+
24
+
25
+ <span class="title">Top Level Namespace</span>
26
+
27
+ </div>
28
+
29
+ <div id="search">
30
+ <a id="class_list_link" href="#">Namespace List</a>
31
+ <a id="method_list_link" href="#">Method List</a>
32
+ <a id ="file_list_link" href="#">File List</a>
33
+ </div>
34
+
35
+ <div class="clear"></div>
36
+ </div>
37
+
38
+ <iframe id="search_frame"></iframe>
39
+
40
+ <div id="content"><h1>Top Level Namespace
41
+
42
+
43
+ </h1>
44
+
45
+ <dl class="box">
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+ </dl>
54
+ <div class="clear"></div>
55
+
56
+ <h2>Defined Under Namespace</h2>
57
+ <p class="children">
58
+
59
+
60
+ <strong class="modules">Modules:</strong> <a href="ActiveRecord.html" title="ActiveRecord">ActiveRecord</a>, <a href="WhyValidationsSuckIn96.html" title="WhyValidationsSuckIn96">WhyValidationsSuckIn96</a>
61
+
62
+
63
+
64
+ <strong class="classes">Classes:</strong> <a href="FalseClass.html" title="FalseClass">FalseClass</a>, <a href="NilClass.html" title="NilClass">NilClass</a>, <a href="Numeric.html" title="Numeric">Numeric</a>, <a href="Object.html" title="Object">Object</a>, <a href="String.html" title="String">String</a>, <a href="TrueClass.html" title="TrueClass">TrueClass</a>
65
+
66
+
67
+ </p>
68
+
69
+
70
+
71
+
72
+ </div>
73
+
74
+ <div id="footer">
75
+ Generated on Sun Dec 20 19:49:47 2009 by
76
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool">yard</a>
77
+ 0.5.2 (ruby-1.8.7).
78
+ </div>
79
+
80
+ </body>
81
+ </html>
@@ -0,0 +1,46 @@
1
+ module WhyValidationsSuckIn96
2
+ # A mixin to help handle the most common case of validating a single attribute on an object. This module has a
3
+ # dependency on SkippableValidation that will most likely be removed in future releases, but is something to be
4
+ # aware of currently.
5
+ module AttributeBasedValidation
6
+
7
+ # An initializer for a validation that checks to see if the required options have been passed for
8
+ # attribute based validation to work as expected.
9
+ # @param [Object] validatable An object to be validated
10
+ # @param [Hash] options The options to set up the validation with
11
+ # @option options [Symbol] :attribute The attribute on the validatable object to validate against
12
+ # @option options [true, false] :allow_nil If true, skips validation of the value of the attribute is #nil?
13
+ # @option options [true, false] :allow_blank If true, skips validation of the value of the attribute is #blank?
14
+ def initialize(validatable, options = {})
15
+ raise(ArgumentError, "The attribute to validate must be specified as :attribute") unless options[:attribute]
16
+ super
17
+ end
18
+
19
+ # The attribute to validate against
20
+ def attribute
21
+ options[:attribute]
22
+ end
23
+
24
+ # The value of the attribute to validate against
25
+ def attribute_value
26
+ validatable.send(options[:attribute])
27
+ end
28
+
29
+ # A default validate implementation that skips on #nil?/#blank? attribute values if :allow_nil or :allow_blank
30
+ # have been set.
31
+ def validate
32
+ skip if skip_on_blank? || skip_on_nil?
33
+ super
34
+ end
35
+
36
+ private
37
+
38
+ def skip_on_nil?
39
+ options[:allow_nil] && attribute_value.nil?
40
+ end
41
+
42
+ def skip_on_blank?
43
+ options[:allow_blank] && attribute_value.blank?
44
+ end
45
+ end # AttributeBasedValidation
46
+ end # WhyValidationsSuckIn96
@@ -0,0 +1,3 @@
1
+ module WhyValidationsSuckIn96
2
+
3
+ end
@@ -0,0 +1,47 @@
1
+ class Object
2
+ unless instance_methods(false).include?("blank?")
3
+ def blank?
4
+ respond_to?(:empty?) ? empty? : !self
5
+ end
6
+ end
7
+ end
8
+
9
+ class String
10
+ unless instance_methods(false).include?("blank?")
11
+ def blank?
12
+ self !~ /\S/
13
+ end
14
+ end
15
+ end
16
+
17
+ class Numeric
18
+ unless instance_methods(false).include?("blank?")
19
+ def blank?
20
+ false
21
+ end
22
+ end
23
+ end
24
+
25
+ class TrueClass
26
+ unless instance_methods(false).include?("blank?")
27
+ def blank?
28
+ false
29
+ end
30
+ end
31
+ end
32
+
33
+ class FalseClass
34
+ unless instance_methods(false).include?("blank?")
35
+ def blank?
36
+ true
37
+ end
38
+ end
39
+ end
40
+
41
+ class NilClass
42
+ unless instance_methods(false).include?("blank?")
43
+ def blank?
44
+ true
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,36 @@
1
+ require 'whyvalidationssuckin96/skippable_validation'
2
+ require 'whyvalidationssuckin96/attribute_based_validation'
3
+
4
+ module WhyValidationsSuckIn96
5
+
6
+ # Validates the acceptance of an attribute, such as the "I agree to the terms and conditions" checkbox value returned
7
+ # by a form post.
8
+ #
9
+ # @example Default usage
10
+ # setup_validations do
11
+ # validates_acceptance_of :privacy_policy, :terms_and_conditions
12
+ # end
13
+ #
14
+ # @example Changing the :accept value
15
+ # setup_validations do
16
+ # validates_acceptance_of :privacy_policy, :accept => "yep"
17
+ # end
18
+ class ValidatesAcceptance < Validation
19
+ DefaultOptions = {:allow_nil => true, :accept => "1", :message => "must be accepted"}
20
+
21
+ include WhyValidationsSuckIn96::SkippableValidation
22
+ include WhyValidationsSuckIn96::AttributeBasedValidation
23
+
24
+ def validate
25
+ super
26
+ if options[:accept] == attribute_value
27
+ pass
28
+ else
29
+ fail
30
+ end
31
+ end
32
+
33
+ end # Validation
34
+
35
+ ValidationBuilder.register_macro :validates_acceptance_of, WhyValidationsSuckIn96::ValidatesAcceptance
36
+ end # WhyValidationsSuckIn96
@@ -0,0 +1,33 @@
1
+ require 'whyvalidationssuckin96/skippable_validation'
2
+ require 'whyvalidationssuckin96/attribute_based_validation'
3
+
4
+ module WhyValidationsSuckIn96
5
+
6
+ # Checks the validity of any associated objects, such as an ActiveRecord association.
7
+ #
8
+ # @example Checking the validity of an associated collection of tracks
9
+ # setup_validations do
10
+ # validates_associated :tracks
11
+ # end
12
+ #
13
+ # @example Checking the validity of an associated artist
14
+ # setup_validations do
15
+ # validates_associated :artist
16
+ # end
17
+ class ValidatesAssociated < Validation
18
+ DefaultOptions = {:message => "is invalid"}
19
+
20
+ include WhyValidationsSuckIn96::SkippableValidation
21
+ include WhyValidationsSuckIn96::AttributeBasedValidation
22
+
23
+ def validate
24
+ super
25
+ Array(attribute_value).collect do |assoc|
26
+ assoc.valid?
27
+ end.all? ? pass : fail
28
+ end
29
+
30
+ end # Validation
31
+
32
+ ValidationBuilder.register_macro :validates_associated, WhyValidationsSuckIn96::ValidatesAssociated
33
+ end # WhyValidationsSuckIn96
@@ -0,0 +1,40 @@
1
+ require 'whyvalidationssuckin96/skippable_validation'
2
+ require 'whyvalidationssuckin96/attribute_based_validation'
3
+
4
+ module WhyValidationsSuckIn96
5
+
6
+ # Checks the validity of an attribute against a confirmation field. Note that this validation does
7
+ # not set up the confirmation field on the object, leaving this up to the implementer.
8
+ #
9
+ # @example Default usage
10
+ # class Account
11
+ # attr_accessor :password, :password_confirmation
12
+ # setup_validations do
13
+ # validates_confirmation_of :password
14
+ # end
15
+ # end
16
+ class ValidatesConfirmation < Validation
17
+ include WhyValidationsSuckIn96::SkippableValidation
18
+ include WhyValidationsSuckIn96::AttributeBasedValidation
19
+
20
+ DefaultOptions = {:message => "does not match the confirmation"}
21
+
22
+ def validate
23
+ super
24
+ skip unless confirmation_value = validatable.send(confirmation_field)
25
+ if confirmation_value == attribute_value
26
+ pass
27
+ else
28
+ fail
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def confirmation_field
35
+ :"#{attribute}_confirmation"
36
+ end
37
+ end # Validation
38
+
39
+ ValidationBuilder.register_macro :validates_confirmation_of, WhyValidationsSuckIn96::ValidatesAcceptance
40
+ end # WhyValidationsSuckIn96
@@ -0,0 +1,38 @@
1
+ require 'whyvalidationssuckin96/skippable_validation'
2
+ require 'whyvalidationssuckin96/attribute_based_validation'
3
+
4
+ module WhyValidationsSuckIn96
5
+
6
+ # Checks the validity of an attribute against a collection of excluded values.
7
+ #
8
+ # @example Default usage
9
+ # setup_validations do
10
+ # validates_exclusion_of :subdomain, :in => %w[www ftp]
11
+ # end
12
+ class ValidatesExclusion < Validation
13
+ include WhyValidationsSuckIn96::SkippableValidation
14
+ include WhyValidationsSuckIn96::AttributeBasedValidation
15
+
16
+ DefaultOptions = {:message => "is in the excluded collection"}
17
+
18
+ # @param [Object] validatable An object to be validated.
19
+ # @param [Hash] options The options to set up the validation with.
20
+ # @option options [#include?] :in A collection to check against for exclusion.
21
+ def initialize(validatable, options = {})
22
+ super
23
+ raise(ArgumentError, "Collection to check for exclusion against should be specified with :in") unless options[:in]
24
+ end
25
+
26
+ def validate
27
+ super
28
+ if options[:in].include?(attribute_value)
29
+ fail
30
+ else
31
+ pass
32
+ end
33
+ end
34
+
35
+ end # Validation
36
+
37
+ ValidationBuilder.register_macro :validates_exclusion_of, WhyValidationsSuckIn96::ValidatesExclusion
38
+ end # WhyValidationsSuckIn96
@@ -0,0 +1,38 @@
1
+ require 'whyvalidationssuckin96/skippable_validation'
2
+ require 'whyvalidationssuckin96/attribute_based_validation'
3
+
4
+ module WhyValidationsSuckIn96
5
+
6
+ # Checks the validity of an attribute against a regular expression.
7
+ #
8
+ # @example Default usage
9
+ # setup_validations do
10
+ # validates_format_of :username, :with => /[a-z0-9]/i
11
+ # end
12
+ class ValidatesFormat < Validation
13
+ include WhyValidationsSuckIn96::SkippableValidation
14
+ include WhyValidationsSuckIn96::AttributeBasedValidation
15
+
16
+ DefaultOptions = {:message => "does not match the given format"}
17
+
18
+ # @param [Object] validatable An object to be validated
19
+ # @param [Hash] options The options to set up the validation with
20
+ # @option options [Regexp] :with A regular expression to check against
21
+ def initialize(validatable, options = {})
22
+ super
23
+ raise(ArgumentError, "Regular expression to check against must be given as :with") unless options[:with]
24
+ end
25
+
26
+ def validate
27
+ super
28
+ if attribute_value.to_s =~ options[:with]
29
+ pass
30
+ else
31
+ fail
32
+ end
33
+ end
34
+
35
+ end # Validation
36
+
37
+ ValidationBuilder.register_macro :validates_format_of, WhyValidationsSuckIn96::ValidatesFormat
38
+ end # WhyValidationsSuckIn96
@@ -0,0 +1,38 @@
1
+ require 'whyvalidationssuckin96/skippable_validation'
2
+ require 'whyvalidationssuckin96/attribute_based_validation'
3
+
4
+ module WhyValidationsSuckIn96
5
+
6
+ # Checks the validity of an attribute against a list of values for it to be included in.
7
+ #
8
+ # @example Default usage
9
+ # setup_validations do
10
+ # validates_inclusion_of :unit_system, :in => %w[imperial metric]
11
+ # end
12
+ class ValidatesInclusion < Validation
13
+ include WhyValidationsSuckIn96::SkippableValidation
14
+ include WhyValidationsSuckIn96::AttributeBasedValidation
15
+
16
+ DefaultOptions = {:message => "is not in the acceptable collection"}
17
+
18
+ # @param [Object] validatable An object to be validated.
19
+ # @param [Hash] options The options to set up the validation with.
20
+ # @option options [#include?] :in A collection to check against for inclusion.
21
+ def initialize(validatable, options = {})
22
+ super
23
+ raise(ArgumentError, "Collection to check for inclusion against should be specified with :in") unless options[:in]
24
+ end
25
+
26
+ def validate
27
+ super
28
+ if options[:in].include?(attribute_value)
29
+ pass
30
+ else
31
+ fail
32
+ end
33
+ end
34
+
35
+ end # Validation
36
+
37
+ ValidationBuilder.register_macro :validates_inclusion_of, WhyValidationsSuckIn96::ValidatesInclusion
38
+ end # WhyValidationsSuckIn96
@@ -0,0 +1,98 @@
1
+ require 'whyvalidationssuckin96/skippable_validation'
2
+ require 'whyvalidationssuckin96/attribute_based_validation'
3
+
4
+ module WhyValidationsSuckIn96
5
+
6
+ # Checks the validity of an attribute against a given set of sizes.
7
+ #
8
+ # @example Checking against an exact value
9
+ # setup_validations do
10
+ # validates_length_of :choices, :is => 4
11
+ # end
12
+ #
13
+ # @example Checking against a range
14
+ # setup_validations do
15
+ # validates_length_of :choices, :in => 1..10
16
+ # end
17
+ #
18
+ # @example Checking against a minimum value
19
+ # setup_validations do
20
+ # validates_length_of :choices, :minimum => 1
21
+ # end
22
+ #
23
+ # @example Checking against a maximum value
24
+ # setup_validations do
25
+ # validates_length_of :choices, :maximum => 10
26
+ # end
27
+ #
28
+ # @example Checking against a minimum and maximum value
29
+ # setup_validations do
30
+ # validates_length_of :choices, :minimum => 1, :maximum => 10
31
+ # end
32
+ class ValidatesLength < Validation
33
+ include WhyValidationsSuckIn96::SkippableValidation
34
+ include WhyValidationsSuckIn96::AttributeBasedValidation
35
+
36
+ DefaultOptions = {:message => "does not meet the given length restrictions"}
37
+ ValidOptions = [:is, :in, :minimum, :maximum]
38
+ OptionIncompatibility = {
39
+ :is => [:minimum, :maximum, :in],
40
+ :in => [:minimum, :maximum, :is]
41
+ }
42
+
43
+ # @param [Object] validatable An object to be validated.
44
+ # @param [Hash] options The options to set up the validation with.
45
+ # @option options [#==] :is An exact value to check the validatable object's #size against.
46
+ # @option options [#include?] :in A range to check the validatable object's #size against.
47
+ # @option options [#<=] :minimum A minimum value to check the validatable object's size against.
48
+ # @option options [#>=] :maximum A maximum value to check the validatable object's size against.
49
+ def initialize(validatable, options = {})
50
+ super
51
+ check_options(options)
52
+ end
53
+
54
+ def validate
55
+ super
56
+ all_valid = ValidOptions.collect do |opt_name|
57
+ next(true) if options[opt_name].nil?
58
+ send(:"validate_#{opt_name}")
59
+ end.all?
60
+ all_valid ? pass : fail
61
+ end
62
+
63
+ private
64
+
65
+ def validate_is
66
+ options[:is] == attribute_value.size
67
+ end
68
+
69
+ def validate_in
70
+ options[:in].include?(attribute_value.size)
71
+ end
72
+
73
+ def validate_minimum
74
+ options[:minimum] <= attribute_value.size
75
+ end
76
+
77
+ def validate_maximum
78
+ options[:maximum] >= attribute_value.size
79
+ end
80
+
81
+ def check_options(options_hash)
82
+ OptionIncompatibility.each do |opt,incompat|
83
+ next unless options_hash[opt]
84
+ bad_opt = incompat.detect { |opt_name| options_hash.keys.include?(opt_name) }
85
+ if bad_opt
86
+ names = [opt.inspect.to_s, bad_opt.inspect.to_s].sort
87
+ raise(ArgumentError, "Option #{names.first} can not be mixed with #{names.last}")
88
+ end
89
+ end
90
+ raise(ArgumentError, "Length options must be given as :minimum, :maximum, :is, or :in") unless options_hash.keys.any? do |opt|
91
+ ValidOptions.include?(opt)
92
+ end
93
+ end
94
+
95
+ end # Validation
96
+
97
+ ValidationBuilder.register_macro :validates_length_of, WhyValidationsSuckIn96::ValidatesLength
98
+ end # WhyValidationsSuckIn96
@@ -0,0 +1,56 @@
1
+ require 'whyvalidationssuckin96/skippable_validation'
2
+ require 'whyvalidationssuckin96/attribute_based_validation'
3
+
4
+ module WhyValidationsSuckIn96
5
+
6
+ # Checks to see if a given attribute is a valid numerical value. Allows a certain degree of latitude in determining
7
+ # what is a valid numerical value, like allowing commas and spaces in the value for example.
8
+ #
9
+ # @example Default usage
10
+ # setup_validations do
11
+ # validates_numericality_of :cost
12
+ # end
13
+ #
14
+ # @example Only allow integer values
15
+ # setup_validations do
16
+ # validates_numericality_of :cost, :only_integer => true
17
+ # end
18
+ class ValidatesNumericality < Validation
19
+ include WhyValidationsSuckIn96::SkippableValidation
20
+ include WhyValidationsSuckIn96::AttributeBasedValidation
21
+
22
+ DefaultOptions = {:message => "is not a numerical value"}
23
+ StripNonNumeric = /[^-+e\d.]/im
24
+ ValidNumericChars = /\A[-+e\d.,\s]+\Z/im
25
+
26
+ def validate
27
+ super
28
+ if options[:only_integer]
29
+ validate_as_integer
30
+ else
31
+ validate_as_float
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def validate_as_integer
38
+ fail if attribute_value.to_s !~ ValidNumericChars
39
+ Integer(attribute_value.to_s.gsub(StripNonNumeric, ""))
40
+ pass
41
+ rescue ArgumentError, TypeError
42
+ fail
43
+ end
44
+
45
+ def validate_as_float
46
+ fail if attribute_value.to_s !~ ValidNumericChars
47
+ Kernel.Float(attribute_value.to_s.gsub(StripNonNumeric, ""))
48
+ pass
49
+ rescue ArgumentError, TypeError
50
+ fail
51
+ end
52
+
53
+ end # Validation
54
+
55
+ ValidationBuilder.register_macro :validates_numericality_of, WhyValidationsSuckIn96::ValidatesNumericality
56
+ end # WhyValidationsSuckIn96
@@ -0,0 +1,30 @@
1
+ require 'whyvalidationssuckin96/skippable_validation'
2
+ require 'whyvalidationssuckin96/attribute_based_validation'
3
+
4
+ module WhyValidationsSuckIn96
5
+
6
+ # Checks for the presence of a given attribute.
7
+ #
8
+ # @example Default usage
9
+ # setup_validations do
10
+ # validates_presence_of :name
11
+ # end
12
+ class ValidatesPresence < Validation
13
+ include WhyValidationsSuckIn96::SkippableValidation
14
+ include WhyValidationsSuckIn96::AttributeBasedValidation
15
+
16
+ DefaultOptions = {:message => "is not present"}
17
+
18
+ def validate
19
+ super
20
+ if attribute_value.blank?
21
+ fail
22
+ else
23
+ pass
24
+ end
25
+ end
26
+
27
+ end # Validation
28
+
29
+ ValidationBuilder.register_macro :validates_presence_of, WhyValidationsSuckIn96::ValidatesPresence
30
+ end # WhyValidationsSuckIn96
@@ -0,0 +1,9 @@
1
+ require 'whyvalidationssuckin96/macros/validates_acceptance'
2
+ require 'whyvalidationssuckin96/macros/validates_associated'
3
+ require 'whyvalidationssuckin96/macros/validates_confirmation'
4
+ require 'whyvalidationssuckin96/macros/validates_exclusion'
5
+ require 'whyvalidationssuckin96/macros/validates_format'
6
+ require 'whyvalidationssuckin96/macros/validates_inclusion'
7
+ require 'whyvalidationssuckin96/macros/validates_length'
8
+ require 'whyvalidationssuckin96/macros/validates_numericality'
9
+ require 'whyvalidationssuckin96/macros/validates_presence'