29 Commits

Author SHA1 Message Date
Jim Weirich
db3bbdcf45 Better test name in the java interop koan 2010-12-23 15:04:16 -05:00
Jim Weirich
1a0d82a402 Added .rbc to clean list. 2010-12-23 12:28:39 -05:00
Jim Weirich
c8b4c3e6c5 [5458710] Added koans about to_str 2010-12-23 12:28:24 -05:00
Jim Weirich
204cd44ea9 [5462710] Fixed equality koan on symbols. 2010-12-23 12:08:03 -05:00
Jim Weirich
325ad5bce3 Result summary now in order of running. 2010-12-23 11:54:41 -05:00
Jim Weirich
b733076165 Added .rbc to ignore list 2010-12-23 11:48:40 -05:00
Jim Weirich
5e9083e754 Remove dbgs from Rakefile 2010-12-23 11:48:15 -05:00
Jim Weirich
ab59dc4791 Merge branch 'more_jruby' into m
* more_jruby:
  [5553333] Updated java interop on to_java method.
  Added cruise task
  java coercion
2010-12-23 11:46:29 -05:00
Jim Weirich
ccfa664b48 [5553333] Updated java interop on to_java method. 2010-12-23 11:45:46 -05:00
Jim Weirich
9b9eb640f8 Added cruise task 2010-12-23 11:29:39 -05:00
Jim Weirich
297cfde6a3 [7439987] Changed symbol inclusion test to use strings. 2010-12-23 10:16:34 -05:00
Jim Weirich
3dab146b8d Added --/++ markers around the dice class. 2010-12-23 09:26:55 -05:00
Marc Peabody
0b9727f299 fix mistake in about_symbols.rb 2010-12-14 09:12:49 -05:00
Jim Weirich
d3ce64a768 Updatd exception koan to be clearer about StandardError VS RuntimeError 2010-11-29 09:02:22 -05:00
Luke Pearce
9291f534c6 Fixed exceptions typo 2010-11-29 13:24:40 +00:00
Jim Weirich
71f670ac1d Disabled colored output on windows. 2010-10-21 07:05:06 -04:00
Jim Weirich
1864c9c346 Updated koans for about_symbols fix 2010-10-21 07:04:54 -04:00
Jim Weirich
cfd5b6bbe1 Fixed test_symbols_with_spaces_can_be_built method name collision. 2010-10-21 07:02:10 -04:00
Marc Peabody
e26666280c java coercion 2010-10-02 10:11:18 -04:00
Jim Weirich
e5843f64fd Fixed bug where some koans were not generated properly. 2010-10-01 11:05:25 -04:00
Jim Weirich
fdb8774c95 Added Java Interop koans if running jruby. 2010-09-28 14:49:43 -04:00
Jim Weirich
5b483df29b Added descriptions to rake tasks. 2010-09-28 14:49:20 -04:00
Jim Weirich
7dee146a8c Added missing __ replacements 2010-09-28 14:49:06 -04:00
Jim Weirich
e24d94eeff Updated koans from source. 2010-09-28 14:43:34 -04:00
Jim Weirich
4789e831df Added enumerable collections and open java classes to jruby koan. 2010-09-28 14:43:03 -04:00
Jim Weirich
b41d6167b4 Updated koans from src. 2010-09-28 14:17:46 -04:00
Jim Weirich
c0bbe773d9 Moved splat example to later + several typo corrections. 2010-09-28 14:15:08 -04:00
Srdjan Pejic
6fb8e3c3af Cool test; Still can't believe there is no standard implementation of first/rest 2010-09-28 14:11:08 -04:00
Marc Peabody + Jim Weirich
1dcd9babd4 Added more think about its to the ruby/java string comparisons. 2010-09-27 18:24:25 -04:00
28 changed files with 514 additions and 63 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
dist
.project_env.rc
.path_progress
*.rbc

View File

@@ -15,6 +15,7 @@ today = Time.now.strftime("%Y-%m-%d")
TAR_FILE = "#{DIST_DIR}/rubykoans-#{today}.tgz"
ZIP_FILE = "#{DIST_DIR}/rubykoans-#{today}.zip"
CLEAN.include("**/*.rbc")
CLOBBER.include(DIST_DIR)
module Koans
@@ -57,6 +58,27 @@ module Koans
end
end
module RubyImpls
# Calculate the list of relevant Ruby implementations.
def self.find_ruby_impls
rubys = `rvm list`.gsub(/=>/,'').split(/\n/).sort
expected.map { |impl|
last = rubys.grep(Regexp.new(Regexp.quote(impl))).last
last ? last.split.first : nil
}.compact
end
# Return a (cached) list of relevant Ruby implementations.
def self.list
@list ||= find_ruby_impls
end
# List of expected ruby implementations.
def self.expected
%w(ruby-1.8.6 ruby-1.8.7 ruby-1.9.2 jruby ree)
end
end
task :default => :walk_the_path
task :walk_the_path do
@@ -107,3 +129,38 @@ SRC_FILES.each do |koan_src|
Koans.make_koan_file koan_src, t.name
end
end
task :run do
puts 'koans'
Dir.chdir("src") do
puts "in #{Dir.pwd}"
sh "ruby path_to_enlightenment.rb"
end
end
desc "Pre-checkin tests (=> run_all)"
task :cruise => :run_all
desc "Run the completed koans againts a list of relevant Ruby Implementations"
task :run_all do
results = []
RubyImpls.list.each do |impl|
puts "=" * 40
puts "On Ruby #{impl}"
sh "rvm #{impl} rake run"
results << [impl, "RAN"]
puts
end
puts "=" * 40
puts "Summary:"
puts
results.each do |impl, res|
puts "#{impl} => RAN"
end
puts
RubyImpls.expected.each do |requested_impl|
impl_pattern = Regexp.new(Regexp.quote(requested_impl))
puts "No Results for #{requested_impl}" unless results.detect { |x| x.first =~ impl_pattern }
end
end

View File

@@ -18,13 +18,19 @@ class AboutArrayAssignment < EdgeCase::Koan
assert_equal __, last_name
end
def test_parallel_assignments_with_extra_variables
def test_parallel_assignments_with_splat_operator
first_name, *last_name = ["John", "Smith", "III"]
assert_equal __, first_name
assert_equal __, last_name
end
def test_parallel_assignments_with_too_few_variables
first_name, last_name = ["Cher"]
assert_equal __, first_name
assert_equal __, last_name
end
def test_parallel_assignements_with_subarrays
def test_parallel_assignments_with_subarrays
first_name, last_name = [["Willie", "Rae"], "Johnson"]
assert_equal __, first_name
assert_equal __, last_name

View File

@@ -45,9 +45,9 @@ class AboutArrays < EdgeCase::Koan
end
def test_arrays_and_ranges
assert_equal Range, (1..5).class
assert_equal __, (1..5).class
assert_not_equal [1,2,3,4,5], (1..5)
assert_equal [1,2,3,4,5], (1..5).to_a
assert_equal __, (1..5).to_a
assert_equal __, (1...5).to_a
end

View File

@@ -130,7 +130,7 @@ class AboutClasses < EdgeCase::Koan
fido = Dog6.new("Fido")
rover = Dog6.new("Rover")
assert_not_equal rover.name, fido.name
assert_equal __, rover.name != fido.name
end
# ------------------------------------------------------------------
@@ -164,12 +164,12 @@ class AboutClasses < EdgeCase::Koan
def test_to_s_provides_a_string_version_of_the_object
fido = Dog7.new("Fido")
assert_equal "Fido", fido.to_s
assert_equal __, fido.to_s
end
def test_to_s_is_used_in_string_interpolation
fido = Dog7.new("Fido")
assert_equal "My dog is Fido", "My dog is #{fido}"
assert_equal __, "My dog is #{fido}"
end
def test_inspect_provides_a_more_complete_string_version

View File

@@ -1,11 +1,10 @@
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
class DiceSet
attr_reader :values
def roll(n)
@values = (1..n).map { rand(6) + 1 }
end
end
# Implement a DiceSet Class here:
#
# class DiceSet
# code ...
# end
class AboutDiceProject < EdgeCase::Koan
def test_can_create_a_dice_set

View File

@@ -22,8 +22,8 @@ class AboutExceptions < EdgeCase::Koan
assert_equal __, result
assert ex.is_a?(StandardError), "Failure message."
assert ex.is_a?(RuntimeError), "Failure message."
assert_equal __, ex.is_a?(StandardError), "Should be a Standard Error"
assert_equal __, ex.is_a?(RuntimeError), "Should be a Runtime Error"
assert RuntimeError.ancestors.include?(StandardError),
"RuntimeError is a subclass of StandardError"

View File

@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/edgecase')
class AboutHashes < EdgeCase::Koan
def test_creating_hashes
empty_hash = Hash.new
assert_equal Hash, empty_hash.class
assert_equal __, empty_hash.class
assert_equal({}, empty_hash)
assert_equal __, empty_hash.size
end
@@ -25,7 +25,7 @@ class AboutHashes < EdgeCase::Koan
hash[:one] = "eins"
expected = { :one => __, :two => "dos" }
assert_equal expected, hash
assert_equal __, expected == hash
# Bonus Question: Why was "expected" broken out into a variable
# rather than used as a literal?
@@ -35,7 +35,7 @@ class AboutHashes < EdgeCase::Koan
hash1 = { :one => "uno", :two => "dos" }
hash2 = { :two => "dos", :one => "uno" }
assert_equal hash1, hash2
assert_equal __, hash1 == hash2
end
def test_hash_keys
@@ -43,7 +43,7 @@ class AboutHashes < EdgeCase::Koan
assert_equal __, hash.keys.size
assert_equal __, hash.keys.include?(:one)
assert_equal __, hash.keys.include?(:two)
assert_equal Array, hash.keys.class
assert_equal __, hash.keys.class
end
def test_hash_values
@@ -51,16 +51,16 @@ class AboutHashes < EdgeCase::Koan
assert_equal __, hash.values.size
assert_equal __, hash.values.include?("uno")
assert_equal __, hash.values.include?("dos")
assert_equal Array, hash.values.class
assert_equal __, hash.values.class
end
def test_combining_hashes
hash = { "jim" => 53, "amy" => 20, "dan" => 23 }
new_hash = hash.merge({ "jim" => 54, "jenny" => 26 })
assert_not_equal hash, new_hash
assert_equal __, hash != new_hash
expected = { "jim" => __, "amy" => 20, "dan" => 23, "jenny" => __ }
assert_equal expected, new_hash
assert_equal __, expected == new_hash
end
end

View File

@@ -12,7 +12,7 @@ class AboutIteration < EdgeCase::Koan
array.each do |item|
sum += item
end
assert_equal 6, sum
assert_equal __, sum
end
def test_each_can_use_curly_brace_blocks_too

137
koans/about_java_interop.rb Normal file
View File

@@ -0,0 +1,137 @@
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
include Java
# Concepts
# * Pull in a java class
# * calling a method, Camel vs snake
# * Resovling module/class name conflicts
# * Showing what gets returned
# * Ruby Strings VS Java Strings
# * Calling custom java class
# * Calling Ruby from java???
class AboutJavaInterop < EdgeCase::Koan
def test_using_a_java_library_class
java_array = java.util.ArrayList.new
assert_equal __, java_array.class
end
def test_java_class_can_be_referenced_using_both_ruby_and_java_like_syntax
assert_equal __, Java::JavaUtil::ArrayList == java.util.ArrayList
end
def test_include_class_includes_class_in_module_scope
assert_nil defined?(TreeSet)
include_class "java.util.TreeSet"
assert_equal __, defined?(TreeSet)
end
# THINK ABOUT IT:
#
# What if we use:
#
# include_class "java.lang.String"
#
# What would be the value of the String constant after this
# include_class is run? Would it be useful to provide a way of
# aliasing java classes to different names?
JString = java.lang.String
def test_also_java_class_can_be_given_ruby_aliases
java_string = JString.new("A Java String")
assert_equal __, java_string.class
assert_equal __, JString
end
def test_can_directly_call_java_methods_on_java_objects
java_string = JString.new("A Java String")
assert_equal __, java_string.toLowerCase
end
def test_jruby_provides_snake_case_versions_of_java_methods
java_string = JString.new("A Java String")
assert_equal __, java_string.to_lower_case
end
def test_jruby_provides_question_mark_versions_of_boolean_methods
java_string = JString.new("A Java String")
assert_equal __, java_string.endsWith("String")
assert_equal __, java_string.ends_with("String")
assert_equal __, java_string.ends_with?("String")
end
def test_java_string_are_not_ruby_strings
ruby_string = "A Java String"
java_string = java.lang.String.new(ruby_string)
assert_equal __, java_string.is_a?(java.lang.String)
assert_equal __, java_string.is_a?(String)
end
def test_java_strings_can_be_compared_to_ruby_strings_maybe
ruby_string = "A Java String"
java_string = java.lang.String.new(ruby_string)
assert_equal __, ruby_string == java_string
assert_equal __, java_string == ruby_string
# THINK ABOUT IT:
#
# Is there any possible way for this to be more wrong?
#
# SERIOUSLY, THINK ABOUT IT:
#
# Why do you suppose that Ruby and Java strings compare like that?
#
# ADVANCED THINK ABOUT IT:
#
# Is there a way to make Ruby/Java string comparisons commutative?
# How would you do it?
end
def test_however_most_methods_returning_strings_return_ruby_strings
java_array = java.util.ArrayList.new
assert_equal __, java_array.toString
assert_equal __, java_array.toString.is_a?(String)
assert_equal __, java_array.toString.is_a?(java.lang.String)
end
def test_some_ruby_objects_can_be_coerced_to_java
assert_equal __, "ruby string".to_java.class
assert_equal __, 1.to_java.class
assert_equal __, 9.32.to_java.class
assert_equal __, false.to_java.class
end
def test_some_ruby_objects_are_not_coerced_to_what_you_might_expect
assert_equal __, [].to_java.class == Java::JavaUtil::ArrayList
assert_equal __, {}.to_java.class == Java::JavaUtil::HashMap
assert_equal __, Object.new.to_java.class == Java::JavaLang::Object
end
def test_java_collections_are_enumerable
java_array = java.util.ArrayList.new
java_array << "one" << "two" << "three"
assert_equal __, java_array.map { |item| item.upcase }
end
# ------------------------------------------------------------------
# Open the Java ArrayList class and add a new method.
class Java::JavaUtil::ArrayList
def multiply_all
result = 1
each do |item|
result *= item
end
result
end
end
def test_java_class_are_open_from_ruby
java_array = java.util.ArrayList.new
java_array.add_all([1,2,3,4,5])
assert_equal __, java_array.multiply_all
end
end

View File

@@ -36,12 +36,12 @@ class AboutMethods < EdgeCase::Koan
exception = assert_raise(___) do
my_global_method
end
assert_match(/#{__ of arguments")}/, exception.message)
assert_match(/__/, exception.message)
exception = assert_raise(___) do
my_global_method(1,2,3)
end
assert_match(/#{__ of arguments")}/, exception.message)
assert_match(/__/, exception.message)
end
# ------------------------------------------------------------------

View File

@@ -3,11 +3,11 @@ 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
assert_equal __, /pattern/.class
end
def test_a_regexp_can_search_a_string_for_matching_content
assert_equal "match", "some matching content"[/match/]
assert_equal __, "some matching content"[/match/]
end
def test_a_failed_match_returns_nil

View File

@@ -29,8 +29,8 @@ class AboutScope < EdgeCase::Koan
assert_equal __, fido.identify
assert_equal __, rover.identify
assert_not_equal fido.class, rover.class
assert_not_equal Jims::Dog, Joes::Dog
assert_equal __, fido.class != rover.class
assert_equal __, Jims::Dog != Joes::Dog
end
# ------------------------------------------------------------------

View File

@@ -11,8 +11,8 @@ class AboutSymbols < EdgeCase::Koan
symbol2 = :a_symbol
symbol3 = :something_else
assert symbol1 == __
assert symbol1 != __
assert_equal __, symbol1 == symbol2
assert_equal __, symbol1 == symbol3
end
def test_identical_symbols_are_a_single_internal_object
@@ -24,14 +24,14 @@ class AboutSymbols < EdgeCase::Koan
end
def test_method_names_become_symbols
all_symbols = Symbol.all_symbols
assert_equal __, all_symbols.include?(:test_method_names_become_symbols)
symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
assert_equal __, symbols_as_strings.include?("test_method_names_become_symbols")
end
# THINK ABOUT IT:
#
# Why do we capture the list of symbols before we check for the
# method name?
# Why do we convert the list of symbols to strings and then compare
# against the string value rather than against symbols?
in_ruby_version("mri") do
RubyConstant = "What is the sound of one hand clapping?"
@@ -53,7 +53,7 @@ class AboutSymbols < EdgeCase::Koan
assert_equal symbol, __.to_sym
end
def test_symbols_with_spaces_can_be_built
def test_symbols_with_interpolation_can_be_built
value = "and"
symbol = :"cats #{value} dogs"

54
koans/about_to_str.rb Normal file
View File

@@ -0,0 +1,54 @@
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
class AboutToStr < EdgeCase::Koan
class CanNotBeTreatedAsString
def to_s
"non-string-like"
end
end
def test_to_s_returns_a_string_representation
not_like_a_string = CanNotBeTreatedAsString.new
assert_equal __, not_like_a_string.to_s
end
def test_normally_objects_cannot_be_used_where_strings_are_expected
assert_raise(___) do
File.exist?(CanNotBeTreatedAsString.new)
end
end
# ------------------------------------------------------------------
class CanBeTreatedAsString
def to_s
"string-like"
end
def to_str
to_s
end
end
def test_to_str_also_returns_a_string_representation
like_a_string = CanBeTreatedAsString.new
assert_equal __, like_a_string.to_str
end
def test_to_str_allows_objects_to_be_treated_as_strings
assert_equal __, File.exist?(CanBeTreatedAsString.new)
end
# ------------------------------------------------------------------
def acts_like_a_string?(string)
string = string.to_str if string.respond_to?(:to_str)
string.is_a?(String)
end
def test_user_defined_code_can_check_for_to_str
assert_equal __, acts_like_a_string?(CanNotBeTreatedAsString.new)
assert_equal __, acts_like_a_string?(CanBeTreatedAsString.new)
end
end

View File

@@ -3,6 +3,10 @@
require 'test/unit/assertions'
# --------------------------------------------------------------------
# Support code for the Ruby Koans.
# --------------------------------------------------------------------
class FillMeInError < StandardError
end
@@ -16,6 +20,8 @@ def in_ruby_version(*versions)
yield if versions.any? { |v| ruby_version?(v) }
end
# Standard, generic replacement value.
# If value19 is given, it is used inplace of value for Ruby 1.9.
def __(value="FILL ME IN", value19=:mu)
if RUBY_VERSION < "1.9"
value
@@ -24,6 +30,7 @@ def __(value="FILL ME IN", value19=:mu)
end
end
# Numeric replacement value.
def _n_(value=999999, value19=:mu)
if RUBY_VERSION < "1.9"
value
@@ -32,10 +39,12 @@ def _n_(value=999999, value19=:mu)
end
end
# Error object replacement value.
def ___(value=FillMeInError)
value
end
# Method name replacement.
class Object
def ____(method=nil)
if method
@@ -48,7 +57,25 @@ class Object
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
@@ -66,16 +93,29 @@ module EdgeCase
end
def colorize(string, color_value)
if ENV['NO_COLOR']
string
else
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?
! using_windows?
else
ENV['ANSI_COLOR'] =~ /^(t|y)/i
end
end
def using_windows?
File::ALT_SEPARATOR
end
end
class Sensei
@@ -176,6 +216,21 @@ module EdgeCase
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
,, , ,,
: ::::, :::,
@@ -193,7 +248,7 @@ module EdgeCase
:::::::::::, ,::::::::::::
::::::::::::: ,::::::::::::
:::::::::::: Ruby Koans ::::::::::::,
:::::::::::: ,::::::::::::,
::::::::::::#{ ruby_version },::::::::::::,
:::::::::::, , ::::::::::::
,:::::::::::::, brought to you by ,,::::::::::::,
:::::::::::::: ,::::::::::::
@@ -260,7 +315,7 @@ ENDTEXT
def find_interesting_lines(backtrace)
backtrace.reject { |line|
line =~ /test\/unit\/|edgecase\.rb/
line =~ /test\/unit\/|edgecase\.rb|minitest/
}
end

View File

@@ -31,4 +31,8 @@ require 'about_scope'
require 'about_class_methods'
require 'about_message_passing'
require 'about_proxy_object_project'
require 'about_to_str'
in_ruby_version("jruby") do
require 'about_java_interop'
end
require 'about_extra_credit'

View File

@@ -15,6 +15,7 @@ namespace "check" do
puts
end
desc "Check that asserts have __ replacements"
task :asserts do
puts "Checking for asserts missing the replacement text:"
begin
@@ -28,4 +29,5 @@ namespace "check" do
end
end
desc "Run some simple consistancy checks"
task :check => ["check:abouts", "check:asserts"]

View File

@@ -18,13 +18,19 @@ class AboutArrayAssignment < EdgeCase::Koan
assert_equal __("Smith"), last_name
end
def test_parallel_assignments_with_extra_variables
def test_parallel_assignments_with_splat_operator
first_name, *last_name = ["John", "Smith", "III"]
assert_equal __("John"), first_name
assert_equal __(["Smith","III"]), last_name
end
def test_parallel_assignments_with_too_few_variables
first_name, last_name = ["Cher"]
assert_equal __("Cher"), first_name
assert_equal __(nil), last_name
end
def test_parallel_assignements_with_subarrays
def test_parallel_assignments_with_subarrays
first_name, last_name = [["Willie", "Rae"], "Johnson"]
assert_equal __(["Willie", "Rae"]), first_name
assert_equal __("Johnson"), last_name

View File

@@ -1,5 +1,12 @@
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
# Implement a DiceSet Class here:
#
# class DiceSet
# code ...
# end
#--
class DiceSet
attr_reader :values
def roll(n)
@@ -7,6 +14,7 @@ class DiceSet
end
end
#++
class AboutDiceProject < EdgeCase::Koan
def test_can_create_a_dice_set
dice = DiceSet.new

View File

@@ -22,8 +22,8 @@ class AboutExceptions < EdgeCase::Koan
assert_equal __(:exception_handled), result
assert ex.is_a?(___(StandardError)), "Failure message."
assert ex.is_a?(___(RuntimeError)), "Failure message."
assert_equal __(true), ex.is_a?(StandardError), "Should be a Standard Error"
assert_equal __(true), ex.is_a?(RuntimeError), "Should be a Runtime Error"
assert RuntimeError.ancestors.include?(StandardError), # __
"RuntimeError is a subclass of StandardError"

View File

@@ -75,7 +75,17 @@ class AboutJavaInterop < EdgeCase::Koan
assert_equal __(true), java_string == ruby_string
# THINK ABOUT IT:
#
# Is there any possible way for this to be more wrong?
#
# SERIOUSLY, THINK ABOUT IT:
#
# Why do you suppose that Ruby and Java strings compare like that?
#
# ADVANCED THINK ABOUT IT:
#
# Is there a way to make Ruby/Java string comparisons commutative?
# How would you do it?
end
def test_however_most_methods_returning_strings_return_ruby_strings
@@ -85,5 +95,43 @@ class AboutJavaInterop < EdgeCase::Koan
assert_equal __(false), java_array.toString.is_a?(java.lang.String)
end
def test_some_ruby_objects_can_be_coerced_to_java
assert_equal __(Java::JavaLang::String), "ruby string".to_java.class
assert_equal __(Java::JavaLang::Long), 1.to_java.class
assert_equal __(Java::JavaLang::Double), 9.32.to_java.class
assert_equal __(Java::JavaLang::Boolean), false.to_java.class
end
def test_some_ruby_objects_are_not_coerced_to_what_you_might_expect
assert_equal __(false), [].to_java.class == Java::JavaUtil::ArrayList
assert_equal __(false), {}.to_java.class == Java::JavaUtil::HashMap
assert_equal __(false), Object.new.to_java.class == Java::JavaLang::Object
end
def test_java_collections_are_enumerable
java_array = java.util.ArrayList.new
java_array << "one" << "two" << "three"
assert_equal __(["ONE", "TWO", "THREE"]), java_array.map { |item| item.upcase }
end
# ------------------------------------------------------------------
# Open the Java ArrayList class and add a new method.
class Java::JavaUtil::ArrayList
def multiply_all
result = 1
each do |item|
result *= item
end
result
end
end
def test_java_class_are_open_from_ruby
java_array = java.util.ArrayList.new
java_array.add_all([1,2,3,4,5])
assert_equal __(120), java_array.multiply_all
end
end

View File

@@ -43,12 +43,15 @@ class AboutMethods < EdgeCase::Koan
exception = assert_raise(___(ArgumentError)) do
my_global_method
end
assert_match(/#{__("wrong (number|#) of arguments")}/, exception.message)
#--
pattern = "wrong (number|#) of arguments"
#++
assert_match(/#{__(pattern)}/, exception.message)
exception = assert_raise(___(ArgumentError)) do
my_global_method(1,2,3)
end
assert_match(/#{__("wrong (number|#) of arguments")}/, exception.message)
assert_match(/#{__(pattern)}/, exception.message)
end
# ------------------------------------------------------------------

View File

@@ -11,8 +11,8 @@ class AboutSymbols < EdgeCase::Koan
symbol2 = :a_symbol
symbol3 = :something_else
assert symbol1 == __(symbol2)
assert symbol1 != __(symbol3)
assert_equal __(true), symbol1 == symbol2
assert_equal __(false), symbol1 == symbol3
end
def test_identical_symbols_are_a_single_internal_object
@@ -24,14 +24,14 @@ class AboutSymbols < EdgeCase::Koan
end
def test_method_names_become_symbols
all_symbols = Symbol.all_symbols
assert_equal __(true), all_symbols.include?(:test_method_names_become_symbols)
symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
assert_equal __(true), symbols_as_strings.include?("test_method_names_become_symbols")
end
# THINK ABOUT IT:
#
# Why do we capture the list of symbols before we check for the
# method name?
# Why do we convert the list of symbols to strings and then compare
# against the string value rather than against symbols?
in_ruby_version("mri") do
RubyConstant = "What is the sound of one hand clapping?"
@@ -53,7 +53,7 @@ class AboutSymbols < EdgeCase::Koan
assert_equal symbol, __("cats and dogs").to_sym
end
def test_symbols_with_spaces_can_be_built
def test_symbols_with_interpolation_can_be_built
value = "and"
symbol = :"cats #{value} dogs"

54
src/about_to_str.rb Normal file
View File

@@ -0,0 +1,54 @@
require File.expand_path(File.dirname(__FILE__) + '/edgecase')
class AboutToStr < EdgeCase::Koan
class CanNotBeTreatedAsString
def to_s
"non-string-like"
end
end
def test_to_s_returns_a_string_representation
not_like_a_string = CanNotBeTreatedAsString.new
assert_equal __("non-string-like"), not_like_a_string.to_s
end
def test_normally_objects_cannot_be_used_where_strings_are_expected
assert_raise(___(TypeError)) do
File.exist?(CanNotBeTreatedAsString.new)
end
end
# ------------------------------------------------------------------
class CanBeTreatedAsString
def to_s
"string-like"
end
def to_str
to_s
end
end
def test_to_str_also_returns_a_string_representation
like_a_string = CanBeTreatedAsString.new
assert_equal __("string-like"), like_a_string.to_str
end
def test_to_str_allows_objects_to_be_treated_as_strings
assert_equal __(false), File.exist?(CanBeTreatedAsString.new)
end
# ------------------------------------------------------------------
def acts_like_a_string?(string)
string = string.to_str if string.respond_to?(:to_str)
string.is_a?(String)
end
def test_user_defined_code_can_check_for_to_str
assert_equal __(false), acts_like_a_string?(CanNotBeTreatedAsString.new)
assert_equal __(true), acts_like_a_string?(CanBeTreatedAsString.new)
end
end

View File

@@ -93,16 +93,29 @@ module EdgeCase
end
def colorize(string, color_value)
if ENV['NO_COLOR']
string
else
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?
! using_windows?
else
ENV['ANSI_COLOR'] =~ /^(t|y)/i
end
end
def using_windows?
File::ALT_SEPARATOR
end
end
class Sensei

View File

@@ -31,4 +31,8 @@ require 'about_scope'
require 'about_class_methods'
require 'about_message_passing'
require 'about_proxy_object_project'
require 'about_to_str'
in_ruby_version("jruby") do
require 'about_java_interop'
end
require 'about_extra_credit'