remarkable_activerecord 3.1.13 → 4.0.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +3 -3
- data/lib/remarkable_activerecord.rb +1 -3
- data/lib/remarkable_activerecord/base.rb +1 -247
- data/lib/remarkable_activerecord/matchers/have_default_scope_matcher.rb +1 -2
- data/lib/remarkable_activerecord/matchers/have_scope_matcher.rb +35 -19
- data/lib/remarkable_activerecord/matchers/validate_associated_matcher.rb +4 -7
- data/lib/remarkable_activerecord/matchers/validate_uniqueness_of_matcher.rb +1 -1
- data/remarkable_activerecord.gemspec +44 -14
- metadata +60 -33
- data/lib/remarkable_activerecord/describe.rb +0 -198
- data/lib/remarkable_activerecord/human_names.rb +0 -37
- data/lib/remarkable_activerecord/matchers/allow_values_for_matcher.rb +0 -88
- data/lib/remarkable_activerecord/matchers/validate_acceptance_of_matcher.rb +0 -50
- data/lib/remarkable_activerecord/matchers/validate_confirmation_of_matcher.rb +0 -44
- data/lib/remarkable_activerecord/matchers/validate_exclusion_of_matcher.rb +0 -57
- data/lib/remarkable_activerecord/matchers/validate_inclusion_of_matcher.rb +0 -57
- data/lib/remarkable_activerecord/matchers/validate_length_of_matcher.rb +0 -150
- data/lib/remarkable_activerecord/matchers/validate_numericality_of_matcher.rb +0 -188
- data/lib/remarkable_activerecord/matchers/validate_presence_of_matcher.rb +0 -91
@@ -1,88 +0,0 @@
|
|
1
|
-
module Remarkable
|
2
|
-
module ActiveRecord
|
3
|
-
module Matchers
|
4
|
-
class AllowValuesForMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
5
|
-
include Remarkable::Negative
|
6
|
-
arguments :collection => :attributes, :as => :attribute
|
7
|
-
|
8
|
-
optional :message
|
9
|
-
optional :in, :splat => true
|
10
|
-
optional :allow_nil, :allow_blank, :default => true
|
11
|
-
|
12
|
-
collection_assertions :is_valid?, :is_invalid?, :allow_nil?, :allow_blank?
|
13
|
-
|
14
|
-
default_options :message => /.*/
|
15
|
-
|
16
|
-
before_assert do
|
17
|
-
first_value = @options[:in].is_a?(Array) ? @options[:in].first : @options[:in]
|
18
|
-
@in_range = first_value.is_a?(Range)
|
19
|
-
|
20
|
-
@options[:in] = if @in_range
|
21
|
-
first_value.to_a[0,2] + first_value.to_a[-2,2]
|
22
|
-
else
|
23
|
-
[*@options[:in]].compact
|
24
|
-
end
|
25
|
-
|
26
|
-
@options[:in].uniq!
|
27
|
-
end
|
28
|
-
|
29
|
-
protected
|
30
|
-
|
31
|
-
def is_valid?
|
32
|
-
assert_collection :value, valid_values do |value|
|
33
|
-
good?(value)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def is_invalid?
|
38
|
-
assert_collection :value, invalid_values do |value|
|
39
|
-
bad?(value)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def valid_values
|
44
|
-
@options[:in]
|
45
|
-
end
|
46
|
-
|
47
|
-
def invalid_values
|
48
|
-
[]
|
49
|
-
end
|
50
|
-
|
51
|
-
def interpolation_options
|
52
|
-
options = if @in_range
|
53
|
-
{ :in => (@options[:in].first..@options[:in].last).inspect }
|
54
|
-
elsif @options[:in].is_a?(Array)
|
55
|
-
{ :in => array_to_sentence(@options[:in], true, '[]') }
|
56
|
-
else
|
57
|
-
{ :in => @options[:in].inspect }
|
58
|
-
end
|
59
|
-
|
60
|
-
options.merge!(:behavior => @behavior.to_s)
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
# Ensures that the attribute can be set to the given values. It checks
|
66
|
-
# for any message in the given attribute unless a :message is explicitely
|
67
|
-
# given.
|
68
|
-
#
|
69
|
-
# == Options
|
70
|
-
#
|
71
|
-
# * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
|
72
|
-
# * <tt>:allow_blank</tt> - when supplied, validates if it allows blank or not.
|
73
|
-
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
74
|
-
# Regexp, string or symbol. Default = <tt>/.*/</tt>
|
75
|
-
#
|
76
|
-
# == Examples
|
77
|
-
#
|
78
|
-
# should_allow_values_for :isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0"
|
79
|
-
# it { should allow_values_for(:isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0") }
|
80
|
-
#
|
81
|
-
def allow_values_for(attribute, *args, &block)
|
82
|
-
options = args.extract_options!
|
83
|
-
AllowValuesForMatcher.new(attribute, options.merge!(:in => args), &block).spec(self)
|
84
|
-
end
|
85
|
-
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
module Remarkable
|
2
|
-
module ActiveRecord
|
3
|
-
module Matchers
|
4
|
-
class ValidateAcceptanceOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
5
|
-
arguments :collection => :attributes, :as => :attribute
|
6
|
-
|
7
|
-
optional :accept, :message
|
8
|
-
optional :allow_nil, :default => true
|
9
|
-
|
10
|
-
collection_assertions :requires_acceptance?, :accept_is_valid?, :allow_nil?
|
11
|
-
|
12
|
-
default_options :message => :accepted
|
13
|
-
|
14
|
-
protected
|
15
|
-
|
16
|
-
def requires_acceptance?
|
17
|
-
bad?(false)
|
18
|
-
end
|
19
|
-
|
20
|
-
def accept_is_valid?
|
21
|
-
return true unless @options.key?(:accept)
|
22
|
-
good?(@options[:accept])
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
# Ensures that the model cannot be saved if one of the attributes listed is not accepted.
|
28
|
-
#
|
29
|
-
# == Options
|
30
|
-
#
|
31
|
-
# * <tt>:accept</tt> - the expected value to be accepted.
|
32
|
-
# * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
|
33
|
-
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
34
|
-
# Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.accepted')</tt>
|
35
|
-
#
|
36
|
-
# == Examples
|
37
|
-
#
|
38
|
-
# should_validate_acceptance_of :eula, :terms
|
39
|
-
# should_validate_acceptance_of :eula, :terms, :accept => true
|
40
|
-
#
|
41
|
-
# it { should validate_acceptance_of(:eula, :terms) }
|
42
|
-
# it { should validate_acceptance_of(:eula, :terms, :accept => true) }
|
43
|
-
#
|
44
|
-
def validate_acceptance_of(*attributes, &block)
|
45
|
-
ValidateAcceptanceOfMatcher.new(*attributes, &block).spec(self)
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
module Remarkable
|
2
|
-
module ActiveRecord
|
3
|
-
module Matchers
|
4
|
-
class ValidateConfirmationOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
5
|
-
arguments :collection => :attributes, :as => :attribute
|
6
|
-
|
7
|
-
optional :message
|
8
|
-
collection_assertions :responds_to_confirmation?, :confirms?
|
9
|
-
|
10
|
-
default_options :message => :confirmation
|
11
|
-
|
12
|
-
protected
|
13
|
-
|
14
|
-
def responds_to_confirmation?
|
15
|
-
@subject.respond_to?(:"#{@attribute}_confirmation=")
|
16
|
-
end
|
17
|
-
|
18
|
-
def confirms?
|
19
|
-
@subject.send(:"#{@attribute}_confirmation=", 'something')
|
20
|
-
bad?('different')
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
# Ensures that the model cannot be saved if one of the attributes is not confirmed.
|
26
|
-
#
|
27
|
-
# == Options
|
28
|
-
#
|
29
|
-
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
30
|
-
# Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.confirmation')</tt>
|
31
|
-
#
|
32
|
-
# == Examples
|
33
|
-
#
|
34
|
-
# should_validate_confirmation_of :email, :password
|
35
|
-
#
|
36
|
-
# it { should validate_confirmation_of(:email, :password) }
|
37
|
-
#
|
38
|
-
def validate_confirmation_of(*attributes, &block)
|
39
|
-
ValidateConfirmationOfMatcher.new(*attributes, &block).spec(self)
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'allow_values_for_matcher')
|
2
|
-
|
3
|
-
module Remarkable
|
4
|
-
module ActiveRecord
|
5
|
-
module Matchers
|
6
|
-
class ValidateExclusionOfMatcher < AllowValuesForMatcher #:nodoc:
|
7
|
-
# Don't allow it to behave in the negative way.
|
8
|
-
undef_method :does_not_match?
|
9
|
-
|
10
|
-
default_options :message => :exclusion
|
11
|
-
|
12
|
-
protected
|
13
|
-
|
14
|
-
def valid_values
|
15
|
-
if @in_range
|
16
|
-
[ @options[:in].first - 1, @options[:in].last + 1 ]
|
17
|
-
else
|
18
|
-
value = @options[:in].select{ |i| i.is_a?(String) }.max
|
19
|
-
value ? [ value.next ] : []
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def invalid_values
|
24
|
-
@options[:in]
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
# Ensures that given values are not valid for the attribute. If a range
|
30
|
-
# is given, ensures that the attribute is not valid in the given range.
|
31
|
-
#
|
32
|
-
# If you give that :username does not accept ["admin", "user"], it will
|
33
|
-
# test that "uses" (the next of the array max value) is allowed.
|
34
|
-
#
|
35
|
-
# == Options
|
36
|
-
#
|
37
|
-
# * <tt>:in</tt> - values to test exclusion.
|
38
|
-
# * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
|
39
|
-
# * <tt>:allow_blank</tt> - when supplied, validates if it allows blank or not.
|
40
|
-
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
41
|
-
# Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.exclusion')</tt>
|
42
|
-
#
|
43
|
-
# == Examples
|
44
|
-
#
|
45
|
-
# it { should validate_exclusion_of(:username, :in => ["admin", "user"]) }
|
46
|
-
# it { should validate_exclusion_of(:age, :in => 30..60) }
|
47
|
-
#
|
48
|
-
# should_validate_exclusion_of :username, :in => ["admin", "user"]
|
49
|
-
# should_validate_exclusion_of :age, :in => 30..60
|
50
|
-
#
|
51
|
-
def validate_exclusion_of(*args, &block)
|
52
|
-
ValidateExclusionOfMatcher.new(*args, &block).spec(self)
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'allow_values_for_matcher')
|
2
|
-
|
3
|
-
module Remarkable
|
4
|
-
module ActiveRecord
|
5
|
-
module Matchers
|
6
|
-
class ValidateInclusionOfMatcher < AllowValuesForMatcher #:nodoc:
|
7
|
-
# Don't allow it to behave in the negative way.
|
8
|
-
undef_method :does_not_match?
|
9
|
-
|
10
|
-
default_options :message => :inclusion
|
11
|
-
|
12
|
-
protected
|
13
|
-
|
14
|
-
def valid_values
|
15
|
-
@options[:in]
|
16
|
-
end
|
17
|
-
|
18
|
-
def invalid_values
|
19
|
-
if @in_range
|
20
|
-
[ @options[:in].first - 1, @options[:in].last + 1 ]
|
21
|
-
else
|
22
|
-
value = @options[:in].select{ |i| i.is_a?(String) }.max
|
23
|
-
value ? [ value.next ] : []
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
# Ensures that given values are valid for the attribute. If a range
|
30
|
-
# is given, ensures that the attribute is valid in the given range.
|
31
|
-
#
|
32
|
-
# If you give that :size accepts ["S", "M", "L"], it will test that "T"
|
33
|
-
# (the next of the array max value) is not allowed.
|
34
|
-
#
|
35
|
-
# == Options
|
36
|
-
#
|
37
|
-
# * <tt>:in</tt> - values to test inclusion.
|
38
|
-
# * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
|
39
|
-
# * <tt>:allow_blank</tt> - when supplied, validates if it allows blank or not.
|
40
|
-
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
41
|
-
# Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.inclusion')</tt>
|
42
|
-
#
|
43
|
-
# == Examples
|
44
|
-
#
|
45
|
-
# should_validate_inclusion_of :size, :in => ["S", "M", "L", "XL"]
|
46
|
-
# should_validate_inclusion_of :age, :in => 18..100
|
47
|
-
#
|
48
|
-
# it { should validate_inclusion_of(:size, :in => ["S", "M", "L", "XL"]) }
|
49
|
-
# it { should validate_inclusion_of(:age, :in => 18..100) }
|
50
|
-
#
|
51
|
-
def validate_inclusion_of(*args, &block)
|
52
|
-
ValidateInclusionOfMatcher.new(*args, &block).spec(self)
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,150 +0,0 @@
|
|
1
|
-
module Remarkable
|
2
|
-
module ActiveRecord
|
3
|
-
module Matchers
|
4
|
-
class ValidateLengthOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
5
|
-
arguments :collection => :attributes, :as => :attribute
|
6
|
-
|
7
|
-
optional :within, :alias => :in
|
8
|
-
optional :minimum, :maximum, :is
|
9
|
-
optional :token, :separator, :with_kind_of
|
10
|
-
optional :allow_nil, :allow_blank, :default => true
|
11
|
-
optional :message, :too_short, :too_long, :wrong_length
|
12
|
-
|
13
|
-
collection_assertions :less_than_min_length?, :exactly_min_length?,
|
14
|
-
:more_than_max_length?, :exactly_max_length?,
|
15
|
-
:allow_nil?, :allow_blank?
|
16
|
-
|
17
|
-
before_assert do
|
18
|
-
# Reassign :in to :within
|
19
|
-
@options[:within] ||= @options.delete(:in) if @options.key?(:in)
|
20
|
-
|
21
|
-
if @options[:is]
|
22
|
-
@min_value, @max_value = @options[:is], @options[:is]
|
23
|
-
elsif @options[:within]
|
24
|
-
@min_value, @max_value = @options[:within].first, @options[:within].last
|
25
|
-
elsif @options[:maximum]
|
26
|
-
@min_value, @max_value = nil, @options[:maximum]
|
27
|
-
elsif @options[:minimum]
|
28
|
-
@min_value, @max_value = @options[:minimum], nil
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
default_options :too_short => :too_short, :too_long => :too_long, :wrong_length => :wrong_length
|
33
|
-
|
34
|
-
protected
|
35
|
-
def allow_nil?
|
36
|
-
super(default_message_for(:too_short))
|
37
|
-
end
|
38
|
-
|
39
|
-
def allow_blank?
|
40
|
-
super(default_message_for(:too_short))
|
41
|
-
end
|
42
|
-
|
43
|
-
def less_than_min_length?
|
44
|
-
@min_value.nil? || @min_value <= 1 || bad?(value_for_length(@min_value - 1), default_message_for(:too_short))
|
45
|
-
end
|
46
|
-
|
47
|
-
def exactly_min_length?
|
48
|
-
@min_value.nil? || @min_value <= 0 || good?(value_for_length(@min_value), default_message_for(:too_short))
|
49
|
-
end
|
50
|
-
|
51
|
-
def more_than_max_length?
|
52
|
-
@max_value.nil? || bad?(value_for_length(@max_value + 1), default_message_for(:too_long))
|
53
|
-
end
|
54
|
-
|
55
|
-
def exactly_max_length?
|
56
|
-
@max_value.nil? || @min_value == @max_value || good?(value_for_length(@max_value), default_message_for(:too_long))
|
57
|
-
end
|
58
|
-
|
59
|
-
def value_for_length(value)
|
60
|
-
if @options[:with_kind_of]
|
61
|
-
[@options[:with_kind_of].new] * value
|
62
|
-
else
|
63
|
-
([@options.fetch(:token, 'x')] * value).join(@options.fetch(:separator, ''))
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def interpolation_options
|
68
|
-
{ :minimum => @min_value, :maximum => @max_value }
|
69
|
-
end
|
70
|
-
|
71
|
-
# Returns the default message for the validation type.
|
72
|
-
# If user supplied :message, it will return it. Otherwise it will return
|
73
|
-
# wrong_length on :is validation and :too_short or :too_long in the other
|
74
|
-
# types.
|
75
|
-
#
|
76
|
-
def default_message_for(validation_type)
|
77
|
-
return :message if @options[:message]
|
78
|
-
@options.key?(:is) ? :wrong_length : validation_type
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
# Validates the length of the given attributes. You have also to supply
|
83
|
-
# one of the following options: minimum, maximum, is or within.
|
84
|
-
#
|
85
|
-
# Note: this method is also aliased as <tt>validate_size_of</tt>.
|
86
|
-
#
|
87
|
-
# == Options
|
88
|
-
#
|
89
|
-
# * <tt>:minimum</tt> - The minimum size of the attribute.
|
90
|
-
# * <tt>:maximum</tt> - The maximum size of the attribute.
|
91
|
-
# * <tt>:is</tt> - The exact size of the attribute.
|
92
|
-
# * <tt>:within</tt> - A range specifying the minimum and maximum size of the attribute.
|
93
|
-
# * <tt>:in</tt> - A synonym(or alias) for :within.
|
94
|
-
# * <tt>:allow_nil</tt> - when supplied, validates if it allows nil or not.
|
95
|
-
# * <tt>:allow_blank</tt> - when supplied, validates if it allows blank or not.
|
96
|
-
# * <tt>:too_short</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt> when attribute is too short.
|
97
|
-
# Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.too_short') % range.first</tt>
|
98
|
-
# * <tt>:too_long</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt> when attribute is too long.
|
99
|
-
# Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.too_long') % range.last</tt>
|
100
|
-
# * <tt>:wrong_length</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt> when attribute is the wrong length.
|
101
|
-
# Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.wrong_length') % range.last</tt>
|
102
|
-
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
103
|
-
# Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.wrong_length') % value</tt>
|
104
|
-
#
|
105
|
-
# It also accepts an extra option called :with_kind_of. If you are validating
|
106
|
-
# the size of an association array, you have to specify the kind of the array
|
107
|
-
# being validated. For example, if your post accepts maximum 10 comments, you
|
108
|
-
# can do:
|
109
|
-
#
|
110
|
-
# should_validate_length_of :comments, :maximum => 10, :with_kind_of => Comment
|
111
|
-
#
|
112
|
-
# Finally, it also accepts :token and :separator, to specify how the
|
113
|
-
# tokenizer should work. For example, if you are splitting the attribute
|
114
|
-
# per word:
|
115
|
-
#
|
116
|
-
# validates_length_of :essay, :minimum => 100, :tokenizer => lambda {|str| str.scan(/\w+/) }
|
117
|
-
#
|
118
|
-
# You could do this:
|
119
|
-
#
|
120
|
-
# should_validate_length_of :essay, :minimum => 100, :token => "word", :separator => " "
|
121
|
-
#
|
122
|
-
# == Gotcha
|
123
|
-
#
|
124
|
-
# In Rails 2.3.x, when :message is supplied, it overwrites the messages
|
125
|
-
# supplied in :wrong_length, :too_short and :too_long. However, in earlier
|
126
|
-
# versions, Rails ignores the :message option.
|
127
|
-
#
|
128
|
-
# == Examples
|
129
|
-
#
|
130
|
-
# it { should validate_length_of(:password).within(6..20) }
|
131
|
-
# it { should validate_length_of(:password).maximum(20) }
|
132
|
-
# it { should validate_length_of(:password).minimum(6) }
|
133
|
-
# it { should validate_length_of(:age).is(18) }
|
134
|
-
#
|
135
|
-
# should_validate_length_of :password, :within => 6..20
|
136
|
-
# should_validate_length_of :password, :maximum => 20
|
137
|
-
# should_validate_length_of :password, :minimum => 6
|
138
|
-
# should_validate_length_of :age, :is => 18
|
139
|
-
#
|
140
|
-
# should_validate_length_of :password do |m|
|
141
|
-
# m.minimum 6
|
142
|
-
# m.maximum 20
|
143
|
-
# end
|
144
|
-
#
|
145
|
-
def validate_length_of(*attributes, &block)
|
146
|
-
ValidateLengthOfMatcher.new(*attributes, &block).spec(self)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|