Created
October 21, 2012 16:11
-
-
Save ashmoran/3927379 to your computer and use it in GitHub Desktop.
Trailing Stop Loss kata extracts for the Celluloid mailing list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'celluloid' | |
require_relative 'timers/null_timer' | |
require_relative 'timers/too_late_timer' | |
class MarketAgent | |
include Celluloid | |
class ActionError < RuntimeError; end | |
def initialize(dependencies) | |
@market = dependencies.fetch(:market) | |
@delay = dependencies.fetch(:delay) | |
@timer = NullTimer.new | |
end | |
def sell | |
@timer.cancel | |
@timer = after(@delay) do | |
@market.sell | |
@timer = too_late_timer | |
end | |
end | |
def belay | |
@timer.cancel | |
end | |
private | |
def null_timer | |
NullTimer.new | |
end | |
def too_late_timer | |
TooLateTimer.new( | |
ActionError.new("Sell order has already been issued") | |
) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
require 'market_agent' | |
describe MarketAgent, focus: true do | |
include CelluloidHelpers | |
let(:market) { MockMarket.new(sell_action: ->{ sleep 0.07 }) } | |
subject(:agent) { MarketAgent.new(market: market, delay: 0.05) } | |
# Most examples removed | |
context "after the time specified" do | |
it "sells" do | |
agent.sell | |
sleep 0.06 | |
expect(market.actions).to be == [ :sell ] | |
end | |
context "when told to belay" do | |
it "raises an error", focus: true do | |
agent.sell | |
sleep 0.06 | |
expect { | |
agent.belay | |
}.to raise_error(MarketAgent::ActionError, "Sell order has already been issued") | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'celluloid' | |
class MockMarketAgent | |
include Celluloid | |
def initialize(options = { }) | |
@actions = [ ] | |
@sell_action = options.fetch(:sell_action, -> { }) | |
end | |
def sell | |
@sell_action.call | |
@actions << :sell | |
end | |
def belay | |
@actions << :belay | |
end | |
def actions | |
@actions.dup | |
end | |
end | |
# It just turned out they're the exact same thing | |
MockMarket = MockMarketAgent |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class NullTimer | |
def cancel | |
# NOOP | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TooLateTimer | |
def initialize(error) | |
@error = error | |
end | |
def cancel | |
raise @error | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment