Doozer is a simple fixture generation library/plugin that handles all the annoying id management, and association building, allowing you to focus on crafting meaningful test fixtures.

Installation

In your rails project directory, run:

./script/plugin source http://mattmccray.com/svn/rails/plugins/
./script/plugin install doozer

Usage

Doozer scripts are usually ruby files that live in the RAILS_ROOT/text/fixtures/doozers directory.

Let's walk through a simple pages.rb doozer. At the top of the script, we'll add this:

Doozer.define :page do
  field_order :title, :content, :author

  defaults :content=>'Content Here',
           :author=>'System', 
           :created_on=>Time.now.to_s(:db)

  block_affects :child=>:parent_id
end

That tells Doozer that you are going to generate page fixtures. It then generates three macros for you to use: page, page_id, and pages. The first macro is the one you'll use most. It defines, or updates, fixture data.

In the definition block, it maps positional parameters to the fixture data fields. It sets up some default values for the fixture data. And lastly, configures how to handle fixtures defined in a page macro block.

Now we can start to write our test data like this:

page :root, "Home Page" do
  page :news, "News is always Fun!" do
    page :site_launch, "Site launched!", :created_on=>1.week.ago
    page :more_news, "More news", :created_on=>3.days.ago
  end
end

There are a couple of things to go over here...

First, you'll notice the first parameter sent to the page macro is a symbol, it's used as the fixture name. It's optional, if you don't specify a name one will be automatically generated.

We also are mixing positional parameters and named parameters. We specify the field_order of the positional parameters, any named parameters are sent straight to the fixture data whether it's defined in the field_order or not.

So here's a breakdown of an example page macro call:

page :site_launch,   "Site launched!",   :created_on=>1.week.ago    
     ^ fixture name  ^ field_order[0]    ^ sent straight to the
                       :title              fixture data

It will have handled the relationships automatically, as well. Since the :site_launch fixture is defined in a block under :news, the :site_launch fixture will have the appropriate :parent_id set.

In the definition above, we used block_affects :child=>:parent_id to handle our acts_as_tree example. Other options include :child=>:belongs_to and :parent=>:belongs_to, with more to come.

It's worth noting here that you can reference the same fixture multiple times, each time it will add to the fixture data it's associated with. So you can create partial fixtures and complete them elsewhere in the doozer script.

In our example so far, all of the pages will have the default content of "Content Here" (as defined in the defaults hash). Let's change that by calling the page macro again with fixture name and the content attribute. Since the content field isn't the first defined in the field_order we'll use a named parameter.

These lines go at the bottom of the definition file:

page :root,        :content=><<-EOC
Welcome to this this site, please enjoy yourself!

Multiple lines are good too.
EOC

page :news,        :content=>"I'm the parent page to all of the news!"
page :site_launch, :content=>"Really, it was!"
page :more_news,   :content=>"No Gnus is Good Gnus!"

That's the basics of a doozer script. To generate the fixture(s), just run:

rake doozer:build

Here's the generated fixture from our example above:

root: 
  created_on: 2007-03-20 15:21:47
  title: Home Page
  author: System
  id: 1
  content: |
    Welcome to this this site, please enjoy yourself!

    Multiple lines are good too.

news: 
  created_on: 2007-03-20 15:21:47
  title: News is always Fun!
  author: System
  id: 2
  content: I'm the parent page to all of the news!
  parent_id: 1

site_launch: 
  created_on: 2007-03-13 15:21:47.096033 -05:00
  title: Site launched!
  author: System
  id: 3
  content: Really, it was!
  parent_id: 2

more_news: 
  created_on: 2007-03-17 15:21:47.096100 -05:00
  title: More news
  author: System
  id: 4
  content: No Gnus is Good Gnus!
  parent_id: 2

That's it, enjoy!