Eric Hodel wrote:

>>>If you've got a spec like this, why not write a method to autogenerate
>>>test methods?
>> it adds an additional step in the Makefile/build process. 
> No additional steps.  Ruby does it for you:
> 
> require 'test/unit'
> 
> def my_meth(args)
>   args.inject 0 do |acc, item|
>     acc + item
>   end
> end
> 
> class MyTest < Test::Unit::TestCase
> 
>   SPEC_ONE = [[1, 1, 1], 3]
>   SPEC_TWO = [[8, 1, 2], 11]
>   SPEC_THREE = [[8, 3, 4], 15]
>   SPEC_FOUR = [[4, 3, 2], 9]
> 
>   constants.each do |name|
>     next unless name =~ /^SPEC_(.*)/
> 
>     eval "def test_#{$1.downcase}
>       input = self.class.const_get(\"#{name}\")[0]
>       output = self.class.const_get(\"#{name}\")[1]
>       assert_equal output, my_meth(input)
>     end"
>   end
> end

Note that you don't need eval() to do this:

def my_meth(*args)
   args.inject(0) do |state, item|
     state + item
   end
end

class MyTest < Test::Unit::TestCase
   # This is an Array of Arrays of Arrays -- we should really use
   # something with more implicit semantics instead.
   Specs = [
     [[8, 1, 1], 3],
     [[8, 1, 2], 11],
     [[8, 3, 4], 15],
     [[4, 3, 2], 9]
   ]

   Specs.each_with_index do |(input, output), index|
     define_method(:"test_spec_#{index}") do
       assert_equal(output, my_meth(*input))
     end
   end
end

Regards,
Florian Gross