Implicitly call FactoryGirl's syntax methods from dynamic attributes
This commit is contained in:
parent
4682ab0701
commit
29a5ab1a89
|
@ -28,6 +28,7 @@ require 'factory_girl/aliases'
|
||||||
require 'factory_girl/definition'
|
require 'factory_girl/definition'
|
||||||
require 'factory_girl/definition_proxy'
|
require 'factory_girl/definition_proxy'
|
||||||
require 'factory_girl/syntax'
|
require 'factory_girl/syntax'
|
||||||
|
require 'factory_girl/syntax_runner'
|
||||||
require 'factory_girl/find_definitions'
|
require 'factory_girl/find_definitions'
|
||||||
require 'factory_girl/reload'
|
require 'factory_girl/reload'
|
||||||
require 'factory_girl/version'
|
require 'factory_girl/version'
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
module FactoryGirl
|
module FactoryGirl
|
||||||
class AttributeAssigner
|
class AttributeAssigner
|
||||||
def initialize(evaluator, &instance_builder)
|
def initialize(evaluator, build_class, &instance_builder)
|
||||||
|
@build_class = build_class
|
||||||
@instance_builder = instance_builder
|
@instance_builder = instance_builder
|
||||||
@evaluator = evaluator
|
@evaluator = evaluator
|
||||||
@attribute_list = evaluator.class.attribute_list
|
@attribute_list = evaluator.class.attribute_list
|
||||||
|
@ -18,7 +19,7 @@ module FactoryGirl
|
||||||
end
|
end
|
||||||
|
|
||||||
def hash
|
def hash
|
||||||
@evaluator.instance = NullObject.new
|
@evaluator.instance = build_hash
|
||||||
|
|
||||||
attributes_to_set_on_hash.inject({}) do |result, attribute|
|
attributes_to_set_on_hash.inject({}) do |result, attribute|
|
||||||
result[attribute] = get(attribute)
|
result[attribute] = get(attribute)
|
||||||
|
@ -32,6 +33,10 @@ module FactoryGirl
|
||||||
@build_class_instance ||= @evaluator.instance_exec(&@instance_builder)
|
@build_class_instance ||= @evaluator.instance_exec(&@instance_builder)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def build_hash
|
||||||
|
@build_hash ||= NullObject.new(hash_instance_methods_to_respond_to)
|
||||||
|
end
|
||||||
|
|
||||||
def get(attribute_name)
|
def get(attribute_name)
|
||||||
@evaluator.send(attribute_name)
|
@evaluator.send(attribute_name)
|
||||||
end
|
end
|
||||||
|
@ -64,6 +69,10 @@ module FactoryGirl
|
||||||
@evaluator.__overrides.keys
|
@evaluator.__overrides.keys
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def hash_instance_methods_to_respond_to
|
||||||
|
@attribute_list.map(&:name) + override_names + @build_class.instance_methods
|
||||||
|
end
|
||||||
|
|
||||||
def alias_names_to_ignore
|
def alias_names_to_ignore
|
||||||
@attribute_list.reject(&:ignored).map do |attribute|
|
@attribute_list.reject(&:ignored).map do |attribute|
|
||||||
override_names.map {|override| attribute.name if attribute.alias_for?(override) && attribute.name != override && !ignored_attribute_names.include?(override) }
|
override_names.map {|override| attribute.name if attribute.alias_for?(override) && attribute.name != override && !ignored_attribute_names.include?(override) }
|
||||||
|
|
|
@ -47,7 +47,11 @@ module FactoryGirl
|
||||||
if @cached_attributes.key?(method_name)
|
if @cached_attributes.key?(method_name)
|
||||||
@cached_attributes[method_name]
|
@cached_attributes[method_name]
|
||||||
else
|
else
|
||||||
@instance.send(method_name, *args, &block)
|
if @instance.respond_to?(method_name)
|
||||||
|
@instance.send(method_name, *args, &block)
|
||||||
|
else
|
||||||
|
SyntaxRunner.new.send(method_name, *args, &block)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ module FactoryGirl
|
||||||
strategy = strategy_class.new
|
strategy = strategy_class.new
|
||||||
|
|
||||||
evaluator = evaluator_class.new(strategy, overrides.symbolize_keys)
|
evaluator = evaluator_class.new(strategy, overrides.symbolize_keys)
|
||||||
attribute_assigner = AttributeAssigner.new(evaluator, &instance_builder)
|
attribute_assigner = AttributeAssigner.new(evaluator, build_class, &instance_builder)
|
||||||
|
|
||||||
evaluation = Evaluation.new(attribute_assigner, to_create)
|
evaluation = Evaluation.new(attribute_assigner, to_create)
|
||||||
evaluation.add_observer(CallbackRunner.new(callbacks, evaluator))
|
evaluation.add_observer(CallbackRunner.new(callbacks, evaluator))
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
module FactoryGirl
|
module FactoryGirl
|
||||||
class NullObject < ::BasicObject
|
class NullObject < ::BasicObject
|
||||||
def method_missing(*args)
|
def initialize(methods_to_respond_to)
|
||||||
nil
|
@methods_to_respond_to = methods_to_respond_to.map(&:to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_missing(name, *args, &block)
|
||||||
|
if respond_to?(name)
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def respond_to?(method, include_private=false)
|
||||||
|
@methods_to_respond_to.include? method.to_s
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
module FactoryGirl
|
||||||
|
class SyntaxRunner
|
||||||
|
include Syntax::Methods
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,41 @@
|
||||||
|
require "spec_helper"
|
||||||
|
|
||||||
|
describe "syntax methods within dynamic attributes" do
|
||||||
|
before do
|
||||||
|
define_model("Post", title: :string, user_id: :integer) do
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
def generate
|
||||||
|
"generate result"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
define_model("User", email: :string)
|
||||||
|
|
||||||
|
FactoryGirl.define do
|
||||||
|
sequence(:email_address) {|n| "person-#{n}@example.com" }
|
||||||
|
|
||||||
|
factory :user do
|
||||||
|
email { generate(:email_address) }
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :post do
|
||||||
|
title { generate }
|
||||||
|
user { build(:user) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can access syntax methods from dynamic attributes" do
|
||||||
|
FactoryGirl.build(:user).email.should == "person-1@example.com"
|
||||||
|
FactoryGirl.attributes_for(:user)[:email].should == "person-2@example.com"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can access syntax methods from dynamic attributes" do
|
||||||
|
FactoryGirl.build(:post).user.should be_instance_of(User)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can access methods already existing on the class" do
|
||||||
|
FactoryGirl.build(:post).title.should == "generate result"
|
||||||
|
FactoryGirl.attributes_for(:post)[:title].should be_nil
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,8 +1,22 @@
|
||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
|
||||||
describe FactoryGirl::NullObject do
|
describe FactoryGirl::NullObject do
|
||||||
its(:id) { should be_nil }
|
let(:methods_to_respond_to) { %w[id age name admin?] }
|
||||||
its(:age) { should be_nil }
|
let(:methods_to_not_respond_to) { %w[email date_of_birth title] }
|
||||||
its(:name) { should be_nil }
|
|
||||||
its(:admin?) { should be_nil }
|
subject { FactoryGirl::NullObject.new(methods_to_respond_to) }
|
||||||
|
|
||||||
|
it "responds to the given methods" do
|
||||||
|
methods_to_respond_to.each do |method_name|
|
||||||
|
subject.__send__(method_name).should be_nil
|
||||||
|
subject.respond_to?(method_name).should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not respond to other methods" do
|
||||||
|
methods_to_not_respond_to.each do |method_name|
|
||||||
|
expect { subject.__send__(method_name) }.to raise_error(NoMethodError)
|
||||||
|
subject.respond_to?(method_name).should be_false
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue