active_attr 0.4.1 → 0.5.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of active_attr might be problematic. Click here for more details.

Files changed (53) hide show
  1. data/.travis.yml +7 -0
  2. data/CHANGELOG.md +14 -0
  3. data/README.md +57 -25
  4. data/Rakefile +2 -0
  5. data/active_attr.gemspec +3 -2
  6. data/gemfiles/rails_3_1.gemfile +6 -0
  7. data/lib/active_attr.rb +3 -2
  8. data/lib/active_attr/attribute_defaults.rb +120 -0
  9. data/lib/active_attr/attribute_definition.rb +25 -2
  10. data/lib/active_attr/attributes.rb +44 -33
  11. data/lib/active_attr/logger.rb +8 -8
  12. data/lib/active_attr/mass_assignment.rb +2 -1
  13. data/lib/active_attr/matchers/have_attribute_matcher.rb +28 -10
  14. data/lib/active_attr/model.rb +2 -0
  15. data/lib/active_attr/query_attributes.rb +2 -5
  16. data/lib/active_attr/typecasted_attributes.rb +77 -0
  17. data/lib/active_attr/typecasting.rb +60 -0
  18. data/lib/active_attr/typecasting/boolean.rb +6 -0
  19. data/lib/active_attr/typecasting/boolean_typecaster.rb +21 -0
  20. data/lib/active_attr/typecasting/date_time_typecaster.rb +14 -0
  21. data/lib/active_attr/typecasting/date_typecaster.rb +14 -0
  22. data/lib/active_attr/typecasting/float_typecaster.rb +11 -0
  23. data/lib/active_attr/typecasting/integer_typecaster.rb +12 -0
  24. data/lib/active_attr/typecasting/object_typecaster.rb +9 -0
  25. data/lib/active_attr/typecasting/string_typecaster.rb +11 -0
  26. data/lib/active_attr/version.rb +1 -1
  27. data/spec/functional/active_attr/attribute_defaults_spec.rb +136 -0
  28. data/spec/functional/active_attr/attributes_spec.rb +19 -5
  29. data/spec/functional/active_attr/model_spec.rb +34 -4
  30. data/spec/functional/active_attr/typecasted_attributes_spec.rb +116 -0
  31. data/spec/support/mass_assignment_shared_examples.rb +1 -1
  32. data/spec/unit/active_attr/attribute_defaults_spec.rb +43 -0
  33. data/spec/unit/active_attr/attribute_definition_spec.rb +12 -8
  34. data/spec/unit/active_attr/attributes_spec.rb +22 -10
  35. data/spec/unit/active_attr/mass_assignment_spec.rb +1 -0
  36. data/spec/unit/active_attr/matchers/have_attribute_matcher_spec.rb +94 -15
  37. data/spec/unit/active_attr/query_attributes_spec.rb +1 -1
  38. data/spec/unit/active_attr/typecasted_attributes_spec.rb +76 -0
  39. data/spec/unit/active_attr/typecasting/boolean_spec.rb +10 -0
  40. data/spec/unit/active_attr/typecasting/boolean_typecaster_spec.rb +147 -0
  41. data/spec/unit/active_attr/typecasting/date_time_typecaster_spec.rb +67 -0
  42. data/spec/unit/active_attr/typecasting/date_typecaster_spec.rb +55 -0
  43. data/spec/unit/active_attr/typecasting/float_typecaster_spec.rb +27 -0
  44. data/spec/unit/active_attr/typecasting/integer_typecaster_spec.rb +35 -0
  45. data/spec/unit/active_attr/typecasting/object_typecaster_spec.rb +15 -0
  46. data/spec/unit/active_attr/typecasting/string_typecaster_spec.rb +24 -0
  47. data/spec/unit/active_attr/typecasting_spec.rb +87 -0
  48. data/spec/unit/active_attr/version_spec.rb +11 -2
  49. metadata +75 -29
  50. data/lib/active_attr/strict_mass_assignment.rb +0 -44
  51. data/lib/active_attr/unknown_attributes_error.rb +0 -18
  52. data/spec/unit/active_attr/strict_mass_assignment_spec.rb +0 -38
  53. data/spec/unit/active_attr/unknown_attributes_error_spec.rb +0 -9
@@ -11,12 +11,16 @@ module ActiveAttr
11
11
  include Attributes
12
12
 
13
13
  attribute :parent
14
+ attribute :redefined, :type => Symbol
14
15
  end
15
16
  end
16
17
 
17
18
  let! :child_class do
18
- Class.new(parent_class) do
19
- attribute :child
19
+ Class.new(parent_class).tap do |child_class|
20
+ child_class.instance_eval do
21
+ attribute :child
22
+ attribute :redefined, :type => String
23
+ end
20
24
  end
21
25
  end
22
26
 
@@ -32,7 +36,7 @@ module ActiveAttr
32
36
  end
33
37
 
34
38
  it "add attribute definitions to the child" do
35
- child_class.attributes.map(&:name).should include :parent
39
+ child_class.attribute_names.should include "parent"
36
40
  end
37
41
  end
38
42
 
@@ -48,7 +52,17 @@ module ActiveAttr
48
52
  end
49
53
 
50
54
  it "don't add attribute definitions to the parent" do
51
- parent_class.attributes.map(&:name).should_not include :child
55
+ parent_class.attribute_names.should_not include "child"
56
+ end
57
+ end
58
+
59
+ context "attributes redefined on the child" do
60
+ it "redefines the child attribute" do
61
+ child_class.attributes[:redefined].should == AttributeDefinition.new(:redefined, :type => String)
62
+ end
63
+
64
+ it "does not redefine the parent attribute" do
65
+ parent_class.attributes[:redefined].should == AttributeDefinition.new(:redefined, :type => Symbol)
52
66
  end
53
67
  end
54
68
  end
@@ -145,7 +159,7 @@ module ActiveAttr
145
159
  end
146
160
 
147
161
  it "sets the attributes" do
148
- subject.first_name.should == "Chris"
162
+ subject.first_name.should eq "Chris"
149
163
  subject.last_name.should == "Griego"
150
164
  end
151
165
  end
@@ -25,7 +25,7 @@ module ActiveAttr
25
25
 
26
26
  it "reads and writes attributes" do
27
27
  subject.first_name = "Chris"
28
- subject.first_name.should == "Chris"
28
+ subject.first_name.should eq "Chris"
29
29
  subject.attributes["first_name"].should == "Chris"
30
30
  end
31
31
 
@@ -41,7 +41,7 @@ module ActiveAttr
41
41
  end.read_attribute(:first_name).should == "Chris"
42
42
  end
43
43
 
44
- it "processes mass assignment yielding an initialization block" do
44
+ it "processes mass assignment before yielding to an initialization block" do
45
45
  model_class.new(:first_name => "Chris") do |person|
46
46
  person.first_name.should == "Chris"
47
47
  end
@@ -55,14 +55,14 @@ module ActiveAttr
55
55
  model_class.logger = logger
56
56
 
57
57
  model_class.logger?.should be_true
58
- model_class.logger.should == logger
58
+ model_class.logger.should eq logger
59
59
  subject.logger?.should be_true
60
60
  subject.logger.should == logger
61
61
  end
62
62
 
63
63
  it "supports mass assignment with security" do
64
64
  person = model_class.new(:first_name => "Chris", :last_name => "Griego")
65
- person.first_name.should == "Chris"
65
+ person.first_name.should eq "Chris"
66
66
  person.last_name.should be_nil
67
67
  end
68
68
 
@@ -83,5 +83,35 @@ module ActiveAttr
83
83
  it "supports attribute name translation" do
84
84
  model_class.human_attribute_name(:first_name).should == "First name"
85
85
  end
86
+
87
+ context "attribute defaults" do
88
+ let :model_class do
89
+ Class.new do
90
+ include Model
91
+
92
+ attribute :start_date
93
+ attribute :end_date, :default => lambda { start_date }
94
+ attribute :age_limit, :default => 21
95
+ end
96
+ end
97
+
98
+ it "are applied" do
99
+ subject.age_limit.should == 21
100
+ end
101
+
102
+ it "are overridden by mass assigned attributes" do
103
+ model_class.new(:age_limit => 18).age_limit.should == 18
104
+ end
105
+
106
+ it "can access mass assigned attributes" do
107
+ model_class.new(:start_date => Date.today).end_date.should == Date.today
108
+ end
109
+
110
+ it "can access attributes assigned in the initialization block" do
111
+ model_class.new do |event|
112
+ event.start_date = Date.today
113
+ end.end_date.should == Date.today
114
+ end
115
+ end
86
116
  end
87
117
  end
@@ -0,0 +1,116 @@
1
+ require "spec_helper"
2
+ require "active_attr/typecasted_attributes"
3
+ require "active_attr/mass_assignment"
4
+
5
+ module ActiveAttr
6
+ describe TypecastedAttributes do
7
+ subject { model_class.new }
8
+
9
+ let :model_class do
10
+ Class.new do
11
+ include TypecastedAttributes
12
+
13
+ attribute :typeless
14
+ attribute :object, :type => Object
15
+ attribute :boolean, :type => Typecasting::Boolean
16
+ attribute :date, :type => Date
17
+ attribute :date_time, :type => DateTime
18
+ attribute :float, :type => Float
19
+ attribute :integer, :type => Integer
20
+ attribute :string, :type => String
21
+ end
22
+ end
23
+
24
+ context "when assigning nil" do
25
+ it "a typeless attribute returns nil" do
26
+ subject.typeless = nil
27
+ subject.typeless.should be_nil
28
+ end
29
+
30
+ it "an Object attribute returns nil" do
31
+ subject.object = nil
32
+ subject.object.should be_nil
33
+ end
34
+
35
+ it "a Boolean attribute returns nil" do
36
+ subject.boolean = nil
37
+ subject.boolean.should be_nil
38
+ end
39
+
40
+ it "a Date attribute returns nil" do
41
+ subject.date = nil
42
+ subject.date.should be_nil
43
+ end
44
+
45
+ it "a DateTime attribute returns nil" do
46
+ subject.date_time = nil
47
+ subject.date_time.should be_nil
48
+ end
49
+
50
+ it "a Float attribute returns nil" do
51
+ subject.float = nil
52
+ subject.float.should be_nil
53
+ end
54
+
55
+ it "an Integer attribute returns nil" do
56
+ subject.integer = nil
57
+ subject.integer.should be_nil
58
+ end
59
+
60
+ it "a String attribute returns nil" do
61
+ subject.string = nil
62
+ subject.string.should be_nil
63
+ end
64
+ end
65
+
66
+ context "when assigning a valid String" do
67
+ it "a typeless attribute returns the original String" do
68
+ value = "test"
69
+ subject.typeless = value
70
+ subject.typeless.should equal value
71
+ end
72
+
73
+ it "an Object attribute returns the original String" do
74
+ value = "test"
75
+ subject.object = value
76
+ subject.object.should equal value
77
+ end
78
+
79
+ it "a Boolean attribute returns a Boolean" do
80
+ subject.boolean = "false"
81
+ subject.boolean.should eql false
82
+ end
83
+
84
+ it "a Date attribute returns a Date" do
85
+ subject.date = "2012-01-01"
86
+ subject.date.should eql Date.new(2012, 1, 1)
87
+ end
88
+
89
+ it "a Date attribute before typecasting returns the original String" do
90
+ value = "2012-01-01"
91
+ subject.date = value
92
+ subject.date_before_type_cast.should equal value
93
+ end
94
+
95
+ it "a DateTime attribute returns a DateTime" do
96
+ subject.date_time = "2012-01-01"
97
+ subject.date_time.should eql DateTime.new(2012, 1, 1)
98
+ end
99
+
100
+ it "a Float attribute returns a Float" do
101
+ subject.float = "1.1"
102
+ subject.float.should eql 1.1
103
+ end
104
+
105
+ it "an Integer attribute returns an Integer" do
106
+ subject.integer = "1"
107
+ subject.integer.should eql 1
108
+ end
109
+
110
+ it "a String attribute returns the String" do
111
+ subject.string = "1.0"
112
+ subject.string.should eql "1.0"
113
+ end
114
+ end
115
+ end
116
+ end
@@ -17,7 +17,7 @@ shared_examples "mass assignment class", :mass_assignment => true do
17
17
  let(:last_name) { "Griego" }
18
18
 
19
19
  def should_assign_names_to(person)
20
- person.first_name.should == first_name
20
+ person.first_name.should eq first_name
21
21
  person.last_name.should == last_name
22
22
  end
23
23
  end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+ require "active_attr/attribute_defaults"
3
+
4
+ module ActiveAttr
5
+ describe AttributeDefaults do
6
+ subject { model_class.new }
7
+
8
+ let :model_class do
9
+ Class.new do
10
+ include InitializationVerifier
11
+ include AttributeDefaults
12
+ attribute :first_name, :default => "John"
13
+ attribute :age, :default => nil
14
+ attribute :created_at, :default => lambda { Time.now }
15
+ end
16
+ end
17
+
18
+ describe "#attribute_defaults" do
19
+ subject { model_class.new.attribute_defaults }
20
+
21
+ it { should be_a_kind_of Hash }
22
+
23
+ it "includes declared literal string attribute defaults" do
24
+ subject["first_name"].should == "John"
25
+ end
26
+
27
+ it "includes declared nil attribute defaults" do
28
+ subject.should include "age"
29
+ subject['age'].should be_nil
30
+ end
31
+
32
+ it "includes declared dynamic attribute defaults" do
33
+ subject['created_at'].should be_a_kind_of Time
34
+ end
35
+ end
36
+
37
+ describe "#initialize" do
38
+ it "invokes the superclass initializer" do
39
+ should be_initialized
40
+ end
41
+ end
42
+ end
43
+ end
@@ -3,14 +3,14 @@ require "active_attr/attribute_definition"
3
3
 
4
4
  module ActiveAttr
5
5
  describe AttributeDefinition do
6
- subject { described_class.new(:amount) }
6
+ subject { described_class.new(:amount, :default => "default") }
7
7
 
8
8
  describe "#<=>" do
9
9
  it "is nil if the right side is not an #{described_class}" do
10
10
  (subject <=> nil).should be_nil
11
11
  end
12
12
 
13
- it "prefers neither when both sides use the same attribute name" do
13
+ it "prefers neither when both sides use the same attribute name and options" do
14
14
  (subject <=> subject).should == 0
15
15
  end
16
16
 
@@ -31,6 +31,16 @@ module ActiveAttr
31
31
  it "returns false when another object is compared" do
32
32
  described_class.new(:amount).should_not == Struct.new(:name).new(:amount)
33
33
  end
34
+
35
+ it "returns false when options differ" do
36
+ described_class.new(:amount).should_not == described_class.new(:amount, :type => String)
37
+ end
38
+ end
39
+
40
+ describe "#[]" do
41
+ it "reads an attribute option" do
42
+ subject[:default].should == "default"
43
+ end
34
44
  end
35
45
 
36
46
  describe "#initialize" do
@@ -51,12 +61,6 @@ module ActiveAttr
51
61
  end
52
62
  end
53
63
 
54
- describe "#inspect" do
55
- it "renders the name" do
56
- subject.inspect.should == "amount"
57
- end
58
- end
59
-
60
64
  describe "#name" do
61
65
  it { should respond_to(:name) }
62
66
  end
@@ -8,7 +8,6 @@ module ActiveAttr
8
8
 
9
9
  let :model_class do
10
10
  Class.new do
11
- include InitializationVerifier
12
11
  include Attributes
13
12
  attribute :first_name
14
13
  attribute :last_name
@@ -35,7 +34,7 @@ module ActiveAttr
35
34
  end
36
35
 
37
36
  def initialize(first_name=nil)
38
- super
37
+ super()
39
38
  write_attribute(:first_name, first_name)
40
39
  end
41
40
  end
@@ -53,7 +52,7 @@ module ActiveAttr
53
52
 
54
53
  describe ".attribute" do
55
54
  it "creates an attribute with no options" do
56
- model_class.attributes.should include(AttributeDefinition.new(:first_name))
55
+ model_class.attributes.values.should include(AttributeDefinition.new(:first_name))
57
56
  end
58
57
 
59
58
  it "returns the attribute definition" do
@@ -87,11 +86,30 @@ module ActiveAttr
87
86
  attribute :name
88
87
  end.should have(1).attributes
89
88
  end
89
+
90
+ it "redefining an attribute replaces the attribute definition" do
91
+ klass = Class.new do
92
+ include Attributes
93
+ attribute :name, :type => Symbol
94
+ attribute :name, :type => String
95
+ end
96
+
97
+ klass.should have(1).attributes
98
+ klass.attributes[:name].should == AttributeDefinition.new(:name, :type => String)
99
+ end
90
100
  end
91
101
 
92
102
  describe ".attributes" do
93
103
  it { model_class.should respond_to(:attributes) }
94
104
 
105
+ it "can access AttributeDefinition with a Symbol" do
106
+ model_class.attributes[:first_name].should == AttributeDefinition.new(:first_name)
107
+ end
108
+
109
+ it "can access AttributeDefinition with a String" do
110
+ model_class.attributes['first_name'].should == AttributeDefinition.new(:first_name)
111
+ end
112
+
95
113
  context "when no attributes exist" do
96
114
  it { attributeless.attributes.should be_empty }
97
115
  end
@@ -99,7 +117,7 @@ module ActiveAttr
99
117
 
100
118
  describe ".inspect" do
101
119
  it "renders the class name" do
102
- model_class.inspect.should match /^Foo\(.*\)$/
120
+ model_class.inspect.should match(/^Foo\(.*\)$/)
103
121
  end
104
122
 
105
123
  it "renders the attribute names in alphabetical order" do
@@ -153,12 +171,6 @@ module ActiveAttr
153
171
  end
154
172
  end
155
173
 
156
- describe "#initialize" do
157
- it "invokes the superclass initializer" do
158
- should be_initialized
159
- end
160
- end
161
-
162
174
  describe "#inspect" do
163
175
  before { subject.first_name = "Ben" }
164
176
 
@@ -14,6 +14,7 @@ module ActiveAttr
14
14
 
15
15
  it "ignores attributes which do not have a writer" do
16
16
  person = mass_assign_attributes(:middle_initial => "J")
17
+ person.instance_eval { @middle_initial ||= nil }
17
18
  person.instance_variable_get("@middle_initial").should be_nil
18
19
  person.should_not respond_to :middle_initial
19
20
  end
@@ -10,14 +10,14 @@ module ActiveAttr
10
10
  it { should respond_to(:have_attribute).with(1).argument }
11
11
 
12
12
  describe "#have_attribute" do
13
- subject { dsl.have_attribute(:name) }
13
+ subject { dsl.have_attribute(:first_name) }
14
14
 
15
- it "builds a HaveAttributeMatcher with the given attribute name" do
15
+ it "builds a HaveAttributeMatcher" do
16
16
  should be_a_kind_of Matchers::HaveAttributeMatcher
17
17
  end
18
18
 
19
19
  it "uses the given attribute name to construct the matcher" do
20
- subject.attribute_name.should == :name
20
+ subject.send(:attribute_name).should == :first_name
21
21
  end
22
22
  end
23
23
  end
@@ -27,7 +27,9 @@ module ActiveAttr
27
27
  let :model_class do
28
28
  Class.new do
29
29
  include Attributes
30
- attribute :name
30
+ attribute :first_name, :default => "John"
31
+ attribute :last_name
32
+ attribute :admin, :default => false
31
33
 
32
34
  def self.to_s
33
35
  "Person"
@@ -36,24 +38,27 @@ module ActiveAttr
36
38
  end
37
39
 
38
40
  subject { positive_matcher }
39
- let(:positive_matcher) { described_class.new(:name) }
41
+ let(:positive_matcher) { described_class.new(:first_name) }
40
42
  let(:negative_matcher) { described_class.new(:age) }
43
+ let(:positive_matcher_with_default) { described_class.new(:first_name).with_default_value_of("John") }
44
+ let(:positive_matcher_with_false_default) { described_class.new(:admin).with_default_value_of(false) }
45
+ let(:negative_matcher_with_wrong_default) { described_class.new(:first_name).with_default_value_of("Doe") }
46
+ let(:negative_matcher_with_default_no_attribute) { described_class.new(:age).with_default_value_of(21) }
47
+ let(:negative_matcher_with_nil_default) { described_class.new(:first_name).with_default_value_of(nil) }
41
48
 
42
49
  it { described_class.should respond_to(:new).with(1).argument }
43
50
 
44
- describe "#attribute_name" do
45
- it "returns the value used to initialize the matcher" do
46
- subject.attribute_name.should == :name
51
+ describe "#description" do
52
+ it "returns a description appropriate to the expectation" do
53
+ subject.description.should == "have attribute named first_name"
47
54
  end
48
55
 
49
- it "converts the value used to initialize the matcher to a symbol" do
50
- described_class.new('name').attribute_name.should == :name
56
+ it "mentions the default value if set" do
57
+ positive_matcher_with_default.description.should == %{have attribute named first_name with a default value of "John"}
51
58
  end
52
- end
53
59
 
54
- describe "#description" do
55
- it "returns a description appropriate to the expectation" do
56
- subject.description.should == "have attribute named name"
60
+ it "mentions the default value if set to false" do
61
+ positive_matcher_with_false_default.description.should == %{have attribute named admin with a default value of false}
57
62
  end
58
63
  end
59
64
 
@@ -63,6 +68,18 @@ module ActiveAttr
63
68
  matcher.matches? model_class
64
69
  end.failure_message.should == "Expected Person to have attribute named age"
65
70
  end
71
+
72
+ it "mentions the default value if set" do
73
+ negative_matcher_with_wrong_default.tap do |matcher|
74
+ matcher.matches? model_class
75
+ end.failure_message.should == %{Expected Person to have attribute named first_name with a default value of "Doe"}
76
+ end
77
+
78
+ it "mentions the default value if set to false" do
79
+ negative_matcher_with_nil_default.tap do |matcher|
80
+ matcher.matches? model_class
81
+ end.failure_message.should == %{Expected Person to have attribute named first_name with a default value of nil}
82
+ end
66
83
  end
67
84
 
68
85
  describe "#initialize" do
@@ -89,13 +106,75 @@ module ActiveAttr
89
106
  it "is false with a model class that does not have the attribute" do
90
107
  negative_matcher.matches?(model_class).should be_false
91
108
  end
109
+
110
+ context "when the matcher specifies a default value" do
111
+ it "is true with an instance of a model class that has the attribute with the default value" do
112
+ positive_matcher_with_default.matches?(model_class).should be_true
113
+ end
114
+
115
+ it "is true with a model class that has the attribute with the default value" do
116
+ positive_matcher_with_default.matches?(model_class).should be_true
117
+ end
118
+
119
+ it "is false with an instance of a model class that does not have the attribute" do
120
+ negative_matcher_with_default_no_attribute.matches?(model_instance).should be_false
121
+ end
122
+
123
+ it "is false with a model class that does not have the attribute" do
124
+ negative_matcher_with_default_no_attribute.matches?(model_class).should be_false
125
+ end
126
+
127
+ it "is false with an instance of a model class that has the attribute but not with the specified default value" do
128
+ negative_matcher_with_wrong_default.matches?(model_instance).should be_false
129
+ end
130
+
131
+ it "is false with a model class that has the attribute but not with the specified default value" do
132
+ negative_matcher_with_wrong_default.matches?(model_class).should be_false
133
+ end
134
+
135
+ it "is true with an instance of a model class that has the attribute with the default value of false" do
136
+ positive_matcher_with_false_default.matches?(model_class).should be_true
137
+ end
138
+
139
+ it "is true with a model class that has the attribute with the default value where the default value is false" do
140
+ positive_matcher_with_false_default.matches?(model_class).should be_true
141
+ end
142
+
143
+ it "is true with an instance of a model class that has the attribute with the default value where the default value is false" do
144
+ positive_matcher_with_false_default.matches?(model_class).should be_true
145
+ end
146
+
147
+ it "is true with a model class that has the attribute with the default value false" do
148
+ positive_matcher_with_false_default.matches?(model_class).should be_true
149
+ end
150
+
151
+ it "is false with an instance of a model class that has the attribute but not with the specified default value where the specified default value is nil" do
152
+ negative_matcher_with_nil_default.matches?(model_instance).should be_false
153
+ end
154
+
155
+ it "is false with a model class that has the attribute but not with the specified default value where the specified default value is nil" do
156
+ negative_matcher_with_nil_default.matches?(model_class).should be_false
157
+ end
158
+ end
92
159
  end
93
160
 
94
161
  describe "#negative_failure_message" do
95
162
  it "returns a failure message appropriate to the expectation and subject" do
96
163
  positive_matcher.tap do |matcher|
97
164
  matcher.matches? model_class
98
- end.negative_failure_message.should == "Expected Person to not have attribute named name"
165
+ end.negative_failure_message.should == "Expected Person to not have attribute named first_name"
166
+ end
167
+
168
+ it "mentions the default value if set" do
169
+ positive_matcher_with_default.tap do |matcher|
170
+ matcher.matches? model_class
171
+ end.negative_failure_message.should == %{Expected Person to not have attribute named first_name with a default value of "John"}
172
+ end
173
+
174
+ it "mentions the default value if set to false" do
175
+ positive_matcher_with_false_default.tap do |matcher|
176
+ matcher.matches? model_class
177
+ end.negative_failure_message.should == %{Expected Person to not have attribute named admin with a default value of false}
99
178
  end
100
179
  end
101
180
  end