| Module | Shoulda::ActiveRecord::Macros |
| In: |
lib/shoulda/active_record/macros.rb
|
These helpers will test most of the validations and associations for your ActiveRecord models.
class UserTest < Test::Unit::TestCase
should_validate_presence_of :name, :phone_number
should_not_allow_values_for :phone_number, "abcd", "1234"
should_allow_values_for :phone_number, "(123) 456-7890"
should_not_allow_mass_assignment_of :password
should_have_one :profile
should_have_many :dogs
should_have_many :messes, :through => :dogs
should_belong_to :lover
end
For all of these helpers, the last parameter may be a hash of options.
Ensures that the attribute can be set on mass update.
should_allow_mass_assignment_of :first_name, :last_name
# File lib/shoulda/active_record/macros.rb, line 83
83: def should_allow_mass_assignment_of(*attributes)
84: get_options!(attributes)
85:
86: attributes.each do |attribute|
87: matcher = allow_mass_assignment_of(attribute)
88: should matcher.description do
89: assert_accepts matcher, subject
90: end
91: end
92: end
Ensures that the attribute can be set to the given values.
Example:
should_allow_values_for :isbn, "isbn 1 2345 6789 0", "ISBN 1-2345-6789-0"
# File lib/shoulda/active_record/macros.rb, line 149
149: def should_allow_values_for(attribute, *good_values)
150: get_options!(good_values)
151: good_values.each do |value|
152: matcher = allow_value(value).for(attribute)
153: should matcher.description do
154: assert_accepts matcher, subject
155: end
156: end
157: end
Ensure that the belongs_to relationship exists.
should_belong_to :parent
# File lib/shoulda/active_record/macros.rb, line 335
335: def should_belong_to(*associations)
336: dependent = get_options!(associations, :dependent)
337: associations.each do |association|
338: matcher = belong_to(association).dependent(dependent)
339: should matcher.description do
340: assert_accepts(matcher, subject)
341: end
342: end
343: end
Ensures that the length of the attribute is at least a certain length
Options:
Example:
should_ensure_length_at_least :name, 3
# File lib/shoulda/active_record/macros.rb, line 194
194: def should_ensure_length_at_least(attribute, min_length, opts = {})
195: short_message = get_options!([opts], :short_message)
196:
197: matcher = ensure_length_of(attribute).
198: is_at_least(min_length).
199: with_short_message(short_message)
200:
201: should matcher.description do
202: assert_accepts matcher, subject
203: end
204: end
Ensures that the length of the attribute is in the given range
Options:
Example:
should_ensure_length_in_range :password, (6..20)
# File lib/shoulda/active_record/macros.rb, line 170
170: def should_ensure_length_in_range(attribute, range, opts = {})
171: short_message, long_message = get_options!([opts],
172: :short_message,
173: :long_message)
174: matcher = ensure_length_of(attribute).
175: is_at_least(range.first).
176: with_short_message(short_message).
177: is_at_most(range.last).
178: with_long_message(long_message)
179:
180: should matcher.description do
181: assert_accepts matcher, subject
182: end
183: end
Ensures that the length of the attribute is exactly a certain length
Options:
Example:
should_ensure_length_is :ssn, 9
# File lib/shoulda/active_record/macros.rb, line 215
215: def should_ensure_length_is(attribute, length, opts = {})
216: message = get_options!([opts], :message)
217: matcher = ensure_length_of(attribute).
218: is_equal_to(length).
219: with_message(message)
220:
221: should matcher.description do
222: assert_accepts matcher, subject
223: end
224: end
Ensure that the attribute is in the range specified
Options:
Example:
should_ensure_value_in_range :age, (0..100)
# File lib/shoulda/active_record/macros.rb, line 237
237: def should_ensure_value_in_range(attribute, range, opts = {})
238: message, low_message, high_message = get_options!([opts],
239: :message,
240: :low_message,
241: :high_message)
242: matcher = ensure_inclusion_of(attribute).
243: in_range(range).
244: with_message(message).
245: with_low_message(low_message).
246: with_high_message(high_message)
247: should matcher.description do
248: assert_accepts matcher, subject
249: end
250: end
Ensures that the has_and_belongs_to_many relationship exists, and that the join table is in place.
should_have_and_belong_to_many :posts, :cars
# File lib/shoulda/active_record/macros.rb, line 320
320: def should_have_and_belong_to_many(*associations)
321: get_options!(associations)
322:
323: associations.each do |association|
324: matcher = have_and_belong_to_many(association)
325: should matcher.description do
326: assert_accepts(matcher, subject)
327: end
328: end
329: end
Ensure that the given class methods are defined on the model.
should_have_class_methods :find, :destroy
# File lib/shoulda/active_record/macros.rb, line 349
349: def should_have_class_methods(*methods)
350: get_options!(methods)
351: klass = described_type
352: methods.each do |method|
353: should "respond to class method ##{method}" do
354: assert_respond_to klass, method, "#{klass.name} does not have class method #{method}"
355: end
356: end
357: end
Ensure that the given columns are defined on the models backing SQL table. Also aliased to should_have_db_column for readability. Takes the same options available in migrations: :type, :precision, :limit, :default, :null, and :scale
Examples:
should_have_db_columns :id, :email, :name, :created_at should_have_db_column :email, :type => "string", :limit => 255 should_have_db_column :salary, :decimal, :precision => 15, :scale => 2 should_have_db_column :admin, :default => false, :null => false
# File lib/shoulda/active_record/macros.rb, line 386
386: def should_have_db_columns(*columns)
387: column_type, precision, limit, default, null, scale, sql_type =
388: get_options!(columns, :type, :precision, :limit,
389: :default, :null, :scale, :sql_type)
390: columns.each do |name|
391: matcher = have_db_column(name).
392: of_type(column_type).
393: with_options(:precision => precision, :limit => limit,
394: :default => default, :null => null,
395: :scale => scale, :sql_type => sql_type)
396: should matcher.description do
397: assert_accepts(matcher, subject)
398: end
399: end
400: end
Ensures that there are DB indices on the given columns or tuples of columns. Also aliased to should_have_db_index for readability
Options:
Examples:
should_have_db_indices :email, :name, [:commentable_type, :commentable_id] should_have_db_index :age should_have_db_index :ssn, :unique => true
# File lib/shoulda/active_record/macros.rb, line 420
420: def should_have_db_indices(*columns)
421: unique = get_options!(columns, :unique)
422:
423: columns.each do |column|
424: matcher = have_db_index(column).unique(unique)
425: should matcher.description do
426: assert_accepts(matcher, subject)
427: end
428: end
429: end
Deprecated. See should_have_db_index
# File lib/shoulda/active_record/macros.rb, line 434
434: def should_have_index(*args)
435: warn "[DEPRECATION] should_have_index is deprecated. " <<
436: "Use should_have_db_index instead."
437: should_have_db_index(*args)
438: end
Deprecated. See should_have_db_indices
# File lib/shoulda/active_record/macros.rb, line 441
441: def should_have_indices(*args)
442: warn "[DEPRECATION] should_have_indices is deprecated. " <<
443: "Use should_have_db_indices instead."
444: should_have_db_indices(*args)
445: end
Ensure that the given instance methods are defined on the model.
should_have_instance_methods :email, :name, :name=
# File lib/shoulda/active_record/macros.rb, line 363
363: def should_have_instance_methods(*methods)
364: get_options!(methods)
365: klass = described_type
366: methods.each do |method|
367: should "respond to instance method ##{method}" do
368: assert_respond_to klass.new, method, "#{klass.name} does not have instance method #{method}"
369: end
370: end
371: end
Ensures that the has_many relationship exists. Will also test that the associated table has the required columns. Works with polymorphic associations.
Options:
Example:
should_have_many :friends should_have_many :enemies, :through => :friends should_have_many :enemies, :dependent => :destroy
# File lib/shoulda/active_record/macros.rb, line 285
285: def should_have_many(*associations)
286: through, dependent = get_options!(associations, :through, :dependent)
287: associations.each do |association|
288: matcher = have_many(association).through(through).dependent(dependent)
289: should matcher.description do
290: assert_accepts(matcher, subject)
291: end
292: end
293: end
Deprecated.
Ensures that the model has a method named scope_name that returns a NamedScope object with the proxy options set to the options you supply. scope_name can be either a symbol, or a method call which will be evaled against the model. The eval‘d method call has access to all the same instance variables that a should statement would.
Options: Any of the options that the named scope would pass on to find.
Example:
should_have_named_scope :visible, :conditions => {:visible => true}
Passes for
named_scope :visible, :conditions => {:visible => true}
Or for
def self.visible
scoped(:conditions => {:visible => true})
end
You can test lambdas or methods that return ActiveRecord#scoped calls:
should_have_named_scope 'recent(5)', :limit => 5 should_have_named_scope 'recent(1)', :limit => 1
Passes for
named_scope :recent, lambda {|c| {:limit => c}}
Or for
def self.recent(c)
scoped(:limit => c)
end
# File lib/shoulda/active_record/macros.rb, line 504
504: def should_have_named_scope(scope_call, find_options = nil)
505: matcher = have_named_scope(scope_call).finding(find_options)
506: should matcher.description do
507: assert_accepts matcher.in_context(self), subject
508: end
509: end
Ensure that the has_one relationship exists. Will also test that the associated table has the required columns. Works with polymorphic associations.
Options:
Example:
should_have_one :god # unless hindu
# File lib/shoulda/active_record/macros.rb, line 305
305: def should_have_one(*associations)
306: dependent, through = get_options!(associations, :dependent, :through)
307: associations.each do |association|
308: matcher = have_one(association).dependent(dependent).through(through)
309: should matcher.description do
310: assert_accepts(matcher, subject)
311: end
312: end
313: end
Ensures that the attribute cannot be changed once the record has been created.
should_have_readonly_attributes :password, :admin_flag
# File lib/shoulda/active_record/macros.rb, line 113
113: def should_have_readonly_attributes(*attributes)
114: get_options!(attributes)
115:
116: attributes.each do |attribute|
117: matcher = have_readonly_attribute(attribute)
118: should matcher.description do
119: assert_accepts matcher, subject
120: end
121: end
122: end
Ensures that the attribute cannot be set on mass update.
should_not_allow_mass_assignment_of :password, :admin_flag
# File lib/shoulda/active_record/macros.rb, line 98
98: def should_not_allow_mass_assignment_of(*attributes)
99: get_options!(attributes)
100:
101: attributes.each do |attribute|
102: matcher = allow_mass_assignment_of(attribute)
103: should "not #{matcher.description}" do
104: assert_rejects matcher, subject
105: end
106: end
107: end
Ensures that the attribute cannot be set to the given values
Options:
Example:
should_not_allow_values_for :isbn, "bad 1", "bad 2"
# File lib/shoulda/active_record/macros.rb, line 134
134: def should_not_allow_values_for(attribute, *bad_values)
135: message = get_options!(bad_values, :message)
136: bad_values.each do |value|
137: matcher = allow_value(value).for(attribute).with_message(message)
138: should "not #{matcher.description}" do
139: assert_rejects matcher, subject
140: end
141: end
142: end
Ensures that the model cannot be saved if one of the attributes listed is not accepted.
Options:
Example:
should_validate_acceptance_of :eula
# File lib/shoulda/active_record/macros.rb, line 456
456: def should_validate_acceptance_of(*attributes)
457: message = get_options!(attributes, :message)
458:
459: attributes.each do |attribute|
460: matcher = validate_acceptance_of(attribute).with_message(message)
461: should matcher.description do
462: assert_accepts matcher, subject
463: end
464: end
465: end
Ensure that the attribute is numeric
Options:
Example:
should_validate_numericality_of :age
# File lib/shoulda/active_record/macros.rb, line 261
261: def should_validate_numericality_of(*attributes)
262: message = get_options!(attributes, :message)
263: attributes.each do |attribute|
264: matcher = validate_numericality_of(attribute).
265: with_message(message)
266: should matcher.description do
267: assert_accepts matcher, subject
268: end
269: end
270: end
Ensures that the model cannot be saved if one of the attributes listed is not present.
Options:
Example:
should_validate_presence_of :name, :phone_number
# File lib/shoulda/active_record/macros.rb, line 35
35: def should_validate_presence_of(*attributes)
36: message = get_options!(attributes, :message)
37:
38: attributes.each do |attribute|
39: matcher = validate_presence_of(attribute).with_message(message)
40: should matcher.description do
41: assert_accepts(matcher, subject)
42: end
43: end
44: end
Examples:
should_validate_uniqueness_of :keyword, :username should_validate_uniqueness_of :name, :message => "O NOES! SOMEONE STOELED YER NAME!" should_validate_uniqueness_of :email, :scoped_to => :name should_validate_uniqueness_of :address, :scoped_to => [:first_name, :last_name] should_validate_uniqueness_of :email, :case_sensitive => false
# File lib/shoulda/active_record/macros.rb, line 64
64: def should_validate_uniqueness_of(*attributes)
65: message, scope, case_sensitive = get_options!(attributes, :message, :scoped_to, :case_sensitive)
66: scope = [*scope].compact
67: case_sensitive = true if case_sensitive.nil?
68:
69: attributes.each do |attribute|
70: matcher = validate_uniqueness_of(attribute).
71: with_message(message).scoped_to(scope)
72: matcher = matcher.case_insensitive unless case_sensitive
73: should matcher.description do
74: assert_accepts(matcher, subject)
75: end
76: end
77: end