Remove koans directory from source control.
[ruby_koans.git] / koans / edgecase.rb
diff --git a/koans/edgecase.rb b/koans/edgecase.rb
deleted file mode 100644 (file)
index 1443807..0000000
+++ /dev/null
@@ -1,490 +0,0 @@
-#!/usr/bin/env ruby
-# -*- ruby -*-
-
-require 'test/unit/assertions'
-begin
-  require 'win32console'
-rescue LoadError
-end
-
-# --------------------------------------------------------------------
-# Support code for the Ruby Koans.
-# --------------------------------------------------------------------
-
-class FillMeInError < StandardError
-end
-
-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
-
-in_ruby_version("1.8") do
-  class KeyError < StandardError
-  end
-end
-
-# Standard, generic replacement value.
-# If value19 is given, it is used in place of value for Ruby 1.9.
-def __(value="FILL ME IN", value19=:mu)
-  if RUBY_VERSION < "1.9"
-    value
-  else
-    (value19 == :mu) ? value : value19
-  end
-end
-
-# Numeric replacement value.
-def _n_(value=999999, value19=:mu)
-  if RUBY_VERSION < "1.9"
-    value
-  else
-    (value19 == :mu) ? value : value19
-  end
-end
-
-# Error object replacement value.
-def ___(value=FillMeInError, value19=:mu)
-  if RUBY_VERSION < "1.9"
-    value
-  else
-    (value19 == :mu) ? value : value19
-  end
-end
-
-# Method name replacement.
-class Object
-  def ____(method=nil)
-    if method
-      self.send(method)
-    end
-  end
-
-  in_ruby_version("1.9") do
-    public :method_missing
-  end
-end
-
-class String
-  def side_padding(width)
-    extra = width - self.size
-    if width < 0
-      self
-    else
-      left_padding = extra / 2
-      right_padding = (extra+1)/2
-      (" " * left_padding) + self + (" " *right_padding)
-    end
-  end
-end
-
-module EdgeCase
-  class << self
-    def simple_output
-      ENV['SIMPLE_KOAN_OUTPUT'] == 'true'
-    end
-  end
-
-  module Color
-    #shamelessly stolen (and modified) from redgreen
-    COLORS = {
-      :clear   => 0,  :black   => 30, :red   => 31,
-      :green   => 32, :yellow  => 33, :blue  => 34,
-      :magenta => 35, :cyan    => 36,
-    }
-
-    module_function
-
-    COLORS.each do |color, value|
-      module_eval "def #{color}(string); colorize(string, #{value}); end"
-      module_function color
-    end
-
-    def colorize(string, color_value)
-      if use_colors?
-        color(color_value) + string + color(COLORS[:clear])
-      else
-        string
-      end
-    end
-
-    def color(color_value)
-      "\e[#{color_value}m"
-    end
-
-    def use_colors?
-      return false if ENV['NO_COLOR']
-      if ENV['ANSI_COLOR'].nil?
-        if using_windows?
-          using_win32console
-        end
-      else
-        ENV['ANSI_COLOR'] =~ /^(t|y)/i
-      end
-    end
-
-    def using_windows?
-      File::ALT_SEPARATOR
-    end
-
-    def using_win32console
-      defined? Win32::Console
-    end
-  end
-
-  class Sensei
-    attr_reader :failure, :failed_test, :pass_count
-
-    in_ruby_version("1.8") do
-      AssertionError = Test::Unit::AssertionFailedError
-    end
-
-    in_ruby_version("1.9") do
-      if defined?(MiniTest)
-        AssertionError = MiniTest::Assertion
-      else
-        AssertionError = Test::Unit::AssertionFailedError
-      end
-    end
-
-    def initialize
-      @pass_count = 0
-      @failure = nil
-      @failed_test = nil
-      @observations = []
-    end
-
-    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
-        else
-          @_contents = []
-        end
-      end
-      @_contents
-    end
-
-    def observe(step)
-      if step.passed?
-        @pass_count += 1
-        if @pass_count > progress.last.to_i
-          @observations << Color.green("#{step.koan_file}##{step.name} has expanded your awareness.")
-        end
-      else
-        @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
-
-    def failed?
-      ! @failure.nil?
-    end
-
-    def assert_failed?
-      failure.is_a?(AssertionError)
-    end
-
-    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?
-        print Color.red('X')
-        print Color.cyan('_'*(bar_width-1-happy_steps))
-      end
-      print Color.green(']')
-      print " #{pass_count}/#{total_tests}"
-      puts
-    end
-
-    def end_screen
-      if EdgeCase.simple_output
-        boring_end_screen
-      else
-        artistic_end_screen
-      end
-    end
-
-    def boring_end_screen
-      puts "Mountains are again merely mountains"
-    end
-
-    def artistic_end_screen
-      "JRuby 1.9.x Koans"
-      ruby_version = "(in #{'J' if defined?(JRUBY_VERSION)}Ruby #{defined?(JRUBY_VERSION) ? JRUBY_VERSION : RUBY_VERSION})"
-      ruby_version = ruby_version.side_padding(54)
-        completed = <<-ENDTEXT
-                                  ,,   ,  ,,
-                                :      ::::,    :::,
-                   ,        ,,: :::::::::::::,,  ::::   :  ,
-                 ,       ,,,   ,:::::::::::::::::::,  ,:  ,: ,,
-            :,        ::,  , , :, ,::::::::::::::::::, :::  ,::::
-           :   :    ::,                          ,:::::::: ::, ,::::
-          ,     ,:::::                                  :,:::::::,::::,
-      ,:     , ,:,,:                                       :::::::::::::
-     ::,:   ,,:::,                                           ,::::::::::::,
-    ,:::, :,,:::                                               ::::::::::::,
-   ,::: :::::::,       Mountains are again merely mountains     ,::::::::::::
-   :::,,,::::::                                                   ::::::::::::
- ,:::::::::::,                                                    ::::::::::::,
- :::::::::::,                                                     ,::::::::::::
-:::::::::::::                                                     ,::::::::::::
-::::::::::::                      Ruby Koans                       ::::::::::::,
-::::::::::::#{                  ruby_version                     },::::::::::::,
-:::::::::::,                                                      , ::::::::::::
-,:::::::::::::,                brought to you by                 ,,::::::::::::,
-::::::::::::::                                                    ,::::::::::::
- ::::::::::::::,                                                 ,:::::::::::::
- ::::::::::::,             EdgeCase Software Artisans           , ::::::::::::
-  :,::::::::: ::::                                               :::::::::::::
-   ,:::::::::::  ,:                                          ,,:::::::::::::,
-     ::::::::::::                                           ,::::::::::::::,
-      :::::::::::::::::,                                  ::::::::::::::::
-       :::::::::::::::::::,                             ::::::::::::::::
-        ::::::::::::::::::::::,                     ,::::,:, , ::::,:::
-          :::::::::::::::::::::::,               ::,: ::,::, ,,: ::::
-              ,::::::::::::::::::::              ::,,  , ,,  ,::::
-                 ,::::::::::::::::              ::,, ,   ,:::,
-                      ,::::                         , ,,
-                                                  ,,,
-ENDTEXT
-        puts completed
-    end
-
-    def encourage
-      puts
-      puts "The Master says:"
-      puts Color.cyan("  You have not yet reached enlightenment.")
-      if ((recents = progress.last(5)) && recents.size == 5 && recents.uniq.size == 1)
-        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.cyan("  Do not lose hope.")
-      elsif progress.last.to_i > 0
-        puts Color.cyan("  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.cyan(t)
-        end
-      }
-    end
-
-    def indent(text)
-      text = text.split(/\n/) if text.is_a?(String)
-      text.collect{|t| "  #{t}"}
-    end
-
-    def find_interesting_lines(backtrace)
-      backtrace.reject { |line|
-        line =~ /test\/unit\/|edgecase\.rb|minitest/
-      }
-    end
-
-    # 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
-      if !failed?
-        zen_statement =  "Mountains are again merely mountains"
-      else
-        zen_statement = case (@pass_count % 10)
-        when 0
-          "mountains are merely mountains"
-        when 1, 2
-          "learn the rules so you know how to break them properly"
-        when 3, 4
-          "remember that silence is sometimes the best answer"
-        when 5, 6
-          "sleep is the best meditation"
-        when 7, 8
-          "when you lose, don't lose the lesson"
-        else
-          "things are not what they appear to be: nor are they otherwise"
-        end
-      end
-      puts Color.green(zen_statement)
-    end
-  end
-
-  class Koan
-    include Test::Unit::Assertions
-
-    attr_reader :name, :failure, :koan_count, :step_count, :koan_file
-
-    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?
-      @failure.nil?
-    end
-
-    def failed(failure)
-      @failure = failure
-    end
-
-    def setup
-    end
-
-    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 if !tests_disabled? && Koan.test_pattern =~ name.to_s
-      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
-
-      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)
-  EdgeCase::ThePath.new.walk
-}