machinist 1.0.6 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +3 -2
  2. data/Gemfile +8 -0
  3. data/MIT-LICENSE +2 -1
  4. data/README.markdown +39 -271
  5. data/Rakefile +22 -14
  6. data/lib/generators/machinist/install/USAGE +2 -0
  7. data/lib/generators/machinist/install/install_generator.rb +48 -0
  8. data/lib/generators/machinist/install/templates/blueprints.rb +9 -0
  9. data/lib/generators/machinist/install/templates/machinist.rb.erb +10 -0
  10. data/lib/generators/machinist/model/model_generator.rb +13 -0
  11. data/lib/machinist.rb +11 -105
  12. data/lib/machinist/active_record.rb +8 -93
  13. data/lib/machinist/active_record/blueprint.rb +41 -0
  14. data/lib/machinist/active_record/lathe.rb +24 -0
  15. data/lib/machinist/blueprint.rb +89 -0
  16. data/lib/machinist/exceptions.rb +32 -0
  17. data/lib/machinist/lathe.rb +69 -0
  18. data/lib/machinist/machinable.rb +97 -0
  19. data/lib/machinist/shop.rb +52 -0
  20. data/lib/machinist/warehouse.rb +36 -0
  21. data/spec/active_record_spec.rb +100 -169
  22. data/spec/blueprint_spec.rb +74 -0
  23. data/spec/exceptions_spec.rb +20 -0
  24. data/spec/inheritance_spec.rb +104 -0
  25. data/spec/machinable_spec.rb +101 -0
  26. data/spec/shop_spec.rb +94 -0
  27. data/spec/spec_helper.rb +4 -6
  28. data/spec/support/active_record_environment.rb +65 -0
  29. data/spec/warehouse_spec.rb +24 -0
  30. metadata +52 -40
  31. data/.autotest +0 -7
  32. data/FAQ.markdown +0 -18
  33. data/VERSION +0 -1
  34. data/init.rb +0 -2
  35. data/lib/machinist/blueprints.rb +0 -25
  36. data/lib/machinist/data_mapper.rb +0 -83
  37. data/lib/machinist/object.rb +0 -30
  38. data/lib/machinist/sequel.rb +0 -62
  39. data/lib/sham.rb +0 -77
  40. data/machinist.gemspec +0 -72
  41. data/spec/data_mapper_spec.rb +0 -134
  42. data/spec/db/.gitignore +0 -1
  43. data/spec/db/schema.rb +0 -20
  44. data/spec/log/.gitignore +0 -1
  45. data/spec/machinist_spec.rb +0 -190
  46. data/spec/sequel_spec.rb +0 -146
  47. data/spec/sham_spec.rb +0 -95
data/machinist.gemspec DELETED
@@ -1,72 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{machinist}
8
- s.version = "1.0.6"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
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
- ]
58
-
59
- if s.respond_to? :specification_version then
60
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
61
- s.specification_version = 3
62
-
63
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
64
- s.add_development_dependency(%q<rspec>, [">= 1.2.8"])
65
- else
66
- s.add_dependency(%q<rspec>, [">= 1.2.8"])
67
- end
68
- else
69
- s.add_dependency(%q<rspec>, [">= 1.2.8"])
70
- end
71
- end
72
-
@@ -1,134 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
- require 'machinist/data_mapper'
3
- require 'dm-validations'
4
-
5
- module MachinistDataMapperSpecs
6
-
7
- class Person
8
- include DataMapper::Resource
9
- property :id, Serial
10
- property :name, String, :length => (0..10)
11
- property :type, Discriminator
12
- property :password, String
13
- property :admin, Boolean, :default => false
14
- end
15
-
16
- class Admin < Person
17
- end
18
-
19
- class Post
20
- include DataMapper::Resource
21
- property :id, Serial
22
- property :title, String
23
- property :body, Text
24
- property :published, Boolean, :default => true
25
- has n, :comments
26
- end
27
-
28
- class Comment
29
- include DataMapper::Resource
30
- property :id, Serial
31
- property :post_id, Integer
32
- property :author_id, Integer
33
- belongs_to :post
34
- belongs_to :author, :model => "Person", :child_key => [:author_id]
35
- end
36
-
37
- describe Machinist, "DataMapper adapter" do
38
- before(:suite) do
39
- DataMapper::Logger.new(File.dirname(__FILE__) + "/log/test.log", :debug)
40
- DataMapper.setup(:default, "sqlite3::memory:")
41
- DataMapper.auto_migrate!
42
- end
43
-
44
- before(:each) do
45
- [Person, Admin, Post, Comment].each(&:clear_blueprints!)
46
- end
47
-
48
- describe "make method" do
49
- it "should support inheritance" do
50
- Person.blueprint {}
51
- Admin.blueprint {}
52
-
53
- admin = Admin.make
54
- admin.should_not be_new
55
- admin.type.should_not be_nil
56
- end
57
-
58
- it "should save the constructed object" do
59
- Person.blueprint { }
60
- person = Person.make
61
- person.should_not be_new
62
- end
63
-
64
- it "should create an object through a belongs_to association" do
65
- Post.blueprint { }
66
- Comment.blueprint { post }
67
- Comment.make.post.class.should == Post
68
- end
69
-
70
-
71
- it "should create an object through a belongs_to association with a class_name attribute" do
72
- Person.blueprint { }
73
- Comment.blueprint { author }
74
- Comment.make.author.class.should == Person
75
- end
76
-
77
- it "should raise an exception if the object can't be saved" do
78
- Person.blueprint { }
79
- lambda { Person.make(:name => "More than ten characters") }.should raise_error(RuntimeError)
80
- end
81
- end
82
-
83
- describe "plan method" do
84
- it "should not save the constructed object" do
85
- person_count = Person.all.length
86
- Person.blueprint { }
87
- person = Person.plan
88
- Person.all.length.should == person_count
89
- end
90
-
91
- it "should return a regular attribute in the hash" do
92
- Post.blueprint { title "Test" }
93
- post = Post.plan
94
- post[:title].should == "Test"
95
- end
96
-
97
- it "should create an object through a belongs_to association, and return its id" do
98
- Post.blueprint { }
99
- Comment.blueprint { post }
100
- post_count = Post.all.length
101
- comment = Comment.plan
102
- Post.all.length.should == post_count + 1
103
- comment[:post].should be_nil
104
- comment[:post_id].should_not be_nil
105
- end
106
- end
107
-
108
- describe "make_unsaved method" do
109
- it "should not save the constructed object" do
110
- Person.blueprint { }
111
- person = Person.make_unsaved
112
- person.should be_new
113
- end
114
-
115
- it "should not save associated objects" do
116
- Post.blueprint { }
117
- Comment.blueprint { post }
118
- comment = Comment.make_unsaved
119
- comment.post.should be_new
120
- end
121
-
122
- it "should save objects made within a passed-in block" do
123
- Post.blueprint { }
124
- Comment.blueprint { }
125
- comment = nil
126
- post = Post.make_unsaved { comment = Comment.make }
127
- post.should be_new
128
- comment.should_not be_new
129
- end
130
- end
131
-
132
- end
133
- end
134
-
data/spec/db/.gitignore DELETED
@@ -1 +0,0 @@
1
- *.sqlite3
data/spec/db/schema.rb DELETED
@@ -1,20 +0,0 @@
1
- ActiveRecord::Schema.define(:version => 0) do
2
- create_table :people, :force => true do |t|
3
- t.column :name, :string
4
- t.column :type, :string
5
- t.column :password, :string
6
- t.column :admin, :boolean, :default => false
7
- end
8
-
9
- create_table :posts, :force => true do |t|
10
- t.column :title, :string
11
- t.column :body, :text
12
- t.column :published, :boolean, :default => true
13
- end
14
-
15
- create_table :comments, :force => true do |t|
16
- t.column :post_id, :integer
17
- t.column :author_id, :integer
18
- t.column :body, :text
19
- end
20
- end
data/spec/log/.gitignore DELETED
@@ -1 +0,0 @@
1
- *.log
@@ -1,190 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
- require 'machinist/object'
3
-
4
- module MachinistSpecs
5
-
6
- class Person
7
- attr_accessor :name, :admin
8
- end
9
-
10
- class Post
11
- attr_accessor :title, :body, :published
12
- end
13
-
14
- class Grandpa
15
- attr_accessor :name
16
- end
17
-
18
- class Dad < Grandpa
19
- attr_accessor :name
20
- end
21
-
22
- class Son < Dad
23
- attr_accessor :name
24
- end
25
-
26
- describe Machinist do
27
- before(:each) do
28
- [Person, Post, Grandpa, Dad, Son].each(&:clear_blueprints!)
29
- end
30
-
31
- it "should raise for make on a class with no blueprint" do
32
- lambda { Person.make }.should raise_error(RuntimeError)
33
- end
34
-
35
- it "should set an attribute on the constructed object from a constant in the blueprint" do
36
- Person.blueprint do
37
- name "Fred"
38
- end
39
- Person.make.name.should == "Fred"
40
- end
41
-
42
- it "should set an attribute on the constructed object from a block in the blueprint" do
43
- Person.blueprint do
44
- name { "Fred" }
45
- end
46
- Person.make.name.should == "Fred"
47
- end
48
-
49
- it "should default to calling Sham for an attribute in the blueprint" do
50
- Sham.clear
51
- Sham.name { "Fred" }
52
- Person.blueprint { name }
53
- Person.make.name.should == "Fred"
54
- end
55
-
56
- it "should let the blueprint override an attribute with a default value" do
57
- Post.blueprint do
58
- published { false }
59
- end
60
- Post.make.published.should be_false
61
- end
62
-
63
- it "should override an attribute from the blueprint with a passed-in attribute" do
64
- Person.blueprint do
65
- name "Fred"
66
- end
67
- Person.make(:name => "Bill").name.should == "Bill"
68
- end
69
-
70
- it "should allow overridden attribute names to be strings" do
71
- Person.blueprint do
72
- name "Fred"
73
- end
74
- Person.make("name" => "Bill").name.should == "Bill"
75
- end
76
-
77
- it "should not call a block in the blueprint if that attribute is passed in" do
78
- block_called = false
79
- Person.blueprint do
80
- name { block_called = true; "Fred" }
81
- end
82
- Person.make(:name => "Bill").name.should == "Bill"
83
- block_called.should be_false
84
- end
85
-
86
- it "should call a passed-in block with the object being constructed" do
87
- Person.blueprint { }
88
- block_called = false
89
- Person.make do |person|
90
- block_called = true
91
- person.class.should == Person
92
- end
93
- block_called.should be_true
94
- end
95
-
96
- it "should provide access to the object being constructed from within the blueprint" do
97
- person = nil
98
- Person.blueprint { person = object }
99
- Person.make
100
- person.class.should == Person
101
- end
102
-
103
- it "should allow reading of a previously assigned attribute from within the blueprint" do
104
- Post.blueprint do
105
- title "Test"
106
- body { title }
107
- end
108
- Post.make.body.should == "Test"
109
- end
110
-
111
- describe "named blueprints" do
112
- before do
113
- @block_called = false
114
- Person.blueprint do
115
- name { "Fred" }
116
- admin { @block_called = true; false }
117
- end
118
- Person.blueprint(:admin) do
119
- admin { true }
120
- end
121
- @person = Person.make(:admin)
122
- end
123
-
124
- it "should override an attribute from the parent blueprint in the child blueprint" do
125
- @person.admin.should == true
126
- end
127
-
128
- it "should not call the block for an attribute from the parent blueprint if that attribute is overridden in the child" do
129
- @block_called.should be_false
130
- end
131
-
132
- it "should set an attribute defined in the parent blueprint" do
133
- @person.name.should == "Fred"
134
- end
135
-
136
- it "should return the correct list of named blueprints" do
137
- Person.blueprint(:foo) { }
138
- Person.blueprint(:bar) { }
139
- Person.named_blueprints.to_set.should == [:admin, :foo, :bar].to_set
140
- end
141
- end
142
-
143
- describe "blueprint inheritance" do
144
- it "should inherit blueprinted attributes from the parent class" do
145
- Dad.blueprint { name "Fred" }
146
- Son.blueprint { }
147
- Son.make.name.should == "Fred"
148
- end
149
-
150
- it "should override blueprinted attributes in the child class" do
151
- Dad.blueprint { name "Fred" }
152
- Son.blueprint { name "George" }
153
- Dad.make.name.should == "Fred"
154
- Son.make.name.should == "George"
155
- end
156
-
157
- it "should inherit from blueprinted attributes in ancestor class" do
158
- Grandpa.blueprint { name "Fred" }
159
- Son.blueprint { }
160
- Grandpa.make.name.should == "Fred"
161
- lambda { Dad.make }.should raise_error(RuntimeError)
162
- Son.make.name.should == "Fred"
163
- end
164
-
165
- it "should follow inheritance for named blueprints correctly" do
166
- Dad.blueprint { name "John" }
167
- Dad.blueprint(:special) { name "Paul" }
168
- Son.blueprint { }
169
- Son.blueprint(:special) { }
170
- Son.make(:special).name.should == "John"
171
- end
172
- end
173
-
174
- describe "clear_blueprints! method" do
175
- it "should clear the list of blueprints" do
176
- Person.blueprint(:foo){}
177
- Person.clear_blueprints!
178
- Person.named_blueprints.should == []
179
- end
180
-
181
- it "should clear master blueprint too" do
182
- Person.blueprint(:foo) {}
183
- Person.blueprint {} # master
184
- Person.clear_blueprints!
185
- lambda { Person.make }.should raise_error(RuntimeError)
186
- end
187
- end
188
-
189
- end
190
- end
data/spec/sequel_spec.rb DELETED
@@ -1,146 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
- require 'machinist/sequel'
3
-
4
- # We have to define this here because Sequel needs a DB connection
5
- # setup before you can define models
6
- DB = Sequel.sqlite(:logger => Logger.new(File.dirname(__FILE__) + "/log/test.log"))
7
-
8
- DB.create_table :people do
9
- primary_key :id
10
- String :name
11
- String :type
12
- String :password
13
- Boolean :admin, :default => false
14
- end
15
-
16
- DB.create_table :posts do
17
- primary_key :id
18
- String :title
19
- String :body
20
- Boolean :published, :default => true
21
- end
22
-
23
- DB.create_table :comments do
24
- primary_key :id
25
- Integer :post_id
26
- Integer :author_id
27
- String :body
28
- end
29
-
30
- module MachinistSequelSpecs
31
-
32
- class Person < Sequel::Model
33
- set_restricted_columns :password
34
- end
35
-
36
- class Post < Sequel::Model
37
- one_to_many :comments, :class => "MachinistSequelSpecs::Comment"
38
- end
39
-
40
- class Comment < Sequel::Model
41
- many_to_one :post, :class => "MachinistSequelSpecs::Post"
42
- many_to_one :author, :class => "MachinistSequelSpecs::Person"
43
- end
44
-
45
- describe Machinist, "Sequel adapter" do
46
-
47
- before(:each) do
48
- Person.clear_blueprints!
49
- Post.clear_blueprints!
50
- Comment.clear_blueprints!
51
- end
52
-
53
- describe "make method" do
54
- it "should save the constructed object" do
55
- Person.blueprint { }
56
- person = Person.make
57
- person.should_not be_new
58
- end
59
-
60
- it "should create and object through a many_to_one association" do
61
- Post.blueprint { }
62
- Comment.blueprint { post }
63
- Comment.make.post.class.should == Post
64
- end
65
-
66
- it "should create an object through many_to_one association with a class_name attribute" do
67
- Person.blueprint { }
68
- Comment.blueprint { author }
69
- Comment.make.author.class.should == Person
70
- end
71
-
72
- it "should allow setting a protected attribute in the blueprint" do
73
- Person.blueprint do
74
- password "Test"
75
- end
76
- Person.make.password.should == "Test"
77
- end
78
-
79
- it "should allow overriding a protected attribute" do
80
- Person.blueprint do
81
- password "Test"
82
- end
83
- Person.make(:password => "New").password.should == "New"
84
- end
85
-
86
- it "should allow setting the id attribute in a blueprint" do
87
- Person.blueprint { id 12345 }
88
- Person.make.id.should == 12345
89
- end
90
-
91
- # it "should allow setting the type attribute in a blueprint" do
92
- # Person.blueprint { type "Person" }
93
- # Person.make.type.should == "Person"
94
- # end
95
- end
96
-
97
- describe "plan method" do
98
- it "should not save the constructed object" do
99
- lambda {
100
- Person.blueprint { }
101
- person = Person.plan
102
- }.should_not change(Person,:count)
103
- end
104
-
105
- it "should return a regular attribute in the hash" do
106
- Post.blueprint { title "Test" }
107
- post = Post.plan
108
- post[:title].should == "Test"
109
- end
110
-
111
- it "should create an object through a many_to_one association, and return its id" do
112
- Post.blueprint { }
113
- Comment.blueprint { post }
114
- lambda {
115
- comment = Comment.plan
116
- comment[:post].should be_nil
117
- comment[:post_id].should_not be_nil
118
- }.should change(Post, :count).by(1)
119
- end
120
- end
121
-
122
- # Note that building up an unsaved object graph using just the
123
- # association methods is not possible in Sequel, so
124
- # make_unsaved will break in amusing ways unless you manually
125
- # override the setters.
126
- #
127
- # From sequel-talk "Sequel does not have such an API and will not be adding one"
128
- # Feb 17
129
- describe "make_unsaved method" do
130
- it "should not save the constructed object" do
131
- Person.blueprint { }
132
- person = Person.make_unsaved
133
- person.should be_new
134
- end
135
-
136
- it "should save objects made within a passed-in block" do
137
- Post.blueprint { }
138
- Comment.blueprint { }
139
- comment = nil
140
- post = Post.make_unsaved { comment = Comment.make }
141
- post.should be_new
142
- comment.should_not be_new
143
- end
144
- end
145
- end
146
- end