Find file
Fetching contributors…
Cannot retrieve contributors at this time
80 lines (67 sloc) 2.89 KB
# MotherSubber is an experimental tool which allows you to replace
# objects deep within aggregates. The intention is that you create
# aggregates in an ObjectMother and then use MotherSubber to replace
# bits and pieces for individual tests.
# It's rather easy to use MotherSubber. You simply include MotherSubber
# in a class and then use the 'with' method to replace a piece. In the
# simplest case, you supply 'with' with a list containing exactly one
# symbol. MotherSubber walks through the object and all of its sub-objects
# and it tries to find an instance variable with that name. If it finds
# exactly one, it sets that instance variable to point to the object you
# supply as the other argument to 'with.' If MotherSubber finds zero or
# more than one matches, it throws an exception. Since MotherSubber is
# intended to be used in tests, it is convenient to just throw an exception
# when it's obvious that the internals of the object aren't what the user
# expected them to be.
# If you've read this far you are probably thinking that it is rather
# ridiculous assume that all instance variables in an aggregate are
# uniquely named. What MotherSubber says (through it's API) is "wouldn't
# it be nice if they were?" But, since reality often intrudes in awkward
# ways, MotherSubber accepts a list of symbols which represent a partial
# path to an object. You can specify just as many leading instance
# variable names as you need to disambiguate the object you want to replace.
require 'mothersubber'
require 'obj'
describe MotherSubber do
it "should throw when there is no match" do
lambda {[:@foo], 0) }.should raise_error(MotherSubber::NoMatchException)
it "should substitute when it matches" do
object = "foo" => 0
object.with([:@foo], 1) == 1
it "should substitute when it matches a sub-object attribute" do
object = "foo" => ( "bar" => 0)
object.with([:@bar], 1) == 1
it "should run to completion even when it has cyclic references" do
a = "other" => 0
b = "other" => 0
a.other = b
b.other = a
lambda { a.with([:@other], 0) }
it "should throw when there is more than one attribute match" do
object = "dup" => 0, "foo" => ( "dup" => 1)
lambda { object.with([:@dup], }.should raise_error(MotherSubber::TooManyMatchesException)
it "should substitute when it is given a path" do
object = "foo" => ( "bar" => 0)
object.with([:@foo, :@bar], 1) == 1
it "should substitute on an inner match" do
f = "g" => 0
e = "f" => f
d = "e" => e
c = "d" => d
b = "c" => c
a = "b" => b
a.with([:@d, :@e], 1)
a.b.c.d.e.should == 1