Skip to content

Commit

Permalink
Add FactoryGirl integration
Browse files Browse the repository at this point in the history
Introduce optional FactoryGirl syntax that makes it easier to use
Formulaic to fill in attributes from a factory with a single argument:
`fill_with_factory(:user)`; limit the attributes from a factory:
`fill_with_factory(:user, :name, :address)`; and even pass arguments to
the factory, such as traits and overrides:
`fill_with_factory(:user, :name, :address, factory_arguments: [:with_verified_address]`.

Resolves #11.
  • Loading branch information
calebhearth committed Mar 14, 2014
1 parent f48ee1d commit eade5c9
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 6 deletions.
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,35 @@ end
### Integration with [FactoryGirl](https://github.com/thoughtbot/factory_girl)

```ruby
fill_form(:user, attributes_for(:user))
require 'formulaic/factory_girl'

fill_with_factory(:user, attributes_for(:user))
```

You may have attributes included in your `User` factory that don’t pertain to
sign up:

```ruby
fill_form(:user, attributes_for(:user).slice(sign_up_attributes))
require 'formulaic/factory_girl'

# ...
def sign_up_attributes
[:name, :email, :terms_of_service]
end
fill_with_factory(:user, :name, :email, :terms_of_service)
```

If you need to pass specific arguments to the factory, such as [traits] or to
override values, pass them in the `factory_arguments` parameter.

[traits]: https://github.com/thoughtbot/factory\_girl/blob/master/GETTING\_STARTED.md#traits

```ruby
require 'formulaic/factory_girl'

fill_with_factory(:user, factory_arguments: [:registered, name: 'Frank'])
```

Which is roughly equivalent to calling:

```ruby
fill_form(:user, attributes_for(:user, :registered, name: 'Frank'))
```

## Assumptions
Expand Down
1 change: 1 addition & 0 deletions formulaic.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rake'
spec.add_development_dependency 'rspec'
spec.add_development_dependency 'pry'
spec.add_development_dependency 'factory_girl'
end
25 changes: 25 additions & 0 deletions lib/formulaic/factory_girl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'formulaic/dsl'
require 'factory_girl'
require 'active_support/concern'

module Formulaic
module FactoryGirl
include ::FactoryGirl::Syntax::Methods
def fill_with_factory(model_name, *attribute_whitelist, factory_arguments: [])
attributes = attributes_for(model_name, *factory_arguments)

if attribute_whitelist.any?
attributes = attributes.slice(*attribute_whitelist)
end

fill_form(model_name, attributes)
end
end

Formulaic::Dsl.send(:include, Formulaic::FactoryGirl)
end

#fill_with_factory(:user, :name, :age, factory_arguments: [:authenticated, :super_old, name: 'george'])
#=>
#Formulaic::Dsl.fill_form(FactoryGirl.attributes_for(:user, :authenticated, :super_old, name: 'george').slice(:name, :age))

62 changes: 62 additions & 0 deletions spec/formulaic/factory_girl_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
require 'spec_helper'
require 'formulaic/factory_girl'

describe Formulaic::FactoryGirl, :factory_girl do
before(:all) do
define_user_factory(user_class)
end

after(:all) do
FactoryGirl.factories.clear
end

it 'sets attributes to FactoryGirl.attributes_for(model_name) if attributes is omitted' do
allow(class_with_dsl).to receive(:fill_form)

fill_with_factory(:user)

expect(class_with_dsl).to have_received(:fill_form).with(:user, FactoryGirl.attributes_for(:user))
end

it 'slices the attributes if an attribute whitelist is included' do
allow(class_with_dsl).to receive(:fill_form)

fill_with_factory(:user, :name)

expect(class_with_dsl).to have_received(:fill_form).with(:user, FactoryGirl.attributes_for(:user).slice(:name))
end

it 'merges overrides into the attributes' do
allow(class_with_dsl).to receive(:fill_form)

fill_with_factory :user, :name, factory_arguments: [name: 'Tao' ]

expect(class_with_dsl).to have_received(:fill_form).with(:user, { name: 'Tao' })
end

delegate :fill_with_factory, to: :class_with_dsl

def class_with_dsl
@class ||= Class.new { include Formulaic::Dsl }.new
end

def user_class
@user ||= Class.new do
attr_accessor :name, :age

def initialize(options)
@name = options[:name]
@age = options[:age]
end
end
end

def define_user_factory(user_class)
FactoryGirl.define do
factory :user, class: user_class do
name 'Roen Tan'
age 31
end
end
end
end
3 changes: 3 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
require 'formulaic'
require 'pry'

I18n.enforce_available_locales = false

module SpecHelper
def input(model, field)
page.find("##{model}_#{field}")
Expand Down Expand Up @@ -37,4 +39,5 @@ def load_translations

RSpec.configure do |c|
c.include SpecHelper
c.treat_symbols_as_metadata_keys_with_true_values = true
end

0 comments on commit eade5c9

Please sign in to comment.