Skip to content

Instantly share code, notes, and snippets.

@adomokos
Created January 21, 2012 22:11
Show Gist options
  • Save adomokos/1654233 to your computer and use it in GitHub Desktop.
Save adomokos/1654233 to your computer and use it in GitHub Desktop.
Blog Post - Refactoring Workflows to Chain of Actions
should = require 'should'
House = {
leave: (dude) ->
'leaves the house'
closeTheDoor: (dude) ->
'closes the door'
}
Car = {
jumpIn: (dude) ->
'jumps in the car'
driveToThePark: (dude) ->
'drives to the park'
parkTheCar: (dude) ->
'parks the car'
}
Bicycle = {
jumpOn: (dude) ->
'jumps on the bike'
rideToThePark: (dude) ->
'rides to the park'
parkTheBike: (dude) ->
'parks the bike'
}
Park = {
enter: (dude) ->
'enters the park'
}
class GoesToThePark
constructor: ->
@messages = []
toEnjoyTheWeather: (dude)->
@messages.push House.leave(dude)
@messages.push House.closeTheDoor(dude)
if dude.hasCar()
@messages.push Car.jumpIn(dude)
@messages.push Car.driveToThePark(dude)
@messages.push Car.parkTheCar(dude)
else
@messages.push Bicycle.jumpOn(dude)
@messages.push Bicycle.rideToThePark(dude)
@messages.push Bicycle.parkTheBike(dude)
@messages.push Park.enter(dude)
hasMessage = (message)->
@messages.indexOf(message) > -1
describe 'GoesToThePark', ->
describe 'when the dude has car', ->
beforeEach ->
dude = { hasCar: -> true }
@goesToThePark = new GoesToThePark
@goesToThePark.hasMessage = hasMessage
@goesToThePark.toEnjoyTheWeather(dude)
it 'leaves the house', ->
@goesToThePark.hasMessage('leaves the house') \
.should.be.true
it 'closes the door', ->
@goesToThePark.hasMessage('closes the door') \
.should.be.true
it 'jumps in the car', ->
@goesToThePark.hasMessage('jumps in the car') \
.should.be.true
it 'drives to the park', ->
@goesToThePark.hasMessage('drives to the park') \
.should.be.true
it 'parks the car', ->
@goesToThePark.hasMessage('parks the car') \
.should.be.true
it 'enters the park', ->
@goesToThePark.hasMessage('enters the park') \
.should.be.true
describe 'when the dude has no car, but has a bike', ->
beforeEach ->
dude = { hasCar: -> false }
@goesToThePark = new GoesToThePark
@goesToThePark.hasMessage = hasMessage
@goesToThePark.toEnjoyTheWeather(dude)
it 'leaves the house', ->
@goesToThePark.hasMessage('leaves the house') \
.should.be.true
it 'closes the door', ->
@goesToThePark.hasMessage('closes the door') \
.should.be.true
it 'jumps on the bike', ->
@goesToThePark.hasMessage('jumps on the bike') \
.should.be.true
it 'rides to the park', ->
@goesToThePark.hasMessage('rides to the park') \
.should.be.true
it 'parks the bike', ->
@goesToThePark.hasMessage('parks the bike') \
.should.be.true
it 'enters the park', ->
@goesToThePark.hasMessage('enters the park') \
.should.be.true
should = require 'should'
sinon = require 'sinon'
House = {
leave: (dude) ->
'leaves the house'
closeTheDoor: (dude) ->
'closes the door'
}
Car = {
jumpIn: (dude) ->
'jumps in the car'
driveToThePark: (dude) ->
'drives to the park'
parkTheCar: (dude) ->
'parks the car'
}
Bicycle = {
jumpOn: (dude) ->
'jumps on the bike'
rideToThePark: (dude) ->
'rides to the park'
parkTheBike: (dude) ->
'parks the bike'
}
Park = {
enter: (dude) ->
'enters the park'
}
LeavesTheHouse = {
execute: (messages, dude) ->
messages.push House.leave(dude)
messages.push House.closeTheDoor(dude)
}
DrivesToThePark = {
execute: (messages, dude) ->
return unless dude.hasCar()
messages.push Car.jumpIn(dude)
messages.push Car.driveToThePark(dude)
messages.push Car.parkTheCar(dude)
}
RidesToThePark = {
execute: (messages, dude) ->
return if dude.hasCar()
messages.push Bicycle.jumpOn(dude)
messages.push Bicycle.rideToThePark(dude)
messages.push Bicycle.parkTheBike(dude)
}
EntersThePark = {
execute: (messages, dude) ->
messages.push Park.enter(dude)
}
class GoesToThePark
constructor: ->
@messages = []
toEnjoyTheWeather: (dude)->
for action in [LeavesTheHouse, DrivesToThePark, RidesToThePark, EntersThePark]
do =>
action.execute(@messages, dude)
hasMessage = (message)->
@messages.indexOf(message) > -1
describe 'GoesToThePark', ->
it 'calls the actions in order', ->
goesToThePark = new GoesToThePark
messages = goesToThePark.messages
dude = {}
leavesTheHouseStub = sinon.stub(LeavesTheHouse, 'execute') \
.withArgs(messages, dude)
drivesToTheParkStub = sinon.stub(DrivesToThePark, 'execute') \
.withArgs(messages, dude)
ridesToTheParkStub = sinon.stub(RidesToThePark, 'execute') \
.withArgs(messages, dude)
entersTheParkStub = sinon.stub(EntersThePark, 'execute') \
.withArgs(messages, dude)
goesToThePark.toEnjoyTheWeather(dude)
entersTheParkStub.called.should.be.true
drivesToTheParkStub.called.should.be.true
ridesToTheParkStub.called.should.be.true
entersTheParkStub.called.should.be.true
should = require 'should'
House = {
leave: (dude) ->
'leaves the house'
closeTheDoor: (dude) ->
'closes the door'
}
Car = {
jumpIn: (dude) ->
'jumps in the car'
driveToThePark: (dude) ->
'drives to the park'
parkTheCar: (dude) ->
'parks the car'
}
Bicycle = {
jumpOn: (dude) ->
'jumps on the bike'
rideToThePark: (dude) ->
'rides to the park'
parkTheBike: (dude) ->
'parks the bike'
}
Park = {
enter: (dude) ->
'enters the park'
}
LeavesTheHouse = {
execute: (messages, dude) ->
messages.push House.leave(dude)
messages.push House.closeTheDoor(dude)
}
DrivesToThePark = {
execute: (messages, dude) ->
return unless dude.hasCar()
messages.push Car.jumpIn(dude)
messages.push Car.driveToThePark(dude)
messages.push Car.parkTheCar(dude)
}
RidesToThePark = {
execute: (messages, dude) ->
return if dude.hasCar()
messages.push Bicycle.jumpOn(dude)
messages.push Bicycle.rideToThePark(dude)
messages.push Bicycle.parkTheBike(dude)
}
EntersThePark = {
execute: (messages, dude) ->
messages.push Park.enter(dude)
}
class GoesToThePark
constructor: ->
@messages = []
toEnjoyTheWeather: (dude)->
for action in [LeavesTheHouse, DrivesToThePark, RidesToThePark, EntersThePark]
do =>
action.execute(@messages, dude)
hasMessage = (message)->
@messages.indexOf(message) > -1
describe 'GoesToThePark', ->
describe 'when the dude has car', ->
beforeEach ->
dude = { hasCar: -> true }
@goesToThePark = new GoesToThePark
@goesToThePark.hasMessage = hasMessage
@goesToThePark.toEnjoyTheWeather(dude)
it 'leaves the house', ->
@goesToThePark.hasMessage('leaves the house') \
.should.be.true
it 'closes the door', ->
@goesToThePark.hasMessage('closes the door') \
.should.be.true
it 'jumps in the car', ->
@goesToThePark.hasMessage('jumps in the car') \
.should.be.true
it 'drives to the park', ->
@goesToThePark.hasMessage('drives to the park') \
.should.be.true
it 'parks the car', ->
@goesToThePark.hasMessage('parks the car') \
.should.be.true
it 'enters the park', ->
@goesToThePark.hasMessage('enters the park') \
.should.be.true
describe 'when the dude has no car, but has a bike', ->
beforeEach ->
dude = { hasCar: -> false }
@goesToThePark = new GoesToThePark
@goesToThePark.hasMessage = hasMessage
@goesToThePark.toEnjoyTheWeather(dude)
it 'leaves the house', ->
@goesToThePark.hasMessage('leaves the house') \
.should.be.true
it 'closes the door', ->
@goesToThePark.hasMessage('closes the door') \
.should.be.true
it 'jumps on the bike', ->
@goesToThePark.hasMessage('jumps on the bike') \
.should.be.true
it 'rides to the park', ->
@goesToThePark.hasMessage('rides to the park') \
.should.be.true
it 'parks the bike', ->
@goesToThePark.hasMessage('parks the bike') \
.should.be.true
it 'enters the park', ->
@goesToThePark.hasMessage('enters the park') \
.should.be.true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment