Created
May 6, 2016 12:15
-
-
Save ignar/d5c713e8cc007cab5364553cd7fcd97a to your computer and use it in GitHub Desktop.
This file contains 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 'active_support/all' | |
class User | |
attr_accessor :name, :admin | |
def initialize(options = {}, &block) | |
options.each do |k,v| | |
self.public_send "#{k}=", v | |
end | |
end | |
end | |
class UserJob | |
attr_accessor :name, :admin | |
def initialize(name, options = {}) | |
self.name = name | |
options.each do |k,v| | |
self.public_send "#{k}=", v | |
end | |
end | |
end | |
module Klassifier | |
def get_klass(klass) | |
_klass = klass | |
if klass.is_a?(Symbol) || klass.is_a?(String) | |
_klass = klass.to_s.classify.constantize | |
end | |
_klass | |
end | |
end | |
class FactoryBoy | |
extend Klassifier | |
class InvalidArg < StandardError; end | |
class NotRegistered < StandardError; end | |
class Registry | |
include Singleton | |
include Klassifier | |
attr_accessor :factories | |
def push(klass, args, &block) | |
self.factories ||= {} | |
factories[get_klass(klass)] = {args: args, block: block} | |
end | |
def get(klass) | |
factories[get_klass(klass)] | |
end | |
def clear | |
self.factories = {} | |
end | |
end | |
class << self | |
def register(klass, *args, &block) | |
Registry.instance.push(klass, args, &block) | |
end | |
def clear | |
Registry.instance.clear | |
end | |
def create(klass, *arg, &block) | |
_klass = get_klass(klass) | |
raise NotRegistered unless Registry.instance.get(_klass) | |
raise InvalidArg unless _klass.respond_to?(:new) | |
inst = _klass.new(*arg) | |
if block_given? | |
Class.new do | |
def initialize(inst); @inst = inst; end | |
def method_missing(method, *args) | |
@inst.public_send("#{method}=", *args) | |
end | |
end.new(inst).instance_eval(&block) | |
end | |
inst | |
end | |
end | |
end | |
describe FactoryBoy::Registry do | |
before { described_class.instance.clear } | |
context 'with no args' do | |
it 'should register' do | |
FactoryBoy.register(:user) | |
expect(described_class.instance.get(:user)).to be_kind_of(Hash) | |
end | |
end | |
context 'with args' do | |
it 'should register' do | |
attrs = {name: 'name'} | |
FactoryBoy.register(:user, attrs) | |
factory = described_class.instance.get(:user) | |
expect(factory).to be_kind_of(Hash) | |
expect(factory[:args]).to eq([attrs]) | |
end | |
it 'when params' do | |
attrs = {name: 'name'} | |
name = 'name' | |
FactoryBoy.register(:user_job, name, attrs) | |
factory = described_class.instance.get(:user_job) | |
expect(factory).to be_kind_of(Hash) | |
expect(factory[:args]).to eq([name, attrs]) | |
end | |
it 'when params' do | |
FactoryBoy.register(:user){ admin true } | |
factory = described_class.instance.get(:user) | |
expect(factory).to be_kind_of(Hash) | |
expect(factory[:block]).to be_kind_of(Proc) | |
end | |
end | |
end | |
describe FactoryBoy do | |
before { described_class.clear } | |
describe '.create' do | |
context 'not fail' do | |
it 'should return instance' do | |
described_class.register(User) | |
expect(described_class.create(User)).to be_an_instance_of(User) | |
end | |
it 'should return instance' do | |
described_class.register(:user) | |
expect(described_class.create(:user)).to be_an_instance_of(User) | |
end | |
it 'should return instance' do | |
described_class.register(:user_job) | |
expect(described_class.create(:user_job, 'me')).to be_an_instance_of(UserJob) | |
end | |
context 'with args' do | |
before do | |
described_class.register(:user_job) | |
end | |
it 'should return instance' do | |
expect(described_class.create(:user_job, 'name')).to be_an_instance_of(UserJob) | |
end | |
it 'should correctly assign attrs' do | |
name = 'name' | |
inst = described_class.create(:user_job, name) | |
expect(inst.name).to eq(name) | |
end | |
it 'should correctly assign attrs' do | |
name = 'name' | |
admin = true | |
inst = described_class.create(:user_job, name, admin: admin) | |
expect(inst.name).to eq(name) | |
expect(inst.admin).to eq(admin) | |
end | |
it 'should correctly assign attrs' do | |
name = 'name' | |
admin = true | |
inst = described_class.create(:user_job, name){ admin true } | |
expect(inst.name).to eq(name) | |
expect(inst.admin).to eq(admin) | |
end | |
end | |
context 'with register' do | |
end | |
end | |
context 'fail' do | |
it 'should fail unless arg is klass' do | |
module Foo; end | |
described_class.register(Foo) | |
expect { | |
described_class.create(Foo) | |
}.to raise_error(described_class::InvalidArg) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment