Last active
November 30, 2021 23:27
-
-
Save caius/768dcc66a2a6ce4a1f95dbc1bada05de to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "factory_bot" | |
require "active_support/all" | |
module LocalFactory | |
class Factory | |
attr_reader :factories | |
def initialize | |
@factories = {} | |
end | |
# Public: factory method to build a FactoryBot factory out | |
# | |
# @param name [Symbol, #to_sym] name of the factory, passed to `build` later | |
# @param class: [Object] class the factory should instantiate | |
# @param **options [Hash] @see FactoryBot::Factory#initialize | |
# @param &block [Proc] @see FactoryBot::DefinitionProxy for available methods | |
# @return nothing | |
# | |
# @example defining and using factory in spec | |
# | |
# RSpec.describe "testing some crazy idea out" do | |
# include LocalFactory | |
# | |
# local_factory.factory(:user) do | |
# sequence(:name) { |n| "User #{n}" } | |
# age { 0xBADC0FFEE } | |
# end | |
# | |
# it "things" do | |
# thing = local_factory.build(:user, age: 911) | |
# expect(thing.name).to eq("User 1") | |
# expect(thing.age).to eq(911) | |
# end | |
# end | |
# | |
def factory(name, **options, &block) | |
klass = options.key?(:class) ? options.delete(:class) : OpenStruct | |
factories[name.to_sym] = FactoryBot::Factory.new(name, class: klass, **options) | |
# Apply definition to factory through definition proxy (hattip to FactoryBot source code) | |
FactoryBot::DefinitionProxy.new(factories[name.to_sym].definition).instance_eval(&block) | |
nil | |
end | |
# Public: build an instance from a factory | |
# | |
# @param name [Symbol, #to_sym] name of the factory to invoke | |
# @param **overrides [Hash] @see FactoryBot::Factory#run for options | |
# @return [Object] instantiated instance from factory | |
def build(name, **overrides) | |
factories.fetch(name.to_sym).run(FactoryBot::Strategy::Build, overrides) | |
end | |
end | |
# Internal: setup spec class for localised factorying | |
# | |
# You could argue this is the local factory factory. /me laughs in java | |
# | |
# @param klass [Object] class object module included into | |
# @return nothing | |
def self.included(klass) | |
klass.cattr_accessor :local_factory | |
klass.local_factory = Factory.new | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment