-
-
Notifications
You must be signed in to change notification settings - Fork 912
/
have_readonly_attribute_matcher.rb
71 lines (64 loc) · 1.89 KB
/
have_readonly_attribute_matcher.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
module Shoulda
module Matchers
module ActiveRecord
# The `have_readonly_attribute` matcher tests usage of the
# `attr_readonly` macro.
#
# class User < ActiveRecord::Base
# attr_readonly :password
# end
#
# # RSpec
# RSpec.describe User, type: :model do
# it { should have_readonly_attribute(:password) }
# end
#
# # Minitest (Shoulda)
# class UserTest < ActiveSupport::TestCase
# should have_readonly_attribute(:password)
# end
#
# @return [HaveReadonlyAttributeMatcher]
#
def have_readonly_attribute(value)
HaveReadonlyAttributeMatcher.new(value)
end
# @private
class HaveReadonlyAttributeMatcher
def initialize(attribute)
@attribute = attribute.to_s
end
attr_reader :failure_message, :failure_message_when_negated
def matches?(subject)
@subject = subject
if readonly_attributes.include?(@attribute)
@failure_message_when_negated = "Did not expect #{@attribute}"\
' to be read-only'
true
else
@failure_message =
if readonly_attributes.empty?
"#{class_name} attribute #{@attribute} " <<
'is not read-only'
else
"#{class_name} is making " <<
"#{readonly_attributes.to_a.to_sentence} " <<
"read-only, but not #{@attribute}."
end
false
end
end
def description
"make #{@attribute} read-only"
end
private
def readonly_attributes
@_readonly_attributes ||= @subject.class.readonly_attributes || []
end
def class_name
@subject.class.name
end
end
end
end
end