Skip to content

Instantly share code, notes, and snippets.

@patmaddox
Created September 18, 2008 06:42
Show Gist options
  • Save patmaddox/11390 to your computer and use it in GitHub Desktop.
Save patmaddox/11390 to your computer and use it in GitHub Desktop.
require "rubygems"
require "spec"
class AccountService
def withdraw(account, amount)
account.debit(amount)
end
def deposit(account, amount)
account.credit(amount)
end
end
class SimpleAccount
attr_reader :balance
def initialize(balance)
@balance = balance
end
def debit(amount)
@balance -= amount
end
def credit(amount)
@balance += amount
end
end
class SavingsAccount
attr_reader :balance
def initialize(balance)
@balance = balance
end
def debit(amount)
@balance -= (amount + 5)
end
end
module RolePlay
ROLE_GROUPS = []
def role(role_name)
ROLE_GROUPS << self
SimpleAccount.new(200)
end
module ExampleGroupMethods
def should_fulfill_role(role_name)
candidate = instance
Spec::Runner.configuration.after(:suite) do
unless $generated_groups
$generated_groups = true
ROLE_GROUPS.each do |example_group|
impl = example_group.instance_variable_get(:@_implementation)
description = example_group.description
example_group.class.describe("#{example_group.class.description} - Candidate #{candidate}") do
define_method(:role) {|name| candidate }
it(description) { instance_eval(&impl) }
end
end
Spec::Runner.options.run_examples
end
end
end
end
end
Spec::Example::ExampleGroup.send :include, RolePlay
Spec::Example::ExampleGroup.extend RolePlay::ExampleGroupMethods
describe SavingsAccount do
def self.instance
SavingsAccount.new(123)
end
should_fulfill_role "account"
end
describe AccountService do
before(:each) do
@service = AccountService.new
@account = role("account")
end
it "should withdraw from an account" do
puts "in account service withdraw"
p @account
beginning = @account.balance
@service.withdraw @account, 50
@account.balance.should < beginning
end
it "should deposit to the account" do
puts "in account service deposit"
p @account
beginning = @account.balance
@service.deposit @account, 50
@account.balance.should > beginning
end
end
class AccountReporter
def initialize(account)
@account = account
end
def report
"balance: #{@account.balance}"
end
end
describe AccountReporter do
it "should report the balance of an account" do
puts "in account reporter"
account = role("account")
p account
AccountReporter.new(account).report.should =~ /^balance: (\d+)/
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment