creating YAML fixtures from existing data

I just came across this cool tip from Tom Preston-Werner of rubyisawesome.com. Basically, if you end a mysql commandline query with \G instead of a semicolon, you’ll get a nicely formatted query that is suitable for pasting into a YAML file.

But what if you are not using mysql? We have a project with postgres. There’s probably a psql command to do something similar, but there is also a database agnostic way: Just use the rails console! :)


>> puts User.find(:all).to_yaml
---
- !ruby/object:User 
  attributes: 
    status: unverified
    salt: L52b2pxGCL
    can_invite: "0" 
    hashed_password: L50/yIQjPCBiU
    is_admin: "0" 
    id: "478674008" 
    first_name: Mickey
    last_name: Mouse
    watchlist_by_email: "0" 
    created_at: 2008-01-30 15:34:26
    email: mickey@mouse.com

		
		
	

a yaml_to_shoulda rake task

Inspired by err’s cryptic yaml_to_spec rake task, I wrote my own version for shoulda, based off of Jeremy Hubert’s textmate bundle It’s a bit less cryptic, and it for extra nerd points it uses recursion to allow for nested contexts. :)


desc "Converts a YAML file into a Shoulda skeleton" 
task :yaml_to_shoulda do
  require 'yaml'

  def yaml_to_context hash, indent=0
    indent1 = '  '*indent
    indent2 = '  '*(indent+1)
    hash.each_pair do |context,shoulds|
      puts indent1+"context \"#{context}\" do" 
      puts    
      shoulds.each do |should|
        yaml_to_context( should, indent+1 ) and next if should.is_a?( Hash )
        puts indent2+"should_eventually \"#{should.gsub(/^should +/,'')}\" do" 
        puts indent2+"end" 
        puts
      end
    puts indent1+"end" 
  end 

  yaml_to_context( YAML.load_file( ENV['FILE'] || !puts("Pass in FILE argument.") && exit ) )
end

Here is an example YAML file and it’s output:

This blog post:
- should mention shoulda
- should be concise
- should be written by me
- when saved as a draft:
  - should have multiple revisions
  - should not be published publicly



context "This blog post" do

  should_eventually "mention shoulda" do
  end

  should_eventually "be concise" do
  end

  should_eventually "be written by me" do
  end

  context "when saved as a draft" do

    should_eventually "have multiple revisions" do
    end

    should_eventually "not be published publicly" do
    end

  end
end

I will be adding this to my shoulda textmate bundle.

actionmailer ActionView ajax alphadecimal audio autotest BDD blocks capistrano ssh ruby controller css dashboard widget delegate dog puppy naming name DRM email obfuscation exceptions factory pattern filemerge find and replace finder fink fixtures fun gem google maps helper helpers imagemagick Intertrust javascript logo math meetup model openssl OS X patch Pioneer Electronics plugin polymorphism prototype.js rails rake rmagick RSA encryption ruby script shoulda subversion SyncTV TDD testing textmate tricks unique hashes unix shell validation view yaml zebra stripes