Created
July 11, 2011 12:29
-
-
Save peterc/1075747 to your computer and use it in GitHub Desktop.
testrocket: My entry to the CodeBrawl.com "Ruby testing libraries" contest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TestRocket is a simple, tiny testing library for Ruby 1.9. | |
If => in a hash is a "hash rocket", then +-> and --> for tests should be | |
"test rockets"! | |
Simple syntax: | |
+-> { block that should succeed } | |
--> { block that should fail } | |
These tests would both pass: | |
+-> { 2 == 2 } | |
--> { 10 / 0 } | |
See the demonstration test "suite" for more. | |
Unique features (I hope): | |
* Unary plus/minus to denote expectations. | |
* Ability to fit the entire library into a single tweet/single line. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# A SINGLE FILE CONTAINING THE TEST LIBRARY | |
# A CLASS TO TEST, AND THE TESTS THEMSELVES | |
# =========================================================== | |
# TESTROCKET TESTING LIBRARY | |
module TestRocket | |
def _test(a, b) | |
send((call rescue()) ? a : b) | |
end | |
def +@; puts _test :_pass, :_fail; end | |
def -@; puts _test :_fail, :_pass; end | |
def _pass; ' OK'; end | |
def _fail; " FAIL @ #{source_location.join(':')}"; end | |
end | |
Proc.send :include, TestRocket | |
# A functionally equivalent single liner. I figured you'd rather be able to read the code and output though. | |
# class Proc;def _t;call rescue();end;def +@;p _t ? '.' : _f; end;def -@; p _t ? _f : '.'; end;def _f; "F "+to_s;end;end | |
# =========================================================== | |
# "DIE" - Simple dice simulator for us to test | |
class Die | |
attr_reader :sides | |
def initialize(sides = 6) | |
raise ArgumentError if sides < 2 | |
@sides = sides | |
end | |
def roll | |
rand(@sides) + 1 | |
end | |
end | |
# =========================================================== | |
# EXAMPLE TEST "SUITE" FOR "DIE" | |
# | |
# USAGE | |
# +-> { block that should succeed } | |
# --> { block that should fail } | |
+-> { Die.new(2) } | |
--> { Die.new(1) } | |
+-> { (1..6) === Die.new(6).roll } | |
+-> { Die.new.sides == 6 } | |
+-> { die = Die.new(6) | |
1000.times { raise unless (1..6) === die.roll } } | |
+-> { die = Die.new(6) | |
1000.times { raise if die.roll.zero? } } | |
# These two tests will deliberately fail | |
+-> { raise } | |
--> { true } |
I like this approach and extended this test suite a litte bit (with "description" and "pending" operators).
Woah, I haven't seen the @
part of the method definition before. What's the deal with it? Does it only work for Procs?
Would someone be so kind as to point me to the documentation for it? It's one of those things that's hard to Google...
@peterbrowne I haven't seen it before also. Some googling led me to know it's overloading the unary method definition.
It means you can to things like
class String
def !@
"!! " << self << " !!"
end
end
! "Hello World" # output => "!! Hello World !!"
The @
is for the (four) unary operators, which can be overloaded.
Maybe we should read !@
like "operator in front of object", wrote another example code for showing differences.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Awesome!