Permalink
Browse files

Working on the README.

  • Loading branch information...
1 parent c32193d commit cc9bd0368ea0553868249e8cd098b1e7ac0760cd @notahat committed Jun 19, 2011
Showing with 195 additions and 15 deletions.
  1. +195 −15 README.markdown
View
@@ -19,19 +19,16 @@ release version of Machinist, [then go with Machinist
1](http://github.com/notahat/machinist/tree/1.0-maintenance).
- [Home page](http://github.com/notahat/machinist)
-- [What's new in Machinist 2](http://wiki.github.com/notahat/machinist/machinist-2)
-- [Installation](http://wiki.github.com/notahat/machinist/installation)
-- [Documentation](http://wiki.github.com/notahat/machinist/getting-started)
-- [Google group](http://groups.google.com/group/machinist-users)
-- [Bug tracker](http://github.com/notahat/machinist/issues)
+- [Google group](http://groups.google.com/group/machinist-users), for support
+- [Bug tracker](http://github.com/notahat/machinist/issues), for Machinist bugs
-# Introduction
+## Introduction
-Machinist makes it easy to create objects within your tests. It generates data
+Machinist makes it easy to create objects for use in tests. It generates data
for the attributes you don't care about, and constructs any necessary
-associated objects, leaving you to specify only the attributes you *do* care
-about in your tests. For example:
+associated objects, leaving you to specify only the fields you care about in
+your test. For example:
describe Comment do
it "should not include spam in the without_spam scope" do
@@ -43,14 +40,15 @@ about in your tests. For example:
end
end
+
You tell Machinist how to do this with blueprints:
require 'machinist/active_record'
User.blueprint do
username { "user#{sn}" } # Each user gets a unique serial number.
end
-
+
Post.blueprint do
author
title { "Post #{sn}" }
@@ -59,13 +57,195 @@ You tell Machinist how to do this with blueprints:
Comment.blueprint do
post
- email { "commenter-#{sn}@example.com" }
+ email { "commenter#{sn}@example.com" }
body { "Lorem ipsum..." }
end
-Check out the
-[documentation](http://wiki.github.com/notahat/machinist/getting-started) for
-more info.
+
+## Installation
+
+### Upgrading from Machinist 1
+
+See [the wiki](http://wiki.github.com/notahat/machinist/machinist-2)
+
+### Rails 3
+
+In your app's `Gemfile`, in the `group :test` section, add:
+
+ gem 'machinist', '>= 2.0.0.beta2'
+
+Then run:
+
+ bundle
+ rails generate machinist:install
+
+If you want Machinist to automatically add a blueprint to your blueprints file
+whenever you generate a model, add the following to your
+`config/application.rb` in the `config.generators` section:
+
+ g.fixture_replacement :machinist
+
+
+### Rails 2
+
+See [the wiki](http://wiki.github.com/notahat/machinist/rails-2)
+
+
+## Usage
+
+### Blueprints
+
+A blueprint describes how to generate an object. The idea is that you let the
+blueprint take care of making up values for attributes that you don't care
+about in your test, leaving you to focus on the just the things that you're
+testing.
+
+A simple blueprint might look like this:
+
+ Post.blueprint do
+ title { "Post #{sn}" }
+ body { "Lorem ipsum..." }
+ end
+
+You can then construct a Post from this blueprint with:
+
+ Post.make!
+
+When you call `make!`, Machinist calls `Post.new`, then runs through the
+attributes in your blueprint, calling the block for each attribute to generate
+a value. It then saves and reloads the Post. (It throws an exception if the
+Post can't be saved.)
+
+For attributes that need to be unique, you can call the `sn` method from
+within the attribute block to get a unique serial number for the object.
+
+You can override values defined in the blueprint by passing a hash to make:
+
+ Post.make!(:title => "A Specific Title")
+
+If you want to generate an object without saving it to the database, replace
+`make!` with `make`.
+
+You can refer to already assigned attributes when constructing a new attribute:
+
+ Post.blueprint do
+ author { "Fred Author" }
+ body { "Post by #{object.author}" }
+ end
+
+
+### Named Blueprints
+
+Named blueprints let you define variations on an object. For example, suppose
+some of your Users are administrators:
+
+ User.blueprint do
+ name { "User #{sn}" }
+ email { "user-#{sn}@example.com" }
+ end
+
+ User.blueprint(:admin) do
+ name { "Admin User #{sn}" }
+ admin { true }
+ end
+
+Calling:
+
+ User.make!(:admin)
+
+will use the `:admin` blueprint.
+
+Named blueprints call the default blueprint to set any attributes not
+specifically provided, so in this example the `email` attribute will still be
+generated even for an admin user.
+
+You must define a default blueprint for any class that has a named blueprint,
+even if the default blueprint is empty.
+
+
+### Associations
+
+If your object needs associated objects, you can generate them like this:
+
+ Comment.blueprint do
+ post { Post.make }
+ end
+
+Calling `Comment.make!` will construct a Comment and its associated Post, and
+save both.
+
+If you want to override the value for post when constructing the comment, you
+can do this:
+
+ post = Post.make(:title => "A particular title)
+ comment = Comment.make(:post => post)
+
+Machinist is smart enough to look at the association and work out what sort of
+object it needs to create, so you can shorten the above blueprint to:
+
+ Comment.blueprint do
+ post
+ end
+
+For `has_many` and `has_and_belongs_to_many` associations, you can create
+multiple associated objects like this:
+
+ Post.blueprint do
+ comments(3)
+ end
+
+
+### Blueprints on Plain Old Ruby Objects
+
+Machinist also works with plain old Ruby objects. Let's say you have a class like:
+
+ class Post
+ extend Machinist::Machinable
+
+ attr_accessor :title
+ attr_accessor :body
+ end
+
+You can blueprint the Post class just like anything else:
+
+ Post.blueprint do
+ title { "A title!" }
+ body { "A body!" }
+ end
+
+And `Post.make` will construct a new Post.
+
+
+## Compatibility
+
+I've tested this with:
+
+Ruby versions: 1.8.7, 1.9.2
+Rails versions: 2.3, 3.0, 3.1
+
+It may well be happy with other versions too, but I'm not promising anything.
+Compatibility patches are welcome.
+
+
+## Developing
+
+The Machinist specs and source code were written to be read, and I'm pretty
+happy with them. Don't be have a look under the hood.
+
+- Fork the project.
+- Make your feature addition or bug fix.
+- Add tests for it. This is important so I don't break it in a
+ future version unintentionally.
+- Commit, do not mess with rakefile, version, or history.
+ (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)
+- Send me a pull request. Bonus points for topic branches.
+
+
+## Status
+
+In active use in a number of large Rails 2 apps.
+
+Development has been sporadic, but is picking up again.
## Contributors
@@ -100,4 +280,4 @@ Thanks to Thoughtbot's [Factory
Girl](http://github.com/thoughtbot/factory_girl/tree/master). Machinist was
written because I loved the idea behind Factory Girl, but I thought the
philosophy wasn't quite right, and I hated the syntax.
-
+

0 comments on commit cc9bd03

Please sign in to comment.