forked from notahat/machinist
/
machinist_spec.rb
197 lines (166 loc) · 5.64 KB
/
machinist_spec.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
require File.dirname(__FILE__) + '/spec_helper'
require 'machinist/object'
module MachinistSpecs
class Person
attr_accessor :name, :admin
end
class Post
attr_accessor :title, :body, :published
end
class Grandpa
attr_accessor :name
end
class Dad < Grandpa
attr_accessor :name
end
class Son < Dad
attr_accessor :name
end
describe Machinist do
before(:each) do
[Person, Post, Grandpa, Dad, Son].each(&:clear_blueprints!)
end
it "should raise for make on a class with no blueprint" do
lambda { Person.make }.should raise_error(RuntimeError, "No blueprint for class MachinistSpecs::Person")
end
it "should set an attribute on the constructed object from a constant in the blueprint" do
Person.blueprint do
name "Fred"
end
Person.make.name.should == "Fred"
end
it "should set an attribute on the constructed object from a block in the blueprint" do
Person.blueprint do
name { "Fred" }
end
Person.make.name.should == "Fred"
end
it "should default to calling Sham for an attribute in the blueprint" do
Sham.clear
Sham.name { "Fred" }
Person.blueprint { name }
Person.make.name.should == "Fred"
end
it "should let the blueprint override an attribute with a default value" do
Post.blueprint do
published { false }
end
Post.make.published.should be_false
end
it "should override an attribute from the blueprint with a passed-in attribute" do
Person.blueprint do
name "Fred"
end
Person.make(:name => "Bill").name.should == "Bill"
end
it "should allow overridden attribute names to be strings" do
Person.blueprint do
name "Fred"
end
Person.make("name" => "Bill").name.should == "Bill"
end
it "should not call a block in the blueprint if that attribute is passed in" do
block_called = false
Person.blueprint do
name { block_called = true; "Fred" }
end
Person.make(:name => "Bill").name.should == "Bill"
block_called.should be_false
end
it "should call a passed-in block with the object being constructed" do
Person.blueprint { }
block_called = false
Person.make do |person|
block_called = true
person.class.should == Person
end
block_called.should be_true
end
it "should provide access to the object being constructed from within the blueprint" do
person = nil
Person.blueprint { person = object }
Person.make
person.class.should == Person
end
it "should allow reading of a previously assigned attribute from within the blueprint" do
Post.blueprint do
title "Test"
body { title }
end
Post.make.body.should == "Test"
end
describe "named blueprints" do
before do
@block_called = false
Person.blueprint do
name { "Fred" }
admin { @block_called = true; false }
end
Person.blueprint(:admin) do
admin { true }
end
@person = Person.make(:admin)
end
it "should override an attribute from the parent blueprint in the child blueprint" do
@person.admin.should == true
end
it "should not call the block for an attribute from the parent blueprint if that attribute is overridden in the child" do
@block_called.should be_false
end
it "should set an attribute defined in the parent blueprint" do
@person.name.should == "Fred"
end
it "should return the correct list of named blueprints" do
Person.blueprint(:foo) { }
Person.blueprint(:bar) { }
Person.named_blueprints.to_set.should == [:admin, :foo, :bar].to_set
end
it "should raise a sensible error when calling a named blueprint with no master" do
Post.blueprint(:foo) { }
lambda { Post.make(:foo) }.should raise_error(
RuntimeError, "Can't construct an object from a named blueprint without a default blueprint for class MachinistSpecs::Post"
)
end
end
describe "blueprint inheritance" do
it "should inherit blueprinted attributes from the parent class" do
Dad.blueprint { name "Fred" }
Son.blueprint { }
Son.make.name.should == "Fred"
end
it "should override blueprinted attributes in the child class" do
Dad.blueprint { name "Fred" }
Son.blueprint { name "George" }
Dad.make.name.should == "Fred"
Son.make.name.should == "George"
end
it "should inherit from blueprinted attributes in ancestor class" do
Grandpa.blueprint { name "Fred" }
Son.blueprint { }
Grandpa.make.name.should == "Fred"
lambda { Dad.make }.should raise_error(RuntimeError)
Son.make.name.should == "Fred"
end
it "should follow inheritance for named blueprints correctly" do
Dad.blueprint { name "John" }
Dad.blueprint(:special) { name "Paul" }
Son.blueprint { }
Son.blueprint(:special) { }
Son.make(:special).name.should == "John"
end
end
describe "clear_blueprints! method" do
it "should clear the list of blueprints" do
Person.blueprint(:foo){}
Person.clear_blueprints!
Person.named_blueprints.should == []
end
it "should clear master blueprint too" do
Person.blueprint(:foo) {}
Person.blueprint {} # master
Person.clear_blueprints!
lambda { Person.make }.should raise_error(RuntimeError)
end
end
end
end