Skip to content

Instantly share code, notes, and snippets.

@raul
Created August 23, 2010 06:46
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save raul/544948 to your computer and use it in GitHub Desktop.
Save raul/544948 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# encoding: UTF-8
#
# LearnRubyByExample:
#
# Ruby is a highly expressive programming language.
# Testing software is an expressive way to communicate how it works.
#
# In the middle of a night awake for allergy and insomnia, and some days after the 1st _why day,
# I've tried to combine Ruby and testing to help teaching ruby with some goals in mind:
#
# - it should be easy to read for non-programmers
# - it should be based in examples
# - it should run as a test suite, so all examples should work like a charm
# - it should have a few requirements (test/unit) and size (1 file, < 50 LOC)
#
# To see it working, download this gist and run the examples suite below.
#
# If you like it, fork this gist and help spreading the Ruby love out there! :D
require 'test/unit'
class LearnRubyByExample
module TestCaseTemplate
def after(&code)
@setup_code = code
end
def this_code(&code)
instance_eval &@setup_code if @setup_code
@last_result = code.call
end
def returns(expected)
assert_equal expected, @last_result
end
end
class TestCaseFactory
def self.build(description)
new_class_name = class_name(description)
eval <<-CODE
class #{new_class_name} < Test::Unit::TestCase
include LearnRubyByExample::TestCaseTemplate
end
#{new_class_name}
CODE
end
def self.class_name(string)
string.gsub(/[^a-zA-Z]/,'_') + "TestCase"
end
end
end
class String
def For_example(&code)
new_test_case_class = LearnRubyByExample::TestCaseFactory.build(self)
new_test_case_class.class_eval{ define_method "test #{self}", code }
end
alias :For_instance :For_example
alias :i_e :For_example
end
# Thanks Matz, _why, fxn and all the nice and generous Ruby people.
#
# Copyright (c) 2010 Raul Murciano
# - web: http://raul.murciano.net
# - email: raul@murciano.net
# - twitter: @happywebcoder
# - code: http://github.com/raul
#
#
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"In Ruby, everything is an object and has a class, even the numbers". For_example {
this_code {
1.class
}
returns Fixnum
}
"In Ruby, you can share code easily with modules". For_instance {
after {
module Singer
def sing(lyrics)
" ♫ ♬ #{lyrics} ♫ ♬"
end
end
class Tenor
include Singer
end
class RockStar
include Singer
end
}
this_code {
luciano = Tenor.new
luciano.sing "La donna è mobileeee"
}
returns " ♫ ♬ La donna è mobileeee ♫ ♬"
this_code {
freddy = RockStar.new
freddy.sing "Empty spaces - what are we living for?"
}
returns " ♫ ♬ Empty spaces - what are we living for? ♫ ♬"
}
"In Ruby, you can redefine a method for an object without affecting its class". For_example {
after {
class Person
def talk
"Hi there!"
end
end
@mike = Person.new
@raul = Person.new
def hi_guys
[@mike.talk, @raul.talk]
end
}
this_code{
hi_guys
}
returns ["Hi there!", "Hi there!"]
this_code{
def @raul.talk
"Hola!"
end
hi_guys
}
returns ["Hi there!", "Hola!"]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment