From: Piergiuliano Bossi Date: 2004-02-26T19:14:52+09:00 Subject: language contest ==> unit test framework from lisp to ruby A few days ago I made a post (rubytalk:92963 ==> [2]) about the development of a mini-framework in ruby related to unit testing and inspired by Peter Seibel [1]. Unfortunately, I have got no comments about it. Anyway, after some feedback on another mailing list from Gabriele Renzi, I have come up with the following version: **********************CUT HERE********************** def stack caller[3..-1].map {|m| m[/test_.*(?=')/]}.compact.reverse.join " " end def check(*tests) tests.map! {|t| puts "#{(v=eval(t)) ? 'pass' : 'FAIL'} ... (#{stack}) #{t.strip}"; v} combine_results(*tests) end def combine_results(*tests) tests.inject {|t1, t2| t1 && t2} end def test_plus check( "1 + 2 == 3", "1 + 2 + 3 == 6", "-1 + -3 == -4") end def test_multiply check( "2 * 2 == 4", "3 * 5 == 15") end def test_aritmetic combine_results( test_plus, test_multiply) end def test_math test_aritmetic end result = test_math puts "result=#{result}" **********************CUT HERE********************** As you can see, my ruby version looks more compact and more easily undestandable to my non-lisper eyes than Seibel's version. I have challenged a few friends to build the most compact version of the framework. There's a perl fan, a few ruby guys and a smalltalker in the arena. Constraints: *) the framework should express same functionality as Seibel's version as much as possible, nothing more, nothing less, given the peculiar limitations of the chosen language *) code should be "understandable" by the majority of participants *) if a line is longer than 70 chars then it is automatically splitted *) the program with the smallest amount of lines is the champion My version is 10 lines long, +1 for a line longer than 70 chars = 11, but I don't really participate, I'm the judge (wow!) and I'm financing the prize (some food, I think, probably pizza). A ruby guy has already anticipated that he has reached a version which is only 5 lines long. Inspired and challenged by his words I have come up with another version that based on the definition above is only 5 lines long too: **********************CUT HERE********************** def check(*tests) stack = caller.map {|m| m[/\w*(?=')/]}.compact.reverse.join " " tests.inject(true) {|ret, t| puts "#{(v=eval(t)) ? 'pass' : 'FAIL'} .... (#{stack}) #{t.strip}"; ret && v} end **********************CUT HERE********************** Doing this way there is no need of combine_results method, and several tests may be combined in one method simply using '&&' (or 'and') like the following: **********************CUT HERE********************** def test_aritmetic test_plus && test_multiply end **********************CUT HERE********************** Contest deadline is next Monday, 1st of March. I'll let you know the results, of course, but I'm curious to have your early feedback too, if possible. Ciao, Giuliano [1] - http://tinyurl.com/2b99d [2] - http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/92963 -- If you want to send me an email in the address you have to write 'p', then a dot, followed by 'bossi' at 'quinary', another dot and 'com' at last