Every repository with this icon (
Every repository with this icon (
Example Usage
Create a .doctest document, for example, “simple.doctest”, and begin documenting your application, like this:
Here is an example doctest file (say called simple.doctest):
This is an example test that succeeds
>> 1 + 2
=> 3
And here’s a test that will fail
>> 1 + 2
=> 4
Test a some multiline statements
>> class Person
attr_accessor :name
end
>> Person
=> Person
>> p = Person.new
>> p.name = “Tom”
>> p.name
=> “Tom”
doctest: you split a file into separate named tests by adding a doctest: directive
>> 1 + 2
=> 4
Or, put your pastes in as comments within your ruby code, say, factorial.rb, like this:
- doctest: factorial should give correct results for 0 to 2
- >> factorial(0)
- => 1
- >> factorial(1)
- => 1
#
- comments describing the parameters can be included
- this is how it works with 2:
- >> factorial(2)
- => 2
def factorial(n)
if n == 0
1
else
n * factorial(n-1)
end
end
#
- doctest: should work for 3, too
- >> factorial(3)
- => 6
When the above code is run, i.e. with the command “rubydoctest factorial.rb”, it shows the following results:
=== Testing 'factorial.rb'...
OK | factorial should give correct results for 0 to 3
OK | should work for 3, too
6 comparisons | 2 doctests | 0 failures | 0 errors
You can do multiline statements like this, as long as the indentation level is greater than the >> start line (note that ‘end’ is at an unnatural indentation level):
# >> all_true = true
# >> 3.times do |t|
# all_true &&= (a[t] == b[t])
# end
# >> all_true
# => true
Here’s a more advanced usage example, in a Rails model, book.rb:
require File.join(File.dirname(__FILE__), "..", "rubydoctest_helper")
class Book < ActiveRecord::Base
- === Description
- Extension for sections and chapters collections
- e.g. book.sections.approved_only, book.chapters.dirty!
- === Tests
- doctest: Sample data should provide an example of a book with both approved
- and unapproved sections.
- >> v_a_books = Book.varied(:approved)
- >> v_a_books.size > 0
- => true
- doctest: Sample data should provide an example of a book with both dirty
- and non-dirty sections.
- >> v_d_books = Book.varied(:dirty)
- >> v_d_books.size > 0
- => true
module SectionExtension
- === Tests
- doctest: Book#sections.approved_only should return approved sections,
- including first-level sections, i.e “chapters”.
- >> s = v_a_books.first.sections.approved_only
- >> s.size > 1
- => true
- >> s.any?{ |t| t.approved? }
- => true
- >> s.any?{ |t| !t.approved? }
- => false
def approved_only
self.select{ |s| s.approved? }
end
- === Tests
- doctest: Book#sections.unapproved_only should return unapproved sections,
- including first-level sections, i.e “chapters”.
- >> s = v_a_books.first.sections.unapproved_only
- >> s.size > 1
- => true
- >> s.any?{ |t| t.approved? }
- => false
- >> s.any?{ |t| !t.approved? }
- => true
def unapproved_only
self.select{ |s| !s.approved? }
end
- === Tests
- doctest: Book#sections.dirty! should set the dirty flag for sections
- specific to the particular book it was called on.
- >> book = v_d_books.first
- >> (yes = book.sections.count(:conditions => [“dirty = ?”, true])) > 0
- => true
- >> (no = book.sections.count(:conditions => [“dirty = ?”, false])) > 0
- => true
- >> v_d_books.first.sections.dirty!
- >> book.sections.count(:conditions => [“dirty = ?”, true])
- => yes + no
- >> book.sections.count(:conditions => [“dirty = ?”, false])
- => 0
def dirty!
self.update_all [“dirty = ?”, true]
end
end
has_many :sections, :extend => SectionExtension
- === Description
- Find books with a diverse set of sections with a certain property.
- === Examples
- @see SectionExtension module
def self.varied(field, min = 2)
find_by_sql \
“SELECT * FROM books WHERE id IN
(SELECT book_id FROM sections
GROUP BY book_id
HAVING COUNT >= #{min})”
end
end
See the Rails Usage page for more information about the rubydoctest_helper script mentioned above.
In each case, you run your tests using the rubydoctest command-line tool, e.g.:
$ rubydoctest doc/sample.doctest
$ rubydoctest factorial.rb
$ rubydoctest app/models/book.rb
Note also that you can use =begin and =end to suround the tests, ex: factorial.rb
def factorial(n)
if n == 0
1
else
n * factorial(n-1)
end
end
=begin
doctest: fact
>> factorial(0)
=> 1
=end
And that tests can be interspersed with comments, a la
- doctest: factial 0 is 1
- >> factorial(0)
- => 1
#
- These numbers grow much larger with a higher n:
#
- >> factorial(10)
- => 3628800
And since your test code and comments will appear in the rdocs, you’ve made instant documentation for parameters to your functions.
And all it cost was a copy and past from an irb session.







