rom-factory

Gem Version Build Status Dependency Status Code Climate Test Coverage Inline docs

Data generator with support for persistence backends, built on top of rom-rb and dry-rb.

Installation

Add this line to your application's Gemfile:

gem 'rom-factory'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rom-factory

Configuration

First, you have to define ROM container:

rom = ROM.container(:sql, 'sqlite::memory') do |conf|
  conf.default.create_table(:users) do
    primary_key :id
    column :last_name, String, null: false
    column :first_name, String, null: false
    column :email, String, null: false
    column :admin, TrueClass, null: false, default: false
    column :created_at, Time, null: false
    column :updated_at, Time, null: false
  end
end

Notice that if you're using ROM in your application, then simply set up factory using your existing ROM container

Once that is done, you will have to specify which container ROM::Factory will use:

Factory = ROM::Factory.configure do |config|
  config.rom = rom
end

This returns a new factory ready to be used.

Simple use case

After configuration is done, you can define builders using your Factory:

Factory.define(:user) do |f|
  f.first_name "Janis"
  f.last_name "Miezitis"
  f.email "[email protected]"
end

Then you can use it to generate data:

user = Factory[:user]
user.email #=> "[email protected]"

Callable properties

You can easily define dynamic (callbale) properties if value needs to change every time it needs to be called. Anything that responds to .call can be a dynamic property.

Factory.define(:user) do |f|
  f.first_name "Janis"
  f.last_name "Miezitis"
  f.email "[email protected]"
  f.created_at {Time.now}
end

user = Factory[:user]
user.created_at #=> 2016-08-27 18:17:08 -0500

Sequencing

If you want attributes to be unique each time you generate data, you can use sequence to achieve that:

Factory.define(:user) do |f|
  f.first_name "Janis"
  f.last_name "Miezitis"
  f.sequence :email do |n|
    "janjiss#{n}@gmail.com"
  end
end

user1 = Factory[:user]
user2 = Factory[:user]

user1.email #=> [email protected]
user2.email #=> [email protected]

Timestamps

There is a support for timestamps for created_at and updated_at attributes:

Factory.define(:user) do |f|
  f.first_name "Janis"
  f.last_name "Miezitis"
  f.email "[email protected]"
  f.timestamps
end

user = Factory[:user]
user.created_at #=> 2016-08-27 18:17:08 -0500
user.updated_at #=> 2016-08-27 18:17:10 -0500

Associations

If you defined associations in your relations, you can use association builder:

factories.define(:user) do |f|
  f.first_name 'Jane'
  f.last_name 'Doe'
  f.email '[email protected]'
  f.timestamps
end

factories.define(:task) do |f|
  f.title 'A task'
  f.association(:user)
end

task = factories[:task]

Currently only belongs_to is supported

Fake data generator

There's a builtin support for Faker gem with a fake shortcut in the DSL:

factories.define(:user) do |f|
  f.first_name { fake(:name, :first_name) }
  f.last_name { fake(:name, :last_name) }
  f.email { fake(:internet, :email) }
  f.timestamps
end

Extending existing builders

You can create a hierarchy of builders easily, which is useful if you want to share data generation logic across multiple definitions:

Factory.define(:user) do |f|
  f.first_name "Janis"
  f.last_name "Miezitis"
  f.email "[email protected]"
  f.admin false
  f.timestamps
end

Factory.define(admin: :user) do |f|
  f.admin true
end

user = Factory[:admin]

user.admin # true

Setting up relation backend explicitly

By default, relation is configured automatically based on the builder name. For example if your builder is called :user, then :users relation name will be inferred. If you want to set up a relation explicitly, use :relation option:

Factory.define(:user, relation: :people) do |f|
  f.first_name "Janis"
  f.last_name "Miezitis"
  f.email "[email protected]"
  f.admin false
  f.timestamps
end

Generating structs without persistence

You can generate struct objects without persisting them using #structs generator:

Factory.define(:user) do |f|
  f.first_name "Janis"
  f.last_name "Miezitis"
  f.email "[email protected]"
  f.admin false
  f.timestamps
end

user = Factory.structs[:user]

user.id # auto-generated fake PK
user.first_name # "Janis"

Credits

This project was originally created by Jānis Miezītis and eventually moved to rom-rb organization.

License

See LICENSE.txt file.