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,188 +0,0 @@
|
|
1
|
-
module Remarkable
|
2
|
-
module ActiveRecord
|
3
|
-
module Matchers
|
4
|
-
class ValidateNumericalityOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
5
|
-
arguments :collection => :attributes, :as => :attribute
|
6
|
-
|
7
|
-
optional :equal_to, :greater_than_or_equal_to, :greater_than,
|
8
|
-
:less_than_or_equal_to, :less_than, :message
|
9
|
-
|
10
|
-
optional :only_integer, :odd, :even, :allow_nil, :allow_blank, :default => true
|
11
|
-
|
12
|
-
collection_assertions :only_numeric_values?, :allow_blank?, :allow_nil?,
|
13
|
-
:only_integer?, :only_odd?, :only_even?, :equals_to?,
|
14
|
-
:less_than_minimum?, :more_than_maximum?
|
15
|
-
|
16
|
-
# Before assertions, we rearrange the values.
|
17
|
-
#
|
18
|
-
# Notice that :less_than gives a maximum value while :more_than given
|
19
|
-
# a minimum value. While :equal_to generate both.
|
20
|
-
#
|
21
|
-
before_assert do
|
22
|
-
@maximum_values = {}
|
23
|
-
@minimum_values = {}
|
24
|
-
|
25
|
-
if value = @options[:equal_to]
|
26
|
-
@maximum_values[:equal_to] = value
|
27
|
-
@minimum_values[:equal_to] = value
|
28
|
-
elsif value = @options[:less_than]
|
29
|
-
@maximum_values[:less_than] = value - 1
|
30
|
-
elsif value = @options[:greater_than]
|
31
|
-
@minimum_values[:greater_than] = value + 1
|
32
|
-
elsif value = @options[:less_than_or_equal_to]
|
33
|
-
@maximum_values[:less_than_or_equal_to] = value
|
34
|
-
elsif value = @options[:greater_than_or_equal_to]
|
35
|
-
@minimum_values[:greater_than_or_equal_to] = value
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def allow_nil?
|
42
|
-
super(default_message_for(:not_a_number))
|
43
|
-
end
|
44
|
-
|
45
|
-
def allow_blank?
|
46
|
-
super(default_message_for(:not_a_number))
|
47
|
-
end
|
48
|
-
|
49
|
-
def only_numeric_values?
|
50
|
-
bad?("abcd", default_message_for(:not_a_number))
|
51
|
-
end
|
52
|
-
|
53
|
-
def only_integer?
|
54
|
-
assert_bad_or_good_if_key(:only_integer, valid_value_for_test.to_f, default_message_for(:not_a_number))
|
55
|
-
end
|
56
|
-
|
57
|
-
# In ActiveRecord, when we supply :even, does not matter the value, it
|
58
|
-
# considers that should even values should be accepted.
|
59
|
-
#
|
60
|
-
def only_even?
|
61
|
-
return true unless @options[:even]
|
62
|
-
bad?(even_valid_value_for_test + 1, default_message_for(:even))
|
63
|
-
end
|
64
|
-
|
65
|
-
# In ActiveRecord, when we supply :odd, does not matter the value, it
|
66
|
-
# considers that should odd values should be accepted.
|
67
|
-
#
|
68
|
-
def only_odd?
|
69
|
-
return true unless @options[:odd]
|
70
|
-
bad?(even_valid_value_for_test, default_message_for(:odd))
|
71
|
-
end
|
72
|
-
|
73
|
-
# Check equal_to for all registered values.
|
74
|
-
#
|
75
|
-
def equals_to?
|
76
|
-
values = {}
|
77
|
-
@maximum_values.each { |k, v| values[k] = v }
|
78
|
-
@minimum_values.each { |k, v| values[k] = v }
|
79
|
-
|
80
|
-
values.each do |key, value|
|
81
|
-
return false, :count => value unless good?(value, default_message_for(key))
|
82
|
-
end
|
83
|
-
true
|
84
|
-
end
|
85
|
-
|
86
|
-
# Check more_than_maximum? for equal_to, less_than and
|
87
|
-
# less_than_or_equal_to options.
|
88
|
-
#
|
89
|
-
def more_than_maximum?
|
90
|
-
@maximum_values.each do |key, value|
|
91
|
-
return false, :count => value unless bad?(value + 1, default_message_for(key))
|
92
|
-
end
|
93
|
-
true
|
94
|
-
end
|
95
|
-
|
96
|
-
# Check less_than_minimum? for equal_to, more_than and
|
97
|
-
# more_than_or_equal_to options.
|
98
|
-
#
|
99
|
-
def less_than_minimum?
|
100
|
-
@minimum_values.each do |key, value|
|
101
|
-
return false, :count => value unless bad?(value - 1, default_message_for(key))
|
102
|
-
end
|
103
|
-
true
|
104
|
-
end
|
105
|
-
|
106
|
-
# Returns a valid value for test.
|
107
|
-
#
|
108
|
-
def valid_value_for_test
|
109
|
-
value = @options[:equal_to] || @options[:less_than_or_equal_to] || @options[:greater_than_or_equal_to]
|
110
|
-
|
111
|
-
value ||= @options[:less_than] - 1 if @options[:less_than]
|
112
|
-
value ||= @options[:greater_than] + 1 if @options[:greater_than]
|
113
|
-
|
114
|
-
value ||= 10
|
115
|
-
|
116
|
-
if @options[:even]
|
117
|
-
value = (value / 2) * 2
|
118
|
-
elsif @options[:odd]
|
119
|
-
value = ((value / 2) * 2) + 1
|
120
|
-
end
|
121
|
-
|
122
|
-
value
|
123
|
-
end
|
124
|
-
|
125
|
-
# Returns a valid even value for test.
|
126
|
-
# The method valid_value_for_test checks for :even option but does not
|
127
|
-
# return necessarily an even value
|
128
|
-
#
|
129
|
-
def even_valid_value_for_test
|
130
|
-
(valid_value_for_test / 2) * 2
|
131
|
-
end
|
132
|
-
|
133
|
-
# Returns the default message for each key (:odd, :even, :equal_to, ...).
|
134
|
-
# If the user provided a message, we use it, otherwise we should use
|
135
|
-
# the given key as message.
|
136
|
-
#
|
137
|
-
# For example, a default_message_for(:odd), if none is provided, will be
|
138
|
-
# :odd. So we have create :odd_message in the options hash, that when
|
139
|
-
# called later, will return :odd.
|
140
|
-
#
|
141
|
-
def default_message_for(key)
|
142
|
-
if @options[:message]
|
143
|
-
:message
|
144
|
-
else
|
145
|
-
@options[:"#{key}_message"] = key
|
146
|
-
:"#{key}_message"
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
# Ensures that the given attributes accepts only numbers.
|
152
|
-
#
|
153
|
-
# == Options
|
154
|
-
#
|
155
|
-
# * <tt>:only_integer</tt> - when supplied, checks if it accepts only integers or not
|
156
|
-
# * <tt>:odd</tt> - when supplied, checks if it accepts only odd values or not
|
157
|
-
# * <tt>:even</tt> - when supplied, checks if it accepts only even values or not
|
158
|
-
# * <tt>:equal_to</tt> - when supplied, checks if attributes are only valid when equal to given value
|
159
|
-
# * <tt>:less_than</tt> - when supplied, checks if attributes are only valid when less than given value
|
160
|
-
# * <tt>:greater_than</tt> - when supplied, checks if attributes are only valid when greater than given value
|
161
|
-
# * <tt>:less_than_or_equal_to</tt> - when supplied, checks if attributes are only valid when less than or equal to given value
|
162
|
-
# * <tt>:greater_than_or_equal_to</tt> - when supplied, checks if attributes are only valid when greater than or equal to given value
|
163
|
-
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
164
|
-
# Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.not_a_number')</tt>
|
165
|
-
#
|
166
|
-
# == Examples
|
167
|
-
#
|
168
|
-
# it { should validate_numericality_of(:age).odd }
|
169
|
-
# it { should validate_numericality_of(:age).even }
|
170
|
-
# it { should validate_numericality_of(:age).only_integer }
|
171
|
-
# it { should validate_numericality_of(:age, :odd => true) }
|
172
|
-
# it { should validate_numericality_of(:age, :even => true) }
|
173
|
-
#
|
174
|
-
# should_validate_numericality_of :age, :price
|
175
|
-
# should_validate_numericality_of :price, :only_integer => false, :greater_than => 10
|
176
|
-
#
|
177
|
-
# should_validate_numericality_of :price do |m|
|
178
|
-
# m.only_integer = false
|
179
|
-
# m.greater_than = 10
|
180
|
-
# end
|
181
|
-
#
|
182
|
-
def validate_numericality_of(*attributes, &block)
|
183
|
-
ValidateNumericalityOfMatcher.new(*attributes, &block).spec(self)
|
184
|
-
end
|
185
|
-
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
@@ -1,91 +0,0 @@
|
|
1
|
-
module Remarkable
|
2
|
-
module ActiveRecord
|
3
|
-
# Holds ActiveRecord matchers.
|
4
|
-
#
|
5
|
-
# == Validations matchers
|
6
|
-
#
|
7
|
-
# Remarkable supports all ActiveRecord validations, and the only options
|
8
|
-
# not supported in those matchers is the :on options. So whenever you have
|
9
|
-
# to test that a validation runs on update, you have to do reproduce the
|
10
|
-
# state in your tests:
|
11
|
-
#
|
12
|
-
# describe Project do
|
13
|
-
# describe 'validations on create' do
|
14
|
-
# should_validate_presence_of :title
|
15
|
-
# end
|
16
|
-
#
|
17
|
-
# describe 'validations on update' do
|
18
|
-
# subject { Post.create!(@valid_attributes) }
|
19
|
-
# should_validate_presence_of :updated_at
|
20
|
-
# end
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# Another behavior in validations is the :message option. Whenever you change
|
24
|
-
# the message in your model, it must be given in your tests too:
|
25
|
-
#
|
26
|
-
# class Post < ActiveRecord::Base
|
27
|
-
# validates_presence_of :title, :message => 'must be filled'
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# describe Post do
|
31
|
-
# should_validate_presence_of :title #=> fails
|
32
|
-
# should_validate_presence_of :title, :message => 'must be filled'
|
33
|
-
# end
|
34
|
-
#
|
35
|
-
# However, if you change the title using the I18n API, you don't need to
|
36
|
-
# specify the message in your tests, because it's retrieved properly.
|
37
|
-
#
|
38
|
-
module Matchers
|
39
|
-
class ValidatePresenceOfMatcher < Remarkable::ActiveRecord::Base #:nodoc:
|
40
|
-
arguments :collection => :attributes, :as => :attribute
|
41
|
-
optional :message
|
42
|
-
|
43
|
-
collection_assertions :allow_nil?
|
44
|
-
default_options :message => :blank
|
45
|
-
|
46
|
-
protected
|
47
|
-
|
48
|
-
def allow_nil?
|
49
|
-
bad?(blank_value, :message)
|
50
|
-
end
|
51
|
-
|
52
|
-
def blank_value
|
53
|
-
collection? ? [] : nil
|
54
|
-
end
|
55
|
-
|
56
|
-
def collection?
|
57
|
-
if reflection = find_reflection
|
58
|
-
[:has_many, :has_and_belongs_to_many].include?(reflection.macro)
|
59
|
-
else
|
60
|
-
false
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
|
66
|
-
def find_reflection
|
67
|
-
if subject_class.respond_to?(:reflect_on_association)
|
68
|
-
subject_class.reflect_on_association(@attribute)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
# Ensures that the model cannot be saved if one of the attributes listed is not present.
|
75
|
-
#
|
76
|
-
# == Options
|
77
|
-
#
|
78
|
-
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>.
|
79
|
-
# Regexp, string or symbol. Default = <tt>I18n.translate('activerecord.errors.messages.blank')</tt>
|
80
|
-
#
|
81
|
-
# == Examples
|
82
|
-
#
|
83
|
-
# should_validate_presence_of :name, :phone_number
|
84
|
-
# it { should validate_presence_of(:name, :phone_number) }
|
85
|
-
#
|
86
|
-
def validate_presence_of(*args, &block)
|
87
|
-
ValidatePresenceOfMatcher.new(*args, &block).spec(self)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|