active_attr 0.4.1 → 0.5.0.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of active_attr might be problematic. Click here for more details.
- data/.travis.yml +7 -0
- data/CHANGELOG.md +14 -0
- data/README.md +57 -25
- data/Rakefile +2 -0
- data/active_attr.gemspec +3 -2
- data/gemfiles/rails_3_1.gemfile +6 -0
- data/lib/active_attr.rb +3 -2
- data/lib/active_attr/attribute_defaults.rb +120 -0
- data/lib/active_attr/attribute_definition.rb +25 -2
- data/lib/active_attr/attributes.rb +44 -33
- data/lib/active_attr/logger.rb +8 -8
- data/lib/active_attr/mass_assignment.rb +2 -1
- data/lib/active_attr/matchers/have_attribute_matcher.rb +28 -10
- data/lib/active_attr/model.rb +2 -0
- data/lib/active_attr/query_attributes.rb +2 -5
- data/lib/active_attr/typecasted_attributes.rb +77 -0
- data/lib/active_attr/typecasting.rb +60 -0
- data/lib/active_attr/typecasting/boolean.rb +6 -0
- data/lib/active_attr/typecasting/boolean_typecaster.rb +21 -0
- data/lib/active_attr/typecasting/date_time_typecaster.rb +14 -0
- data/lib/active_attr/typecasting/date_typecaster.rb +14 -0
- data/lib/active_attr/typecasting/float_typecaster.rb +11 -0
- data/lib/active_attr/typecasting/integer_typecaster.rb +12 -0
- data/lib/active_attr/typecasting/object_typecaster.rb +9 -0
- data/lib/active_attr/typecasting/string_typecaster.rb +11 -0
- data/lib/active_attr/version.rb +1 -1
- data/spec/functional/active_attr/attribute_defaults_spec.rb +136 -0
- data/spec/functional/active_attr/attributes_spec.rb +19 -5
- data/spec/functional/active_attr/model_spec.rb +34 -4
- data/spec/functional/active_attr/typecasted_attributes_spec.rb +116 -0
- data/spec/support/mass_assignment_shared_examples.rb +1 -1
- data/spec/unit/active_attr/attribute_defaults_spec.rb +43 -0
- data/spec/unit/active_attr/attribute_definition_spec.rb +12 -8
- data/spec/unit/active_attr/attributes_spec.rb +22 -10
- data/spec/unit/active_attr/mass_assignment_spec.rb +1 -0
- data/spec/unit/active_attr/matchers/have_attribute_matcher_spec.rb +94 -15
- data/spec/unit/active_attr/query_attributes_spec.rb +1 -1
- data/spec/unit/active_attr/typecasted_attributes_spec.rb +76 -0
- data/spec/unit/active_attr/typecasting/boolean_spec.rb +10 -0
- data/spec/unit/active_attr/typecasting/boolean_typecaster_spec.rb +147 -0
- data/spec/unit/active_attr/typecasting/date_time_typecaster_spec.rb +67 -0
- data/spec/unit/active_attr/typecasting/date_typecaster_spec.rb +55 -0
- data/spec/unit/active_attr/typecasting/float_typecaster_spec.rb +27 -0
- data/spec/unit/active_attr/typecasting/integer_typecaster_spec.rb +35 -0
- data/spec/unit/active_attr/typecasting/object_typecaster_spec.rb +15 -0
- data/spec/unit/active_attr/typecasting/string_typecaster_spec.rb +24 -0
- data/spec/unit/active_attr/typecasting_spec.rb +87 -0
- data/spec/unit/active_attr/version_spec.rb +11 -2
- metadata +75 -29
- data/lib/active_attr/strict_mass_assignment.rb +0 -44
- data/lib/active_attr/unknown_attributes_error.rb +0 -18
- data/spec/unit/active_attr/strict_mass_assignment_spec.rb +0 -38
- 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
|
-
|
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.
|
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.
|
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
|
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
|
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
|
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
|
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
|
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
|
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(:
|
13
|
+
subject { dsl.have_attribute(:first_name) }
|
14
14
|
|
15
|
-
it "builds a HaveAttributeMatcher
|
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 == :
|
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 :
|
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(:
|
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 "#
|
45
|
-
it "returns
|
46
|
-
subject.
|
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 "
|
50
|
-
|
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
|
-
|
55
|
-
|
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
|
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
|