Skip to content

Instantly share code, notes, and snippets.

@wtnabe
Created February 2, 2011 23:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wtnabe/808643 to your computer and use it in GitHub Desktop.
Save wtnabe/808643 to your computer and use it in GitHub Desktop.
easy fabricator command for Ruby's fabrication library

Usage

Usage: easy_fabricator [options] FABRICATOR
    -n, --num NUM ( default 1 )
    -y, --output-yaml
    -c, --output-csv ( default )

Fabricator

Create Fabricator file. For example:

# -*- coding: utf-8 -*-

require 'forgery'

def address_fabricator
  code    { rand( 1000 ) + 1000 }
  name    { Forgery(:name).company_name }
  tel     { addr.phone }
  address { [addr.street_address, addr.city, addr.state].join(', ') }
end

def addr
  Forgery(:address)
end

if defined? EasyFabricator
  EasyFabricator.configure do |config|
    config.fields do
      [:code, :name, :tel, :address]
    end

    config.fab do
      Fabricator( :model ) do
        address_fabricator
      end
    end
  end
else
  Fabricator(:address)
end

requirements

  • fields block
  • fab block

above address_fabricator method does not need if you only use that with easy_fabricator.

If you use fabricator as fixture replacement, I recommend to you define method like above.

Example

$ ruby easy_fabricator.rb user.rb

create 1 user with CSV format

$ ruby easy_fabricator.rb -n 30 -y company.rb

create 30 companies with YAML format

Benefit

You can divert fabricated data to fixtures

Limitation

  • 1 execution : 1 model

License

MIT License

#! /usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'optparse'
require 'singleton'
require 'rubygems' unless defined? ::Gem
require 'fabrication'
class EasyFabricator
class Configure
include Singleton
def initialize
@_fields = nil
@_fab = nil
end
def fields
if block_given?
@_fields = yield
else
@_fields
end
end
def fab( &block )
if block_given?
@_fab = block
else
@_fab.call if @_fab
end
end
end
def self.configure(&block)
block.call(Configure.instance)
end
def initialize
@num = 1
@format = 'csv'
@config = Configure.instance
end
attr_reader :config
def run
args.parse!( ARGV )
if ( file = ARGV.shift and File.exist?( file ) )
load file
Object.const_set( 'Model', Struct.new( *config.fields ) )
config.fab
send( "output_#{@format}" )
else
puts args
end
end
def output_csv
require 'fastercsv' if RUBY_VERSION < '1.9'
puts FasterCSV.generate { |csv|
csv << config.fields
}
puts FasterCSV.generate { |csv|
@num.times {
c = Fabricate.build( :model )
csv << config.fields.map { |field|
c[field]
}
}
}
end
def output_yaml
$KCODE = 'u' unless defined? ::Encoding
puts (1..@num).to_a.map { |id|
record = Fabricate.build( :model )
hash = {}
record.each_pair { |k, v|
hash[k.to_s] = v
}
to_yaml( id => hash ).sub( /--- \n/, '' )
}
end
def args
OptionParser.new { |opt|
opt.banner << " fabricator"
opt.on( '-n', '--num NUM ( default 1 )' ) { |num|
@num = num.to_i if num =~ /\A[0-9]+\z/
}
opt.on( '-y', '--output-yaml' ) {
@format = 'yaml'
prepare_yaml
}
opt.on( '-c', '--output-csv ( default )' ) {
@format = 'csv'
}
}
end
private
def prepare_yaml
begin
require 'ya2yaml'
rescue LoadError
require 'yaml'
end
class << self
if ( defined? Ya2YAML )
def to_yaml( obj )
obj.ya2yaml
end
else
def to_yaml( obj )
obj.to_yaml
end
end
end
end
end
if ( __FILE__ == $0 )
EasyFabricator.new.run
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment