Refactor spec to avoid a general fixture

* Removes let blocks
* Introduces factory methods for common test setup
This commit is contained in:
Joe Ferris 2012-09-14 13:19:16 -04:00 committed by Joshua Clayton
parent 451457600b
commit 41e1ff7cd6
1 changed files with 54 additions and 20 deletions

View File

@ -1,44 +1,78 @@
require "spec_helper"
describe FactoryGirl::EvaluatorClassDefiner do
let(:simple_attribute) { stub("simple attribute", name: :simple, to_proc: -> { 1 }) }
let(:relative_attribute) { stub("relative attribute", name: :relative, to_proc: -> { simple + 1 }) }
let(:attribute_that_raises_a_second_time) { stub("attribute that would raise without a cache", name: :raises_without_proper_cache, to_proc: -> { raise "failed" if @run; @run = true; nil }) }
let(:attributes) { [simple_attribute, relative_attribute, attribute_that_raises_a_second_time] }
let(:class_definer) { FactoryGirl::EvaluatorClassDefiner.new(attributes, FactoryGirl::Evaluator) }
let(:evaluator) { class_definer.evaluator_class.new(stub("build strategy", add_observer: true)) }
it "returns an evaluator when accessing the evaluator class" do
evaluator = define_evaluator(parent_class: FactoryGirl::Evaluator)
evaluator.should be_a(FactoryGirl::Evaluator)
end
it "adds each attribute to the evaluator" do
evaluator.simple.should == 1
attribute = stub_attribute(:attribute) { 1 }
evaluator = define_evaluator(attributes: [attribute])
evaluator.attribute.should == 1
end
it "evaluates the block in the context of the evaluator" do
evaluator.relative.should == 2
dependency_attribute = stub("dependency", name: :dependency, to_proc: -> { 1 })
dependency_attribute = stub_attribute(:dependency) { 1 }
attribute = stub_attribute(:attribute) { dependency + 1 }
evaluator = define_evaluator(attributes: [dependency_attribute, attribute])
evaluator.attribute.should == 2
end
it "only instance_execs the block once even when returning nil" do
expect {
2.times { evaluator.raises_without_proper_cache }
}.to_not raise_error
count = 0
attribute = stub_attribute :attribute do
count += 1
nil
end
evaluator = define_evaluator(attributes: [attribute])
2.times { evaluator.attribute }
count.should == 1
end
it "sets attributes on the evaluator class" do
class_definer.evaluator_class.attribute_lists.should == [attributes]
attributes = [stub_attribute, stub_attribute]
evaluator = define_evaluator(attributes: attributes)
evaluator.attribute_lists.should == [attributes]
end
context "with a custom evaluator as a parent class" do
let(:child_attributes) { [stub("child attribute", name: :simple, to_proc: -> { 1 })] }
let(:child_definer) { FactoryGirl::EvaluatorClassDefiner.new(child_attributes, class_definer.evaluator_class) }
subject { child_definer.evaluator_class }
it "bases its attribute lists on itself and its parent evaluator" do
subject.attribute_lists.should == [attributes, child_attributes]
parent_attributes = [stub_attribute, stub_attribute]
parent_evaluator_class = define_evaluator_class(attributes: parent_attributes)
child_attributes = [stub_attribute, stub_attribute]
child_evaluator = define_evaluator(
attributes: child_attributes,
parent_class: parent_evaluator_class
)
child_evaluator.attribute_lists.
should == [parent_attributes, child_attributes]
end
end
def define_evaluator(arguments = {})
evaluator_class = define_evaluator_class(arguments)
evaluator_class.new(FactoryGirl::Strategy::Null)
end
def define_evaluator_class(arguments = {})
evaluator_class_definer = FactoryGirl::EvaluatorClassDefiner.new(
arguments[:attributes] || [],
arguments[:parent_class] || FactoryGirl::Evaluator
)
evaluator_class_definer.evaluator_class
end
def stub_attribute(name = :attribute, &value)
value ||= -> {}
stub(name.to_s, name: name.to_sym, to_proc: value)
end
end