Skip to content

Commit

Permalink
end screen with koans logo ascii art
Browse files Browse the repository at this point in the history
  • Loading branch information
Marc Peabody committed Sep 22, 2010
1 parent 3ed32b4 commit 493300b
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 57 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,2 +1,3 @@
dist
.project_env.rc
.path_progress
244 changes: 187 additions & 57 deletions src/edgecase.rb
Expand Up @@ -73,7 +73,7 @@ def color(color_value)
end

class Sensei
attr_reader :failure, :failed_test
attr_reader :failure, :failed_test, :pass_count

in_ruby_version("1.8") do
AssertionError = Test::Unit::AssertionFailedError
Expand All @@ -91,16 +91,41 @@ def initialize
@pass_count = 0
@failure = nil
@failed_test = nil
@observations = []
end

def accumulate(test)
if test.passed?
PROGRESS_FILE_NAME = '.path_progress'

def add_progress(prog)
@_contents = nil
exists = File.exists?(PROGRESS_FILE_NAME)
File.open(PROGRESS_FILE_NAME,'a+') do |f|
f.print "#{',' if exists}#{prog}"
end
end

def progress
if @_contents.nil?
if File.exists?(PROGRESS_FILE_NAME)
File.open(PROGRESS_FILE_NAME,'r') do |f|
@_contents = f.read.to_s.gsub(/\s/,'').split(',')
end
end
end
@_contents
end

def observe(step)
if step.passed?
@pass_count += 1
puts Color.green(" #{test.name} has expanded your awareness.")
if @pass_count > progress.last.to_i
@observations << Color.green("#{step.koan_file}##{step.name} has expanded your awareness.")
end
else
puts Color.red(" #{test.name} has damaged your karma.")
@failed_test = test
@failure = test.failure
@failed_test = step
@failure = step.failure
add_progress(@pass_count)
@observations << Color.red("#{step.koan_file}##{step.name} has damaged your karma.")
throw :edgecase_exit
end
end
Expand All @@ -113,22 +138,115 @@ def assert_failed?
failure.is_a?(AssertionError)
end

def report
def instruct
if failed?
@observations.each{|c| puts c }
encourage
guide_through_error
a_zenlike_statement
show_progress
else
end_screen
end
end

def show_progress
bar_width = 50
total_tests = EdgeCase::Koan.total_tests
scale = bar_width.to_f/total_tests
print Color.green("your path thus far [")
happy_steps = (pass_count*scale).to_i
happy_steps = 1 if happy_steps == 0 && pass_count > 0
print Color.green('.'*happy_steps)
if failed?
puts
puts Color.green("You have not yet reached enlightenment ...")
puts Color.red(failure.message)
puts
puts Color.green("Please meditate on the following code:")
if assert_failed?
#puts find_interesting_lines(failure.backtrace)
puts find_interesting_lines(failure.backtrace).collect {|l| Color.red(l) }
print Color.red('X')
print Color.blue('_'*(bar_width-1-happy_steps))
end
print Color.green(']')
print " #{pass_count}/#{total_tests}"
puts
end

def end_screen
completed = <<-ENDTEXT
,, , ,,
: ::::, :::,
, ,,: :::::::::::::,, :::: : ,
, ,,, ,:::::::::::::::::::, ,: ,: ,,
:, ::, , , :, ,:::::::::::::::::::, ::: ,::::
: : ::, ,:::::::: ::, ,::::
, ,::::: :,:::::::,::::,
,: , ,:,,: :::::::::::::
::,: ,,:::, ,::::::::::::,
,:::, :,,::: ::::::::::::,
,::: :::::::, Mountains are again merely mountains ,::::::::::::
:::,,,:::::: ::::::::::::
,:::::::::::, ::::::::::::,
:::::::::::, ,::::::::::::
::::::::::::: ,::::::::::::
,:::::::::::: Ruby Koans ::::::::::::,
::::::::::::: ,::::::::::::,
,:::::::::::, , ::::::::::::
,:::::::::::::, brought to you by ,,::::::::::::,
:::::::::::::: ,::::::::::::
::::::::::::::, :::::::::::::
::::::::::::, EdgeCase Software Artisans , ::::::::::::
:,::::::::: :::: :::::::::::::
,::::::::::: ,: ,,:::::::::::::,
:::::::::::: ,::::::::::::::,
:::::::::::::::::, ::::::::::::::::
:::::::::::::::::::, ::::::::::::::::
::::::::::::::::::::::, ,::::,:, , ::::,:::
:::::::::::::::::::::::, ::,: ::,::, ,,: ::::
,:::::::::::::::::::: ::,, , ,, ,::::
,:::::::::::::::: ::,, , ,:::,
,:::: , ,,
,,,
ENDTEXT
puts completed
end

def encourage
puts
puts "The Master says:"
puts Color.blue(" You have not yet reached enlightenment.")
if ((recents = progress.last(5)) && recents.size == 5 && recents.uniq.size == 1)
puts Color.blue(" I sense frustration. Do not be afraid to ask for help.")
elsif progress.last(2).size == 2 && progress.last(2).uniq.size == 1
puts Color.blue(" Do not lose hope.")
elsif progress.last.to_i > 0
puts Color.blue(" You are progressing. Excellent. #{progress.last} completed.")
end
end

def guide_through_error
puts
puts "The answers you seek..."
puts Color.red(indent(failure.message).join)
puts
puts "Please meditate on the following code:"
if assert_failed?
puts embolden_first_line_only(indent(find_interesting_lines(failure.backtrace)))
else
puts embolden_first_line_only(indent(failure.backtrace))
end
puts
end

def embolden_first_line_only(text)
first_line = true
text.collect { |t|
if first_line
first_line = false
Color.red(t)
else
puts Color.red(failure.backtrace)
Color.blue(t)
end
puts
end
puts Color.green(a_zenlike_statement)
}
end

def indent(text)
text.collect{|t| " #{t}"}
end

def find_interesting_lines(backtrace)
Expand All @@ -140,7 +258,6 @@ def find_interesting_lines(backtrace)
# Hat's tip to Ara T. Howard for the zen statements from his
# metakoans Ruby Quiz (http://rubyquiz.com/quiz67.html)
def a_zenlike_statement
puts
if !failed?
zen_statement = "Mountains are again merely mountains"
else
Expand All @@ -159,18 +276,21 @@ def a_zenlike_statement
"things are not what they appear to be: nor are they otherwise"
end
end
zen_statement
puts Color.green(zen_statement)
end
end

class Koan
include Test::Unit::Assertions

attr_reader :name, :failure
attr_reader :name, :failure, :koan_count, :step_count, :koan_file

def initialize(name)
def initialize(name, koan_file=nil, koan_count=0, step_count=0)
@name = name
@failure = nil
@koan_count = koan_count
@step_count = step_count
@koan_file = koan_file
end

def passed?
Expand All @@ -187,39 +307,30 @@ def setup
def teardown
end

def meditate
setup
begin
send(name)
rescue StandardError, EdgeCase::Sensei::AssertionError => ex
failed(ex)
ensure
begin
teardown
rescue StandardError, EdgeCase::Sensei::AssertionError => ex
failed(ex) if passed?
end
end
self
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 Color.green("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, EdgeCase::Sensei::AssertionError => ex
test.failed(ex)
ensure
begin
test.teardown
rescue StandardError, EdgeCase::Sensei::AssertionError => ex
test.failed(ex) if test.passed?
end
end
accumulator.accumulate(test)
testmethods << name if !tests_disabled? && Koan.test_pattern =~ name.to_s
end

def end_of_enlightenment
Expand Down Expand Up @@ -261,17 +372,36 @@ def test_pattern
@test_pattern ||= /^test_/
end

def total_tests
self.subclasses.inject(0){|total, k| total + k.testmethods.size }
end
end
end

class ThePath
def walk
sensei = EdgeCase::Sensei.new
each_step do |step|
sensei.observe(step.meditate)
end
sensei.instruct
end

def each_step
catch(:edgecase_exit) {
step_count = 0
EdgeCase::Koan.subclasses.each_with_index do |koan,koan_index|
koan.testmethods.each do |method_name|
step = koan.new(method_name, koan.to_s, koan_index+1, step_count+=1)
yield step
end
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
EdgeCase::ThePath.new.walk
}

0 comments on commit 493300b

Please sign in to comment.