Skip to content

Instantly share code, notes, and snippets.

@brentertz
Forked from joshuaclayton/cream_and_sugar.rb
Created November 9, 2012 14:46
Show Gist options
  • Save brentertz/4046090 to your computer and use it in GitHub Desktop.
Save brentertz/4046090 to your computer and use it in GitHub Desktop.
Ruby Decorators using BasicObject
require "money"
class Decorator < BasicObject
undef_method :==
def initialize(component)
@component = component
end
def method_missing(name, *args, &block)
@component.send(name, *args, &block)
end
def send(symbol, *args)
__send__(symbol, *args)
end
end
class Cream < Decorator
def cost
@component.cost + ::Money.new(50, "USD")
end
end
class Sugar < Decorator
def cost
@component.cost + ::Money.new(20, "USD")
end
end
class Coffee
def cost
::Money.new(200, "USD")
end
def origin
"Columbia"
end
end
describe Coffee do
its(:cost) { should == 2 }
its(:origin) { should == "Columbia" }
it { should be_an_instance_of(Coffee) }
end
describe "Coffee with Sugar" do
let(:coffee) { Coffee.new }
subject { Sugar.new(coffee) }
it { (subject == coffee).should be_true }
its(:cost) { should == 2.2 }
its(:origin) { should == "Columbia" }
its(:object_id) { should == coffee.object_id }
its(:class) { should == coffee.class }
it { should be_an_instance_of(Coffee) }
end
describe "Coffee with two Sugar" do
let(:coffee) { Coffee.new }
subject { Sugar.new(Sugar.new(coffee)) }
it { (subject == coffee).should be_true }
its(:cost) { should == 2.4 }
its(:origin) { should == "Columbia" }
its(:object_id) { should == coffee.object_id }
its(:class) { should == coffee.class }
it { should be_an_instance_of(Coffee) }
end
describe "Coffee with Sugar and Cream" do
let(:coffee) { Coffee.new }
subject { Sugar.new(Cream.new(coffee)) }
it { (subject == coffee).should be_true }
its(:cost) { should == 2.7 }
its(:origin) { should == "Columbia" }
its(:object_id) { should == coffee.object_id }
its(:class) { should == coffee.class }
it { should be_an_instance_of(Coffee) }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment