mirror of
https://github.com/edgecase/ruby_koans.git
synced 2026-04-15 07:23:19 -04:00
moving to a new repo
This commit is contained in:
208
edgecase.rb
Normal file
208
edgecase.rb
Normal file
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/env ruby
|
||||
# -*- ruby -*-
|
||||
|
||||
require 'test/unit/assertions'
|
||||
|
||||
class FillMeInError < StandardError
|
||||
end
|
||||
|
||||
def __(value="FILL ME IN")
|
||||
value
|
||||
end
|
||||
|
||||
def ___(value=FillMeInError)
|
||||
value
|
||||
end
|
||||
|
||||
module EdgeCase
|
||||
class Sensei
|
||||
attr_reader :failure, :failed_test
|
||||
|
||||
AssertionError = Test::Unit::AssertionFailedError
|
||||
|
||||
def initialize
|
||||
@pass_count = 0
|
||||
@failure = nil
|
||||
@failed_test = nil
|
||||
end
|
||||
|
||||
def accumulate(test)
|
||||
if test.passed?
|
||||
@pass_count += 1
|
||||
puts " #{test.name} has expanded your awareness."
|
||||
else
|
||||
puts " #{test.name} has damaged your karma."
|
||||
@failed_test = test
|
||||
@failure = test.failure
|
||||
throw :edgecase_exit
|
||||
end
|
||||
end
|
||||
|
||||
def failed?
|
||||
! @failure.nil?
|
||||
end
|
||||
|
||||
def assert_failed?
|
||||
failure.is_a?(AssertionError)
|
||||
end
|
||||
|
||||
def report
|
||||
if failed?
|
||||
puts
|
||||
puts "You have not yet reached enlightenment ..."
|
||||
puts failure.message
|
||||
puts
|
||||
puts "Please meditate on the following code:"
|
||||
if assert_failed?
|
||||
puts find_interesting_lines(failure.backtrace)
|
||||
else
|
||||
puts failure.backtrace
|
||||
end
|
||||
puts
|
||||
end
|
||||
say_something_zenlike
|
||||
end
|
||||
|
||||
def find_interesting_lines(backtrace)
|
||||
backtrace.reject { |line|
|
||||
line =~ /test\/unit\/|edgecase\.rb/
|
||||
}
|
||||
end
|
||||
|
||||
# Hat's tip to Ara T. Howard for the zen statements from his
|
||||
# metakoans Ruby Quiz (http://rubyquiz.com/quiz67.html)
|
||||
def say_something_zenlike
|
||||
puts
|
||||
if !failed?
|
||||
puts "Mountains are again merely mountains"
|
||||
else
|
||||
case (@pass_count % 10)
|
||||
when 0
|
||||
puts "mountains are merely mountains"
|
||||
when 1, 2
|
||||
puts "learn the rules so you know how to break them properly"
|
||||
when 3, 4
|
||||
puts "remember that silence is sometimes the best answer"
|
||||
when 5, 6
|
||||
puts "sleep is the best meditation"
|
||||
when 7, 8
|
||||
puts "when you lose, don't lose the lesson"
|
||||
else
|
||||
puts "things are not what they appear to be: nor are they otherwise"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Koan
|
||||
include Test::Unit::Assertions
|
||||
|
||||
attr_reader :name, :failure
|
||||
|
||||
def initialize(name)
|
||||
@name = name
|
||||
@failure = nil
|
||||
end
|
||||
|
||||
def passed?
|
||||
@failure.nil?
|
||||
end
|
||||
|
||||
def failed(failure)
|
||||
@failure = failure
|
||||
end
|
||||
|
||||
def setup
|
||||
end
|
||||
|
||||
def teardown
|
||||
end
|
||||
|
||||
# Class methods for the EdgeCase test suite.
|
||||
class << self
|
||||
def inherited(subclass)
|
||||
subclasses << subclass
|
||||
end
|
||||
|
||||
def method_added(name)
|
||||
testmethods << name unless tests_disabled?
|
||||
end
|
||||
|
||||
def run_tests(accumulator)
|
||||
puts
|
||||
puts "Thinking #{self}"
|
||||
testmethods.each do |m|
|
||||
self.run_test(m, accumulator) if Koan.test_pattern =~ m.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def run_test(method, accumulator)
|
||||
test = self.new(method)
|
||||
test.setup
|
||||
begin
|
||||
test.send(method)
|
||||
rescue StandardError => ex
|
||||
test.failed(ex)
|
||||
ensure
|
||||
begin
|
||||
test.teardown
|
||||
rescue StandardError => ex
|
||||
test.failed(ex) if test.passed?
|
||||
end
|
||||
end
|
||||
accumulator.accumulate(test)
|
||||
end
|
||||
|
||||
def end_of_enlightenment
|
||||
@tests_disabled = true
|
||||
end
|
||||
|
||||
def command_line(args)
|
||||
args.each do |arg|
|
||||
case arg
|
||||
when /^-n\/(.*)\/$/
|
||||
@test_pattern = Regexp.new($1)
|
||||
when /^-n(.*)$/
|
||||
@test_pattern = Regexp.new(Regexp.quote($1))
|
||||
else
|
||||
if File.exist?(arg)
|
||||
load(arg)
|
||||
else
|
||||
fail "Unknown command line argument '#{arg}'"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Lazy initialize list of subclasses
|
||||
def subclasses
|
||||
@subclasses ||= []
|
||||
end
|
||||
|
||||
# Lazy initialize list of test methods.
|
||||
def testmethods
|
||||
@test_methods ||= []
|
||||
end
|
||||
|
||||
def tests_disabled?
|
||||
@tests_disabled ||= false
|
||||
end
|
||||
|
||||
def test_pattern
|
||||
@test_pattern ||= /^test_/
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
END {
|
||||
EdgeCase::Koan.command_line(ARGV)
|
||||
zen_master = EdgeCase::Sensei.new
|
||||
catch(:edgecase_exit) {
|
||||
EdgeCase::Koan.subclasses.each do |sc|
|
||||
sc.run_tests(zen_master)
|
||||
end
|
||||
}
|
||||
zen_master.report
|
||||
}
|
||||
Reference in New Issue
Block a user