Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 296 lines (193 sloc) 8.206 kb
4dade1a @notahat Started taking notes for the README.
authored
1 # Machinist 2
2
634ec69 @notahat More documentation scribblings.
authored
3 *Fixtures aren't fun. Machinist is.*
4
67c6b28 @notahat Encourage the use of Machinist 2.
authored
5 Machinist 2 is **still in beta**!
6
7 If you're using Rails 3, you'll want to give Machinist 2 a go, but be aware
8dcfcaa @notahat Slowly getting the docs in place.
authored
8 that the documentation is still patchy.
67c6b28 @notahat Encourage the use of Machinist 2.
authored
9
10 That said, have a look at [the
11 specs](https://github.com/notahat/machinist/tree/master/spec), starting with
12 [the spec for
13 Machinable](https://github.com/notahat/machinist/blob/master/spec/machinable_spec.rb).
14 No, really, have a look. I wrote this code to be read, and the specs do a
15 pretty clean job of documenting what it all does.
16
17 If, on the other hand, you want the tried, tested, and well-documented official
18 release version of Machinist, [then go with Machinist
3761daa @notahat Added a link back to Machinist 1 to the readme.
authored
19 1](http://github.com/notahat/machinist/tree/1.0-maintenance).
20
df75114 @notahat README had a link to the old machinist2 branch.
authored
21 - [Home page](http://github.com/notahat/machinist)
cc9bd03 @notahat Working on the README.
authored
22 - [Google group](http://groups.google.com/group/machinist-users), for support
8dcfcaa @notahat Slowly getting the docs in place.
authored
23 - [Bug tracker](http://github.com/notahat/machinist/issues), for reporting Machinist bugs
634ec69 @notahat More documentation scribblings.
authored
24
966d19e @notahat Moved more stuff from the README to the wiki.
authored
25
cc9bd03 @notahat Working on the README.
authored
26 ## Introduction
634ec69 @notahat More documentation scribblings.
authored
27
cc9bd03 @notahat Working on the README.
authored
28 Machinist makes it easy to create objects for use in tests. It generates data
d0f0941 @notahat Documentation.
authored
29 for the attributes you don't care about, and constructs any necessary
cc9bd03 @notahat Working on the README.
authored
30 associated objects, leaving you to specify only the fields you care about in
31 your test. For example:
634ec69 @notahat More documentation scribblings.
authored
32
ba72241 @notahat Working my way through documenting everything.
authored
33 describe Comment do
34 it "should not include spam in the without_spam scope" do
d0f0941 @notahat Documentation.
authored
35 # This will make a Comment, a Post, and a User (the author of the
36 # Post), generate values for all their attributes, and save them:
ba72241 @notahat Working my way through documenting everything.
authored
37 spam = Comment.make!(:spam => true)
634ec69 @notahat More documentation scribblings.
authored
38
ba72241 @notahat Working my way through documenting everything.
authored
39 Comment.without_spam.should_not include(spam)
40 end
634ec69 @notahat More documentation scribblings.
authored
41 end
42
cc9bd03 @notahat Working on the README.
authored
43
ba72241 @notahat Working my way through documenting everything.
authored
44 You tell Machinist how to do this with blueprints:
634ec69 @notahat More documentation scribblings.
authored
45
ba72241 @notahat Working my way through documenting everything.
authored
46 require 'machinist/active_record'
634ec69 @notahat More documentation scribblings.
authored
47
ba72241 @notahat Working my way through documenting everything.
authored
48 User.blueprint do
49 username { "user#{sn}" } # Each user gets a unique serial number.
50 end
cc9bd03 @notahat Working on the README.
authored
51
ba72241 @notahat Working my way through documenting everything.
authored
52 Post.blueprint do
53 author
54 title { "Post #{sn}" }
55 body { "Lorem ipsum..." }
56 end
634ec69 @notahat More documentation scribblings.
authored
57
ba72241 @notahat Working my way through documenting everything.
authored
58 Comment.blueprint do
59 post
cc9bd03 @notahat Working on the README.
authored
60 email { "commenter#{sn}@example.com" }
ba72241 @notahat Working my way through documenting everything.
authored
61 body { "Lorem ipsum..." }
62 end
634ec69 @notahat More documentation scribblings.
authored
63
cc9bd03 @notahat Working on the README.
authored
64
65 ## Installation
66
67 ### Upgrading from Machinist 1
68
7e439d5 @notahat More README improvements.
authored
69 See [the wiki](http://wiki.github.com/notahat/machinist/machinist-2).
cc9bd03 @notahat Working on the README.
authored
70
71 ### Rails 3
72
73 In your app's `Gemfile`, in the `group :test` section, add:
74
75 gem 'machinist', '>= 2.0.0.beta2'
76
77 Then run:
78
79 bundle
80 rails generate machinist:install
81
82 If you want Machinist to automatically add a blueprint to your blueprints file
83 whenever you generate a model, add the following to your
84 `config/application.rb` in the `config.generators` section:
85
86 g.fixture_replacement :machinist
87
88
89 ### Rails 2
90
7e439d5 @notahat More README improvements.
authored
91 See [the wiki](http://wiki.github.com/notahat/machinist/rails-2).
cc9bd03 @notahat Working on the README.
authored
92
93
94 ## Usage
95
96 ### Blueprints
97
7e439d5 @notahat More README improvements.
authored
98 A blueprint describes how to generate an object. The blueprint takes care of
99 providing attributes that your test doesn't care about, leaving you to focus on
100 the just the attributes that are important for the test.
cc9bd03 @notahat Working on the README.
authored
101
102 A simple blueprint might look like this:
103
104 Post.blueprint do
7e439d5 @notahat More README improvements.
authored
105 title { "A Post" }
cc9bd03 @notahat Working on the README.
authored
106 body { "Lorem ipsum..." }
107 end
108
109 You can then construct a Post from this blueprint with:
110
111 Post.make!
112
113 When you call `make!`, Machinist calls `Post.new`, then runs through the
114 attributes in your blueprint, calling the block for each attribute to generate
115 a value. It then saves and reloads the Post. (It throws an exception if the
116 Post can't be saved.)
117
118 You can override values defined in the blueprint by passing a hash to make:
119
120 Post.make!(:title => "A Specific Title")
7e439d5 @notahat More README improvements.
authored
121
cc9bd03 @notahat Working on the README.
authored
122 If you want to generate an object without saving it to the database, replace
123 `make!` with `make`.
124
125
7e439d5 @notahat More README improvements.
authored
126 ### Unique Attributes
127
128 For attributes that need to be unique, you can call the `sn` method from
129 within the attribute block to get a unique serial number for the object.
cc9bd03 @notahat Working on the README.
authored
130
131 User.blueprint do
7e439d5 @notahat More README improvements.
authored
132 username { "user-#{sn}" }
cc9bd03 @notahat Working on the README.
authored
133 end
7e439d5 @notahat More README improvements.
authored
134
cc9bd03 @notahat Working on the README.
authored
135
136 ### Associations
137
138 If your object needs associated objects, you can generate them like this:
139
140 Comment.blueprint do
141 post { Post.make }
142 end
143
144 Calling `Comment.make!` will construct a Comment and its associated Post, and
145 save both.
c4f99a4 @notahat Aaannnddd more README tweaks.
authored
146
cc9bd03 @notahat Working on the README.
authored
147 Machinist is smart enough to look at the association and work out what sort of
148 object it needs to create, so you can shorten the above blueprint to:
149
150 Comment.blueprint do
151 post
152 end
153
c4f99a4 @notahat Aaannnddd more README tweaks.
authored
154 If you want to override the value for post when constructing the comment, you
155 can do this:
156
157 post = Post.make(:title => "A particular title)
158 comment = Comment.make(:post => post)
159
160
cc9bd03 @notahat Working on the README.
authored
161 For `has_many` and `has_and_belongs_to_many` associations, you can create
162 multiple associated objects like this:
163
164 Post.blueprint do
c4f99a4 @notahat Aaannnddd more README tweaks.
authored
165 comments(3) # Makes 3 comments.
cc9bd03 @notahat Working on the README.
authored
166 end
167
168
7e439d5 @notahat More README improvements.
authored
169 ### Named Blueprints
170
171 Named blueprints let you define variations on an object. For example, suppose
172 some of your Users are administrators:
173
174 User.blueprint do
175 name { "User #{sn}" }
176 email { "user-#{sn}@example.com" }
177 end
178
179 User.blueprint(:admin) do
180 name { "Admin User #{sn}" }
181 admin { true }
182 end
183
184 Calling:
185
186 User.make!(:admin)
187
188 will use the `:admin` blueprint.
189
190 Named blueprints call the default blueprint to set any attributes not
191 specifically provided, so in this example the `email` attribute will still be
192 generated even for an admin user.
193
194 You must define a default blueprint for any class that has a named blueprint,
195 even if the default blueprint is empty.
196
197
cc9bd03 @notahat Working on the README.
authored
198 ### Blueprints on Plain Old Ruby Objects
199
200 Machinist also works with plain old Ruby objects. Let's say you have a class like:
201
202 class Post
203 extend Machinist::Machinable
204
205 attr_accessor :title
206 attr_accessor :body
207 end
208
209 You can blueprint the Post class just like anything else:
210
211 Post.blueprint do
212 title { "A title!" }
213 body { "A body!" }
214 end
215
216 And `Post.make` will construct a new Post.
7e439d5 @notahat More README improvements.
authored
217
218
219 ### Other Tricks
220
221 You can refer to already assigned attributes when constructing a new attribute:
cc9bd03 @notahat Working on the README.
authored
222
7e439d5 @notahat More README improvements.
authored
223 Post.blueprint do
224 author { "Author #{sn}" }
225 body { "Post by #{object.author}" }
226 end
227
cc9bd03 @notahat Working on the README.
authored
228
229 ## Compatibility
230
231 I've tested this with:
232
233 Ruby versions: 1.8.7, 1.9.2
8dcfcaa @notahat Slowly getting the docs in place.
authored
234 Rails versions: 2.3, 3.0
cc9bd03 @notahat Working on the README.
authored
235
236 It may well be happy with other versions too, but I'm not promising anything.
237 Compatibility patches are welcome.
238
239
240 ## Developing
241
242 The Machinist specs and source code were written to be read, and I'm pretty
c4f99a4 @notahat Aaannnddd more README tweaks.
authored
243 happy with them. Don't be afraid to have a look under the hood!
cc9bd03 @notahat Working on the README.
authored
244
8dcfcaa @notahat Slowly getting the docs in place.
authored
245 If you want to submit a patch:
246
cc9bd03 @notahat Working on the README.
authored
247 - Fork the project.
248 - Make your feature addition or bug fix.
249 - Add tests for it. This is important so I don't break it in a
250 future version unintentionally.
251 - Commit, do not mess with rakefile, version, or history.
252 (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
253 - Send me a pull request. Bonus points for topic branches.
254
255
256 ## Status
257
258 In active use in a number of large Rails 2 apps.
259
260 Development has been sporadic, but is picking up again.
d7dbd50 @notahat Added Rails 2 installation instructions.
authored
261
262
ba72241 @notahat Working my way through documenting everything.
authored
263 ## Contributors
264
265 Machinist is maintained by Pete Yandell ([pete@notahat.com](mailto:pete@notahat.com), [@notahat](http://twitter.com/notahat))
266
267 Other contributors include:
268
269 [Marcos Arias](http://github.com/yizzreel),
270 [Jack Dempsey](http://github.com/jackdempsey),
df48e93 @notahat Added Jeremy Durham to contributors.
authored
271 [Jeremy Durham](http://github.com/jeremydurham),
ba72241 @notahat Working my way through documenting everything.
authored
272 [Clinton Forbes](http://github.com/clinton),
273 [Perryn Fowler](http://github.com/perryn),
274 [Niels Ganser](http://github.com/Nielsomat),
275 [Jeremy Grant](http://github.com/jeremygrant),
276 [Jon Guymon](http://github.com/gnarg),
277 [James Healy](http://github.com/yob),
417d24c @notahat Belatedly added Ben H and Xavier to contributors.
authored
278 [Ben Hoskings](http://github.com/benhoskings),
ba72241 @notahat Working my way through documenting everything.
authored
279 [Evan David Light](http://github.com/elight),
280 [Chris Lloyd](http://github.com/chrislloyd),
281 [Adam Meehan](http://github.com/adzap),
282 [Kyle Neath](http://github.com/kneath),
283 [Lawrence Pit](http://github.com/lawrencepit),
417d24c @notahat Belatedly added Ben H and Xavier to contributors.
authored
284 [Xavier Shay](http://github.com/xaviershay),
ba72241 @notahat Working my way through documenting everything.
authored
285 [T.J. Sheehy](http://github.com/tjsheehy),
286 [Roland Swingler](http://github.com/knaveofdiamonds),
287 [Gareth Townsend](http://github.com/quamen),
288 [Matt Wastrodowski](http://github.com/towski),
289 [Ian White](http://github.com/ianwhite)
290
291 Thanks to Thoughtbot's [Factory
292 Girl](http://github.com/thoughtbot/factory_girl/tree/master). Machinist was
293 written because I loved the idea behind Factory Girl, but I thought the
294 philosophy wasn't quite right, and I hated the syntax.
cc9bd03 @notahat Working on the README.
authored
295
Something went wrong with that request. Please try again.