Skip to content

Commit

Permalink
Working on the README.
Browse files Browse the repository at this point in the history
  • Loading branch information
notahat committed Jun 19, 2011
1 parent c32193d commit cc9bd03
Showing 1 changed file with 195 additions and 15 deletions.
210 changes: 195 additions & 15 deletions README.markdown
Expand Up @@ -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
Expand All @@ -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}" }
Expand All @@ -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
Expand Down Expand Up @@ -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.