Skip to content

Instantly share code, notes, and snippets.

@joshski
Created October 19, 2009 07:48
Show Gist options
  • Save joshski/213190 to your computer and use it in GitHub Desktop.
Save joshski/213190 to your computer and use it in GitHub Desktop.
Feature: Anaphora example
Scenario: Punish bad pets
Given I am a pet owner
And I have a dog called Derek
And I have a cat called Connie
Then I should give them dinner
And I should not give them treats
When Derek barks at Connie
Then I should give Connie treats
And I should not give Derek dinner
And Connie scratches Derek
Then I should give them treats
And I should not give them dinner
Scenario: Punish bad pets from a named owner
Given Fred is a pet owner
And he has a dog called Derek
And he has a cat called Connie
Then he should give them dinner
And he should not give them treats
When Derek barks at Connie
Then Fred should give Connie treats
And he should not give Derek dinner
And Connie scratches Derek
Then Fred should give them treats
And Fred should not give them dinner
Scenario: Punish bad pets from independent owners
Given Fred is a pet owner
And Judy is a pet owner
And Fred has a dog called Derek
And Judy has a cat called Connie
When Derek barks at Connie
Then Judy should give Connie treats
And Judy should give Connie dinner
And Fred should not give Derek treats
And Fred should not give Derek dinner
And Judy should not give Derek treats
And Judy should not give Derek dinner
And Fred should not give them dinner
When Connie scratches Derek
Then Judy should not give Connie dinner
module Cucumber
module RbSupport
# monkey-patched to not create a new regexp if the pattern argument is already a regexp
class RbTransform
def initialize(rb_language, pattern, proc)
raise MissingProc if proc.nil? || proc.arity < 1
@rb_language, @regexp, @proc = rb_language, (pattern.is_a?(Regexp) ? pattern : Regexp.new(pattern)), proc
end
end
end
end
# proof of concept hack: shares state between instances, which is unnecessary
class Anaphora < Regexp
def initialize
@@state = {}
super(/^$/)
end
def regexp
Regexp.new("^" + @@state.keys.join("|") + "$")
end
def match(str)
regexp.match(str)
end
def []=(key, value)
@@state[key] = value
end
def [](key)
@@state[key]
end
def inspect
regexp.inspect
end
end
class AnaphoraWorld
attr_reader :anaphora
def initialize
@anaphora = Anaphora.new
end
end
World { AnaphoraWorld.new }
Transform Anaphora.new do |arg|
anaphora[arg]
end
class PetOwner
def initialize
@attackers, @defenders = [], []
end
def witness_attack(attacker, defender)
@attackers << attacker
@defenders << defender
end
def deserves_dinner?(pet)
[email protected]?(pet) && pet.owner == self
end
def deserves_treats?(pet)
@defenders.include?(pet)
end
end
class Pet
attr_accessor :name, :owner
def attack(subject)
@owner.witness_attack(self, subject)
subject.owner.witness_attack(self, subject)
end
end
class Dog < Pet
def bark(subject)
attack(subject)
end
end
class Cat < Pet
def scratch(subject)
attack(subject)
end
end
Transform /^(cat|dog|pet owner)$/ do |step_arg|
class_name = step_arg.split(' ').map { |p| p.capitalize }.join('')
Object.module_eval("::#{class_name}").new
end
Given /^(.+) (?:am|is) a (.+)$/ do |name, thing|
anaphora[name] = anaphora["he"] = anaphora["she"] = thing
end
Given /^(.+) (?:have|has) a (cat|dog) called (.+?)$/ do |owner, pet, name|
pet.owner = owner
pet.name = name
anaphora[name] = pet
(anaphora["them"] ||= []) << pet
end
When /^(.+) barks at (.+)$/ do |barker, barked_at|
barker.bark barked_at
end
When /^(.+) scratches (.+)$/ do |scratcher, scratched|
scratcher.scratch scratched
end
Then /^(.+) should give (.+) (dinner|treats)$/ do |owner, pets, what|
[pets].flatten.each { |pet| owner.send("deserves_#{what}?", pet).should be_true }
end
Then /^(.+) should not give (.+) (dinner|treats)$/ do |owner, pets, what|
[pets].flatten.each { |pet| owner.send("deserves_#{what}?", pet).should be_false }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment