From 493300b24d85e708eb4ad3bd5a5e985752c46a6a Mon Sep 17 00:00:00 2001 From: Marc Peabody Date: Wed, 22 Sep 2010 14:08:38 -0400 Subject: [PATCH 1/7] end screen with koans logo ascii art --- .gitignore | 1 + src/edgecase.rb | 246 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 189 insertions(+), 58 deletions(-) diff --git a/.gitignore b/.gitignore index 1487603..c92368f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ dist .project_env.rc +.path_progress diff --git a/src/edgecase.rb b/src/edgecase.rb index 99cefc7..9d31ea6 100644 --- a/src/edgecase.rb +++ b/src/edgecase.rb @@ -73,7 +73,7 @@ module EdgeCase 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 @@ -91,16 +91,41 @@ module EdgeCase @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 @@ -113,22 +138,115 @@ module EdgeCase failure.is_a?(AssertionError) end - def report + def instruct 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) } - else - puts Color.red(failure.backtrace) - end - puts + @observations.each{|c| puts c } + encourage + guide_through_error + a_zenlike_statement + show_progress + else + end_screen end - puts Color.green(a_zenlike_statement) + 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? + 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 + Color.blue(t) + end + } + end + + def indent(text) + text.collect{|t| " #{t}"} end def find_interesting_lines(backtrace) @@ -140,7 +258,6 @@ module EdgeCase # 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 @@ -159,18 +276,21 @@ module EdgeCase "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? @@ -187,6 +307,22 @@ module EdgeCase 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) @@ -194,32 +330,7 @@ module EdgeCase 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 @@ -261,17 +372,36 @@ module EdgeCase @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 } From 1492d7003a8ece942abc7e9157e71debeb3e19c8 Mon Sep 17 00:00:00 2001 From: Marc Peabody Date: Wed, 22 Sep 2010 14:10:34 -0400 Subject: [PATCH 2/7] regen for updated koans/edgecase.rb --- koans/edgecase.rb | 246 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 188 insertions(+), 58 deletions(-) diff --git a/koans/edgecase.rb b/koans/edgecase.rb index 99cefc7..9d31ea6 100644 --- a/koans/edgecase.rb +++ b/koans/edgecase.rb @@ -73,7 +73,7 @@ module EdgeCase 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 @@ -91,16 +91,41 @@ module EdgeCase @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 @@ -113,22 +138,115 @@ module EdgeCase failure.is_a?(AssertionError) end - def report + def instruct 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) } - else - puts Color.red(failure.backtrace) - end - puts + @observations.each{|c| puts c } + encourage + guide_through_error + a_zenlike_statement + show_progress + else + end_screen end - puts Color.green(a_zenlike_statement) + 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? + 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 + Color.blue(t) + end + } + end + + def indent(text) + text.collect{|t| " #{t}"} end def find_interesting_lines(backtrace) @@ -140,7 +258,6 @@ module EdgeCase # 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 @@ -159,18 +276,21 @@ module EdgeCase "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? @@ -187,6 +307,22 @@ module EdgeCase 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) @@ -194,32 +330,7 @@ module EdgeCase 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 @@ -261,17 +372,36 @@ module EdgeCase @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 } From 754a7694ad3455f44f5e15bd35b313dade4f190b Mon Sep 17 00:00:00 2001 From: Jim Weirich Date: Wed, 22 Sep 2010 14:50:25 -0400 Subject: [PATCH 3/7] Added else clause if progress file is not there. --- src/edgecase.rb | 68 +++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/edgecase.rb b/src/edgecase.rb index 9d31ea6..def4acc 100644 --- a/src/edgecase.rb +++ b/src/edgecase.rb @@ -110,6 +110,8 @@ module EdgeCase File.open(PROGRESS_FILE_NAME,'r') do |f| @_contents = f.read.to_s.gsub(/\s/,'').split(',') end + else + @_contents = [] end end @_contents @@ -169,39 +171,39 @@ module EdgeCase def end_screen completed = <<-ENDTEXT - ,, , ,, - : ::::, :::, - , ,,: :::::::::::::,, :::: : , - , ,,, ,:::::::::::::::::::, ,: ,: ,, - :, ::, , , :, ,:::::::::::::::::::, ::: ,:::: - : : ::, ,:::::::: ::, ,:::: - , ,::::: :,:::::::,::::, - ,: , ,:,,: ::::::::::::: - ::,: ,,:::, ,::::::::::::, - ,:::, :,,::: ::::::::::::, - ,::: :::::::, Mountains are again merely mountains ,:::::::::::: - :::,,,:::::: :::::::::::: - ,:::::::::::, ::::::::::::, - :::::::::::, ,:::::::::::: - ::::::::::::: ,:::::::::::: -,:::::::::::: Ruby Koans ::::::::::::, -::::::::::::: ,::::::::::::, -,:::::::::::, , :::::::::::: - ,:::::::::::::, brought to you by ,,::::::::::::, - :::::::::::::: ,:::::::::::: - ::::::::::::::, ::::::::::::: - ::::::::::::, EdgeCase Software Artisans , :::::::::::: - :,::::::::: :::: ::::::::::::: - ,::::::::::: ,: ,,:::::::::::::, - :::::::::::: ,::::::::::::::, - :::::::::::::::::, :::::::::::::::: - :::::::::::::::::::, :::::::::::::::: - ::::::::::::::::::::::, ,::::,:, , ::::,::: - :::::::::::::::::::::::, ::,: ::,::, ,,: :::: - ,:::::::::::::::::::: ::,, , ,, ,:::: - ,:::::::::::::::: ::,, , ,:::, - ,:::: , ,, - ,,, + ,, , ,, + : ::::, :::, + , ,,: :::::::::::::,, :::: : , + , ,,, ,:::::::::::::::::::, ,: ,: ,, + :, ::, , , :, ,:::::::::::::::::::, ::: ,:::: + : : ::, ,:::::::: ::, ,:::: + , ,::::: :,:::::::,::::, + ,: , ,:,,: ::::::::::::: + ::,: ,,:::, ,::::::::::::, + ,:::, :,,::: ::::::::::::, + ,::: :::::::, Mountains are again merely mountains ,:::::::::::: + :::,,,:::::: :::::::::::: + ,:::::::::::, ::::::::::::, + :::::::::::, ,:::::::::::: + ::::::::::::: ,:::::::::::: +,:::::::::::: Ruby Koans ::::::::::::, +::::::::::::: ,::::::::::::, +,:::::::::::, , :::::::::::: + ,:::::::::::::, brought to you by ,,::::::::::::, + :::::::::::::: ,:::::::::::: + ::::::::::::::, ::::::::::::: + ::::::::::::, EdgeCase Software Artisans , :::::::::::: + :,::::::::: :::: ::::::::::::: + ,::::::::::: ,: ,,:::::::::::::, + :::::::::::: ,::::::::::::::, + :::::::::::::::::, :::::::::::::::: + :::::::::::::::::::, :::::::::::::::: + ::::::::::::::::::::::, ,::::,:, , ::::,::: + :::::::::::::::::::::::, ::,: ::,::, ,,: :::: + ,:::::::::::::::::::: ::,, , ,, ,:::: + ,:::::::::::::::: ::,, , ,:::, + ,:::: , ,, + ,,, ENDTEXT puts completed end From b4e907e30e6a8f6c52da16e120146b63b60dbd34 Mon Sep 17 00:00:00 2001 From: Jim Weirich Date: Wed, 22 Sep 2010 14:54:42 -0400 Subject: [PATCH 4/7] Updated Koans directory --- koans/edgecase.rb | 68 ++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/koans/edgecase.rb b/koans/edgecase.rb index 9d31ea6..def4acc 100644 --- a/koans/edgecase.rb +++ b/koans/edgecase.rb @@ -110,6 +110,8 @@ module EdgeCase File.open(PROGRESS_FILE_NAME,'r') do |f| @_contents = f.read.to_s.gsub(/\s/,'').split(',') end + else + @_contents = [] end end @_contents @@ -169,39 +171,39 @@ module EdgeCase def end_screen completed = <<-ENDTEXT - ,, , ,, - : ::::, :::, - , ,,: :::::::::::::,, :::: : , - , ,,, ,:::::::::::::::::::, ,: ,: ,, - :, ::, , , :, ,:::::::::::::::::::, ::: ,:::: - : : ::, ,:::::::: ::, ,:::: - , ,::::: :,:::::::,::::, - ,: , ,:,,: ::::::::::::: - ::,: ,,:::, ,::::::::::::, - ,:::, :,,::: ::::::::::::, - ,::: :::::::, Mountains are again merely mountains ,:::::::::::: - :::,,,:::::: :::::::::::: - ,:::::::::::, ::::::::::::, - :::::::::::, ,:::::::::::: - ::::::::::::: ,:::::::::::: -,:::::::::::: Ruby Koans ::::::::::::, -::::::::::::: ,::::::::::::, -,:::::::::::, , :::::::::::: - ,:::::::::::::, brought to you by ,,::::::::::::, - :::::::::::::: ,:::::::::::: - ::::::::::::::, ::::::::::::: - ::::::::::::, EdgeCase Software Artisans , :::::::::::: - :,::::::::: :::: ::::::::::::: - ,::::::::::: ,: ,,:::::::::::::, - :::::::::::: ,::::::::::::::, - :::::::::::::::::, :::::::::::::::: - :::::::::::::::::::, :::::::::::::::: - ::::::::::::::::::::::, ,::::,:, , ::::,::: - :::::::::::::::::::::::, ::,: ::,::, ,,: :::: - ,:::::::::::::::::::: ::,, , ,, ,:::: - ,:::::::::::::::: ::,, , ,:::, - ,:::: , ,, - ,,, + ,, , ,, + : ::::, :::, + , ,,: :::::::::::::,, :::: : , + , ,,, ,:::::::::::::::::::, ,: ,: ,, + :, ::, , , :, ,:::::::::::::::::::, ::: ,:::: + : : ::, ,:::::::: ::, ,:::: + , ,::::: :,:::::::,::::, + ,: , ,:,,: ::::::::::::: + ::,: ,,:::, ,::::::::::::, + ,:::, :,,::: ::::::::::::, + ,::: :::::::, Mountains are again merely mountains ,:::::::::::: + :::,,,:::::: :::::::::::: + ,:::::::::::, ::::::::::::, + :::::::::::, ,:::::::::::: + ::::::::::::: ,:::::::::::: +,:::::::::::: Ruby Koans ::::::::::::, +::::::::::::: ,::::::::::::, +,:::::::::::, , :::::::::::: + ,:::::::::::::, brought to you by ,,::::::::::::, + :::::::::::::: ,:::::::::::: + ::::::::::::::, ::::::::::::: + ::::::::::::, EdgeCase Software Artisans , :::::::::::: + :,::::::::: :::: ::::::::::::: + ,::::::::::: ,: ,,:::::::::::::, + :::::::::::: ,::::::::::::::, + :::::::::::::::::, :::::::::::::::: + :::::::::::::::::::, :::::::::::::::: + ::::::::::::::::::::::, ,::::,:, , ::::,::: + :::::::::::::::::::::::, ::,: ::,::, ,,: :::: + ,:::::::::::::::::::: ::,, , ,, ,:::: + ,:::::::::::::::: ::,, , ,:::, + ,:::: , ,, + ,,, ENDTEXT puts completed end From 15551eaf530e44b301144c9b4143ffa137742017 Mon Sep 17 00:00:00 2001 From: Marc Peabody Date: Wed, 22 Sep 2010 15:09:08 -0400 Subject: [PATCH 5/7] 80 char limit to end screen --- koans/edgecase.rb | 66 +++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/koans/edgecase.rb b/koans/edgecase.rb index 9d31ea6..80116aa 100644 --- a/koans/edgecase.rb +++ b/koans/edgecase.rb @@ -169,39 +169,39 @@ module EdgeCase def end_screen completed = <<-ENDTEXT - ,, , ,, - : ::::, :::, - , ,,: :::::::::::::,, :::: : , - , ,,, ,:::::::::::::::::::, ,: ,: ,, - :, ::, , , :, ,:::::::::::::::::::, ::: ,:::: - : : ::, ,:::::::: ::, ,:::: - , ,::::: :,:::::::,::::, - ,: , ,:,,: ::::::::::::: - ::,: ,,:::, ,::::::::::::, - ,:::, :,,::: ::::::::::::, - ,::: :::::::, Mountains are again merely mountains ,:::::::::::: - :::,,,:::::: :::::::::::: - ,:::::::::::, ::::::::::::, - :::::::::::, ,:::::::::::: - ::::::::::::: ,:::::::::::: -,:::::::::::: Ruby Koans ::::::::::::, -::::::::::::: ,::::::::::::, -,:::::::::::, , :::::::::::: - ,:::::::::::::, brought to you by ,,::::::::::::, - :::::::::::::: ,:::::::::::: - ::::::::::::::, ::::::::::::: - ::::::::::::, EdgeCase Software Artisans , :::::::::::: - :,::::::::: :::: ::::::::::::: - ,::::::::::: ,: ,,:::::::::::::, - :::::::::::: ,::::::::::::::, - :::::::::::::::::, :::::::::::::::: - :::::::::::::::::::, :::::::::::::::: - ::::::::::::::::::::::, ,::::,:, , ::::,::: - :::::::::::::::::::::::, ::,: ::,::, ,,: :::: - ,:::::::::::::::::::: ::,, , ,, ,:::: - ,:::::::::::::::: ::,, , ,:::, - ,:::: , ,, - ,,, + ,, , ,, + : ::::, :::, + , ,,: :::::::::::::,, :::: : , + , ,,, ,:::::::::::::::::::, ,: ,: ,, + :, ::, , , :, ,::::::::::::::::::, ::: ,:::: + : : ::, ,:::::::: ::, ,:::: + , ,::::: :,:::::::,::::, + ,: , ,:,,: ::::::::::::: + ::,: ,,:::, ,::::::::::::, + ,:::, :,,::: ::::::::::::, + ,::: :::::::, Mountains are again merely mountains ,:::::::::::: + :::,,,:::::: :::::::::::: + ,:::::::::::, ::::::::::::, + :::::::::::, ,:::::::::::: +::::::::::::: ,:::::::::::: +:::::::::::: Ruby Koans ::::::::::::, +:::::::::::: ,::::::::::::, +:::::::::::, , :::::::::::: +,:::::::::::::, brought to you by ,,::::::::::::, +:::::::::::::: ,:::::::::::: + ::::::::::::::, ,::::::::::::: + ::::::::::::, EdgeCase Software Artisans , :::::::::::: + :,::::::::: :::: ::::::::::::: + ,::::::::::: ,: ,,:::::::::::::, + :::::::::::: ,::::::::::::::, + :::::::::::::::::, :::::::::::::::: + :::::::::::::::::::, :::::::::::::::: + ::::::::::::::::::::::, ,::::,:, , ::::,::: + :::::::::::::::::::::::, ::,: ::,::, ,,: :::: + ,:::::::::::::::::::: ::,, , ,, ,:::: + ,:::::::::::::::: ::,, , ,:::, + ,:::: , ,, + ,,, ENDTEXT puts completed end From b2c47e0c0f8156e7bb4dea0504a8faf6a5d8925c Mon Sep 17 00:00:00 2001 From: Jim Weirich Date: Mon, 27 Sep 2010 10:37:35 -0400 Subject: [PATCH 6/7] Switch blue color to cyan for better contrast on dark terminals. --- koans/edgecase.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/koans/edgecase.rb b/koans/edgecase.rb index 96617f9..6ee835e 100644 --- a/koans/edgecase.rb +++ b/koans/edgecase.rb @@ -162,7 +162,7 @@ module EdgeCase print Color.green('.'*happy_steps) if failed? print Color.red('X') - print Color.blue('_'*(bar_width-1-happy_steps)) + print Color.cyan('_'*(bar_width-1-happy_steps)) end print Color.green(']') print " #{pass_count}/#{total_tests}" @@ -211,13 +211,13 @@ ENDTEXT def encourage puts puts "The Master says:" - puts Color.blue(" You have not yet reached enlightenment.") + puts Color.cyan(" 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.") + puts Color.cyan(" 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.") + puts Color.cyan(" Do not lose hope.") elsif progress.last.to_i > 0 - puts Color.blue(" You are progressing. Excellent. #{progress.last} completed.") + puts Color.cyan(" You are progressing. Excellent. #{progress.last} completed.") end end @@ -242,7 +242,7 @@ ENDTEXT first_line = false Color.red(t) else - Color.blue(t) + Color.cyan(t) end } end From 584b26e532a41ff28e22a5e6b05b2f01d585090a Mon Sep 17 00:00:00 2001 From: Jim Weirich Date: Mon, 27 Sep 2010 10:44:58 -0400 Subject: [PATCH 7/7] Updated for JRuby --- src/about_methods.rb | 10 +++++----- src/about_symbols.rb | 35 +++++++++++++++++++++++++++++------ src/edgecase.rb | 23 +++++++++++++++-------- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/about_methods.rb b/src/about_methods.rb index 3b6ad57..42a06cf 100644 --- a/src/about_methods.rb +++ b/src/about_methods.rb @@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/edgecase') def my_global_method(a,b) a + b end - + class AboutMethods < EdgeCase::Koan def test_calling_global_methods @@ -36,19 +36,19 @@ class AboutMethods < EdgeCase::Koan # Rewrite the eval string to continue. # end - + # NOTE: wrong number of argument is not a SYNTAX error, but a # runtime error. def test_calling_global_methods_with_wrong_number_of_arguments exception = assert_raise(___(ArgumentError)) do my_global_method end - assert_match(/#{__("wrong number of arguments")}/, exception.message) + assert_match(/#{__("wrong (number|#) of arguments")}/, exception.message) exception = assert_raise(___(ArgumentError)) do my_global_method(1,2,3) end - assert_match(/#{__("wrong number of arguments")}/, exception.message) + assert_match(/#{__("wrong (number|#) of arguments")}/, exception.message) end # ------------------------------------------------------------------ @@ -142,7 +142,7 @@ class AboutMethods < EdgeCase::Koan "tail" end end - + def test_calling_methods_in_other_objects_require_explicit_receiver rover = Dog.new assert_equal __("Fido"), rover.name diff --git a/src/about_symbols.rb b/src/about_symbols.rb index 17dfa81..e265df8 100644 --- a/src/about_symbols.rb +++ b/src/about_symbols.rb @@ -25,15 +25,21 @@ class AboutSymbols < EdgeCase::Koan def test_method_names_become_symbols all_symbols = Symbol.all_symbols - - assert_equal __(true), all_symbols.include?(:test_method_names_are_symbols) + assert_equal __(true), all_symbols.include?(:test_method_names_become_symbols) end - RubyConstant = "What is the sound of one hand clapping?" - def test_constants_become_symbols - all_symbols = Symbol.all_symbols + # THINK ABOUT IT: + # + # Why do we capture the list of symbols before we check for the + # method name? - assert_equal true, all_symbols.include?(__(:RubyConstant)) + in_ruby_version("mri") do + RubyConstant = "What is the sound of one hand clapping?" + def test_constants_become_symbols + all_symbols = Symbol.all_symbols + + assert_equal __(true), all_symbols.include?(__(:RubyConstant)) + end end def test_symbols_can_be_made_from_strings @@ -47,6 +53,13 @@ class AboutSymbols < EdgeCase::Koan assert_equal symbol, __("cats and dogs").to_sym end + def test_symbols_with_spaces_can_be_built + value = "and" + symbol = :"cats #{value} dogs" + + assert_equal symbol, __("cats and dogs").to_sym + end + def test_to_s_is_called_on_interpolated_symbols symbol = :cats string = "It is raining #{symbol} and dogs." @@ -65,13 +78,23 @@ class AboutSymbols < EdgeCase::Koan assert_equal __(false), symbol.respond_to?(:each_char) assert_equal __(false), symbol.respond_to?(:reverse) end + # It's important to realize that symbols are not "immutable # strings", though they are immutable. None of the # interesting string operations are available on symbols. + def test_symbols_cannot_be_concatenated # Exceptions will be pondered further father down the path assert_raise(___(NoMethodError)) do :cats + :dogs end end + + def test_symbols_can_be_dynamically_created + assert_equal __(:catsdogs), ("cats" + "dogs").to_sym + end + + # THINK ABOUT IT: + # + # Why is it not a good idea to dynamically create a lot of symbols? end diff --git a/src/edgecase.rb b/src/edgecase.rb index 96617f9..1a5b882 100644 --- a/src/edgecase.rb +++ b/src/edgecase.rb @@ -6,8 +6,14 @@ require 'test/unit/assertions' class FillMeInError < StandardError end -def in_ruby_version(version) - yield if RUBY_VERSION =~ /^#{version}/ +def ruby_version?(version) + RUBY_VERSION =~ /^#{version}/ || + (version == 'jruby' && defined?(JRUBY_VERSION)) || + (version == 'mri' && ! defined?(JRUBY_VERSION)) +end + +def in_ruby_version(*versions) + yield if versions.any? { |v| ruby_version?(v) } end def __(value="FILL ME IN", value19=:mu) @@ -162,7 +168,7 @@ module EdgeCase print Color.green('.'*happy_steps) if failed? print Color.red('X') - print Color.blue('_'*(bar_width-1-happy_steps)) + print Color.cyan('_'*(bar_width-1-happy_steps)) end print Color.green(']') print " #{pass_count}/#{total_tests}" @@ -211,13 +217,13 @@ ENDTEXT def encourage puts puts "The Master says:" - puts Color.blue(" You have not yet reached enlightenment.") + puts Color.cyan(" 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.") + puts Color.cyan(" 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.") + puts Color.cyan(" Do not lose hope.") elsif progress.last.to_i > 0 - puts Color.blue(" You are progressing. Excellent. #{progress.last} completed.") + puts Color.cyan(" You are progressing. Excellent. #{progress.last} completed.") end end @@ -242,12 +248,13 @@ ENDTEXT first_line = false Color.red(t) else - Color.blue(t) + Color.cyan(t) end } end def indent(text) + text = text.split(/\n/) if text.is_a?(String) text.collect{|t| " #{t}"} end