Skip to content

Instantly share code, notes, and snippets.

@v2e4lisp
Last active August 29, 2015 14:02
Show Gist options
  • Select an option

  • Save v2e4lisp/3f2b755c46465c7fb708 to your computer and use it in GitHub Desktop.

Select an option

Save v2e4lisp/3f2b755c46465c7fb708 to your computer and use it in GitHub Desktop.
simple test framework for ruby
F.*
sample test
Tape::Failure
/tmp/tape.rb:118:in `fail!'
/tmp/tape.rb:104:in `fail_if'
/tmp/1.rb:14:in `block in <main>'
/tmp/tape.rb:43:in `instance_eval'
/tmp/tape.rb:43:in `call'
/tmp/tape.rb:128:in `block in run'
/tmp/tape.rb:126:in `each'
/tmp/tape.rb:126:in `run'
/tmp/1.rb:40:in `<main>'
PASSED: 1
FAILED: 1
TODO: 1
require '/tmp/tape.rb'
include Tape
def user_info
@user = "wenjun.yan"
@age = 24
end
def user
"name"
end
test "sample test" do
fail_if { user == "name" }
fail_if { 1 == 1 }
end
test("user info") {
user_info
ok { @age == 24 }
ok { @user == "wenjun.yan" }
}
test {
ok { 1 == 1 }
ok { 2 == 2 }
fail!
}
test "not yet implemented"
class TestsWithDescription
def run(tests)
tests.select { |t| t.desc != "[NO DESCRIPTION]" }
end
end
Tape.config[:filter] = TestsWithDescription
Tape::World.run
# p Tape::World.tests
module Tape
def self.config
@config ||= {:matcher => Matcher,
:reporter => Reporter,
:filter => nil,
:before => nil,
:after => nil}
end
def self.[](key)
config[key]
end
def test desc=nil, &block
World.add Test.new(desc || "[NO DESCRIPTION]", &block)
end
class Failure < StandardError; end
class Result < Struct.new(:status, :exception, :desc); end
class FilterBase
def run(tests); tests; end
end
class ReporterBase
def after_each(result); end
def after_all(results); end
end
class Test
attr_accessor :desc, :result
def initialize desc="", &block
@desc = desc
@block = block
@result = nil
end
def call
return @result if @result
return @result = Tape::Result.new(:todo, nil, @desc) unless @block
begin
context.instance_eval &@block
rescue => e
@result = Tape::Result.new :failed, e, @desc
else
@result = Tape::Result.new :passed, nil, @desc
end
end
def context
@context ||= Object.new.extend *Array(Tape[:matcher])
end
end
class Reporter < ReporterBase
def initialize
@stat = {:passed => 0,
:failed => 0,
:todo => 0}
end
def after_each(result)
return unless result
case result.status
when :passed
print "."
when :failed
print "F"
when :todo
print "*"
end
@stat[result.status] += 1
end
def after_all(results)
puts
results.each {|result|
if result.status == :failed
puts
puts result.desc
puts "\t#{result.exception.message}"
puts result.exception.backtrace
end
}
puts
puts " PASSED: #{@stat[:passed]}"
puts " FAILED: #{@stat[:failed]}"
puts " TODO: #{@stat[:todo]}"
puts
end
end
module Matcher
def ok
yield or fail!
end
def fail_if
!yield or fail!
end
def should_raise
begin
yield
rescue => e
return
else
fail!
end
end
def fail!
raise Tape::Failure
end
end
module World
module_function
def run
runnable.each { |t|
Array(Tape[:before]).each(&:call)
reporter.after_each(t.call)
Array(Tape[:after]).each(&:call)
}
reporter.after_all(results)
end
def add(test)
tests << test
end
def runnable
@_tests ||= Tape[:filter] ? Tape[:filter].new.run(tests) : tests
end
def tests
@tests ||= []
end
def results
runnable.map(&:result)
end
def reporter
@reporter ||= Tape[:reporter].new
end
end
end
@v2e4lisp

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment