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.
@@ -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