<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>PaulBarry.com - A Ruby Test Framework in One Line</title>
  <subtitle type="html">My thoughts, ideas, questions and concerns on technology, sports, music and life</subtitle>
  <id>tag:paulbarry.com,2007:Paulbarry.com</id>
  <generator uri="http://www.paulbarry.com" version="3.0">PaulBarry.com</generator>
  <link href="http://paulbarry.com/xml/atom/article/4901/feed.xml" rel="self" type="application/atom+xml"/>
  <link href="http://paulbarry.com/articles/2008/05/23/a-ruby-test-framework-in-one-line" rel="alternate" type="text/html"/>

  <updated>2008-11-06T00:06:29-05:00</updated>
  <entry>
    <author>
      <name>Paul Barry</name>
      <email>mail@paulbarry.com</email>
    </author>
    <id>urn:uuid:8ecccd7b-ccd8-428a-8528-ced8a518175a</id>

    <published>2008-05-23T11:17:48-04:00</published>
    <updated>2008-05-23T11:17:48-04:00</updated>
    <title type="html">A Ruby Test Framework in One Line</title>
    <link href="http://paulbarry.com/articles/2008/05/23/a-ruby-test-framework-in-one-line" rel="alternate" type="text/html"/>

    <category term="technology" scheme="http://paulbarry.com/articles/category/technology" label="Technology"/>
        <category term="Ruby" scheme="http://paulbarry.com/articles/tag/ruby"/>
        <summary type="html">&lt;p&gt;Time for a little Friday fun with Ruby.  I love Ruby for things like this.  I realize this has little practical usage, but the fact that it&apos;s possible says a lot about the language.  You can build a test &quot;framework&quot; in one line of code in Ruby.  Let&apos;s say we are going to write a method that take 0 to n arguments and adds them up.  So following TDD, we write the tests first: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tests = {
  &quot;sum&quot; =&amp;gt; 0,
  &quot;sum(7)&quot; =&amp;gt; 7,
  &quot;sum(2, 3)&quot; =&amp;gt; 5,
  &quot;sum(2, 3, 5)&quot; =&amp;gt; 10
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The tests are defined in a hash where the key is the code to be tested in a string and the value is the expected result.  Next we write our implementation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def sum(*args)
  (args || 0).inject(0){|s,e| s+e}
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally, we create and execute our test framework in one line of code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tests.each{|e,v| puts((r=eval(e))==v ? &quot;. #{e}&quot; : &quot;! #{e} was &apos;#{r}&apos;, expected &apos;#{v}&apos;&quot;)}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The output looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;. sum
. sum(2, 3, 5)
. sum(7)
. sum(2, 3)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If we change one of our tests to show a failure, you get this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;. sum
. sum(2, 3, 5)
. sum(7)
! sum(2, 3) was &apos;5&apos;, expected &apos;8&apos;
&lt;/code&gt;&lt;/pre&gt;
</summary>
    <content type="html">&lt;p&gt;Time for a little Friday fun with Ruby.  I love Ruby for things like this.  I realize this has little practical usage, but the fact that it&apos;s possible says a lot about the language.  You can build a test &quot;framework&quot; in one line of code in Ruby.  Let&apos;s say we are going to write a method that take 0 to n arguments and adds them up.  So following TDD, we write the tests first: &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tests = {
  &quot;sum&quot; =&amp;gt; 0,
  &quot;sum(7)&quot; =&amp;gt; 7,
  &quot;sum(2, 3)&quot; =&amp;gt; 5,
  &quot;sum(2, 3, 5)&quot; =&amp;gt; 10
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The tests are defined in a hash where the key is the code to be tested in a string and the value is the expected result.  Next we write our implementation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def sum(*args)
  (args || 0).inject(0){|s,e| s+e}
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally, we create and execute our test framework in one line of code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tests.each{|e,v| puts((r=eval(e))==v ? &quot;. #{e}&quot; : &quot;! #{e} was &apos;#{r}&apos;, expected &apos;#{v}&apos;&quot;)}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The output looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;. sum
. sum(2, 3, 5)
. sum(7)
. sum(2, 3)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If we change one of our tests to show a failure, you get this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;. sum
. sum(2, 3, 5)
. sum(7)
! sum(2, 3) was &apos;5&apos;, expected &apos;8&apos;
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <author>
      <name>Ryan Davis</name>
    </author>
    <id>urn:uuid:bf5e20a7-a1e2-4ac2-ac56-cdf5206dee3d</id>
    <published>2008-05-23T19:19:41-04:00</published>
    <updated>2008-05-23T19:19:41-04:00</updated>
    <title type="html">Comment on "A Ruby Test Framework in One Line" by Ryan Davis</title>
    <link href="http://paulbarry.com/articles/2008/05/23/a-ruby-test-framework-in-one-line#comment-5141" rel="alternate" type="text/html"/>
    <content type="html">cute! I like the simplicity of the runner.&lt;br/&gt;&lt;br/&gt;But your impl looks flawed.... shouldn&apos;t it be:&lt;br/&gt;&lt;br/&gt;    args.inject(0) {|s,e| s+e}&lt;br/&gt;&lt;br/&gt;the || 0 part would only help you if you explicitly passed in nil or false. You might as well blow up if they&apos;re passing in bad data.</content>
  </entry>
  <entry>
    <author>
      <name>Paul Barry</name>
    </author>
    <id>urn:uuid:f187c186-85a2-4f4c-81d6-78f12dcc983c</id>
    <published>2008-05-23T21:09:03-04:00</published>
    <updated>2008-05-23T21:09:03-04:00</updated>
    <title type="html">Comment on "A Ruby Test Framework in One Line" by Paul Barry</title>
    <link href="http://paulbarry.com/articles/2008/05/23/a-ruby-test-framework-in-one-line#comment-5142" rel="alternate" type="text/html"/>
    <content type="html">@Ryan&lt;br/&gt;&lt;br/&gt;Good point, for some reason I was thinking that passing no args would mean that args would be nil, but it is an empty array.  I think this is the right implementation:&lt;br/&gt;&lt;br/&gt;args.inject(0){|s,e| s+e.to_i}&lt;br/&gt;&lt;br/&gt;Which allows sum(nil, &amp;quot;1&amp;quot;, 2) to return 3, which of course I was easily able to add a test for.  Yay for TDD!</content>
  </entry>
  <entry>
    <author>
      <name>Fran&#231;ois Vaux</name>
    </author>
    <id>urn:uuid:caedf0ec-8437-481b-a544-eba2ee29d025</id>
    <published>2008-05-30T05:23:09-04:00</published>
    <updated>2008-05-30T05:23:09-04:00</updated>
    <title type="html">Comment on "A Ruby Test Framework in One Line" by Fran&#231;ois Vaux</title>
    <link href="http://paulbarry.com/articles/2008/05/23/a-ruby-test-framework-in-one-line#comment-5145" rel="alternate" type="text/html"/>
    <content type="html">Nice one-liner :-)&lt;br/&gt;&lt;br/&gt;I&apos;ve been inspired by this and built a more robust one, but it&apos;s 20 lines long :P&lt;br/&gt;&lt;br/&gt;def MTest(tests)&lt;br/&gt;  if tests[0].is_a?(String) then puts tests.shift end&lt;br/&gt;  threads = []&lt;br/&gt;  results = {:pass =&amp;gt; 0, :fail =&amp;gt; 0, :err =&amp;gt; 0}&lt;br/&gt;  tests.each do |t|&lt;br/&gt;    e,p,v = *t&lt;br/&gt;    threads &amp;lt;&amp;lt; Thread.new do&lt;br/&gt;      begin&lt;br/&gt;        puts(if (r = p.call) == v&lt;br/&gt;          results[:pass] += 1&lt;br/&gt;          &amp;quot;. #{e}&amp;quot;&lt;br/&gt;        else&lt;br/&gt;          results[:fail] += 1&lt;br/&gt;          &amp;quot;! #{e} was #{r}, expected #{v}&amp;quot;&lt;br/&gt;        end)&lt;br/&gt;      rescue =&amp;gt; x&lt;br/&gt;        results[:err] += 1&lt;br/&gt;        puts &amp;quot;@ #{x.class} at line #{x.backtrace[0].split(&apos;:&apos;)[1]}&amp;quot;&lt;br/&gt;      end&lt;br/&gt;    end&lt;br/&gt;  end&lt;br/&gt;  threads.join&lt;br/&gt;  results&lt;br/&gt;end&lt;br/&gt;&lt;br/&gt;This allows you many tricks like naming your tests, don&apos;t abort on exceptions but show a notice and get a summary for your tests.</content>
  </entry>
  <entry>
    <author>
      <name>Fran&#231;ois Vaux</name>
    </author>
    <id>urn:uuid:3db3bbd9-7f0c-4488-baef-cc545f94dae9</id>
    <published>2008-05-30T05:25:09-04:00</published>
    <updated>2008-05-30T05:25:09-04:00</updated>
    <title type="html">Comment on "A Ruby Test Framework in One Line" by Fran&#231;ois Vaux</title>
    <link href="http://paulbarry.com/articles/2008/05/23/a-ruby-test-framework-in-one-line#comment-5146" rel="alternate" type="text/html"/>
    <content type="html">I forgot to notice that the test format is now as follows : &lt;br/&gt;&lt;br/&gt;tests = [&lt;br/&gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;quot;= Some Basic Tests =&amp;quot;,&lt;br/&gt;&amp;amp;nbsp;&amp;amp;nbsp;[&apos;true&apos;, proc { true }, true],&lt;br/&gt;&amp;amp;nbsp;&amp;amp;nbsp;[&apos;true&apos;, proc { false }, true],&lt;br/&gt;&amp;amp;nbsp;&amp;amp;nbsp;[&apos;sum(2,5)&apos;, proc { sum(2,5) }, 7]&lt;br/&gt;]&lt;br/&gt;&lt;br/&gt;And you just have to call MTest(tests)&lt;br/&gt;&lt;br/&gt;(sorry for screwing the indent in my last post)</content>
  </entry>
  <entry>
    <author>
      <name>Kerry Gunther</name>
    </author>
    <id>urn:uuid:5ff8b6e6-cc20-4a91-b64b-10734199c4a7</id>
    <published>2008-08-05T15:55:53-04:00</published>
    <updated>2008-08-05T15:55:53-04:00</updated>
    <title type="html">Comment on "A Ruby Test Framework in One Line" by Kerry Gunther</title>
    <link href="http://paulbarry.com/articles/2008/05/23/a-ruby-test-framework-in-one-line#comment-5170" rel="alternate" type="text/html"/>
    <content type="html">outstanding!</content>
  </entry>
  </feed>