machinist 1.0.6 → 2.0
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.
- data/.gitignore +7 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +47 -0
- data/MIT-LICENSE +2 -1
- data/README.markdown +182 -204
- data/Rakefile +22 -29
- data/VERSION +1 -1
- data/lib/generators/machinist/install/USAGE +2 -0
- data/lib/generators/machinist/install/install_generator.rb +46 -0
- data/lib/generators/machinist/install/templates/blueprints.rb +9 -0
- data/lib/generators/machinist/install/templates/machinist.rb.erb +7 -0
- data/lib/generators/machinist/model/model_generator.rb +13 -0
- data/lib/machinist/active_record/blueprint.rb +16 -0
- data/lib/machinist/active_record/lathe.rb +24 -0
- data/lib/machinist/active_record.rb +8 -93
- data/lib/machinist/blueprint.rb +89 -0
- data/lib/machinist/exceptions.rb +32 -0
- data/lib/machinist/lathe.rb +68 -0
- data/lib/machinist/machinable.rb +95 -0
- data/lib/machinist/version.rb +3 -0
- data/lib/machinist.rb +4 -109
- data/machinist.gemspec +20 -65
- data/spec/active_record_spec.rb +85 -171
- data/spec/blueprint_spec.rb +76 -0
- data/spec/exceptions_spec.rb +20 -0
- data/spec/inheritance_spec.rb +104 -0
- data/spec/machinable_spec.rb +101 -0
- data/spec/spec_helper.rb +4 -6
- data/spec/support/active_record_environment.rb +65 -0
- metadata +125 -37
- data/.autotest +0 -7
- data/FAQ.markdown +0 -18
- data/init.rb +0 -2
- data/lib/machinist/blueprints.rb +0 -25
- data/lib/machinist/data_mapper.rb +0 -83
- data/lib/machinist/object.rb +0 -30
- data/lib/machinist/sequel.rb +0 -62
- data/lib/sham.rb +0 -77
- data/spec/data_mapper_spec.rb +0 -134
- data/spec/db/.gitignore +0 -1
- data/spec/db/schema.rb +0 -20
- data/spec/log/.gitignore +0 -1
- data/spec/machinist_spec.rb +0 -190
- data/spec/sequel_spec.rb +0 -146
- data/spec/sham_spec.rb +0 -95
data/machinist.gemspec
CHANGED
@@ -1,72 +1,27 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "machinist/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |s|
|
7
|
-
s.name
|
8
|
-
s.version
|
6
|
+
s.name = "machinist"
|
7
|
+
s.version = Machinist::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Pete Yandell"]
|
10
|
+
s.email = ["pete@notahat.com"]
|
11
|
+
s.homepage = "http://github.com/notahat/machinist"
|
12
|
+
s.summary = "Fixtures aren't fun. Machinist is."
|
9
13
|
|
10
|
-
s.
|
11
|
-
s.authors = ["Pete Yandell"]
|
12
|
-
s.date = %q{2009-11-29}
|
13
|
-
s.email = %q{pete@notahat.com}
|
14
|
-
s.extra_rdoc_files = [
|
15
|
-
"README.markdown"
|
16
|
-
]
|
17
|
-
s.files = [
|
18
|
-
".autotest",
|
19
|
-
".gitignore",
|
20
|
-
"FAQ.markdown",
|
21
|
-
"MIT-LICENSE",
|
22
|
-
"README.markdown",
|
23
|
-
"Rakefile",
|
24
|
-
"VERSION",
|
25
|
-
"init.rb",
|
26
|
-
"lib/machinist.rb",
|
27
|
-
"lib/machinist/active_record.rb",
|
28
|
-
"lib/machinist/blueprints.rb",
|
29
|
-
"lib/machinist/data_mapper.rb",
|
30
|
-
"lib/machinist/object.rb",
|
31
|
-
"lib/machinist/sequel.rb",
|
32
|
-
"lib/sham.rb",
|
33
|
-
"machinist.gemspec",
|
34
|
-
"spec/active_record_spec.rb",
|
35
|
-
"spec/data_mapper_spec.rb",
|
36
|
-
"spec/db/.gitignore",
|
37
|
-
"spec/db/schema.rb",
|
38
|
-
"spec/log/.gitignore",
|
39
|
-
"spec/machinist_spec.rb",
|
40
|
-
"spec/sequel_spec.rb",
|
41
|
-
"spec/sham_spec.rb",
|
42
|
-
"spec/spec_helper.rb"
|
43
|
-
]
|
44
|
-
s.homepage = %q{http://github.com/notahat/machinist}
|
45
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
46
|
-
s.require_paths = ["lib"]
|
47
|
-
s.rubygems_version = %q{1.3.5}
|
48
|
-
s.summary = %q{Fixtures aren't fun. Machinist is.}
|
49
|
-
s.test_files = [
|
50
|
-
"spec/active_record_spec.rb",
|
51
|
-
"spec/data_mapper_spec.rb",
|
52
|
-
"spec/db/schema.rb",
|
53
|
-
"spec/machinist_spec.rb",
|
54
|
-
"spec/sequel_spec.rb",
|
55
|
-
"spec/sham_spec.rb",
|
56
|
-
"spec/spec_helper.rb"
|
57
|
-
]
|
14
|
+
s.rubyforge_project = "machinist"
|
58
15
|
|
59
|
-
|
60
|
-
|
61
|
-
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
62
20
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
s.add_dependency(%q<rspec>, [">= 1.2.8"])
|
70
|
-
end
|
21
|
+
s.add_development_dependency "activerecord"
|
22
|
+
s.add_development_dependency "mysql"
|
23
|
+
s.add_development_dependency "rake"
|
24
|
+
s.add_development_dependency "rcov"
|
25
|
+
s.add_development_dependency "rspec"
|
26
|
+
s.add_development_dependency "rdoc"
|
71
27
|
end
|
72
|
-
|
data/spec/active_record_spec.rb
CHANGED
@@ -1,194 +1,108 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
-
require '
|
3
|
-
require 'active_support/whiny_nil'
|
2
|
+
require 'support/active_record_environment'
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
class Person < ActiveRecord::Base
|
8
|
-
attr_protected :password
|
9
|
-
end
|
4
|
+
describe Machinist::ActiveRecord do
|
5
|
+
include ActiveRecordEnvironment
|
10
6
|
|
11
|
-
|
7
|
+
before(:each) do
|
8
|
+
empty_database!
|
12
9
|
end
|
13
10
|
|
14
|
-
|
15
|
-
|
11
|
+
context "make" do
|
12
|
+
it "returns an unsaved object" do
|
13
|
+
Post.blueprint { }
|
14
|
+
post = Post.make
|
15
|
+
post.should be_a(Post)
|
16
|
+
post.should be_new_record
|
17
|
+
end
|
16
18
|
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
context "make!" do
|
21
|
+
it "makes and saves objects" do
|
22
|
+
Post.blueprint { }
|
23
|
+
post = Post.make!
|
24
|
+
post.should be_a(Post)
|
25
|
+
post.should_not be_new_record
|
26
|
+
end
|
22
27
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
it "raises an exception for an invalid object" do
|
29
|
+
User.blueprint { }
|
30
|
+
lambda {
|
31
|
+
User.make!(:username => "")
|
32
|
+
}.should raise_error(ActiveRecord::RecordInvalid)
|
28
33
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
34
|
+
end
|
35
|
+
|
36
|
+
context "associations support" do
|
37
|
+
it "handles belongs_to associations" do
|
38
|
+
User.blueprint do
|
39
|
+
username { "user_#{sn}" }
|
40
|
+
end
|
41
|
+
Post.blueprint do
|
42
|
+
author
|
43
|
+
end
|
44
|
+
post = Post.make!
|
45
|
+
post.should be_a(Post)
|
46
|
+
post.should_not be_new_record
|
47
|
+
post.author.should be_a(User)
|
48
|
+
post.author.should_not be_new_record
|
32
49
|
end
|
33
|
-
|
34
|
-
describe "make method" do
|
35
|
-
it "should support single-table inheritance" do
|
36
|
-
Person.blueprint { }
|
37
|
-
Admin.blueprint { }
|
38
|
-
admin = Admin.make
|
39
|
-
admin.should_not be_new_record
|
40
|
-
admin.type.should == "Admin"
|
41
|
-
end
|
42
50
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
it "should create an object through belongs_to association with a class_name attribute" do
|
56
|
-
Person.blueprint { }
|
57
|
-
Comment.blueprint { author }
|
58
|
-
Comment.make.author.class.should == Person
|
51
|
+
it "handles has_many associations" do
|
52
|
+
Post.blueprint do
|
53
|
+
comments(3)
|
54
|
+
end
|
55
|
+
Comment.blueprint { }
|
56
|
+
post = Post.make!
|
57
|
+
post.should be_a(Post)
|
58
|
+
post.should_not be_new_record
|
59
|
+
post.should have(3).comments
|
60
|
+
post.comments.each do |comment|
|
61
|
+
comment.should be_a(Comment)
|
62
|
+
comment.should_not be_new_record
|
59
63
|
end
|
64
|
+
end
|
60
65
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
Comment.blueprint { post(:dummy) }
|
65
|
-
Comment.make.post.title.should == 'Dummy Post'
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should allow creating an object through a has_many association" do
|
69
|
-
Post.blueprint do
|
70
|
-
comments { [Comment.make] }
|
71
|
-
end
|
72
|
-
Comment.blueprint { }
|
73
|
-
Post.make.comments.should have(1).instance_of(Comment)
|
74
|
-
end
|
75
|
-
|
76
|
-
it "should allow setting a protected attribute in the blueprint" do
|
77
|
-
Person.blueprint do
|
78
|
-
password "Test"
|
79
|
-
end
|
80
|
-
Person.make.password.should == "Test"
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should allow overriding a protected attribute" do
|
84
|
-
Person.blueprint do
|
85
|
-
password "Test"
|
86
|
-
end
|
87
|
-
Person.make(:password => "New").password.should == "New"
|
66
|
+
it "handles habtm associations" do
|
67
|
+
Post.blueprint do
|
68
|
+
tags(3)
|
88
69
|
end
|
89
|
-
|
90
|
-
|
91
|
-
Person.blueprint { id 12345 }
|
92
|
-
Person.make.id.should == 12345
|
70
|
+
Tag.blueprint do
|
71
|
+
name { "tag_#{sn}" }
|
93
72
|
end
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
before do
|
102
|
-
Post.blueprint { }
|
103
|
-
Comment.blueprint { post }
|
104
|
-
@post = Post.make
|
105
|
-
@comment = @post.comments.make
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should save the created object" do
|
109
|
-
@comment.should_not be_new_record
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should set the parent association on the created object" do
|
113
|
-
@comment.post.should == @post
|
114
|
-
end
|
73
|
+
post = Post.make!
|
74
|
+
post.should be_a(Post)
|
75
|
+
post.should_not be_new_record
|
76
|
+
post.should have(3).tags
|
77
|
+
post.tags.each do |tag|
|
78
|
+
tag.should be_a(Tag)
|
79
|
+
tag.should_not be_new_record
|
115
80
|
end
|
116
81
|
end
|
117
82
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
Post.count.should == post_count + 1
|
132
|
-
comment[:post].should be_nil
|
133
|
-
comment[:post_id].should_not be_nil
|
134
|
-
end
|
135
|
-
|
136
|
-
describe "on a belongs_to association" do
|
137
|
-
it "should allow explicitly setting the association to nil" do
|
138
|
-
Comment.blueprint { post }
|
139
|
-
Comment.blueprint(:no_post) { post { nil } }
|
140
|
-
lambda {
|
141
|
-
@comment = Comment.plan(:no_post)
|
142
|
-
}.should_not raise_error
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
describe "on a has_many association" do
|
147
|
-
before do
|
148
|
-
Post.blueprint { }
|
149
|
-
Comment.blueprint do
|
150
|
-
post
|
151
|
-
body { "Test" }
|
152
|
-
end
|
153
|
-
@post = Post.make
|
154
|
-
@post_count = Post.count
|
155
|
-
@comment = @post.comments.plan
|
156
|
-
end
|
157
|
-
|
158
|
-
it "should not include the parent in the returned hash" do
|
159
|
-
@comment[:post].should be_nil
|
160
|
-
@comment[:post_id].should be_nil
|
161
|
-
end
|
162
|
-
|
163
|
-
it "should not create an extra parent object" do
|
164
|
-
Post.count.should == @post_count
|
165
|
-
end
|
166
|
-
end
|
83
|
+
it "handles overriding associations" do
|
84
|
+
User.blueprint do
|
85
|
+
username { "user_#{sn}" }
|
86
|
+
end
|
87
|
+
Post.blueprint do
|
88
|
+
author { User.make(:username => "post_author_#{sn}") }
|
89
|
+
end
|
90
|
+
post = Post.make!
|
91
|
+
post.should be_a(Post)
|
92
|
+
post.should_not be_new_record
|
93
|
+
post.author.should be_a(User)
|
94
|
+
post.author.should_not be_new_record
|
95
|
+
post.author.username.should =~ /^post_author_\d+$/
|
167
96
|
end
|
97
|
+
end
|
168
98
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
it "should not save associated objects" do
|
177
|
-
Post.blueprint { }
|
178
|
-
Comment.blueprint { post }
|
179
|
-
comment = Comment.make_unsaved
|
180
|
-
comment.post.should be_new_record
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should save objects made within a passed-in block" do
|
184
|
-
Post.blueprint { }
|
185
|
-
Comment.blueprint { }
|
186
|
-
comment = nil
|
187
|
-
post = Post.make_unsaved { comment = Comment.make }
|
188
|
-
post.should be_new_record
|
189
|
-
comment.should_not be_new_record
|
190
|
-
end
|
99
|
+
context "error handling" do
|
100
|
+
it "raises an exception for an attribute with no value" do
|
101
|
+
User.blueprint { username }
|
102
|
+
lambda {
|
103
|
+
User.make
|
104
|
+
}.should raise_error(ArgumentError)
|
191
105
|
end
|
192
|
-
|
193
106
|
end
|
107
|
+
|
194
108
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe Machinist::Blueprint do
|
5
|
+
|
6
|
+
it "makes an object of the given class" do
|
7
|
+
blueprint = Machinist::Blueprint.new(OpenStruct) { }
|
8
|
+
blueprint.make.should be_an(OpenStruct)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "constructs an attribute from the blueprint" do
|
12
|
+
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
13
|
+
name { "Fred" }
|
14
|
+
end
|
15
|
+
blueprint.make.name.should == "Fred"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "constructs an array for an attribute in the blueprint" do
|
19
|
+
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
20
|
+
things(3) { Object.new }
|
21
|
+
end
|
22
|
+
things = blueprint.make.things
|
23
|
+
things.should be_an(Array)
|
24
|
+
things.should have(3).elements
|
25
|
+
things.each {|thing| thing.should be_an(Object) }
|
26
|
+
things.uniq.should == things
|
27
|
+
end
|
28
|
+
|
29
|
+
it "allows passing in attributes to override the blueprint" do
|
30
|
+
block_called = false
|
31
|
+
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
32
|
+
name { block_called = true; "Fred" }
|
33
|
+
end
|
34
|
+
blueprint.make(:name => "Bill").name.should == "Bill"
|
35
|
+
block_called.should be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it "provides a serial number within the blueprint" do
|
39
|
+
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
40
|
+
name { "Fred #{sn}" }
|
41
|
+
end
|
42
|
+
blueprint.make.name.should == "Fred 0001"
|
43
|
+
blueprint.make.name.should == "Fred 0002"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "provides access to the object being constructed within the blueprint" do
|
47
|
+
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
48
|
+
title { "Test" }
|
49
|
+
body { object.title }
|
50
|
+
end
|
51
|
+
blueprint.make.body.should == "Test"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "allows attribute names to be strings" do
|
55
|
+
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
56
|
+
name { "Fred" }
|
57
|
+
end
|
58
|
+
blueprint.make("name" => "Bill").name.should == "Bill"
|
59
|
+
end
|
60
|
+
|
61
|
+
# These are normally a problem because of name clashes with the standard (but
|
62
|
+
# deprecated) Ruby methods. This test makes sure we work around this.
|
63
|
+
it "works with type and id attributes" do
|
64
|
+
klass = Class.new do
|
65
|
+
attr_accessor :id, :type
|
66
|
+
end
|
67
|
+
blueprint = Machinist::Blueprint.new(klass) do
|
68
|
+
id { "custom id" }
|
69
|
+
type { "custom type" }
|
70
|
+
end
|
71
|
+
object = blueprint.make
|
72
|
+
object.id.should == "custom id"
|
73
|
+
object.type.should == "custom type"
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Machinist, "exceptions" do
|
4
|
+
|
5
|
+
describe Machinist::BlueprintCantSaveError do
|
6
|
+
it "presents the right message" do
|
7
|
+
blueprint = Machinist::Blueprint.new(String) { }
|
8
|
+
exception = Machinist::BlueprintCantSaveError.new(blueprint)
|
9
|
+
exception.message.should == "make! is not supported by blueprints for class String"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Machinist::NoBlueprintError do
|
14
|
+
it "presents the right message" do
|
15
|
+
exception = Machinist::NoBlueprintError.new(String, :master)
|
16
|
+
exception.message.should == "No master blueprint defined for class String"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module InheritanceSpecs
|
5
|
+
class Grandpa
|
6
|
+
extend Machinist::Machinable
|
7
|
+
attr_accessor :name, :age
|
8
|
+
end
|
9
|
+
|
10
|
+
class Dad < Grandpa
|
11
|
+
extend Machinist::Machinable
|
12
|
+
attr_accessor :name, :age
|
13
|
+
end
|
14
|
+
|
15
|
+
class Son < Dad
|
16
|
+
extend Machinist::Machinable
|
17
|
+
attr_accessor :name, :age
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe Machinist::Blueprint do
|
22
|
+
|
23
|
+
describe "explicit inheritance" do
|
24
|
+
it "inherits attributes from the parent blueprint" do
|
25
|
+
parent_blueprint = Machinist::Blueprint.new(OpenStruct) do
|
26
|
+
name { "Fred" }
|
27
|
+
age { 97 }
|
28
|
+
end
|
29
|
+
|
30
|
+
child_blueprint = Machinist::Blueprint.new(OpenStruct, :parent => parent_blueprint) do
|
31
|
+
name { "Bill" }
|
32
|
+
end
|
33
|
+
|
34
|
+
child = child_blueprint.make
|
35
|
+
child.name.should == "Bill"
|
36
|
+
child.age.should == 97
|
37
|
+
end
|
38
|
+
|
39
|
+
it "takes the serial number from the parent" do
|
40
|
+
parent_blueprint = Machinist::Blueprint.new(OpenStruct) do
|
41
|
+
parent_serial { sn }
|
42
|
+
end
|
43
|
+
|
44
|
+
child_blueprint = Machinist::Blueprint.new(OpenStruct, :parent => parent_blueprint) do
|
45
|
+
child_serial { sn }
|
46
|
+
end
|
47
|
+
|
48
|
+
parent_blueprint.make.parent_serial.should == "0001"
|
49
|
+
child_blueprint.make.child_serial.should == "0002"
|
50
|
+
parent_blueprint.make.parent_serial.should == "0003"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "class inheritance" do
|
55
|
+
before(:each) do
|
56
|
+
[InheritanceSpecs::Grandpa, InheritanceSpecs::Dad, InheritanceSpecs::Son].each(&:clear_blueprints!)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "inherits blueprinted attributes from the parent class" do
|
60
|
+
InheritanceSpecs::Dad.blueprint do
|
61
|
+
name { "Fred" }
|
62
|
+
end
|
63
|
+
InheritanceSpecs::Son.blueprint { }
|
64
|
+
InheritanceSpecs::Son.make.name.should == "Fred"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "overrides blueprinted attributes in the child class" do
|
68
|
+
InheritanceSpecs::Dad.blueprint do
|
69
|
+
name { "Fred" }
|
70
|
+
end
|
71
|
+
InheritanceSpecs::Son.blueprint do
|
72
|
+
name { "George" }
|
73
|
+
end
|
74
|
+
InheritanceSpecs::Dad.make.name.should == "Fred"
|
75
|
+
InheritanceSpecs::Son.make.name.should == "George"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "inherits from blueprinted attributes in ancestor class" do
|
79
|
+
InheritanceSpecs::Grandpa.blueprint do
|
80
|
+
name { "Fred" }
|
81
|
+
end
|
82
|
+
InheritanceSpecs::Son.blueprint { }
|
83
|
+
InheritanceSpecs::Grandpa.make.name.should == "Fred"
|
84
|
+
lambda { InheritanceSpecs::Dad.make }.should raise_error(RuntimeError)
|
85
|
+
InheritanceSpecs::Son.make.name.should == "Fred"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "follows inheritance for named blueprints correctly" do
|
89
|
+
InheritanceSpecs::Dad.blueprint do
|
90
|
+
name { "John" }
|
91
|
+
age { 56 }
|
92
|
+
end
|
93
|
+
InheritanceSpecs::Dad.blueprint(:special) do
|
94
|
+
name { "Paul" }
|
95
|
+
end
|
96
|
+
InheritanceSpecs::Son.blueprint(:special) do
|
97
|
+
age { 37 }
|
98
|
+
end
|
99
|
+
InheritanceSpecs::Son.make(:special).name.should == "John"
|
100
|
+
InheritanceSpecs::Son.make(:special).age.should == 37
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
module MachinableSpecs
|
4
|
+
class Post
|
5
|
+
extend Machinist::Machinable
|
6
|
+
attr_accessor :title, :body, :comments
|
7
|
+
end
|
8
|
+
|
9
|
+
class Comment
|
10
|
+
extend Machinist::Machinable
|
11
|
+
attr_accessor :post, :title
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Machinist::Machinable do
|
16
|
+
|
17
|
+
before(:each) do
|
18
|
+
MachinableSpecs::Post.clear_blueprints!
|
19
|
+
end
|
20
|
+
|
21
|
+
it "makes an object" do
|
22
|
+
MachinableSpecs::Post.blueprint do
|
23
|
+
title { "First Post" }
|
24
|
+
end
|
25
|
+
|
26
|
+
post = MachinableSpecs::Post.make
|
27
|
+
post.should be_a(MachinableSpecs::Post)
|
28
|
+
post.title.should == "First Post"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "makes an object from a named blueprint" do
|
32
|
+
MachinableSpecs::Post.blueprint do
|
33
|
+
title { "First Post" }
|
34
|
+
body { "Woot!" }
|
35
|
+
end
|
36
|
+
|
37
|
+
MachinableSpecs::Post.blueprint(:extra) do
|
38
|
+
title { "Extra!" }
|
39
|
+
end
|
40
|
+
|
41
|
+
post = MachinableSpecs::Post.make(:extra)
|
42
|
+
post.should be_a(MachinableSpecs::Post)
|
43
|
+
post.title.should == "Extra!"
|
44
|
+
post.body.should == "Woot!"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "makes an array of objects" do
|
48
|
+
MachinableSpecs::Post.blueprint do
|
49
|
+
title { "First Post" }
|
50
|
+
end
|
51
|
+
|
52
|
+
posts = MachinableSpecs::Post.make(3)
|
53
|
+
posts.should be_an(Array)
|
54
|
+
posts.should have(3).elements
|
55
|
+
posts.each do |post|
|
56
|
+
post.should be_a(MachinableSpecs::Post)
|
57
|
+
post.title.should == "First Post"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "makes array attributes from the blueprint" do
|
62
|
+
MachinableSpecs::Comment.blueprint { }
|
63
|
+
MachinableSpecs::Post.blueprint do
|
64
|
+
comments(3) { MachinableSpecs::Comment.make }
|
65
|
+
end
|
66
|
+
|
67
|
+
post = MachinableSpecs::Post.make
|
68
|
+
post.comments.should be_a(Array)
|
69
|
+
post.comments.should have(3).elements
|
70
|
+
post.comments.each do |comment|
|
71
|
+
comment.should be_a(MachinableSpecs::Comment)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it "fails without a blueprint" do
|
76
|
+
expect do
|
77
|
+
MachinableSpecs::Post.make
|
78
|
+
end.should raise_error(Machinist::NoBlueprintError) do |exception|
|
79
|
+
exception.klass.should == MachinableSpecs::Post
|
80
|
+
exception.name.should == :master
|
81
|
+
end
|
82
|
+
|
83
|
+
expect do
|
84
|
+
MachinableSpecs::Post.make(:some_name)
|
85
|
+
end.should raise_error(Machinist::NoBlueprintError) do |exception|
|
86
|
+
exception.klass.should == MachinableSpecs::Post
|
87
|
+
exception.name.should == :some_name
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
it "fails when calling make! on an unsavable object" do
|
92
|
+
MachinableSpecs::Post.blueprint { }
|
93
|
+
|
94
|
+
expect do
|
95
|
+
MachinableSpecs::Post.make!
|
96
|
+
end.should raise_error(Machinist::BlueprintCantSaveError) do |exception|
|
97
|
+
exception.blueprint.klass.should == MachinableSpecs::Post
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
3
|
+
|
2
4
|
require 'rubygems'
|
3
5
|
require 'test/unit'
|
4
|
-
require '
|
5
|
-
require '
|
6
|
-
|
7
|
-
Spec::Runner.configure do |config|
|
8
|
-
config.before(:each) { Sham.reset }
|
9
|
-
end
|
6
|
+
require 'rspec'
|
7
|
+
require 'machinist'
|