Literate testing?

Discussion in 'Ruby' started by Massimiliano Mirra - bard, Aug 27, 2004.

  1. I was documenting a class and found myself often copying unit tests
    and pasting them as examples. I think I also read something about
    tests embedded in doc strings in Python. So in the interest of DRY I
    figured something like this could be desirable:

    class Calculator
    extend Literate

    example
    # Addition
    add(2, 8) == 10
    end

    def add(a, b)
    return a + b
    end
    end

    I then came up with a stupid but working proof of concept:

    class Calculator
    extend Literate

    example(__FILE__, __LINE__) do |calc|
    # Addition
    calc.add(2, 8) == 10
    end

    def add(a, b)
    return a + b
    end

    example(__FILE__, __LINE__) do |calc|
    # Integer division
    calc.div(10, 2) == 5
    end

    def div(a, b)
    return a / b + 1
    end
    end

    When examples are run as tests and a test does not pass (as the div
    example above), this is the output:

    Test passed at line 17.
    Test failed at line 27:
    # Integer division
    calc.div(10, 2) == 5

    This is the rest:

    module Literate
    def examples
    @examples ||= []
    end

    def example(file, line, &example)
    @examples ||= []
    @examples << [file, line, example]
    end
    end

    Calculator.examples.each do |file, line, example|
    c = Calculator.new
    if example.call(c)
    puts "Test passed at line #{line}."
    else
    puts "Test failed at line #{line}:"
    puts File.readlines(file)[line, 2]
    end
    end

    What do you think?



    Massimiliano
     
    Massimiliano Mirra - bard, Aug 27, 2004
    #1
    1. Advertising

  2. Massimiliano Mirra - bard wrote:
    > class Calculator
    > extend Literate
    >
    > example(__FILE__, __LINE__) do |calc|

    ...

    Since you are passing a block, you can get the file and line from it, as in:


    def get_fl(&bl)
    eval "[__FILE__, __LINE__]", bl
    end

    class Foo
    puts get_fl {}
    puts [__FILE__, __LINE__]
    end
     
    Joel VanderWerf, Aug 27, 2004
    #2
    1. Advertising

  3. Massimiliano Mirra - bard wrote:
    > I was documenting a class and found myself often copying unit tests
    > and pasting them as examples. I think I also read something about
    > tests embedded in doc strings in Python. So in the interest of DRY I
    > figured something like this could be desirable:
    >
    > class Calculator
    > extend Literate
    >
    > example
    > # Addition
    > add(2, 8) == 10
    > end
    >
    > def add(a, b)
    > return a + b
    > end
    > end
    >
    > I then came up with a stupid but working proof of concept:
    >
    > class Calculator
    > extend Literate
    >
    > example(__FILE__, __LINE__) do |calc|
    > # Addition
    > calc.add(2, 8) == 10
    > end


    Are you planning to extract the example from the source code and
    generate documentation files? This could be done using the file and line
    information and some parsing or just good guesses about indentation.
     
    Joel VanderWerf, Aug 27, 2004
    #3
  4. On Sat, Aug 28, 2004 at 05:40:33AM +0900, Massimiliano Mirra - bard wrote:
    >
    > I was documenting a class and found myself often copying unit tests
    > and pasting them as examples. I think I also read something about
    > tests embedded in doc strings in Python. So in the interest of DRY I
    > figured something like this could be desirable:
    >
    > class Calculator
    > extend Literate
    >
    > example
    > # Addition
    > add(2, 8) == 10
    > end
    >
    > def add(a, b)
    > return a + b
    > end
    > end
    >
    > I then came up with a stupid but working proof of concept:
    >
    > class Calculator
    > extend Literate
    >
    > example(__FILE__, __LINE__) do |calc|
    > # Addition
    > calc.add(2, 8) == 10
    > end


    I believe you can make it look a bit better by using Kernel#caller
    and Module#method_added; it would also be nice to generate test
    cases for Test::Unit (for instance by defining the test_* methods in
    MyClass::LiterateTests so that they can be included in a test suite
    later).

    Reminds me of Florian Groß' 'test extractor' [109712].
    It works "the other way around" though, by extracting the tests from the
    comments (similar to what you describe for Python).

    --
    Running Debian GNU/Linux Sid (unstable)
    batsman dot geo at yahoo dot com
     
    Mauricio Fernández, Aug 27, 2004
    #4
  5. Mauricio Fernández <> writes:

    > I believe you can make it look a bit better by using Kernel#caller
    > and Module#method_added;


    I confess I have absolutely no idea how. :)

    > it would also be nice to generate test
    > cases for Test::Unit (for instance by defining the test_* methods in
    > MyClass::LiterateTests so that they can be included in a test suite
    > later).


    Nice. I tried, and the last call shows test_* methods get defined,
    but Test::Unit says `No tests were specified.'.


    require "test/unit"

    module Literate
    def method_missing(id, *args, &block)
    if id.to_s =~ /example_/
    name = Regexp.last_match.post_match
    self::LiterateTests.send:)define_method, "test_#{name}".intern, &block)
    else
    super(id, *args, &block)
    end
    end
    end

    class Calculator
    extend Literate

    module LiterateTests
    end

    example_add do
    assert @calc.add(2, 8) == 10
    end

    def add(a, b)
    return a + b
    end

    example_div do
    assert @calc.div(10, 2) == 5
    end

    def div(a, b)
    return a / b + 1
    end
    end

    class TestCalculator < Test::Unit::TestCase
    include Calculator::LiterateTests

    def setup
    @calc = Calculator.new
    end
    end

    p TestCalculator.public_instance_methods
     
    Massimiliano Mirra - bard, Aug 27, 2004
    #5
  6. Joel VanderWerf <> writes:

    > Are you planning to extract the example from the source code and
    > generate documentation files?


    I'd rather say `hoping', but yes, that would be the purpose.

    > This could be done using the file and line
    > information and some parsing or just good guesses about indentation.


    Yep. Or by hacking rdoc a bit.

    Thanks for the bit on eval.

    Massimiliano
     
    Massimiliano Mirra - bard, Aug 27, 2004
    #6
  7. On Sat, Aug 28, 2004 at 07:45:33AM +0900, Massimiliano Mirra - bard wrote:
    > Mauricio Fernández <> writes:
    >
    > > I believe you can make it look a bit better by using Kernel#caller
    > > and Module#method_added;

    >
    > I confess I have absolutely no idea how. :)
    >
    > > it would also be nice to generate test
    > > cases for Test::Unit (for instance by defining the test_* methods in
    > > MyClass::LiterateTests so that they can be included in a test suite
    > > later).

    >
    > Nice. I tried, and the last call shows test_* methods get defined,
    > but Test::Unit says `No tests were specified.'.


    I think you were bitten by the IMHO bug explained in
    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/2829

    --
    Running Debian GNU/Linux Sid (unstable)
    batsman dot geo at yahoo dot com
     
    Mauricio Fernández, Aug 30, 2004
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike Maxwell

    XMLMind and Literate Programming

    Mike Maxwell, Nov 2, 2004, in forum: XML
    Replies:
    2
    Views:
    376
    Mike Maxwell
    Nov 3, 2004
  2. How to literate a const char*

    , Jul 14, 2007, in forum: C Programming
    Replies:
    2
    Views:
    350
    Christopher Benson-Manica
    Jul 15, 2007
  3. Paul Miller

    Literate programs in Python

    Paul Miller, May 13, 2008, in forum: Python
    Replies:
    6
    Views:
    314
    Marc 'BlackJack' Rintsch
    May 14, 2008
  4. Hans Georg Schaathun

    Literate Programming

    Hans Georg Schaathun, Apr 7, 2011, in forum: Python
    Replies:
    10
    Views:
    501
    Tim Arnold
    Apr 11, 2011
  5. Ruby Quiz

    [QUIZ] Literate Ruby (#102)

    Ruby Quiz, Nov 17, 2006, in forum: Ruby
    Replies:
    10
    Views:
    214
    James Edward Gray II
    Nov 22, 2006
Loading...

Share This Page