|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
1 |
module ThoughtBot # :nodoc: |
| |
2 |
module Shoulda # :nodoc: |
| |
3 |
# = Macro test helpers for your active record models |
| |
4 |
# |
| |
5 |
# These helpers will test most of the validations and associations for your ActiveRecord models. |
| |
6 |
# |
| |
7 |
# class UserTest < Test::Unit::TestCase |
| |
8 |
# should_require_attributes :name, :phone_number |
| |
9 |
# should_not_allow_values_for :phone_number, "abcd", "1234" |
| |
10 |
# should_allow_values_for :phone_number, "(123) 456-7890" |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
11 |
# |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
12 |
# should_protect_attributes :password |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
13 |
# |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
14 |
# should_have_one :profile |
| |
15 |
# should_have_many :dogs |
| |
16 |
# should_have_many :messes, :through => :dogs |
| |
17 |
# should_belong_to :lover |
| |
18 |
# end |
| |
19 |
# |
| |
20 |
# For all of these helpers, the last parameter may be a hash of options. |
| |
21 |
# |
| |
22 |
module ActiveRecord |
| |
23 |
# Ensures that the model cannot be saved if one of the attributes listed is not present. |
| |
24 |
# |
| |
25 |
# Options: |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
26 |
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
27 |
# Regexp or string. Default = <tt>/blank/</tt> |
| |
28 |
# |
| |
29 |
# Example: |
| |
30 |
# should_require_attributes :name, :phone_number |
| |
31 |
# |
| |
32 |
def should_require_attributes(*attributes) |
| |
33 |
message = get_options!(attributes, :message) |
| |
34 |
message ||= /blank/ |
| |
35 |
attributes.each do |attribute| |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
36 |
should_not_allow_values_for attribute, nil, :message => message, :should => "require #{attribute} to be set" |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
37 |
end |
|
021d7277
»
|
tsaleh |
2007-04-06 |
- refactored into modules |
38 |
end |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
39 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
40 |
# Ensures that the model cannot be saved if one of the attributes listed is not unique. |
| |
41 |
# Requires an existing record |
| |
42 |
# |
| |
43 |
# Options: |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
44 |
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
45 |
# Regexp or string. Default = <tt>/taken/</tt> |
| |
46 |
# * <tt>:scoped_to</tt> - field(s) to scope the uniqueness to. |
| |
47 |
# |
| |
48 |
# Examples: |
| |
49 |
# should_require_unique_attributes :keyword, :username |
| |
50 |
# should_require_unique_attributes :name, :message => "O NOES! SOMEONE STOELED YER NAME!" |
| |
51 |
# should_require_unique_attributes :email, :scoped_to => :name |
| |
52 |
# should_require_unique_attributes :address, :scoped_to => [:first_name, :last_name] |
| |
53 |
# |
| |
54 |
def should_require_unique_attributes(*attributes) |
| |
55 |
message, scope = get_options!(attributes, :message, :scoped_to) |
| |
56 |
scope = [*scope].compact |
| |
57 |
message ||= /taken/ |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
58 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
59 |
klass = model_class |
| |
60 |
attributes.each do |attribute| |
| |
61 |
attribute = attribute.to_sym |
|
66fc5c31
»
|
tsaleh |
2008-06-26 |
fixed naming of should_requ... |
62 |
should "require unique value for #{attribute}#{" scoped to #{scope.join(', ')}" unless scope.blank?}" do |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
63 |
assert existing = klass.find(:first), "Can't find first #{klass}" |
| |
64 |
object = klass.new |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
65 |
existing_value = existing.send(attribute) |
| |
66 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
67 |
if !scope.blank? |
| |
68 |
scope.each do |s| |
| |
69 |
assert_respond_to object, :"#{s}=", "#{klass.name} doesn't seem to have a #{s} attribute." |
|
13f5c2ae
»
|
rmm5t |
2008-06-27 |
Removed unnecessary databas... |
70 |
object.send("#{s}=", existing.send(s)) |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
71 |
end |
|
0a6da8b2
»
|
tsaleh |
2007-03-14 |
Documentation |
72 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
73 |
assert_bad_value(object, attribute, existing_value, message) |
| |
74 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
75 |
# Now test that the object is valid when changing the scoped attribute |
| |
76 |
# TODO: There is a chance that we could change the scoped field |
| |
77 |
# to a value that's already taken. An alternative implementation |
| |
78 |
# could actually find all values for scope and create a unique |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
79 |
# one. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
80 |
if !scope.blank? |
| |
81 |
scope.each do |s| |
| |
82 |
# Assume the scope is a foreign key if the field is nil |
|
13f5c2ae
»
|
rmm5t |
2008-06-27 |
Removed unnecessary databas... |
83 |
object.send("#{s}=", existing.send(s).nil? ? 1 : existing.send(s).next) |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
84 |
assert_good_value(object, attribute, existing_value, message) |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
85 |
end |
|
fc938bb1
»
|
tsaleh |
2008-06-22 |
Removed ThoughtBot module. |
86 |
end |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
87 |
end |
| |
88 |
end |
| |
89 |
end |
|
021d7277
»
|
tsaleh |
2007-04-06 |
- refactored into modules |
90 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
91 |
# Ensures that the attribute cannot be set on mass update. |
| |
92 |
# Requires an existing record. |
| |
93 |
# |
| |
94 |
# should_protect_attributes :password, :admin_flag |
| |
95 |
# |
| |
96 |
def should_protect_attributes(*attributes) |
| |
97 |
get_options!(attributes) |
| |
98 |
klass = model_class |
| |
99 |
|
| |
100 |
attributes.each do |attribute| |
| |
101 |
attribute = attribute.to_sym |
| |
102 |
should "protect #{attribute} from mass updates" do |
| |
103 |
protected = klass.protected_attributes || [] |
| |
104 |
accessible = klass.accessible_attributes || [] |
| |
105 |
|
| |
106 |
assert protected.include?(attribute.to_s) || !accessible.include?(attribute.to_s), |
| |
107 |
(accessible.empty? ? |
| |
108 |
"#{klass} is protecting #{protected.to_a.to_sentence}, but not #{attribute}." : |
| |
109 |
"#{klass} has made #{attribute} accessible") |
| |
110 |
end |
| |
111 |
end |
| |
112 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
113 |
|
|
5eb93044
»
|
boone |
2008-06-24 |
Added should_have_readonly_... |
114 |
# Ensures that the attribute cannot be changed once the record has been created. |
| |
115 |
# Requires an existing record. |
| |
116 |
# |
| |
117 |
# should_have_readonly_attributes :password, :admin_flag |
| |
118 |
# |
| |
119 |
def should_have_readonly_attributes(*attributes) |
| |
120 |
get_options!(attributes) |
| |
121 |
klass = model_class |
| |
122 |
|
| |
123 |
attributes.each do |attribute| |
| |
124 |
attribute = attribute.to_sym |
| |
125 |
should "make #{attribute} read-only" do |
| |
126 |
readonly = klass.readonly_attributes || [] |
| |
127 |
|
| |
128 |
assert readonly.include?(attribute.to_s), |
| |
129 |
(readonly.empty? ? |
| |
130 |
"#{klass} attribute #{attribute} is not read-only" : |
| |
131 |
"#{klass} is making #{readonly.to_a.to_sentence} read-only, but not #{attribute}.") |
| |
132 |
end |
| |
133 |
end |
| |
134 |
end |
| |
135 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
136 |
# Ensures that the attribute cannot be set to the given values |
| |
137 |
# Requires an existing record |
| |
138 |
# |
| |
139 |
# Options: |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
140 |
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
141 |
# Regexp or string. Default = <tt>/invalid/</tt> |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
142 |
# * <tt>:should</tt> - an override of the default should test name. |
| |
143 |
# Usually only used by other macros. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
144 |
# |
| |
145 |
# Example: |
| |
146 |
# should_not_allow_values_for :isbn, "bad 1", "bad 2" |
| |
147 |
# |
| |
148 |
def should_not_allow_values_for(attribute, *bad_values) |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
149 |
message, name = get_options!(bad_values, :message, :should) |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
150 |
message ||= /invalid/ |
| |
151 |
klass = model_class |
| |
152 |
bad_values.each do |v| |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
153 |
name ||= "not allow #{attribute} to be set to #{v.inspect}" |
| |
154 |
should name do |
|
13f5c2ae
»
|
rmm5t |
2008-06-27 |
Removed unnecessary databas... |
155 |
object = klass.new |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
156 |
assert_bad_value(object, attribute, v, message) |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
157 |
end |
| |
158 |
end |
| |
159 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
160 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
161 |
# Ensures that the attribute can be set to the given values. |
| |
162 |
# Requires an existing record |
| |
163 |
# |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
164 |
# Options: |
| |
165 |
# * <tt>:message</tt> - value the test shouldn't find in <tt>errors.on(:attribute)</tt>. |
| |
166 |
# Regexp or string. Default = <tt>//</tt> |
| |
167 |
# * <tt>:should</tt> - an override of the default should test name. |
| |
168 |
# Usually only used by other macros. |
| |
169 |
# |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
170 |
# Example: |
| |
171 |
# should_allow_values_for :isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0" |
| |
172 |
# |
| |
173 |
def should_allow_values_for(attribute, *good_values) |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
174 |
message, name = get_options!(good_values, :message, :should) |
| |
175 |
message ||= // |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
176 |
klass = model_class |
| |
177 |
good_values.each do |v| |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
178 |
name ||= "allow #{attribute} to be set to #{v.inspect}" |
| |
179 |
should name do |
|
13f5c2ae
»
|
rmm5t |
2008-06-27 |
Removed unnecessary databas... |
180 |
object = klass.new |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
181 |
assert_good_value(object, attribute, v, message) |
|
0a6da8b2
»
|
tsaleh |
2007-03-14 |
Documentation |
182 |
end |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
183 |
end |
|
021d7277
»
|
tsaleh |
2007-04-06 |
- refactored into modules |
184 |
end |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
185 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
186 |
# Ensures that the length of the attribute is in the given range |
| |
187 |
# Requires an existing record |
| |
188 |
# |
| |
189 |
# Options: |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
190 |
# * <tt>:short_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
191 |
# Regexp or string. Default = <tt>/short/</tt> |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
192 |
# * <tt>:long_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
193 |
# Regexp or string. Default = <tt>/long/</tt> |
| |
194 |
# |
| |
195 |
# Example: |
| |
196 |
# should_ensure_length_in_range :password, (6..20) |
| |
197 |
# |
| |
198 |
def should_ensure_length_in_range(attribute, range, opts = {}) |
| |
199 |
short_message, long_message = get_options!([opts], :short_message, :long_message) |
| |
200 |
short_message ||= /short/ |
| |
201 |
long_message ||= /long/ |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
202 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
203 |
min_length = range.first |
| |
204 |
max_length = range.last |
| |
205 |
same_length = (min_length == max_length) |
| |
206 |
|
| |
207 |
if min_length > 0 |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
208 |
min_value = "x" * (min_length - 1) |
| |
209 |
should_not_allow_values_for attribute, min_value, :message => short_message, :should => "not allow #{attribute} to be less than #{min_length} chars long" |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
210 |
end |
|
a50e871b
»
|
tsaleh |
2008-02-28 |
fixes to should_ensure_leng... |
211 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
212 |
if min_length > 0 |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
213 |
min_value = "x" * min_length |
| |
214 |
should_allow_values_for attribute, min_value, :message => short_message, :should => "allow #{attribute} to be exactly #{min_length} chars long" |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
215 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
216 |
|
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
217 |
max_value = "x" * (max_length + 1) |
| |
218 |
should_not_allow_values_for attribute, max_value, :message => long_message, :should => "not allow #{attribute} to be more than #{max_length} chars long" |
|
a50e871b
»
|
tsaleh |
2008-02-28 |
fixes to should_ensure_leng... |
219 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
220 |
unless same_length |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
221 |
max_value = "x" * max_length |
| |
222 |
should_allow_values_for attribute, max_value, :message => long_message, :should => "allow #{attribute} to be exactly #{max_length} chars long" |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
223 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
224 |
end |
| |
225 |
|
|
13f5c2ae
»
|
rmm5t |
2008-06-27 |
Removed unnecessary databas... |
226 |
# Ensures that the length of the attribute is at least a certain length |
| |
227 |
# Requires an existing record |
| |
228 |
# |
| |
229 |
# Options: |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
230 |
# * <tt>:short_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
13f5c2ae
»
|
rmm5t |
2008-06-27 |
Removed unnecessary databas... |
231 |
# Regexp or string. Default = <tt>/short/</tt> |
| |
232 |
# |
| |
233 |
# Example: |
| |
234 |
# should_ensure_length_at_least :name, 3 |
| |
235 |
# |
| |
236 |
def should_ensure_length_at_least(attribute, min_length, opts = {}) |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
237 |
short_message = get_options!([opts], :short_message) |
| |
238 |
short_message ||= /short/ |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
239 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
240 |
if min_length > 0 |
| |
241 |
min_value = "x" * (min_length - 1) |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
242 |
should_not_allow_values_for attribute, min_value, :message => short_message, :should => "not allow #{attribute} to be less than #{min_length} chars long" |
|
ec9ead07
»
|
tsaleh |
2008-04-12 |
applied should_ensure_lengt... |
243 |
end |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
244 |
|
| |
245 |
valid_value = "x" * (min_length) |
| |
246 |
should_allow_values_for attribute, valid_value, :message => short_message, :should => "allow #{attribute} to be at least #{min_length} chars long" |
|
ec9ead07
»
|
tsaleh |
2008-04-12 |
applied should_ensure_lengt... |
247 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
248 |
|
|
6511bcf3
»
|
thechrisoshow |
2008-06-19 |
Added should_ensure_length_... |
249 |
# Ensures that the length of the attribute is exactly a certain length |
| |
250 |
# Requires an existing record |
| |
251 |
# |
| |
252 |
# Options: |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
253 |
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
6511bcf3
»
|
thechrisoshow |
2008-06-19 |
Added should_ensure_length_... |
254 |
# Regexp or string. Default = <tt>/short/</tt> |
| |
255 |
# |
| |
256 |
# Example: |
| |
257 |
# should_ensure_length_is :ssn, 9 |
| |
258 |
# |
| |
259 |
def should_ensure_length_is(attribute, length, opts = {}) |
|
13f5c2ae
»
|
rmm5t |
2008-06-27 |
Removed unnecessary databas... |
260 |
message = get_options!([opts], :message) |
| |
261 |
message ||= /wrong length/ |
|
6511bcf3
»
|
thechrisoshow |
2008-06-19 |
Added should_ensure_length_... |
262 |
|
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
263 |
min_value = "x" * (length - 1) |
| |
264 |
should_not_allow_values_for attribute, min_value, :message => message, :should => "not allow #{attribute} to be less than #{length} chars long" |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
265 |
|
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
266 |
max_value = "x" * (length + 1) |
| |
267 |
should_not_allow_values_for attribute, max_value, :message => message, :should => "not allow #{attribute} to be greater than #{length} chars long" |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
268 |
|
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
269 |
valid_value = "x" * (length) |
| |
270 |
should_allow_values_for attribute, valid_value, :message => message, :should => "allow #{attribute} to be #{length} chars long" |
|
13f5c2ae
»
|
rmm5t |
2008-06-27 |
Removed unnecessary databas... |
271 |
end |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
272 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
273 |
# Ensure that the attribute is in the range specified |
| |
274 |
# Requires an existing record |
| |
275 |
# |
| |
276 |
# Options: |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
277 |
# * <tt>:low_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
278 |
# Regexp or string. Default = <tt>/included/</tt> |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
279 |
# * <tt>:high_message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
280 |
# Regexp or string. Default = <tt>/included/</tt> |
| |
281 |
# |
| |
282 |
# Example: |
| |
283 |
# should_ensure_value_in_range :age, (0..100) |
| |
284 |
# |
| |
285 |
def should_ensure_value_in_range(attribute, range, opts = {}) |
| |
286 |
low_message, high_message = get_options!([opts], :low_message, :high_message) |
| |
287 |
low_message ||= /included/ |
| |
288 |
high_message ||= /included/ |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
289 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
290 |
min = range.first |
| |
291 |
max = range.last |
| |
292 |
|
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
293 |
should_not_allow_values_for attribute, (min - 1), :message => low_message, :should => "not allow #{attribute} to be less than #{min}" |
| |
294 |
should_allow_values_for attribute, min, :message => low_message, :should => "allow #{attribute} to be #{min}" |
| |
295 |
should_not_allow_values_for attribute, (max + 1), :message => high_message, :should => "not allow #{attribute} to be more than #{max}" |
| |
296 |
should_allow_values_for attribute, max, :message => high_message, :should => "allow #{attribute} to be #{max}" |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
297 |
end |
| |
298 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
299 |
# Ensure that the attribute is numeric |
| |
300 |
# Requires an existing record |
| |
301 |
# |
| |
302 |
# Options: |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
303 |
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
304 |
# Regexp or string. Default = <tt>/number/</tt> |
| |
305 |
# |
| |
306 |
# Example: |
| |
307 |
# should_only_allow_numeric_values_for :age |
| |
308 |
# |
| |
309 |
def should_only_allow_numeric_values_for(*attributes) |
| |
310 |
message = get_options!(attributes, :message) |
| |
311 |
message ||= /number/ |
| |
312 |
attributes.each do |attribute| |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
313 |
should_not_allow_values_for attribute, "abcd", :message => message, :should => "only allow numeric values for #{attribute}" |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
314 |
end |
|
021d7277
»
|
tsaleh |
2007-04-06 |
- refactored into modules |
315 |
end |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
316 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
317 |
# Ensures that the has_many relationship exists. Will also test that the |
| |
318 |
# associated table has the required columns. Works with polymorphic |
| |
319 |
# associations. |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
320 |
# |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
321 |
# Options: |
| |
322 |
# * <tt>:through</tt> - association name for <tt>has_many :through</tt> |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
323 |
# * <tt>:dependent</tt> - tests that the association makes use of the dependent option. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
324 |
# |
| |
325 |
# Example: |
| |
326 |
# should_have_many :friends |
| |
327 |
# should_have_many :enemies, :through => :friends |
| |
328 |
# should_have_many :enemies, :dependent => :destroy |
| |
329 |
# |
| |
330 |
def should_have_many(*associations) |
| |
331 |
through, dependent = get_options!(associations, :through, :dependent) |
| |
332 |
klass = model_class |
| |
333 |
associations.each do |association| |
| |
334 |
name = "have many #{association}" |
| |
335 |
name += " through #{through}" if through |
| |
336 |
name += " dependent => #{dependent}" if dependent |
| |
337 |
should name do |
| |
338 |
reflection = klass.reflect_on_association(association) |
| |
339 |
assert reflection, "#{klass.name} does not have any relationship to #{association}" |
| |
340 |
assert_equal :has_many, reflection.macro |
|
af11bb11
»
|
tsaleh |
2008-06-07 |
Merge git://github.com/thec... |
341 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
342 |
associated_klass = (reflection.options[:class_name] || association.to_s.classify).constantize |
|
af11bb11
»
|
tsaleh |
2008-06-07 |
Merge git://github.com/thec... |
343 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
344 |
if through |
| |
345 |
through_reflection = klass.reflect_on_association(through) |
| |
346 |
assert through_reflection, "#{klass.name} does not have any relationship to #{through}" |
| |
347 |
assert_equal(through, reflection.options[:through]) |
| |
348 |
end |
|
fc938bb1
»
|
tsaleh |
2008-06-22 |
Removed ThoughtBot module. |
349 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
350 |
if dependent |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
351 |
assert_equal dependent.to_s, |
| |
352 |
reflection.options[:dependent].to_s, |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
353 |
"#{associated_klass.name} should have #{dependent} dependency" |
| |
354 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
355 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
356 |
# Check for the existence of the foreign key on the other table |
| |
357 |
unless reflection.options[:through] |
| |
358 |
if reflection.options[:foreign_key] |
| |
359 |
fk = reflection.options[:foreign_key] |
| |
360 |
elsif reflection.options[:as] |
| |
361 |
fk = reflection.options[:as].to_s.foreign_key |
| |
362 |
else |
| |
363 |
fk = reflection.primary_key_name |
| |
364 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
365 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
366 |
assert associated_klass.column_names.include?(fk.to_s), |
| |
367 |
"#{associated_klass.name} does not have a #{fk} foreign key." |
| |
368 |
end |
| |
369 |
end |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
370 |
end |
|
021d7277
»
|
tsaleh |
2007-04-06 |
- refactored into modules |
371 |
end |
|
fc938bb1
»
|
tsaleh |
2008-06-22 |
Removed ThoughtBot module. |
372 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
373 |
# Ensure that the has_one relationship exists. Will also test that the |
| |
374 |
# associated table has the required columns. Works with polymorphic |
| |
375 |
# associations. |
| |
376 |
# |
| |
377 |
# Example: |
| |
378 |
# should_have_one :god # unless hindu |
| |
379 |
# |
| |
380 |
def should_have_one(*associations) |
| |
381 |
get_options!(associations) |
| |
382 |
klass = model_class |
| |
383 |
associations.each do |association| |
| |
384 |
should "have one #{association}" do |
| |
385 |
reflection = klass.reflect_on_association(association) |
| |
386 |
assert reflection, "#{klass.name} does not have any relationship to #{association}" |
| |
387 |
assert_equal :has_one, reflection.macro |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
388 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
389 |
associated_klass = (reflection.options[:class_name] || association.to_s.camelize).constantize |
|
c397d016
»
|
tsaleh |
2008-02-28 |
fixed http://tammer.lightho... |
390 |
|
|
20c6f910
»
|
tsaleh |
2007-11-28 |
- fixed some overeager helpers |
391 |
if reflection.options[:foreign_key] |
| |
392 |
fk = reflection.options[:foreign_key] |
| |
393 |
elsif reflection.options[:as] |
| |
394 |
fk = reflection.options[:as].to_s.foreign_key |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
395 |
fk_type = fk.gsub(/_id$/, '_type') |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
396 |
assert associated_klass.column_names.include?(fk_type), |
| |
397 |
"#{associated_klass.name} does not have a #{fk_type} column." |
|
20c6f910
»
|
tsaleh |
2007-11-28 |
- fixed some overeager helpers |
398 |
else |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
399 |
fk = klass.name.foreign_key |
|
20c6f910
»
|
tsaleh |
2007-11-28 |
- fixed some overeager helpers |
400 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
401 |
assert associated_klass.column_names.include?(fk.to_s), |
| |
402 |
"#{associated_klass.name} does not have a #{fk} foreign key." |
|
0a6da8b2
»
|
tsaleh |
2007-03-14 |
Documentation |
403 |
end |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
404 |
end |
|
021d7277
»
|
tsaleh |
2007-04-06 |
- refactored into modules |
405 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
406 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
407 |
# Ensures that the has_and_belongs_to_many relationship exists, and that the join |
| |
408 |
# table is in place. |
| |
409 |
# |
| |
410 |
# should_have_and_belong_to_many :posts, :cars |
| |
411 |
# |
| |
412 |
def should_have_and_belong_to_many(*associations) |
| |
413 |
get_options!(associations) |
| |
414 |
klass = model_class |
| |
415 |
|
| |
416 |
associations.each do |association| |
| |
417 |
should "should have and belong to many #{association}" do |
| |
418 |
reflection = klass.reflect_on_association(association) |
| |
419 |
assert reflection, "#{klass.name} does not have any relationship to #{association}" |
| |
420 |
assert_equal :has_and_belongs_to_many, reflection.macro |
| |
421 |
table = reflection.options[:join_table] |
| |
422 |
assert ::ActiveRecord::Base.connection.tables.include?(table), "table #{table} doesn't exist" |
|
be4c51e7
»
|
tsaleh |
2008-02-28 |
refactored should_protect_a... |
423 |
end |
| |
424 |
end |
| |
425 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
426 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
427 |
# Ensure that the belongs_to relationship exists. |
| |
428 |
# |
| |
429 |
# should_belong_to :parent |
| |
430 |
# |
| |
431 |
def should_belong_to(*associations) |
| |
432 |
get_options!(associations) |
| |
433 |
klass = model_class |
| |
434 |
associations.each do |association| |
| |
435 |
should "belong_to #{association}" do |
| |
436 |
reflection = klass.reflect_on_association(association) |
| |
437 |
assert reflection, "#{klass.name} does not have any relationship to #{association}" |
| |
438 |
assert_equal :belongs_to, reflection.macro |
| |
439 |
|
| |
440 |
unless reflection.options[:polymorphic] |
| |
441 |
associated_klass = (reflection.options[:class_name] || association.to_s.classify).constantize |
| |
442 |
fk = reflection.options[:foreign_key] || reflection.primary_key_name |
| |
443 |
assert klass.column_names.include?(fk.to_s), "#{klass.name} does not have a #{fk} foreign key." |
| |
444 |
end |
| |
445 |
end |
|
c07bff35
»
|
tsaleh |
2007-10-31 |
Applied patches from Tim Ca... |
446 |
end |
| |
447 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
448 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
449 |
# Ensure that the given class methods are defined on the model. |
| |
450 |
# |
| |
451 |
# should_have_class_methods :find, :destroy |
| |
452 |
# |
| |
453 |
def should_have_class_methods(*methods) |
| |
454 |
get_options!(methods) |
| |
455 |
klass = model_class |
| |
456 |
methods.each do |method| |
| |
457 |
should "respond to class method ##{method}" do |
| |
458 |
assert_respond_to klass, method, "#{klass.name} does not have class method #{method}" |
|
c07bff35
»
|
tsaleh |
2007-10-31 |
Applied patches from Tim Ca... |
459 |
end |
| |
460 |
end |
| |
461 |
end |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
462 |
|
| |
463 |
# Ensure that the given instance methods are defined on the model. |
| |
464 |
# |
| |
465 |
# should_have_instance_methods :email, :name, :name= |
| |
466 |
# |
| |
467 |
def should_have_instance_methods(*methods) |
| |
468 |
get_options!(methods) |
| |
469 |
klass = model_class |
| |
470 |
methods.each do |method| |
| |
471 |
should "respond to instance method ##{method}" do |
| |
472 |
assert_respond_to klass.new, method, "#{klass.name} does not have instance method #{method}" |
| |
473 |
end |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
474 |
end |
|
021d7277
»
|
tsaleh |
2007-04-06 |
- refactored into modules |
475 |
end |
|
88ce3dab
»
|
tsaleh |
2007-11-23 |
added methods should_have_d... |
476 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
477 |
# Ensure that the given columns are defined on the models backing SQL table. |
| |
478 |
# |
| |
479 |
# should_have_db_columns :id, :email, :name, :created_at |
| |
480 |
# |
| |
481 |
def should_have_db_columns(*columns) |
| |
482 |
column_type = get_options!(columns, :type) |
| |
483 |
klass = model_class |
| |
484 |
columns.each do |name| |
| |
485 |
test_name = "have column #{name}" |
| |
486 |
test_name += " of type #{column_type}" if column_type |
| |
487 |
should test_name do |
| |
488 |
column = klass.columns.detect {|c| c.name == name.to_s } |
| |
489 |
assert column, "#{klass.name} does not have column #{name}" |
| |
490 |
end |
|
88ce3dab
»
|
tsaleh |
2007-11-23 |
added methods should_have_d... |
491 |
end |
| |
492 |
end |
| |
493 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
494 |
# Ensure that the given column is defined on the models backing SQL table. The options are the same as |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
495 |
# the instance variables defined on the column definition: :precision, :limit, :default, :null, |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
496 |
# :primary, :type, :scale, and :sql_type. |
| |
497 |
# |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
498 |
# should_have_db_column :email, :type => "string", :default => nil, :precision => nil, :limit => 255, |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
499 |
# :null => true, :primary => false, :scale => nil, :sql_type => 'varchar(255)' |
| |
500 |
# |
| |
501 |
def should_have_db_column(name, opts = {}) |
| |
502 |
klass = model_class |
| |
503 |
test_name = "have column named :#{name}" |
| |
504 |
test_name += " with options " + opts.inspect unless opts.empty? |
|
88ce3dab
»
|
tsaleh |
2007-11-23 |
added methods should_have_d... |
505 |
should test_name do |
| |
506 |
column = klass.columns.detect {|c| c.name == name.to_s } |
| |
507 |
assert column, "#{klass.name} does not have column #{name}" |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
508 |
opts.each do |k, v| |
| |
509 |
assert_equal column.instance_variable_get("@#{k}").to_s, v.to_s, ":#{name} column on table for #{klass} does not match option :#{k}" |
| |
510 |
end |
|
88ce3dab
»
|
tsaleh |
2007-11-23 |
added methods should_have_d... |
511 |
end |
| |
512 |
end |
|
102fe37a
»
|
tsaleh |
2008-04-26 |
added should_have_indices t... |
513 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
514 |
# Ensures that there are DB indices on the given columns or tuples of columns. |
| |
515 |
# Also aliased to should_have_index for readability |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
516 |
# |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
517 |
# should_have_indices :email, :name, [:commentable_type, :commentable_id] |
| |
518 |
# should_have_index :age |
| |
519 |
# |
| |
520 |
def should_have_indices(*columns) |
| |
521 |
table = model_class.name.tableize |
| |
522 |
indices = ::ActiveRecord::Base.connection.indexes(table).map(&:columns) |
| |
523 |
|
| |
524 |
columns.each do |column| |
| |
525 |
should "have index on #{table} for #{column.inspect}" do |
| |
526 |
columns = [column].flatten.map(&:to_s) |
| |
527 |
assert_contains(indices, columns) |
| |
528 |
end |
|
102fe37a
»
|
tsaleh |
2008-04-26 |
added should_have_indices t... |
529 |
end |
| |
530 |
end |
| |
531 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
532 |
alias_method :should_have_index, :should_have_indices |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
533 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
534 |
# Ensures that the model cannot be saved if one of the attributes listed is not accepted. |
| |
535 |
# |
| |
536 |
# Options: |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
537 |
# * <tt>:message</tt> - value the test expects to find in <tt>errors.on(:attribute)</tt>. |
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
538 |
# Regexp or string. Default = <tt>/must be accepted/</tt> |
| |
539 |
# |
| |
540 |
# Example: |
| |
541 |
# should_require_acceptance_of :eula |
| |
542 |
# |
| |
543 |
def should_require_acceptance_of(*attributes) |
| |
544 |
message = get_options!(attributes, :message) |
| |
545 |
message ||= /must be accepted/ |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
546 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
547 |
attributes.each do |attribute| |
|
063426f7
»
|
rmm5t |
2008-07-28 |
Further DRY'd Active Record... |
548 |
should_not_allow_values_for attribute, false, :message => message, :should => "require #{attribute} to be accepted" |
|
4f4e52f6
»
|
tsaleh |
2008-01-21 |
- added should_require_acce... |
549 |
end |
| |
550 |
end |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
551 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
552 |
private |
|
4c5768d1
»
|
rmm5t |
2008-07-28 |
DRY'd up Active Record macr... |
553 |
|
|
b415bff8
»
|
tsaleh |
2008-06-23 |
Revert bunch of bad commits: |
554 |
include ThoughtBot::Shoulda::Private |
|
7a4202f9
»
|
tsaleh |
2007-03-14 |
Moved everthing to trunk |
555 |
end |
| |
556 |
end |
|
91a3bb5e
»
|
tsaleh |
2008-01-20 |
fixed should_require_unique... |
557 |
end |