Skip to content

Instantly share code, notes, and snippets.

@michaelfeathers
Created September 22, 2020 22:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaelfeathers/361e067d8809b86a35f3354aa95893aa to your computer and use it in GitHub Desktop.
Save michaelfeathers/361e067d8809b86a35f3354aa95893aa to your computer and use it in GitHub Desktop.
Proof of Concept for interactive creation of characterization tests
# Written by Michael Feathers July 10th, 2020
class Command
def run line, session
return unless matches? line
process line, session
end
end
class FixView < Command
def matches? line
line.split == ["fix"]
end
def process line, session
session.fix_view
end
end
class FixNew < Command
def matches? line
line.split == ["fix","new"]
end
def process line, session
session.fix_new
end
end
class FixAdd < Command
def matches? line
line.split.take(2) == ["fix", "add"]
end
def process line, session
session.fix_add(line.split.drop(2).join(" "))
end
end
class FixRemove < Command
def matches? line
line.split.take(2) == ["fix", "remove"]
end
def process line, session
session.fix_remove
end
end
class Ask < Command
def matches? line
line.split.take(1) == ["ask"]
end
def process line, session
session.ask(line.split.drop(1).join(" "))
end
end
class Push < Command
def matches? line
tokens = line.split
tokens.count >= 2 && tokens[0] == "push"
end
def process line, session
session.push(line.split.drop(1).join(" "))
end
end
class C11R
@@commands = [FixNew.new,
FixView.new,
FixAdd.new,
FixRemove.new,
Ask.new,
Push.new]
def initialize
@session = Session.new
end
def run
ARGF.each_line {|li| on_line(li) }
end
def on_line line
puts line
@@commands.each {|c| c.run(line, @session) }
end
end
class Session
def fix
@fix.join("; ")
end
def initialize
fix_new
end
def fix_new
@fix = []
@question = @answer = ""
end
def fix_view
puts "> " + fix
end
def fix_add line
@fix << line
end
def fix_remove
@fix = @fix[0..-2]
end
def ask line
@question = line
@answer = (eval [@fix, @question].join("; ")).to_s
puts "> " + @answer
@answer
end
def push line
puts "> test \"#{line}\""
puts "> #{fix}"
puts "> assert_eq(#{@answer},#{@question}))" unless (@answer.empty? || @question.empty?)
puts "> end"
@question = @answer = ""
end
end
C11R.new.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment