public
Created

testrocket: My entry to the CodeBrawl.com "Ruby testing libraries" contest

  • Download Gist
README
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
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.
testrocket.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
# 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'm loving the test rocket idea and the lack of an assert method. Also, the specs are tiny. Awesome work! :)

Wow, that's really cool!

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.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.