mirror of
https://github.com/edgecase/ruby_koans.git
synced 2026-04-15 07:23:19 -04:00
Compare commits
55 Commits
codemash-2
...
about_symb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ed32b4534 | ||
|
|
aa09d17630 | ||
|
|
a36c3b7a4d | ||
|
|
18cccf33fb | ||
|
|
1597b2f912 | ||
|
|
57f0f4f178 | ||
|
|
0794235441 | ||
|
|
ad99c372c3 | ||
|
|
8d8287365b | ||
|
|
0c18e9742f | ||
|
|
28eec8cc41 | ||
|
|
b0e34a90e0 | ||
|
|
b0a01786f4 | ||
|
|
ed2ef0f439 | ||
|
|
1f6c0e03a5 | ||
|
|
06c47eb284 | ||
|
|
bc1a20a310 | ||
|
|
e6fc8f6434 | ||
|
|
36f93c6c63 | ||
|
|
bc55853983 | ||
|
|
d17cc7b457 | ||
|
|
f88e9f1dfc | ||
|
|
05d5ab9a5e | ||
|
|
1b31a5b4dc | ||
|
|
3aa75e86aa | ||
|
|
9c0ccd53a2 | ||
|
|
9a459a7eb3 | ||
|
|
e1ada6ca9f | ||
|
|
a5180d9ea1 | ||
|
|
7db19b5e92 | ||
|
|
aa21cae64b | ||
|
|
7c52931392 | ||
|
|
028e4a0c75 | ||
|
|
eee3429394 | ||
|
|
6365c8d61d | ||
|
|
f2ac27f52e | ||
|
|
c4549eb24b | ||
|
|
ee9a03740b | ||
|
|
8ef93f1d3a | ||
|
|
7046294343 | ||
|
|
e8456fa321 | ||
|
|
138bc7c9bc | ||
|
|
2c3b65ec79 | ||
|
|
fbd36f6b0d | ||
|
|
56206e0a41 | ||
|
|
308ad5d9c5 | ||
|
|
c40424e9a4 | ||
|
|
f0b1560f34 | ||
|
|
3b824d0e86 | ||
|
|
110ff38b3f | ||
|
|
1d1ab85777 | ||
|
|
d4c9150453 | ||
|
|
ec6458e174 | ||
|
|
6c69bcb0ef | ||
|
|
6052c776bc |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
dist
|
dist
|
||||||
|
.project_env.rc
|
||||||
|
|||||||
3
Rakefile
3
Rakefile
@@ -21,6 +21,7 @@ module Koans
|
|||||||
line = line.gsub(/\b____\([^\)]+\)/, "____")
|
line = line.gsub(/\b____\([^\)]+\)/, "____")
|
||||||
line = line.gsub(/\b___\([^\)]+\)/, "___")
|
line = line.gsub(/\b___\([^\)]+\)/, "___")
|
||||||
line = line.gsub(/\b__\([^\)]+\)/, "__")
|
line = line.gsub(/\b__\([^\)]+\)/, "__")
|
||||||
|
line = line.gsub(/\b_n_\([^\)]+\)/, "_n_")
|
||||||
line = line.gsub(%r(/\#\{__\}/), "/__/")
|
line = line.gsub(%r(/\#\{__\}/), "/__/")
|
||||||
line
|
line
|
||||||
end
|
end
|
||||||
@@ -28,6 +29,8 @@ module Koans
|
|||||||
def Koans.make_koan_file(infile, outfile)
|
def Koans.make_koan_file(infile, outfile)
|
||||||
if infile =~ /edgecase/
|
if infile =~ /edgecase/
|
||||||
cp infile, outfile
|
cp infile, outfile
|
||||||
|
elsif infile =~ /autotest/
|
||||||
|
cp_r infile, outfile
|
||||||
else
|
else
|
||||||
open(infile) do |ins|
|
open(infile) do |ins|
|
||||||
open(outfile, "w") do |outs|
|
open(outfile, "w") do |outs|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutArrayAssignment < EdgeCase::Koan
|
class AboutArrayAssignment < EdgeCase::Koan
|
||||||
def test_non_parallel_assignment
|
def test_non_parallel_assignment
|
||||||
@@ -35,4 +35,11 @@ class AboutArrayAssignment < EdgeCase::Koan
|
|||||||
assert_equal __, first_name
|
assert_equal __, first_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_swapping_with_parallel_assignment
|
||||||
|
first_name = "Roy"
|
||||||
|
last_name = "Rob"
|
||||||
|
first_name, last_name = last_name, first_name
|
||||||
|
assert_equal __, first_name
|
||||||
|
assert_equal __, last_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutArrays < EdgeCase::Koan
|
class AboutArrays < EdgeCase::Koan
|
||||||
def test_creating_arrays
|
def test_creating_arrays
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
# -*- ruby -*-
|
# -*- ruby -*-
|
||||||
|
|
||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutAsserts < EdgeCase::Koan
|
class AboutAsserts < EdgeCase::Koan
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutBlocks < EdgeCase::Koan
|
class AboutBlocks < EdgeCase::Koan
|
||||||
def method_with_block
|
def method_with_block
|
||||||
@@ -60,7 +60,7 @@ class AboutBlocks < EdgeCase::Koan
|
|||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
def test_block_can_effect_variables_in_the_code_where_they_are_created
|
def test_block_can_affect_variables_in_the_code_where_they_are_created
|
||||||
value = :initial_value
|
value = :initial_value
|
||||||
method_with_block { value = :modified_in_a_block }
|
method_with_block { value = :modified_in_a_block }
|
||||||
assert_equal __, value
|
assert_equal __, value
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutClassMethods < EdgeCase::Koan
|
class AboutClassMethods < EdgeCase::Koan
|
||||||
class Dog
|
class Dog
|
||||||
@@ -19,11 +19,11 @@ class AboutClassMethods < EdgeCase::Koan
|
|||||||
|
|
||||||
def test_objects_have_methods
|
def test_objects_have_methods
|
||||||
fido = Dog.new
|
fido = Dog.new
|
||||||
assert_equal __, fido.methods.size
|
assert fido.methods.size > _n_
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_classes_have_methods
|
def test_classes_have_methods
|
||||||
assert_equal __, Dog.methods.size
|
assert Dog.methods.size > _n_
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_you_can_define_methods_on_individual_objects
|
def test_you_can_define_methods_on_individual_objects
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutClasses < EdgeCase::Koan
|
class AboutClasses < EdgeCase::Koan
|
||||||
class Dog
|
class Dog
|
||||||
|
|||||||
87
koans/about_constants.rb
Normal file
87
koans/about_constants.rb
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
|
C = "top level"
|
||||||
|
|
||||||
|
class AboutConstants < EdgeCase::Koan
|
||||||
|
|
||||||
|
C = "nested"
|
||||||
|
|
||||||
|
def test_nested_constants_may_also_be_referenced_with_relative_paths
|
||||||
|
assert_equal __, C
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_top_level_constants_are_referenced_by_double_colons
|
||||||
|
assert_equal __, ::C
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nested_constants_are_referenced_by_their_complete_path
|
||||||
|
assert_equal __, AboutConstants::C
|
||||||
|
assert_equal __, ::AboutConstants::C
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
class Animal
|
||||||
|
LEGS = 4
|
||||||
|
def legs_in_animal
|
||||||
|
LEGS
|
||||||
|
end
|
||||||
|
|
||||||
|
class NestedAnimal
|
||||||
|
def legs_in_nested_animal
|
||||||
|
LEGS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nested_classes_inherit_constants_from_enclosing_classes
|
||||||
|
assert_equal __, Animal::NestedAnimal.new.legs_in_nested_animal
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
class Reptile < Animal
|
||||||
|
def legs_in_reptile
|
||||||
|
LEGS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_subclasses_inherit_constants_from_parent_classes
|
||||||
|
assert_equal __, Reptile.new.legs_in_reptile
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MyAnimals
|
||||||
|
LEGS = 2
|
||||||
|
|
||||||
|
class Bird < Animal
|
||||||
|
def legs_in_bird
|
||||||
|
LEGS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_who_wins_with_both_nested_and_inherited_constants
|
||||||
|
assert_equal __, MyAnimals::Bird.new.legs_in_bird
|
||||||
|
end
|
||||||
|
|
||||||
|
# QUESTION: Which has precedence: The constant in the lexical scope,
|
||||||
|
# or the constant from the inheritance heirarachy?
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MyAnimals::Oyster < Animal
|
||||||
|
def legs_in_oyster
|
||||||
|
LEGS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_who_wins_with_explicit_scoping_on_class_definition
|
||||||
|
assert_equal __, MyAnimals::Oyster.new.legs_in_oyster
|
||||||
|
end
|
||||||
|
|
||||||
|
# QUESTION: Now Which has precedence: The constant in the lexical
|
||||||
|
# scope, or the constant from the inheritance heirarachy? Why is it
|
||||||
|
# different than the previous answer?
|
||||||
|
end
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutControlStatements < EdgeCase::Koan
|
class AboutControlStatements < EdgeCase::Koan
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ class AboutControlStatements < EdgeCase::Koan
|
|||||||
assert_equal __, result
|
assert_equal __, result
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_if_then_else_statements
|
def test_if_then_statements
|
||||||
result = :default_value
|
result = :default_value
|
||||||
if true
|
if true
|
||||||
result = :true_value
|
result = :true_value
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class DiceSet
|
class DiceSet
|
||||||
attr_reader :values
|
attr_reader :values
|
||||||
@@ -7,7 +7,7 @@ class DiceSet
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class AboutDiceSet < EdgeCase::Koan
|
class AboutDiceProject < EdgeCase::Koan
|
||||||
def test_can_create_a_dice_set
|
def test_can_create_a_dice_set
|
||||||
dice = DiceSet.new
|
dice = DiceSet.new
|
||||||
assert_not_nil dice
|
assert_not_nil dice
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutExceptions < EdgeCase::Koan
|
class AboutExceptions < EdgeCase::Koan
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutHashes < EdgeCase::Koan
|
class AboutHashes < EdgeCase::Koan
|
||||||
def test_creating_hashes
|
def test_creating_hashes
|
||||||
@@ -48,7 +48,7 @@ class AboutHashes < EdgeCase::Koan
|
|||||||
|
|
||||||
def test_hash_values
|
def test_hash_values
|
||||||
hash = { :one => "uno", :two => "dos" }
|
hash = { :one => "uno", :two => "dos" }
|
||||||
assert_equal __, hash.keys.size
|
assert_equal __, hash.values.size
|
||||||
assert_equal __, hash.values.include?("uno")
|
assert_equal __, hash.values.include?("uno")
|
||||||
assert_equal __, hash.values.include?("dos")
|
assert_equal __, hash.values.include?("dos")
|
||||||
assert_equal Array, hash.values.class
|
assert_equal Array, hash.values.class
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutInheritance < EdgeCase::Koan
|
class AboutInheritance < EdgeCase::Koan
|
||||||
class Dog
|
class Dog
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutIteration < EdgeCase::Koan
|
class AboutIteration < EdgeCase::Koan
|
||||||
|
|
||||||
@@ -78,16 +78,26 @@ class AboutIteration < EdgeCase::Koan
|
|||||||
assert_equal __, result
|
assert_equal __, result
|
||||||
|
|
||||||
# Files act like a collection of lines
|
# Files act like a collection of lines
|
||||||
file = File.open("example_file.txt")
|
File.open("example_file.txt") do |file|
|
||||||
upcase_lines = file.map { |line| line.strip.upcase }
|
upcase_lines = file.map { |line| line.strip.upcase }
|
||||||
assert_equal __, upcase_lines
|
assert_equal __, upcase_lines
|
||||||
|
end
|
||||||
|
|
||||||
# NOTE: You can create your own collections that work with each,
|
# NOTE: You can create your own collections that work with each,
|
||||||
# map, select, etc.
|
# map, select, etc.
|
||||||
ensure
|
|
||||||
# Arg, this is ugly.
|
|
||||||
# We will figure out how to fix this later.
|
|
||||||
file.close if file
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Bonus Question: In the previous koan, we saw the construct:
|
||||||
|
#
|
||||||
|
# File.open(filename) do |file|
|
||||||
|
# # code to read 'file'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Why did we do it that way instead of the following?
|
||||||
|
#
|
||||||
|
# file = File.open(filename)
|
||||||
|
# # code to read 'file'
|
||||||
|
#
|
||||||
|
# When you get to the "AboutSandwichCode" koan, recheck your answer.
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutMessagePassing < EdgeCase::Koan
|
class AboutMessagePassing < EdgeCase::Koan
|
||||||
|
|
||||||
@@ -49,7 +49,6 @@ class AboutMessagePassing < EdgeCase::Koan
|
|||||||
|
|
||||||
class MessageCatcher
|
class MessageCatcher
|
||||||
def add_a_payload(*args)
|
def add_a_payload(*args)
|
||||||
return :empty unless args
|
|
||||||
args
|
args
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -90,6 +89,18 @@ class AboutMessagePassing < EdgeCase::Koan
|
|||||||
#
|
#
|
||||||
# If the method :method_missing causes the NoMethodError, then
|
# If the method :method_missing causes the NoMethodError, then
|
||||||
# what would happen if we redefine method_missing?
|
# what would happen if we redefine method_missing?
|
||||||
|
#
|
||||||
|
# NOTE:
|
||||||
|
#
|
||||||
|
# In Ruby 1.8 the method_missing method is public and can be
|
||||||
|
# called as shown above. However, in Ruby 1.9 the method_missing
|
||||||
|
# method is private. We explicitly made it public in the testing
|
||||||
|
# framework so this example works in both versions of Ruby. Just
|
||||||
|
# keep in mind you can't call method_missing like that in Ruby
|
||||||
|
# 1.9. normally.
|
||||||
|
#
|
||||||
|
# Thanks. We now return you to your regularly schedule Ruby
|
||||||
|
# Koans.
|
||||||
end
|
end
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
def my_global_method(a,b)
|
def my_global_method(a,b)
|
||||||
a + b
|
a + b
|
||||||
@@ -10,14 +10,14 @@ class AboutMethods < EdgeCase::Koan
|
|||||||
assert_equal __, my_global_method(2,3)
|
assert_equal __, my_global_method(2,3)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_calling_global_methods_without_parenthesis
|
def test_calling_global_methods_without_parentheses
|
||||||
result = my_global_method 2, 3
|
result = my_global_method 2, 3
|
||||||
assert_equal __, result
|
assert_equal __, result
|
||||||
end
|
end
|
||||||
|
|
||||||
# (NOTE: We are Using eval below because the example code is
|
# (NOTE: We are Using eval below because the example code is
|
||||||
# considered to be syntactically invalid).
|
# considered to be syntactically invalid).
|
||||||
def test_sometimes_missing_parenthesis_are_ambiguous
|
def test_sometimes_missing_parentheses_are_ambiguous
|
||||||
eval "assert_equal 5, my_global_method 2, 3" # ENABLE CHECK
|
eval "assert_equal 5, my_global_method 2, 3" # ENABLE CHECK
|
||||||
#
|
#
|
||||||
# Ruby doesn't know if you mean:
|
# Ruby doesn't know if you mean:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutModules < EdgeCase::Koan
|
class AboutModules < EdgeCase::Koan
|
||||||
module Nameable
|
module Nameable
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutNil < EdgeCase::Koan
|
class AboutNil < EdgeCase::Koan
|
||||||
def test_nil_is_an_object
|
def test_nil_is_an_object
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutOpenClasses < EdgeCase::Koan
|
class AboutOpenClasses < EdgeCase::Koan
|
||||||
class Dog
|
class Dog
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
# Project: Create a Proxy Class
|
# Project: Create a Proxy Class
|
||||||
#
|
#
|
||||||
|
|||||||
159
koans/about_regular_expressions.rb
Normal file
159
koans/about_regular_expressions.rb
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
|
class AboutRegularExpressions < EdgeCase::Koan
|
||||||
|
def test_a_pattern_is_a_regular_expression
|
||||||
|
assert_equal Regexp, /pattern/.class
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_a_regexp_can_search_a_string_for_matching_content
|
||||||
|
assert_equal "match", "some matching content"[/match/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_a_failed_match_returns_nil
|
||||||
|
assert_equal __, "some matching content"[/missing/]
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_question_mark_means_optional
|
||||||
|
assert_equal __, "abbcccddddeeeee"[/ab?/]
|
||||||
|
assert_equal __, "abbcccddddeeeee"[/az?/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_plus_means_one_or_more
|
||||||
|
assert_equal __, "abbcccddddeeeee"[/bc+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_asterisk_means_zero_or_more
|
||||||
|
assert_equal __, "abbcccddddeeeee"[/ab*/]
|
||||||
|
assert_equal __, "abbcccddddeeeee"[/az*/]
|
||||||
|
assert_equal __, "abbcccddddeeeee"[/z*/]
|
||||||
|
|
||||||
|
# THINK ABOUT IT:
|
||||||
|
#
|
||||||
|
# When would * fail to match?
|
||||||
|
end
|
||||||
|
|
||||||
|
# THINK ABOUT IT:
|
||||||
|
#
|
||||||
|
# We say that the repetition operators above are "greedy."
|
||||||
|
#
|
||||||
|
# Why?
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_the_left_most_match_wins
|
||||||
|
assert_equal __, "abbccc az"[/az*/]
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_character_classes_give_options_for_a_character
|
||||||
|
animals = ["cat", "bat", "rat", "zat"]
|
||||||
|
assert_equal __, animals.select { |a| a[/[cbr]at/] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_slash_d_is_a_shortcut_for_a_digit_character_class
|
||||||
|
assert_equal __, "the number is 42"[/[0123456789]+/]
|
||||||
|
assert_equal __, "the number is 42"[/\d+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_character_classes_can_include_ranges
|
||||||
|
assert_equal __, "the number is 42"[/[0-9]+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_slash_s_is_a_shortcut_for_a_whitespace_character_class
|
||||||
|
assert_equal __, "space: \t\n"[/\s+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_slash_w_is_a_shortcut_for_a_word_character_class
|
||||||
|
# NOTE: This is more like how a programmer might define a word.
|
||||||
|
assert_equal __, "variable_1 = 42"[/[a-zA-Z0-9_]+/]
|
||||||
|
assert_equal __, "variable_1 = 42"[/\w+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_period_is_a_shortcut_for_any_non_newline_character
|
||||||
|
assert_equal __, "abc\n123"[/a.+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_a_character_class_can_be_negated
|
||||||
|
assert_equal __, "the number is 42"[/[^0-9]+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_shortcut_character_classes_are_negated_with_capitals
|
||||||
|
assert_equal __, "the number is 42"[/\D+/]
|
||||||
|
assert_equal __, "space: \t\n"[/\S+/]
|
||||||
|
assert_equal __, "variable_1 = 42"[/\W+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_slash_a_anchors_to_the_start_of_the_string
|
||||||
|
assert_equal __, "start end"[/\Astart/]
|
||||||
|
assert_equal __, "start end"[/\Aend/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_slash_z_anchors_to_the_end_of_the_string
|
||||||
|
assert_equal __, "start end"[/end\z/]
|
||||||
|
assert_equal __, "start end"[/start\z/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_caret_anchors_to_the_start_of_lines
|
||||||
|
assert_equal __, "num 42\n2 lines"[/^\d+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_dollar_sign_anchors_to_the_end_of_lines
|
||||||
|
assert_equal __, "2 lines\nnum 42"[/\d+$/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_slash_b_anchors_to_a_word_boundary
|
||||||
|
assert_equal __, "bovine vines"[/\bvine./]
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_parentheses_group_contents
|
||||||
|
assert_equal __, "ahahaha"[/(ha)+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_parentheses_also_capture_matched_content_by_number
|
||||||
|
assert_equal __, "Gray, James"[/(\w+), (\w+)/, 1]
|
||||||
|
assert_equal __, "Gray, James"[/(\w+), (\w+)/, 2]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_variables_can_also_be_used_to_access_captures
|
||||||
|
assert_equal __, "Name: Gray, James"[/(\w+), (\w+)/]
|
||||||
|
assert_equal __, $1
|
||||||
|
assert_equal __, $2
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_a_vertical_pipe_means_or
|
||||||
|
grays = /(James|Dana|Summer) Gray/
|
||||||
|
assert_equal __, "James Gray"[grays]
|
||||||
|
assert_equal __, "Summer Gray"[grays, 1]
|
||||||
|
assert_equal __, "Jim Gray"[grays, 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
# THINK ABOUT IT:
|
||||||
|
#
|
||||||
|
# Explain the difference between a character class ([...]) and alternation (|).
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_scan_is_like_find_all
|
||||||
|
assert_equal __, "one two-three".scan(/\w+/)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_sub_is_like_find_and_replace
|
||||||
|
assert_equal __, "one two-three".sub(/(t\w*)/) { $1[0, 1] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_gsub_is_like_find_and_replace_all
|
||||||
|
assert_equal __, "one two-three".gsub(/(t\w*)/) { $1[0, 1] }
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutUsingBlocks < EdgeCase::Koan
|
class AboutSandwichCode < EdgeCase::Koan
|
||||||
|
|
||||||
def count_lines(file_name)
|
def count_lines(file_name)
|
||||||
file = open(file_name)
|
file = open(file_name)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutScope < EdgeCase::Koan
|
class AboutScope < EdgeCase::Koan
|
||||||
module Jims
|
module Jims
|
||||||
@@ -74,6 +74,6 @@ class AboutScope < EdgeCase::Koan
|
|||||||
|
|
||||||
def test_you_can_get_a_list_of_constants_for_any_class_or_module
|
def test_you_can_get_a_list_of_constants_for_any_class_or_module
|
||||||
assert_equal __, Jims.constants
|
assert_equal __, Jims.constants
|
||||||
assert_equal __, Object.constants.size
|
assert Object.constants.size > _n_
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
# Greed is a dice game where you roll up to five dice to accumulate
|
# Greed is a dice game where you roll up to five dice to accumulate
|
||||||
# points. The following "score" function will be used calculate the
|
# points. The following "score" function will be used calculate the
|
||||||
@@ -33,7 +33,7 @@ def score(dice)
|
|||||||
# You need to write this method
|
# You need to write this method
|
||||||
end
|
end
|
||||||
|
|
||||||
class AboutScoringAssignment < EdgeCase::Koan
|
class AboutScoringProject < EdgeCase::Koan
|
||||||
def test_score_of_an_empty_list_is_zero
|
def test_score_of_an_empty_list_is_zero
|
||||||
assert_equal 0, score([])
|
assert_equal 0, score([])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutStrings < EdgeCase::Koan
|
class AboutStrings < EdgeCase::Koan
|
||||||
def test_double_quoted_strings_are_strings
|
def test_double_quoted_strings_are_strings
|
||||||
@@ -146,12 +146,21 @@ EOS
|
|||||||
# Surprised?
|
# Surprised?
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_single_characters_are_represented_by_integers
|
in_ruby_version("1.8") do
|
||||||
|
def test_in_ruby_1_8_single_characters_are_represented_by_integers
|
||||||
assert_equal __, ?a
|
assert_equal __, ?a
|
||||||
assert_equal __, ?a == 97
|
assert_equal __, ?a == 97
|
||||||
|
|
||||||
assert_equal __, ?b == (?a + 1)
|
assert_equal __, ?b == (?a + 1)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
in_ruby_version("1.9") do
|
||||||
|
def test_in_ruby_1_9_single_characters_are_represented_by_strings
|
||||||
|
assert_equal __, ?a
|
||||||
|
assert_equal __, ?a == 97
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_strings_can_be_split
|
def test_strings_can_be_split
|
||||||
string = "Sausage Egg Cheese"
|
string = "Sausage Egg Cheese"
|
||||||
@@ -165,8 +174,8 @@ EOS
|
|||||||
assert_equal [__, __, __, __], words
|
assert_equal [__, __, __, __], words
|
||||||
|
|
||||||
# NOTE: Patterns are formed from Regular Expressions. Ruby has a
|
# NOTE: Patterns are formed from Regular Expressions. Ruby has a
|
||||||
# very powerful Regular Expression library. Unfortunately, time
|
# very powerful Regular Expression library. We will become
|
||||||
# does not permit us to explore it in detail in Ruby 101.
|
# enlightened about them soon.
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_strings_can_be_joined
|
def test_strings_can_be_joined
|
||||||
|
|||||||
77
koans/about_symbols.rb
Normal file
77
koans/about_symbols.rb
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
|
class AboutSymbols < EdgeCase::Koan
|
||||||
|
def test_symbols_are_symbols
|
||||||
|
symbol = :ruby
|
||||||
|
assert_equal __, symbol.is_a?(Symbol)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symbols_can_be_compared
|
||||||
|
symbol1 = :a_symbol
|
||||||
|
symbol2 = :a_symbol
|
||||||
|
symbol3 = :something_else
|
||||||
|
|
||||||
|
assert symbol1 == __
|
||||||
|
assert symbol1 != __
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_identical_symbols_are_a_single_internal_object
|
||||||
|
symbol1 = :a_symbol
|
||||||
|
symbol2 = :a_symbol
|
||||||
|
|
||||||
|
assert symbol1.equal?(__)
|
||||||
|
assert_equal __, symbol2.object_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_method_names_become_symbols
|
||||||
|
all_symbols = Symbol.all_symbols
|
||||||
|
|
||||||
|
assert_equal __, all_symbols.include?(:test_method_names_are_symbols)
|
||||||
|
end
|
||||||
|
|
||||||
|
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?(__)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symbols_can_be_made_from_strings
|
||||||
|
string = "catsAndDogs"
|
||||||
|
assert_equal __, string.to_sym
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symbols_with_spaces_can_be_built
|
||||||
|
symbol = :"cats and dogs"
|
||||||
|
|
||||||
|
assert_equal symbol, __.to_sym
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_to_s_is_called_on_interpolated_symbols
|
||||||
|
symbol = :cats
|
||||||
|
string = "It is raining #{symbol} and dogs."
|
||||||
|
|
||||||
|
assert_equal __, string
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symbols_are_not_strings
|
||||||
|
symbol = :ruby
|
||||||
|
assert_equal __, symbol.is_a?(String)
|
||||||
|
assert_equal __, symbol.eql?("ruby")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symbols_do_not_have_string_methods
|
||||||
|
symbol = :not_a_string
|
||||||
|
assert_equal __, symbol.respond_to?(:each_char)
|
||||||
|
assert_equal __, 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(___) do
|
||||||
|
:cats + :dogs
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
# You need to write the triangle method in the file 'triangle.rb'
|
# You need to write the triangle method in the file 'triangle.rb'
|
||||||
require 'triangle.rb'
|
require 'triangle.rb'
|
||||||
|
|
||||||
class AboutTriangleAssignment < EdgeCase::Koan
|
class AboutTriangleProject < EdgeCase::Koan
|
||||||
def test_equilateral_triangles_have_equal_sides
|
def test_equilateral_triangles_have_equal_sides
|
||||||
assert_equal :equilateral, triangle(2, 2, 2)
|
assert_equal :equilateral, triangle(2, 2, 2)
|
||||||
assert_equal :equilateral, triangle(10, 10, 10)
|
assert_equal :equilateral, triangle(10, 10, 10)
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
# You need to write the triangle method in the file 'triangle.rb'
|
# You need to write the triangle method in the file 'triangle.rb'
|
||||||
require 'triangle.rb'
|
require 'triangle.rb'
|
||||||
|
|
||||||
class AboutTriangleAssignment2 < EdgeCase::Koan
|
class AboutTriangleProject2 < EdgeCase::Koan
|
||||||
# The first assignment did not talk about how to handle errors.
|
# The first assignment did not talk about how to handle errors.
|
||||||
# Let's handle that part now.
|
# Let's handle that part now.
|
||||||
def test_illegal_triangles_throw_exceptions
|
def test_illegal_triangles_throw_exceptions
|
||||||
assert_raise(TriangleError) do triangle(0, 0, 0) end
|
assert_raise(TriangleError) do triangle(0, 0, 0) end
|
||||||
assert_raise(TriangleError) do triangle(3, 4, -5) end
|
assert_raise(TriangleError) do triangle(3, 4, -5) end
|
||||||
|
assert_raise(TriangleError) do triangle(1, 1, 3) end
|
||||||
assert_raise(TriangleError) do triangle(2, 4, 2) end
|
assert_raise(TriangleError) do triangle(2, 4, 2) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutTrueAndFalse < EdgeCase::Koan
|
class AboutTrueAndFalse < EdgeCase::Koan
|
||||||
def truth_value(condition)
|
def truth_value(condition)
|
||||||
|
|||||||
3
koans/autotest/discover.rb
Normal file
3
koans/autotest/discover.rb
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Autotest.add_discovery do
|
||||||
|
"rubykoan" if File.exist? 'path_to_enlightenment.rb'
|
||||||
|
end
|
||||||
24
koans/autotest/rubykoan.rb
Normal file
24
koans/autotest/rubykoan.rb
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
require 'autotest'
|
||||||
|
|
||||||
|
class Autotest::Rubykoan < Autotest
|
||||||
|
def initialize
|
||||||
|
super
|
||||||
|
@exceptions = /\.txt|Rakefile|\.rdoc/
|
||||||
|
|
||||||
|
self.order = :alpha
|
||||||
|
self.add_mapping(/^about_.*rb$/) do |filename, _|
|
||||||
|
filename
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_test_cmd files_to_test
|
||||||
|
"#{ruby} 'path_to_enlightenment.rb'"
|
||||||
|
end
|
||||||
|
|
||||||
|
# quiet test/unit chatter
|
||||||
|
def handle_results(results)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
@@ -1 +1 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|||||||
@@ -6,8 +6,24 @@ require 'test/unit/assertions'
|
|||||||
class FillMeInError < StandardError
|
class FillMeInError < StandardError
|
||||||
end
|
end
|
||||||
|
|
||||||
def __(value="FILL ME IN")
|
def in_ruby_version(version)
|
||||||
|
yield if RUBY_VERSION =~ /^#{version}/
|
||||||
|
end
|
||||||
|
|
||||||
|
def __(value="FILL ME IN", value19=:mu)
|
||||||
|
if RUBY_VERSION < "1.9"
|
||||||
value
|
value
|
||||||
|
else
|
||||||
|
(value19 == :mu) ? value : value19
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def _n_(value=999999, value19=:mu)
|
||||||
|
if RUBY_VERSION < "1.9"
|
||||||
|
value
|
||||||
|
else
|
||||||
|
(value19 == :mu) ? value : value19
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def ___(value=FillMeInError)
|
def ___(value=FillMeInError)
|
||||||
@@ -20,13 +36,56 @@ class Object
|
|||||||
self.send(method)
|
self.send(method)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
in_ruby_version("1.9") do
|
||||||
|
public :method_missing
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module EdgeCase
|
module EdgeCase
|
||||||
|
|
||||||
|
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 ENV['NO_COLOR']
|
||||||
|
string
|
||||||
|
else
|
||||||
|
color(color_value) + string + color(COLORS[:clear])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def color(color_value)
|
||||||
|
"\e[#{color_value}m"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Sensei
|
class Sensei
|
||||||
attr_reader :failure, :failed_test
|
attr_reader :failure, :failed_test
|
||||||
|
|
||||||
|
in_ruby_version("1.8") do
|
||||||
AssertionError = Test::Unit::AssertionFailedError
|
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
|
def initialize
|
||||||
@pass_count = 0
|
@pass_count = 0
|
||||||
@@ -37,9 +96,9 @@ module EdgeCase
|
|||||||
def accumulate(test)
|
def accumulate(test)
|
||||||
if test.passed?
|
if test.passed?
|
||||||
@pass_count += 1
|
@pass_count += 1
|
||||||
puts " #{test.name} has expanded your awareness."
|
puts Color.green(" #{test.name} has expanded your awareness.")
|
||||||
else
|
else
|
||||||
puts " #{test.name} has damaged your karma."
|
puts Color.red(" #{test.name} has damaged your karma.")
|
||||||
@failed_test = test
|
@failed_test = test
|
||||||
@failure = test.failure
|
@failure = test.failure
|
||||||
throw :edgecase_exit
|
throw :edgecase_exit
|
||||||
@@ -57,18 +116,19 @@ module EdgeCase
|
|||||||
def report
|
def report
|
||||||
if failed?
|
if failed?
|
||||||
puts
|
puts
|
||||||
puts "You have not yet reached enlightenment ..."
|
puts Color.green("You have not yet reached enlightenment ...")
|
||||||
puts failure.message
|
puts Color.red(failure.message)
|
||||||
puts
|
puts
|
||||||
puts "Please meditate on the following code:"
|
puts Color.green("Please meditate on the following code:")
|
||||||
if assert_failed?
|
if assert_failed?
|
||||||
puts find_interesting_lines(failure.backtrace)
|
#puts find_interesting_lines(failure.backtrace)
|
||||||
|
puts find_interesting_lines(failure.backtrace).collect {|l| Color.red(l) }
|
||||||
else
|
else
|
||||||
puts failure.backtrace
|
puts Color.red(failure.backtrace)
|
||||||
end
|
end
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
say_something_zenlike
|
puts Color.green(a_zenlike_statement)
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_interesting_lines(backtrace)
|
def find_interesting_lines(backtrace)
|
||||||
@@ -79,26 +139,27 @@ module EdgeCase
|
|||||||
|
|
||||||
# Hat's tip to Ara T. Howard for the zen statements from his
|
# Hat's tip to Ara T. Howard for the zen statements from his
|
||||||
# metakoans Ruby Quiz (http://rubyquiz.com/quiz67.html)
|
# metakoans Ruby Quiz (http://rubyquiz.com/quiz67.html)
|
||||||
def say_something_zenlike
|
def a_zenlike_statement
|
||||||
puts
|
puts
|
||||||
if !failed?
|
if !failed?
|
||||||
puts "Mountains are again merely mountains"
|
zen_statement = "Mountains are again merely mountains"
|
||||||
else
|
else
|
||||||
case (@pass_count % 10)
|
zen_statement = case (@pass_count % 10)
|
||||||
when 0
|
when 0
|
||||||
puts "mountains are merely mountains"
|
"mountains are merely mountains"
|
||||||
when 1, 2
|
when 1, 2
|
||||||
puts "learn the rules so you know how to break them properly"
|
"learn the rules so you know how to break them properly"
|
||||||
when 3, 4
|
when 3, 4
|
||||||
puts "remember that silence is sometimes the best answer"
|
"remember that silence is sometimes the best answer"
|
||||||
when 5, 6
|
when 5, 6
|
||||||
puts "sleep is the best meditation"
|
"sleep is the best meditation"
|
||||||
when 7, 8
|
when 7, 8
|
||||||
puts "when you lose, don't lose the lesson"
|
"when you lose, don't lose the lesson"
|
||||||
else
|
else
|
||||||
puts "things are not what they appear to be: nor are they otherwise"
|
"things are not what they appear to be: nor are they otherwise"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
zen_statement
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -138,7 +199,7 @@ module EdgeCase
|
|||||||
|
|
||||||
def run_tests(accumulator)
|
def run_tests(accumulator)
|
||||||
puts
|
puts
|
||||||
puts "Thinking #{self}"
|
puts Color.green("Thinking #{self}")
|
||||||
testmethods.each do |m|
|
testmethods.each do |m|
|
||||||
self.run_test(m, accumulator) if Koan.test_pattern =~ m.to_s
|
self.run_test(m, accumulator) if Koan.test_pattern =~ m.to_s
|
||||||
end
|
end
|
||||||
@@ -149,12 +210,12 @@ module EdgeCase
|
|||||||
test.setup
|
test.setup
|
||||||
begin
|
begin
|
||||||
test.send(method)
|
test.send(method)
|
||||||
rescue StandardError => ex
|
rescue StandardError, EdgeCase::Sensei::AssertionError => ex
|
||||||
test.failed(ex)
|
test.failed(ex)
|
||||||
ensure
|
ensure
|
||||||
begin
|
begin
|
||||||
test.teardown
|
test.teardown
|
||||||
rescue StandardError => ex
|
rescue StandardError, EdgeCase::Sensei::AssertionError => ex
|
||||||
test.failed(ex) if test.passed?
|
test.failed(ex) if test.passed?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
# The path to Ruby Enlightenment starts with the following:
|
# The path to Ruby Enlightenment starts with the following:
|
||||||
|
|
||||||
|
$LOAD_PATH << File.dirname(__FILE__)
|
||||||
|
|
||||||
require 'about_asserts'
|
require 'about_asserts'
|
||||||
require 'about_nil'
|
require 'about_nil'
|
||||||
require 'about_arrays'
|
require 'about_arrays'
|
||||||
require 'about_array_assignment'
|
require 'about_array_assignment'
|
||||||
require 'about_hashes'
|
require 'about_hashes'
|
||||||
require 'about_strings'
|
require 'about_strings'
|
||||||
|
require 'about_symbols'
|
||||||
|
require 'about_regular_expressions'
|
||||||
require 'about_methods'
|
require 'about_methods'
|
||||||
|
require 'about_constants'
|
||||||
require 'about_control_statements'
|
require 'about_control_statements'
|
||||||
require 'about_true_and_false'
|
require 'about_true_and_false'
|
||||||
require 'about_triangle_project'
|
require 'about_triangle_project'
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutArrayAssignment < EdgeCase::Koan
|
class AboutArrayAssignment < EdgeCase::Koan
|
||||||
def test_non_parallel_assignment
|
def test_non_parallel_assignment
|
||||||
@@ -35,4 +35,11 @@ class AboutArrayAssignment < EdgeCase::Koan
|
|||||||
assert_equal __("John"), first_name
|
assert_equal __("John"), first_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_swapping_with_parallel_assignment
|
||||||
|
first_name = "Roy"
|
||||||
|
last_name = "Rob"
|
||||||
|
first_name, last_name = last_name, first_name
|
||||||
|
assert_equal __('Rob'), first_name
|
||||||
|
assert_equal __('Roy'), last_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutArrays < EdgeCase::Koan
|
class AboutArrays < EdgeCase::Koan
|
||||||
def test_creating_arrays
|
def test_creating_arrays
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
# -*- ruby -*-
|
# -*- ruby -*-
|
||||||
|
|
||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutAsserts < EdgeCase::Koan
|
class AboutAsserts < EdgeCase::Koan
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutBlocks < EdgeCase::Koan
|
class AboutBlocks < EdgeCase::Koan
|
||||||
def method_with_block
|
def method_with_block
|
||||||
@@ -60,7 +60,7 @@ class AboutBlocks < EdgeCase::Koan
|
|||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
def test_block_can_effect_variables_in_the_code_where_they_are_created
|
def test_block_can_affect_variables_in_the_code_where_they_are_created
|
||||||
value = :initial_value
|
value = :initial_value
|
||||||
method_with_block { value = :modified_in_a_block }
|
method_with_block { value = :modified_in_a_block }
|
||||||
assert_equal __(:modified_in_a_block), value
|
assert_equal __(:modified_in_a_block), value
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutClassMethods < EdgeCase::Koan
|
class AboutClassMethods < EdgeCase::Koan
|
||||||
class Dog
|
class Dog
|
||||||
@@ -19,11 +19,11 @@ class AboutClassMethods < EdgeCase::Koan
|
|||||||
|
|
||||||
def test_objects_have_methods
|
def test_objects_have_methods
|
||||||
fido = Dog.new
|
fido = Dog.new
|
||||||
assert_equal __(44), fido.methods.size
|
assert fido.methods.size > _n_(30)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_classes_have_methods
|
def test_classes_have_methods
|
||||||
assert_equal __(79), Dog.methods.size
|
assert Dog.methods.size > _n_(40)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_you_can_define_methods_on_individual_objects
|
def test_you_can_define_methods_on_individual_objects
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutClasses < EdgeCase::Koan
|
class AboutClasses < EdgeCase::Koan
|
||||||
class Dog
|
class Dog
|
||||||
@@ -22,7 +22,7 @@ class AboutClasses < EdgeCase::Koan
|
|||||||
assert_equal __([]), fido.instance_variables
|
assert_equal __([]), fido.instance_variables
|
||||||
|
|
||||||
fido.set_name("Fido")
|
fido.set_name("Fido")
|
||||||
assert_equal __(["@name"]), fido.instance_variables
|
assert_equal __(["@name"], [:@name]), fido.instance_variables
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_instance_variables_cannot_be_accessed_outside_the_class
|
def test_instance_variables_cannot_be_accessed_outside_the_class
|
||||||
@@ -180,7 +180,7 @@ class AboutClasses < EdgeCase::Koan
|
|||||||
def test_all_objects_support_to_s_and_inspect
|
def test_all_objects_support_to_s_and_inspect
|
||||||
array = [1,2,3]
|
array = [1,2,3]
|
||||||
|
|
||||||
assert_equal __("123"), array.to_s
|
assert_equal __("123", "[1, 2, 3]"), array.to_s
|
||||||
assert_equal __("[1, 2, 3]"), array.inspect
|
assert_equal __("[1, 2, 3]"), array.inspect
|
||||||
|
|
||||||
assert_equal __("STRING"), "STRING".to_s
|
assert_equal __("STRING"), "STRING".to_s
|
||||||
|
|||||||
87
src/about_constants.rb
Normal file
87
src/about_constants.rb
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
|
C = "top level"
|
||||||
|
|
||||||
|
class AboutConstants < EdgeCase::Koan
|
||||||
|
|
||||||
|
C = "nested"
|
||||||
|
|
||||||
|
def test_nested_constants_may_also_be_referenced_with_relative_paths
|
||||||
|
assert_equal __("nested"), C
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_top_level_constants_are_referenced_by_double_colons
|
||||||
|
assert_equal __("top level"), ::C
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nested_constants_are_referenced_by_their_complete_path
|
||||||
|
assert_equal __("nested"), AboutConstants::C
|
||||||
|
assert_equal __("nested"), ::AboutConstants::C
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
class Animal
|
||||||
|
LEGS = 4
|
||||||
|
def legs_in_animal
|
||||||
|
LEGS
|
||||||
|
end
|
||||||
|
|
||||||
|
class NestedAnimal
|
||||||
|
def legs_in_nested_animal
|
||||||
|
LEGS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_nested_classes_inherit_constants_from_enclosing_classes
|
||||||
|
assert_equal __(4), Animal::NestedAnimal.new.legs_in_nested_animal
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
class Reptile < Animal
|
||||||
|
def legs_in_reptile
|
||||||
|
LEGS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_subclasses_inherit_constants_from_parent_classes
|
||||||
|
assert_equal __(4), Reptile.new.legs_in_reptile
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MyAnimals
|
||||||
|
LEGS = 2
|
||||||
|
|
||||||
|
class Bird < Animal
|
||||||
|
def legs_in_bird
|
||||||
|
LEGS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_who_wins_with_both_nested_and_inherited_constants
|
||||||
|
assert_equal __(2), MyAnimals::Bird.new.legs_in_bird
|
||||||
|
end
|
||||||
|
|
||||||
|
# QUESTION: Which has precedence: The constant in the lexical scope,
|
||||||
|
# or the constant from the inheritance heirarachy?
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MyAnimals::Oyster < Animal
|
||||||
|
def legs_in_oyster
|
||||||
|
LEGS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_who_wins_with_explicit_scoping_on_class_definition
|
||||||
|
assert_equal __(4), MyAnimals::Oyster.new.legs_in_oyster
|
||||||
|
end
|
||||||
|
|
||||||
|
# QUESTION: Now Which has precedence: The constant in the lexical
|
||||||
|
# scope, or the constant from the inheritance heirarachy? Why is it
|
||||||
|
# different than the previous answer?
|
||||||
|
end
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutControlStatements < EdgeCase::Koan
|
class AboutControlStatements < EdgeCase::Koan
|
||||||
|
|
||||||
@@ -8,10 +8,10 @@ class AboutControlStatements < EdgeCase::Koan
|
|||||||
else
|
else
|
||||||
result = :false_value
|
result = :false_value
|
||||||
end
|
end
|
||||||
assert_equal __, result
|
assert_equal __(:true_value), result
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_if_then_else_statements
|
def test_if_then_statements
|
||||||
result = :default_value
|
result = :default_value
|
||||||
if true
|
if true
|
||||||
result = :true_value
|
result = :true_value
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class DiceSet
|
class DiceSet
|
||||||
attr_reader :values
|
attr_reader :values
|
||||||
@@ -7,7 +7,7 @@ class DiceSet
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class AboutDiceSet < EdgeCase::Koan
|
class AboutDiceProject < EdgeCase::Koan
|
||||||
def test_can_create_a_dice_set
|
def test_can_create_a_dice_set
|
||||||
dice = DiceSet.new
|
dice = DiceSet.new
|
||||||
assert_not_nil dice
|
assert_not_nil dice
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutExceptions < EdgeCase::Koan
|
class AboutExceptions < EdgeCase::Koan
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutHashes < EdgeCase::Koan
|
class AboutHashes < EdgeCase::Koan
|
||||||
def test_creating_hashes
|
def test_creating_hashes
|
||||||
@@ -48,7 +48,7 @@ class AboutHashes < EdgeCase::Koan
|
|||||||
|
|
||||||
def test_hash_values
|
def test_hash_values
|
||||||
hash = { :one => "uno", :two => "dos" }
|
hash = { :one => "uno", :two => "dos" }
|
||||||
assert_equal __(2), hash.keys.size
|
assert_equal __(2), hash.values.size
|
||||||
assert_equal __(true), hash.values.include?("uno")
|
assert_equal __(true), hash.values.include?("uno")
|
||||||
assert_equal __(true), hash.values.include?("dos")
|
assert_equal __(true), hash.values.include?("dos")
|
||||||
assert_equal Array, hash.values.class
|
assert_equal Array, hash.values.class
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutInheritance < EdgeCase::Koan
|
class AboutInheritance < EdgeCase::Koan
|
||||||
class Dog
|
class Dog
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutIteration < EdgeCase::Koan
|
class AboutIteration < EdgeCase::Koan
|
||||||
|
|
||||||
@@ -78,16 +78,26 @@ class AboutIteration < EdgeCase::Koan
|
|||||||
assert_equal __([11, 12, 13]), result
|
assert_equal __([11, 12, 13]), result
|
||||||
|
|
||||||
# Files act like a collection of lines
|
# Files act like a collection of lines
|
||||||
file = File.open("example_file.txt")
|
File.open("example_file.txt") do |file|
|
||||||
upcase_lines = file.map { |line| line.strip.upcase }
|
upcase_lines = file.map { |line| line.strip.upcase }
|
||||||
assert_equal __(["THIS", "IS", "A", "TEST"]), upcase_lines
|
assert_equal __(["THIS", "IS", "A", "TEST"]), upcase_lines
|
||||||
|
end
|
||||||
|
|
||||||
# NOTE: You can create your own collections that work with each,
|
# NOTE: You can create your own collections that work with each,
|
||||||
# map, select, etc.
|
# map, select, etc.
|
||||||
ensure
|
|
||||||
# Arg, this is ugly.
|
|
||||||
# We will figure out how to fix this later.
|
|
||||||
file.close if file
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Bonus Question: In the previous koan, we saw the construct:
|
||||||
|
#
|
||||||
|
# File.open(filename) do |file|
|
||||||
|
# # code to read 'file'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Why did we do it that way instead of the following?
|
||||||
|
#
|
||||||
|
# file = File.open(filename)
|
||||||
|
# # code to read 'file'
|
||||||
|
#
|
||||||
|
# When you get to the "AboutSandwichCode" koan, recheck your answer.
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutMessagePassing < EdgeCase::Koan
|
class AboutMessagePassing < EdgeCase::Koan
|
||||||
|
|
||||||
@@ -49,7 +49,6 @@ class AboutMessagePassing < EdgeCase::Koan
|
|||||||
|
|
||||||
class MessageCatcher
|
class MessageCatcher
|
||||||
def add_a_payload(*args)
|
def add_a_payload(*args)
|
||||||
return :empty unless args
|
|
||||||
args
|
args
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -90,6 +89,18 @@ class AboutMessagePassing < EdgeCase::Koan
|
|||||||
#
|
#
|
||||||
# If the method :method_missing causes the NoMethodError, then
|
# If the method :method_missing causes the NoMethodError, then
|
||||||
# what would happen if we redefine method_missing?
|
# what would happen if we redefine method_missing?
|
||||||
|
#
|
||||||
|
# NOTE:
|
||||||
|
#
|
||||||
|
# In Ruby 1.8 the method_missing method is public and can be
|
||||||
|
# called as shown above. However, in Ruby 1.9 the method_missing
|
||||||
|
# method is private. We explicitly made it public in the testing
|
||||||
|
# framework so this example works in both versions of Ruby. Just
|
||||||
|
# keep in mind you can't call method_missing like that in Ruby
|
||||||
|
# 1.9. normally.
|
||||||
|
#
|
||||||
|
# Thanks. We now return you to your regularly schedule Ruby
|
||||||
|
# Koans.
|
||||||
end
|
end
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
def my_global_method(a,b)
|
def my_global_method(a,b)
|
||||||
a + b
|
a + b
|
||||||
@@ -10,14 +10,14 @@ class AboutMethods < EdgeCase::Koan
|
|||||||
assert_equal __(5), my_global_method(2,3)
|
assert_equal __(5), my_global_method(2,3)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_calling_global_methods_without_parenthesis
|
def test_calling_global_methods_without_parentheses
|
||||||
result = my_global_method 2, 3
|
result = my_global_method 2, 3
|
||||||
assert_equal __(5), result
|
assert_equal __(5), result
|
||||||
end
|
end
|
||||||
|
|
||||||
# (NOTE: We are Using eval below because the example code is
|
# (NOTE: We are Using eval below because the example code is
|
||||||
# considered to be syntactically invalid).
|
# considered to be syntactically invalid).
|
||||||
def test_sometimes_missing_parenthesis_are_ambiguous
|
def test_sometimes_missing_parentheses_are_ambiguous
|
||||||
#--
|
#--
|
||||||
eval "assert_equal 5, my_global_method(2, 3)" # REMOVE CHECK
|
eval "assert_equal 5, my_global_method(2, 3)" # REMOVE CHECK
|
||||||
if false
|
if false
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutModules < EdgeCase::Koan
|
class AboutModules < EdgeCase::Koan
|
||||||
module Nameable
|
module Nameable
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutNil < EdgeCase::Koan
|
class AboutNil < EdgeCase::Koan
|
||||||
def test_nil_is_an_object
|
def test_nil_is_an_object
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutOpenClasses < EdgeCase::Koan
|
class AboutOpenClasses < EdgeCase::Koan
|
||||||
class Dog
|
class Dog
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
# Project: Create a Proxy Class
|
# Project: Create a Proxy Class
|
||||||
#
|
#
|
||||||
|
|||||||
159
src/about_regular_expressions.rb
Normal file
159
src/about_regular_expressions.rb
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
|
class AboutRegularExpressions < EdgeCase::Koan
|
||||||
|
def test_a_pattern_is_a_regular_expression
|
||||||
|
assert_equal Regexp, /pattern/.class
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_a_regexp_can_search_a_string_for_matching_content
|
||||||
|
assert_equal "match", "some matching content"[/match/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_a_failed_match_returns_nil
|
||||||
|
assert_equal __(nil), "some matching content"[/missing/]
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_question_mark_means_optional
|
||||||
|
assert_equal __("ab"), "abbcccddddeeeee"[/ab?/]
|
||||||
|
assert_equal __("a"), "abbcccddddeeeee"[/az?/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_plus_means_one_or_more
|
||||||
|
assert_equal __("bccc"), "abbcccddddeeeee"[/bc+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_asterisk_means_zero_or_more
|
||||||
|
assert_equal __("abb"), "abbcccddddeeeee"[/ab*/]
|
||||||
|
assert_equal __("a"), "abbcccddddeeeee"[/az*/]
|
||||||
|
assert_equal __(""), "abbcccddddeeeee"[/z*/]
|
||||||
|
|
||||||
|
# THINK ABOUT IT:
|
||||||
|
#
|
||||||
|
# When would * fail to match?
|
||||||
|
end
|
||||||
|
|
||||||
|
# THINK ABOUT IT:
|
||||||
|
#
|
||||||
|
# We say that the repetition operators above are "greedy."
|
||||||
|
#
|
||||||
|
# Why?
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_the_left_most_match_wins
|
||||||
|
assert_equal __("a"), "abbccc az"[/az*/]
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_character_classes_give_options_for_a_character
|
||||||
|
animals = ["cat", "bat", "rat", "zat"]
|
||||||
|
assert_equal __(["cat", "bat", "rat"]), animals.select { |a| a[/[cbr]at/] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_slash_d_is_a_shortcut_for_a_digit_character_class
|
||||||
|
assert_equal __("42"), "the number is 42"[/[0123456789]+/]
|
||||||
|
assert_equal __("42"), "the number is 42"[/\d+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_character_classes_can_include_ranges
|
||||||
|
assert_equal __("42"), "the number is 42"[/[0-9]+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_slash_s_is_a_shortcut_for_a_whitespace_character_class
|
||||||
|
assert_equal __(" \t\n"), "space: \t\n"[/\s+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_slash_w_is_a_shortcut_for_a_word_character_class
|
||||||
|
# NOTE: This is more like how a programmer might define a word.
|
||||||
|
assert_equal __("variable_1"), "variable_1 = 42"[/[a-zA-Z0-9_]+/]
|
||||||
|
assert_equal __("variable_1"), "variable_1 = 42"[/\w+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_period_is_a_shortcut_for_any_non_newline_character
|
||||||
|
assert_equal __("abc"), "abc\n123"[/a.+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_a_character_class_can_be_negated
|
||||||
|
assert_equal __("the number is "), "the number is 42"[/[^0-9]+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_shortcut_character_classes_are_negated_with_capitals
|
||||||
|
assert_equal __("the number is "), "the number is 42"[/\D+/]
|
||||||
|
assert_equal __("space:"), "space: \t\n"[/\S+/]
|
||||||
|
assert_equal __(" = "), "variable_1 = 42"[/\W+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_slash_a_anchors_to_the_start_of_the_string
|
||||||
|
assert_equal __("start"), "start end"[/\Astart/]
|
||||||
|
assert_equal __(nil), "start end"[/\Aend/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_slash_z_anchors_to_the_end_of_the_string
|
||||||
|
assert_equal __("end"), "start end"[/end\z/]
|
||||||
|
assert_equal __(nil), "start end"[/start\z/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_caret_anchors_to_the_start_of_lines
|
||||||
|
assert_equal __("2"), "num 42\n2 lines"[/^\d+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_dollar_sign_anchors_to_the_end_of_lines
|
||||||
|
assert_equal __("42"), "2 lines\nnum 42"[/\d+$/]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_slash_b_anchors_to_a_word_boundary
|
||||||
|
assert_equal __("vines"), "bovine vines"[/\bvine./]
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_parentheses_group_contents
|
||||||
|
assert_equal __("hahaha"), "ahahaha"[/(ha)+/]
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_parentheses_also_capture_matched_content_by_number
|
||||||
|
assert_equal __("Gray"), "Gray, James"[/(\w+), (\w+)/, 1]
|
||||||
|
assert_equal __("James"), "Gray, James"[/(\w+), (\w+)/, 2]
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_variables_can_also_be_used_to_access_captures
|
||||||
|
assert_equal __("Gray, James"), "Name: Gray, James"[/(\w+), (\w+)/]
|
||||||
|
assert_equal __("Gray"), $1
|
||||||
|
assert_equal __("James"), $2
|
||||||
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_a_vertical_pipe_means_or
|
||||||
|
grays = /(James|Dana|Summer) Gray/
|
||||||
|
assert_equal __("James Gray"), "James Gray"[grays]
|
||||||
|
assert_equal __("Summer"), "Summer Gray"[grays, 1]
|
||||||
|
assert_equal __(nil), "Jim Gray"[grays, 1]
|
||||||
|
end
|
||||||
|
|
||||||
|
# THINK ABOUT IT:
|
||||||
|
#
|
||||||
|
# Explain the difference between a character class ([...]) and alternation (|).
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_scan_is_like_find_all
|
||||||
|
assert_equal __(["one", "two", "three"]), "one two-three".scan(/\w+/)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_sub_is_like_find_and_replace
|
||||||
|
assert_equal __("one t-three"), "one two-three".sub(/(t\w*)/) { $1[0, 1] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_gsub_is_like_find_and_replace_all
|
||||||
|
assert_equal __("one t-t"), "one two-three".gsub(/(t\w*)/) { $1[0, 1] }
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutUsingBlocks < EdgeCase::Koan
|
class AboutSandwichCode < EdgeCase::Koan
|
||||||
|
|
||||||
def count_lines(file_name)
|
def count_lines(file_name)
|
||||||
file = open(file_name)
|
file = open(file_name)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutScope < EdgeCase::Koan
|
class AboutScope < EdgeCase::Koan
|
||||||
module Jims
|
module Jims
|
||||||
@@ -73,7 +73,7 @@ class AboutScope < EdgeCase::Koan
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_you_can_get_a_list_of_constants_for_any_class_or_module
|
def test_you_can_get_a_list_of_constants_for_any_class_or_module
|
||||||
assert_equal __(["Dog"]), Jims.constants
|
assert_equal __(["Dog"], [:Dog]), Jims.constants
|
||||||
assert_equal __(122), Object.constants.size
|
assert Object.constants.size > _n_(10)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
# Greed is a dice game where you roll up to five dice to accumulate
|
# Greed is a dice game where you roll up to five dice to accumulate
|
||||||
# points. The following "score" function will be used calculate the
|
# points. The following "score" function will be used calculate the
|
||||||
@@ -54,7 +54,7 @@ def score(dice)
|
|||||||
#++
|
#++
|
||||||
end
|
end
|
||||||
|
|
||||||
class AboutScoringAssignment < EdgeCase::Koan
|
class AboutScoringProject < EdgeCase::Koan
|
||||||
def test_score_of_an_empty_list_is_zero
|
def test_score_of_an_empty_list_is_zero
|
||||||
assert_equal 0, score([])
|
assert_equal 0, score([])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutStrings < EdgeCase::Koan
|
class AboutStrings < EdgeCase::Koan
|
||||||
def test_double_quoted_strings_are_strings
|
def test_double_quoted_strings_are_strings
|
||||||
@@ -141,17 +141,26 @@ EOS
|
|||||||
|
|
||||||
def test_you_can_get_a_single_character_from_a_string
|
def test_you_can_get_a_single_character_from_a_string
|
||||||
string = "Bacon, lettuce and tomato"
|
string = "Bacon, lettuce and tomato"
|
||||||
assert_equal __(97), string[1]
|
assert_equal __(97, 'a'), string[1]
|
||||||
|
|
||||||
# Surprised?
|
# Surprised?
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_single_characters_are_represented_by_integers
|
in_ruby_version("1.8") do
|
||||||
assert_equal __(97), ?a
|
def test_in_ruby_1_8_single_characters_are_represented_by_integers
|
||||||
assert_equal __(true), ?a == 97
|
assert_equal __(97, 'a'), ?a
|
||||||
|
assert_equal __(true, false), ?a == 97
|
||||||
|
|
||||||
assert_equal __(true), ?b == (?a + 1)
|
assert_equal __(true), ?b == (?a + 1)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
in_ruby_version("1.9") do
|
||||||
|
def test_in_ruby_1_9_single_characters_are_represented_by_strings
|
||||||
|
assert_equal __('a'), ?a
|
||||||
|
assert_equal __(false), ?a == 97
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_strings_can_be_split
|
def test_strings_can_be_split
|
||||||
string = "Sausage Egg Cheese"
|
string = "Sausage Egg Cheese"
|
||||||
@@ -165,8 +174,8 @@ EOS
|
|||||||
assert_equal [__("the"), __("rain"), __("in"), __("spain")], words
|
assert_equal [__("the"), __("rain"), __("in"), __("spain")], words
|
||||||
|
|
||||||
# NOTE: Patterns are formed from Regular Expressions. Ruby has a
|
# NOTE: Patterns are formed from Regular Expressions. Ruby has a
|
||||||
# very powerful Regular Expression library. Unfortunately, time
|
# very powerful Regular Expression library. We will become
|
||||||
# does not permit us to explore it in detail in Ruby 101.
|
# enlightened about them soon.
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_strings_can_be_joined
|
def test_strings_can_be_joined
|
||||||
|
|||||||
77
src/about_symbols.rb
Normal file
77
src/about_symbols.rb
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
|
class AboutSymbols < EdgeCase::Koan
|
||||||
|
def test_symbols_are_symbols
|
||||||
|
symbol = :ruby
|
||||||
|
assert_equal __(true), symbol.is_a?(Symbol)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symbols_can_be_compared
|
||||||
|
symbol1 = :a_symbol
|
||||||
|
symbol2 = :a_symbol
|
||||||
|
symbol3 = :something_else
|
||||||
|
|
||||||
|
assert symbol1 == __(symbol2)
|
||||||
|
assert symbol1 != __(symbol3)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_identical_symbols_are_a_single_internal_object
|
||||||
|
symbol1 = :a_symbol
|
||||||
|
symbol2 = :a_symbol
|
||||||
|
|
||||||
|
assert symbol1.equal?(__(symbol2))
|
||||||
|
assert_equal __(symbol1.object_id), symbol2.object_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_method_names_become_symbols
|
||||||
|
all_symbols = Symbol.all_symbols
|
||||||
|
|
||||||
|
assert_equal __(true), all_symbols.include?(:test_method_names_are_symbols)
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def test_symbols_can_be_made_from_strings
|
||||||
|
string = "catsAndDogs"
|
||||||
|
assert_equal __(:catsAndDogs), string.to_sym
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symbols_with_spaces_can_be_built
|
||||||
|
symbol = :"cats and 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."
|
||||||
|
|
||||||
|
assert_equal __('It is raining cats and dogs.'), string
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symbols_are_not_strings
|
||||||
|
symbol = :ruby
|
||||||
|
assert_equal __(false), symbol.is_a?(String)
|
||||||
|
assert_equal __(false), symbol.eql?("ruby")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symbols_do_not_have_string_methods
|
||||||
|
symbol = :not_a_string
|
||||||
|
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
|
||||||
|
end
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
# You need to write the triangle method in the file 'triangle.rb'
|
# You need to write the triangle method in the file 'triangle.rb'
|
||||||
require 'triangle.rb'
|
require 'triangle.rb'
|
||||||
|
|
||||||
class AboutTriangleAssignment < EdgeCase::Koan
|
class AboutTriangleProject < EdgeCase::Koan
|
||||||
def test_equilateral_triangles_have_equal_sides
|
def test_equilateral_triangles_have_equal_sides
|
||||||
assert_equal :equilateral, triangle(2, 2, 2)
|
assert_equal :equilateral, triangle(2, 2, 2)
|
||||||
assert_equal :equilateral, triangle(10, 10, 10)
|
assert_equal :equilateral, triangle(10, 10, 10)
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
# You need to write the triangle method in the file 'triangle.rb'
|
# You need to write the triangle method in the file 'triangle.rb'
|
||||||
require 'triangle.rb'
|
require 'triangle.rb'
|
||||||
|
|
||||||
class AboutTriangleAssignment2 < EdgeCase::Koan
|
class AboutTriangleProject2 < EdgeCase::Koan
|
||||||
# The first assignment did not talk about how to handle errors.
|
# The first assignment did not talk about how to handle errors.
|
||||||
# Let's handle that part now.
|
# Let's handle that part now.
|
||||||
def test_illegal_triangles_throw_exceptions
|
def test_illegal_triangles_throw_exceptions
|
||||||
assert_raise(TriangleError) do triangle(0, 0, 0) end
|
assert_raise(TriangleError) do triangle(0, 0, 0) end
|
||||||
assert_raise(TriangleError) do triangle(3, 4, -5) end
|
assert_raise(TriangleError) do triangle(3, 4, -5) end
|
||||||
|
assert_raise(TriangleError) do triangle(1, 1, 3) end
|
||||||
assert_raise(TriangleError) do triangle(2, 4, 2) end
|
assert_raise(TriangleError) do triangle(2, 4, 2) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|
||||||
class AboutTrueAndFalse < EdgeCase::Koan
|
class AboutTrueAndFalse < EdgeCase::Koan
|
||||||
def truth_value(condition)
|
def truth_value(condition)
|
||||||
|
|||||||
3
src/autotest/discover.rb
Normal file
3
src/autotest/discover.rb
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Autotest.add_discovery do
|
||||||
|
"rubykoan" if File.exist? 'path_to_enlightenment.rb'
|
||||||
|
end
|
||||||
24
src/autotest/rubykoan.rb
Normal file
24
src/autotest/rubykoan.rb
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
require 'autotest'
|
||||||
|
|
||||||
|
class Autotest::Rubykoan < Autotest
|
||||||
|
def initialize
|
||||||
|
super
|
||||||
|
@exceptions = /\.txt|Rakefile|\.rdoc/
|
||||||
|
|
||||||
|
self.order = :alpha
|
||||||
|
self.add_mapping(/^about_.*rb$/) do |filename, _|
|
||||||
|
filename
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_test_cmd files_to_test
|
||||||
|
"#{ruby} 'path_to_enlightenment.rb'"
|
||||||
|
end
|
||||||
|
|
||||||
|
# quiet test/unit chatter
|
||||||
|
def handle_results(results)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
@@ -1 +1 @@
|
|||||||
require 'edgecase'
|
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
|
||||||
|
|||||||
103
src/edgecase.rb
103
src/edgecase.rb
@@ -6,8 +6,24 @@ require 'test/unit/assertions'
|
|||||||
class FillMeInError < StandardError
|
class FillMeInError < StandardError
|
||||||
end
|
end
|
||||||
|
|
||||||
def __(value="FILL ME IN")
|
def in_ruby_version(version)
|
||||||
|
yield if RUBY_VERSION =~ /^#{version}/
|
||||||
|
end
|
||||||
|
|
||||||
|
def __(value="FILL ME IN", value19=:mu)
|
||||||
|
if RUBY_VERSION < "1.9"
|
||||||
value
|
value
|
||||||
|
else
|
||||||
|
(value19 == :mu) ? value : value19
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def _n_(value=999999, value19=:mu)
|
||||||
|
if RUBY_VERSION < "1.9"
|
||||||
|
value
|
||||||
|
else
|
||||||
|
(value19 == :mu) ? value : value19
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def ___(value=FillMeInError)
|
def ___(value=FillMeInError)
|
||||||
@@ -20,13 +36,56 @@ class Object
|
|||||||
self.send(method)
|
self.send(method)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
in_ruby_version("1.9") do
|
||||||
|
public :method_missing
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module EdgeCase
|
module EdgeCase
|
||||||
|
|
||||||
|
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 ENV['NO_COLOR']
|
||||||
|
string
|
||||||
|
else
|
||||||
|
color(color_value) + string + color(COLORS[:clear])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def color(color_value)
|
||||||
|
"\e[#{color_value}m"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Sensei
|
class Sensei
|
||||||
attr_reader :failure, :failed_test
|
attr_reader :failure, :failed_test
|
||||||
|
|
||||||
|
in_ruby_version("1.8") do
|
||||||
AssertionError = Test::Unit::AssertionFailedError
|
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
|
def initialize
|
||||||
@pass_count = 0
|
@pass_count = 0
|
||||||
@@ -37,9 +96,9 @@ module EdgeCase
|
|||||||
def accumulate(test)
|
def accumulate(test)
|
||||||
if test.passed?
|
if test.passed?
|
||||||
@pass_count += 1
|
@pass_count += 1
|
||||||
puts " #{test.name} has expanded your awareness."
|
puts Color.green(" #{test.name} has expanded your awareness.")
|
||||||
else
|
else
|
||||||
puts " #{test.name} has damaged your karma."
|
puts Color.red(" #{test.name} has damaged your karma.")
|
||||||
@failed_test = test
|
@failed_test = test
|
||||||
@failure = test.failure
|
@failure = test.failure
|
||||||
throw :edgecase_exit
|
throw :edgecase_exit
|
||||||
@@ -57,18 +116,19 @@ module EdgeCase
|
|||||||
def report
|
def report
|
||||||
if failed?
|
if failed?
|
||||||
puts
|
puts
|
||||||
puts "You have not yet reached enlightenment ..."
|
puts Color.green("You have not yet reached enlightenment ...")
|
||||||
puts failure.message
|
puts Color.red(failure.message)
|
||||||
puts
|
puts
|
||||||
puts "Please meditate on the following code:"
|
puts Color.green("Please meditate on the following code:")
|
||||||
if assert_failed?
|
if assert_failed?
|
||||||
puts find_interesting_lines(failure.backtrace)
|
#puts find_interesting_lines(failure.backtrace)
|
||||||
|
puts find_interesting_lines(failure.backtrace).collect {|l| Color.red(l) }
|
||||||
else
|
else
|
||||||
puts failure.backtrace
|
puts Color.red(failure.backtrace)
|
||||||
end
|
end
|
||||||
puts
|
puts
|
||||||
end
|
end
|
||||||
say_something_zenlike
|
puts Color.green(a_zenlike_statement)
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_interesting_lines(backtrace)
|
def find_interesting_lines(backtrace)
|
||||||
@@ -79,26 +139,27 @@ module EdgeCase
|
|||||||
|
|
||||||
# Hat's tip to Ara T. Howard for the zen statements from his
|
# Hat's tip to Ara T. Howard for the zen statements from his
|
||||||
# metakoans Ruby Quiz (http://rubyquiz.com/quiz67.html)
|
# metakoans Ruby Quiz (http://rubyquiz.com/quiz67.html)
|
||||||
def say_something_zenlike
|
def a_zenlike_statement
|
||||||
puts
|
puts
|
||||||
if !failed?
|
if !failed?
|
||||||
puts "Mountains are again merely mountains"
|
zen_statement = "Mountains are again merely mountains"
|
||||||
else
|
else
|
||||||
case (@pass_count % 10)
|
zen_statement = case (@pass_count % 10)
|
||||||
when 0
|
when 0
|
||||||
puts "mountains are merely mountains"
|
"mountains are merely mountains"
|
||||||
when 1, 2
|
when 1, 2
|
||||||
puts "learn the rules so you know how to break them properly"
|
"learn the rules so you know how to break them properly"
|
||||||
when 3, 4
|
when 3, 4
|
||||||
puts "remember that silence is sometimes the best answer"
|
"remember that silence is sometimes the best answer"
|
||||||
when 5, 6
|
when 5, 6
|
||||||
puts "sleep is the best meditation"
|
"sleep is the best meditation"
|
||||||
when 7, 8
|
when 7, 8
|
||||||
puts "when you lose, don't lose the lesson"
|
"when you lose, don't lose the lesson"
|
||||||
else
|
else
|
||||||
puts "things are not what they appear to be: nor are they otherwise"
|
"things are not what they appear to be: nor are they otherwise"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
zen_statement
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -138,7 +199,7 @@ module EdgeCase
|
|||||||
|
|
||||||
def run_tests(accumulator)
|
def run_tests(accumulator)
|
||||||
puts
|
puts
|
||||||
puts "Thinking #{self}"
|
puts Color.green("Thinking #{self}")
|
||||||
testmethods.each do |m|
|
testmethods.each do |m|
|
||||||
self.run_test(m, accumulator) if Koan.test_pattern =~ m.to_s
|
self.run_test(m, accumulator) if Koan.test_pattern =~ m.to_s
|
||||||
end
|
end
|
||||||
@@ -149,12 +210,12 @@ module EdgeCase
|
|||||||
test.setup
|
test.setup
|
||||||
begin
|
begin
|
||||||
test.send(method)
|
test.send(method)
|
||||||
rescue StandardError => ex
|
rescue StandardError, EdgeCase::Sensei::AssertionError => ex
|
||||||
test.failed(ex)
|
test.failed(ex)
|
||||||
ensure
|
ensure
|
||||||
begin
|
begin
|
||||||
test.teardown
|
test.teardown
|
||||||
rescue StandardError => ex
|
rescue StandardError, EdgeCase::Sensei::AssertionError => ex
|
||||||
test.failed(ex) if test.passed?
|
test.failed(ex) if test.passed?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
# The path to Ruby Enlightenment starts with the following:
|
# The path to Ruby Enlightenment starts with the following:
|
||||||
|
|
||||||
|
$LOAD_PATH << File.dirname(__FILE__)
|
||||||
|
|
||||||
require 'about_asserts'
|
require 'about_asserts'
|
||||||
require 'about_nil'
|
require 'about_nil'
|
||||||
require 'about_arrays'
|
require 'about_arrays'
|
||||||
require 'about_array_assignment'
|
require 'about_array_assignment'
|
||||||
require 'about_hashes'
|
require 'about_hashes'
|
||||||
require 'about_strings'
|
require 'about_strings'
|
||||||
|
require 'about_symbols'
|
||||||
|
require 'about_regular_expressions'
|
||||||
require 'about_methods'
|
require 'about_methods'
|
||||||
|
require 'about_constants'
|
||||||
require 'about_control_statements'
|
require 'about_control_statements'
|
||||||
require 'about_true_and_false'
|
require 'about_true_and_false'
|
||||||
require 'about_triangle_project'
|
require 'about_triangle_project'
|
||||||
|
|||||||
Reference in New Issue
Block a user