machinist 2.0.0.beta2 → 2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -5
- data/Gemfile +2 -8
- data/Gemfile.lock +47 -0
- data/README.markdown +228 -18
- data/Rakefile +5 -20
- data/VERSION +1 -1
- data/lib/generators/machinist/install/install_generator.rb +10 -12
- data/lib/generators/machinist/install/templates/machinist.rb.erb +0 -3
- data/lib/machinist.rb +0 -12
- data/lib/machinist/active_record/blueprint.rb +0 -25
- data/lib/machinist/blueprint.rb +1 -1
- data/lib/machinist/lathe.rb +3 -4
- data/lib/machinist/machinable.rb +2 -8
- data/lib/machinist/version.rb +3 -0
- data/machinist.gemspec +20 -71
- data/spec/active_record_spec.rb +9 -36
- data/spec/blueprint_spec.rb +10 -8
- data/spec/exceptions_spec.rb +2 -2
- data/spec/inheritance_spec.rb +6 -6
- data/spec/machinable_spec.rb +6 -6
- data/spec/spec_helper.rb +0 -4
- metadata +103 -30
- data/lib/machinist/configuration.rb +0 -32
- data/lib/machinist/shop.rb +0 -52
- data/lib/machinist/warehouse.rb +0 -36
- data/spec/shop_spec.rb +0 -94
- data/spec/warehouse_spec.rb +0 -24
data/lib/machinist.rb
CHANGED
@@ -1,17 +1,5 @@
|
|
1
1
|
require 'machinist/blueprint'
|
2
|
-
require 'machinist/configuration'
|
3
2
|
require 'machinist/exceptions'
|
4
3
|
require 'machinist/lathe'
|
5
4
|
require 'machinist/machinable'
|
6
|
-
require 'machinist/shop'
|
7
|
-
require 'machinist/warehouse'
|
8
|
-
|
9
|
-
module Machinist
|
10
|
-
|
11
|
-
# Call this before each test to get Machinist ready.
|
12
|
-
def self.reset_before_test
|
13
|
-
Shop.instance.restock
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
5
|
|
@@ -8,31 +8,6 @@ module Machinist::ActiveRecord
|
|
8
8
|
object.reload
|
9
9
|
end
|
10
10
|
|
11
|
-
# Box an object for storage in the warehouse.
|
12
|
-
def box(object)
|
13
|
-
object.id
|
14
|
-
end
|
15
|
-
|
16
|
-
# Unbox an object from the warehouse.
|
17
|
-
def unbox(id)
|
18
|
-
@klass.find(id)
|
19
|
-
end
|
20
|
-
|
21
|
-
# Execute a block on a separate database connection, so that any database
|
22
|
-
# operations happen outside any open transactions.
|
23
|
-
def outside_transaction
|
24
|
-
# ActiveRecord manages connections per-thread, so the only way to
|
25
|
-
# convince it to open another connection is to start another thread.
|
26
|
-
thread = Thread.new do
|
27
|
-
begin
|
28
|
-
yield
|
29
|
-
ensure
|
30
|
-
::ActiveRecord::Base.connection_pool.checkin(::ActiveRecord::Base.connection)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
thread.value
|
34
|
-
end
|
35
|
-
|
36
11
|
def lathe_class #:nodoc:
|
37
12
|
Machinist::ActiveRecord::Lathe
|
38
13
|
end
|
data/lib/machinist/blueprint.rb
CHANGED
@@ -5,7 +5,7 @@ module Machinist
|
|
5
5
|
|
6
6
|
# Construct a blueprint for the given +klass+.
|
7
7
|
#
|
8
|
-
# Pass in the +:parent+ option
|
8
|
+
# Pass in the +:parent+ option to define a parent blueprint to apply after
|
9
9
|
# this one. You can supply another blueprint, or a class in which to look
|
10
10
|
# for a blueprint. In the latter case, make will walk up the superclass
|
11
11
|
# chain looking for blueprints to apply.
|
data/lib/machinist/lathe.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/inflector'
|
2
|
-
|
3
1
|
module Machinist
|
4
2
|
|
5
3
|
# When you make an object, the blueprint for that object is instance-evaled
|
@@ -19,8 +17,9 @@ module Machinist
|
|
19
17
|
end
|
20
18
|
|
21
19
|
# Returns a unique serial number for the object under construction.
|
22
|
-
|
23
|
-
|
20
|
+
def sn
|
21
|
+
@serial_number
|
22
|
+
end
|
24
23
|
|
25
24
|
# Returns the object under construction.
|
26
25
|
attr_reader :object
|
data/lib/machinist/machinable.rb
CHANGED
@@ -45,17 +45,11 @@ module Machinist
|
|
45
45
|
# :call-seq:
|
46
46
|
# make!([count], [blueprint_name], [attributes = {}])
|
47
47
|
#
|
48
|
-
# A cached object will be returned from the shop if possible. See
|
49
|
-
# Machinist::Shop.
|
50
|
-
#
|
51
48
|
# Arguments are the same as for make.
|
52
49
|
def make!(*args)
|
53
50
|
decode_args_to_make(*args) do |blueprint, attributes|
|
54
|
-
|
55
|
-
|
56
|
-
else
|
57
|
-
blueprint.make!(attributes)
|
58
|
-
end
|
51
|
+
raise BlueprintCantSaveError.new(blueprint) unless blueprint.respond_to?(:make!)
|
52
|
+
blueprint.make!(attributes)
|
59
53
|
end
|
60
54
|
end
|
61
55
|
|
data/machinist.gemspec
CHANGED
@@ -1,78 +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{2010-07-07}
|
13
|
-
s.email = %q{pete@notahat.com}
|
14
|
-
s.extra_rdoc_files = [
|
15
|
-
"README.markdown"
|
16
|
-
]
|
17
|
-
s.files = [
|
18
|
-
".gitignore",
|
19
|
-
"Gemfile",
|
20
|
-
"MIT-LICENSE",
|
21
|
-
"README.markdown",
|
22
|
-
"Rakefile",
|
23
|
-
"VERSION",
|
24
|
-
"lib/generators/machinist/install/USAGE",
|
25
|
-
"lib/generators/machinist/install/install_generator.rb",
|
26
|
-
"lib/generators/machinist/install/templates/blueprints.rb",
|
27
|
-
"lib/generators/machinist/install/templates/machinist.rb.erb",
|
28
|
-
"lib/generators/machinist/model/model_generator.rb",
|
29
|
-
"lib/machinist.rb",
|
30
|
-
"lib/machinist/active_record.rb",
|
31
|
-
"lib/machinist/active_record/blueprint.rb",
|
32
|
-
"lib/machinist/active_record/lathe.rb",
|
33
|
-
"lib/machinist/blueprint.rb",
|
34
|
-
"lib/machinist/configuration.rb",
|
35
|
-
"lib/machinist/exceptions.rb",
|
36
|
-
"lib/machinist/lathe.rb",
|
37
|
-
"lib/machinist/machinable.rb",
|
38
|
-
"lib/machinist/shop.rb",
|
39
|
-
"lib/machinist/warehouse.rb",
|
40
|
-
"machinist.gemspec",
|
41
|
-
"spec/active_record_spec.rb",
|
42
|
-
"spec/blueprint_spec.rb",
|
43
|
-
"spec/exceptions_spec.rb",
|
44
|
-
"spec/inheritance_spec.rb",
|
45
|
-
"spec/machinable_spec.rb",
|
46
|
-
"spec/shop_spec.rb",
|
47
|
-
"spec/spec_helper.rb",
|
48
|
-
"spec/support/active_record_environment.rb",
|
49
|
-
"spec/warehouse_spec.rb"
|
50
|
-
]
|
51
|
-
s.homepage = %q{http://github.com/notahat/machinist}
|
52
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
53
|
-
s.require_paths = ["lib"]
|
54
|
-
s.rubygems_version = %q{1.3.7}
|
55
|
-
s.summary = %q{Fixtures aren't fun. Machinist is.}
|
56
|
-
s.test_files = [
|
57
|
-
"spec/active_record_spec.rb",
|
58
|
-
"spec/blueprint_spec.rb",
|
59
|
-
"spec/exceptions_spec.rb",
|
60
|
-
"spec/inheritance_spec.rb",
|
61
|
-
"spec/machinable_spec.rb",
|
62
|
-
"spec/shop_spec.rb",
|
63
|
-
"spec/spec_helper.rb",
|
64
|
-
"spec/support/active_record_environment.rb",
|
65
|
-
"spec/warehouse_spec.rb"
|
66
|
-
]
|
14
|
+
s.rubyforge_project = "machinist"
|
67
15
|
|
68
|
-
|
69
|
-
|
70
|
-
|
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"]
|
71
20
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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"
|
77
27
|
end
|
78
|
-
|
data/spec/active_record_spec.rb
CHANGED
@@ -5,20 +5,11 @@ describe Machinist::ActiveRecord do
|
|
5
5
|
include ActiveRecordEnvironment
|
6
6
|
|
7
7
|
before(:each) do
|
8
|
-
Machinist::Shop.instance.reset!
|
9
8
|
empty_database!
|
10
9
|
end
|
11
10
|
|
12
|
-
def fake_a_test
|
13
|
-
ActiveRecord::Base.transaction do
|
14
|
-
Machinist.reset_before_test
|
15
|
-
yield
|
16
|
-
raise ActiveRecord::Rollback
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
11
|
context "make" do
|
21
|
-
it "
|
12
|
+
it "returns an unsaved object" do
|
22
13
|
Post.blueprint { }
|
23
14
|
post = Post.make
|
24
15
|
post.should be_a(Post)
|
@@ -27,41 +18,23 @@ describe Machinist::ActiveRecord do
|
|
27
18
|
end
|
28
19
|
|
29
20
|
context "make!" do
|
30
|
-
it "
|
21
|
+
it "makes and saves objects" do
|
31
22
|
Post.blueprint { }
|
32
23
|
post = Post.make!
|
33
24
|
post.should be_a(Post)
|
34
25
|
post.should_not be_new_record
|
35
26
|
end
|
36
27
|
|
37
|
-
it "
|
28
|
+
it "raises an exception for an invalid object" do
|
38
29
|
User.blueprint { }
|
39
30
|
lambda {
|
40
31
|
User.make!(:username => "")
|
41
32
|
}.should raise_error(ActiveRecord::RecordInvalid)
|
42
33
|
end
|
43
|
-
|
44
|
-
it "should buy objects from the shop" do
|
45
|
-
Post.blueprint { }
|
46
|
-
post_a, post_b = nil, nil
|
47
|
-
fake_a_test { post_a = Post.make! }
|
48
|
-
fake_a_test { post_b = Post.make! }
|
49
|
-
post_a.should == post_b
|
50
|
-
end
|
51
|
-
|
52
|
-
it "should not buy objects from the shop if caching is disabled" do
|
53
|
-
Machinist.configuration.cache_objects = false
|
54
|
-
Post.blueprint { }
|
55
|
-
post_a, post_b = nil, nil
|
56
|
-
fake_a_test { post_a = Post.make! }
|
57
|
-
fake_a_test { post_b = Post.make! }
|
58
|
-
post_a.should_not == post_b
|
59
|
-
Machinist.configuration.cache_objects = true
|
60
|
-
end
|
61
34
|
end
|
62
35
|
|
63
36
|
context "associations support" do
|
64
|
-
it "
|
37
|
+
it "handles belongs_to associations" do
|
65
38
|
User.blueprint do
|
66
39
|
username { "user_#{sn}" }
|
67
40
|
end
|
@@ -75,7 +48,7 @@ describe Machinist::ActiveRecord do
|
|
75
48
|
post.author.should_not be_new_record
|
76
49
|
end
|
77
50
|
|
78
|
-
it "
|
51
|
+
it "handles has_many associations" do
|
79
52
|
Post.blueprint do
|
80
53
|
comments(3)
|
81
54
|
end
|
@@ -90,7 +63,7 @@ describe Machinist::ActiveRecord do
|
|
90
63
|
end
|
91
64
|
end
|
92
65
|
|
93
|
-
it "
|
66
|
+
it "handles habtm associations" do
|
94
67
|
Post.blueprint do
|
95
68
|
tags(3)
|
96
69
|
end
|
@@ -107,12 +80,12 @@ describe Machinist::ActiveRecord do
|
|
107
80
|
end
|
108
81
|
end
|
109
82
|
|
110
|
-
it "
|
83
|
+
it "handles overriding associations" do
|
111
84
|
User.blueprint do
|
112
85
|
username { "user_#{sn}" }
|
113
86
|
end
|
114
87
|
Post.blueprint do
|
115
|
-
author { User.make
|
88
|
+
author { User.make(:username => "post_author_#{sn}") }
|
116
89
|
end
|
117
90
|
post = Post.make!
|
118
91
|
post.should be_a(Post)
|
@@ -124,7 +97,7 @@ describe Machinist::ActiveRecord do
|
|
124
97
|
end
|
125
98
|
|
126
99
|
context "error handling" do
|
127
|
-
it "
|
100
|
+
it "raises an exception for an attribute with no value" do
|
128
101
|
User.blueprint { username }
|
129
102
|
lambda {
|
130
103
|
User.make
|
data/spec/blueprint_spec.rb
CHANGED
@@ -3,19 +3,19 @@ require 'ostruct'
|
|
3
3
|
|
4
4
|
describe Machinist::Blueprint do
|
5
5
|
|
6
|
-
it "
|
6
|
+
it "makes an object of the given class" do
|
7
7
|
blueprint = Machinist::Blueprint.new(OpenStruct) { }
|
8
8
|
blueprint.make.should be_an(OpenStruct)
|
9
9
|
end
|
10
10
|
|
11
|
-
it "
|
11
|
+
it "constructs an attribute from the blueprint" do
|
12
12
|
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
13
13
|
name { "Fred" }
|
14
14
|
end
|
15
15
|
blueprint.make.name.should == "Fred"
|
16
16
|
end
|
17
17
|
|
18
|
-
it "
|
18
|
+
it "constructs an array for an attribute in the blueprint" do
|
19
19
|
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
20
20
|
things(3) { Object.new }
|
21
21
|
end
|
@@ -26,7 +26,7 @@ describe Machinist::Blueprint do
|
|
26
26
|
things.uniq.should == things
|
27
27
|
end
|
28
28
|
|
29
|
-
it "
|
29
|
+
it "allows passing in attributes to override the blueprint" do
|
30
30
|
block_called = false
|
31
31
|
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
32
32
|
name { block_called = true; "Fred" }
|
@@ -35,7 +35,7 @@ describe Machinist::Blueprint do
|
|
35
35
|
block_called.should be_false
|
36
36
|
end
|
37
37
|
|
38
|
-
it "
|
38
|
+
it "provides a serial number within the blueprint" do
|
39
39
|
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
40
40
|
name { "Fred #{sn}" }
|
41
41
|
end
|
@@ -43,7 +43,7 @@ describe Machinist::Blueprint do
|
|
43
43
|
blueprint.make.name.should == "Fred 0002"
|
44
44
|
end
|
45
45
|
|
46
|
-
it "
|
46
|
+
it "provides access to the object being constructed within the blueprint" do
|
47
47
|
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
48
48
|
title { "Test" }
|
49
49
|
body { object.title }
|
@@ -51,14 +51,16 @@ describe Machinist::Blueprint do
|
|
51
51
|
blueprint.make.body.should == "Test"
|
52
52
|
end
|
53
53
|
|
54
|
-
it "
|
54
|
+
it "allows attribute names to be strings" do
|
55
55
|
blueprint = Machinist::Blueprint.new(OpenStruct) do
|
56
56
|
name { "Fred" }
|
57
57
|
end
|
58
58
|
blueprint.make("name" => "Bill").name.should == "Bill"
|
59
59
|
end
|
60
60
|
|
61
|
-
|
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
|
62
64
|
klass = Class.new do
|
63
65
|
attr_accessor :id, :type
|
64
66
|
end
|
data/spec/exceptions_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
3
3
|
describe Machinist, "exceptions" do
|
4
4
|
|
5
5
|
describe Machinist::BlueprintCantSaveError do
|
6
|
-
it "
|
6
|
+
it "presents the right message" do
|
7
7
|
blueprint = Machinist::Blueprint.new(String) { }
|
8
8
|
exception = Machinist::BlueprintCantSaveError.new(blueprint)
|
9
9
|
exception.message.should == "make! is not supported by blueprints for class String"
|
@@ -11,7 +11,7 @@ describe Machinist, "exceptions" do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
describe Machinist::NoBlueprintError do
|
14
|
-
it "
|
14
|
+
it "presents the right message" do
|
15
15
|
exception = Machinist::NoBlueprintError.new(String, :master)
|
16
16
|
exception.message.should == "No master blueprint defined for class String"
|
17
17
|
end
|
data/spec/inheritance_spec.rb
CHANGED
@@ -21,7 +21,7 @@ end
|
|
21
21
|
describe Machinist::Blueprint do
|
22
22
|
|
23
23
|
describe "explicit inheritance" do
|
24
|
-
it "
|
24
|
+
it "inherits attributes from the parent blueprint" do
|
25
25
|
parent_blueprint = Machinist::Blueprint.new(OpenStruct) do
|
26
26
|
name { "Fred" }
|
27
27
|
age { 97 }
|
@@ -36,7 +36,7 @@ describe Machinist::Blueprint do
|
|
36
36
|
child.age.should == 97
|
37
37
|
end
|
38
38
|
|
39
|
-
it "
|
39
|
+
it "takes the serial number from the parent" do
|
40
40
|
parent_blueprint = Machinist::Blueprint.new(OpenStruct) do
|
41
41
|
parent_serial { sn }
|
42
42
|
end
|
@@ -56,7 +56,7 @@ describe Machinist::Blueprint do
|
|
56
56
|
[InheritanceSpecs::Grandpa, InheritanceSpecs::Dad, InheritanceSpecs::Son].each(&:clear_blueprints!)
|
57
57
|
end
|
58
58
|
|
59
|
-
it "
|
59
|
+
it "inherits blueprinted attributes from the parent class" do
|
60
60
|
InheritanceSpecs::Dad.blueprint do
|
61
61
|
name { "Fred" }
|
62
62
|
end
|
@@ -64,7 +64,7 @@ describe Machinist::Blueprint do
|
|
64
64
|
InheritanceSpecs::Son.make.name.should == "Fred"
|
65
65
|
end
|
66
66
|
|
67
|
-
it "
|
67
|
+
it "overrides blueprinted attributes in the child class" do
|
68
68
|
InheritanceSpecs::Dad.blueprint do
|
69
69
|
name { "Fred" }
|
70
70
|
end
|
@@ -75,7 +75,7 @@ describe Machinist::Blueprint do
|
|
75
75
|
InheritanceSpecs::Son.make.name.should == "George"
|
76
76
|
end
|
77
77
|
|
78
|
-
it "
|
78
|
+
it "inherits from blueprinted attributes in ancestor class" do
|
79
79
|
InheritanceSpecs::Grandpa.blueprint do
|
80
80
|
name { "Fred" }
|
81
81
|
end
|
@@ -85,7 +85,7 @@ describe Machinist::Blueprint do
|
|
85
85
|
InheritanceSpecs::Son.make.name.should == "Fred"
|
86
86
|
end
|
87
87
|
|
88
|
-
it "
|
88
|
+
it "follows inheritance for named blueprints correctly" do
|
89
89
|
InheritanceSpecs::Dad.blueprint do
|
90
90
|
name { "John" }
|
91
91
|
age { 56 }
|