/
assertions.rb
86 lines (80 loc) · 3.37 KB
/
assertions.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
module Shoulda # :nodoc:
module ActiveRecord # :nodoc:
module Assertions
# Asserts that the given object can be saved
#
# assert_save User.new(params)
def assert_save(obj)
assert obj.save, "Errors: #{pretty_error_messages obj}"
obj.reload
end
# Asserts that the given object is valid
#
# assert_valid User.new(params)
def assert_valid(obj)
assert obj.valid?, "Errors: #{pretty_error_messages obj}"
end
# Asserts that an Active Record model validates with the passed
# <tt>value</tt> by making sure the <tt>error_message_to_avoid</tt> is not
# contained within the list of errors for that attribute.
#
# assert_good_value(User.new, :email, "user@example.com")
# assert_good_value(User.new, :ssn, "123456789", /length/)
#
# If a class is passed as the first argument, a new object will be
# instantiated before the assertion. If an instance variable exists with
# the same name as the class (underscored), that object will be used
# instead.
#
# assert_good_value(User, :email, "user@example.com")
#
# @product = Product.new(:tangible => false)
# assert_good_value(Product, :price, "0")
def assert_good_value(object_or_klass, attribute, value, error_message_to_avoid = //)
object = get_instance_of(object_or_klass)
object.send("#{attribute}=", value)
object.valid?
assert_does_not_contain(object.errors.on(attribute), error_message_to_avoid, "when set to #{value.inspect}")
end
# Asserts that an Active Record model invalidates the passed
# <tt>value</tt> by making sure the <tt>error_message_to_expect</tt> is
# contained within the list of errors for that attribute.
#
# assert_bad_value(User.new, :email, "invalid")
# assert_bad_value(User.new, :ssn, "123", /length/)
#
# If a class is passed as the first argument, a new object will be
# instantiated before the assertion. If an instance variable exists with
# the same name as the class (underscored), that object will be used
# instead.
#
# assert_bad_value(User, :email, "invalid")
#
# @product = Product.new(:tangible => true)
# assert_bad_value(Product, :price, "0")
def assert_bad_value(object_or_klass, attribute, value,
error_message_to_expect = self.class.default_error_message(:invalid))
object = get_instance_of(object_or_klass)
object.send("#{attribute}=", value)
assert !object.valid?, "#{object.class} allowed #{value.inspect} as a value for #{attribute}"
assert object.errors.on(attribute), "There are no errors on #{attribute} after being set to #{value.inspect}"
assert_contains(object.errors.on(attribute), error_message_to_expect, "when set to #{value.inspect}")
end
def pretty_error_messages(obj)
obj.errors.map do |a, m|
msg = "#{a} #{m}"
msg << " (#{obj.send(a).inspect})" unless a.to_sym == :base
end
end
private
def get_instance_of(object_or_klass)
if object_or_klass.is_a?(Class)
klass = object_or_klass
instance_variable_get("@#{klass.to_s.underscore}") || klass.new
else
object_or_klass
end
end
end
end
end