Special Directives

rdp edited this page Sep 14, 2010 · 4 revisions

from: doc/special_directives.doctest

Special Directives

Special directives are keywords that do something outside of the usual eval/result/compare loop. They have to go at the beginning of a line (or after a #) if Ruby DocTest is to detect it as a special directive. See below for a list of all special directives.

The “doctest:” Directive

This directive splits your irb sessions into logical “test units” with descriptions. For example:

	doctest: This is the first test.  Tests if this document is up to date with the code.
	>> RubyDocTest::SpecialDirective::NAMES
	=> ["doctest:", "!!!", "doctest_require:"]

Any irb sessions appearing before the first doctest: directive will be included in an all-encompassing “Default Test”. If you have no “doctest:” directives anywhere in your document, then all irb statements will be placed in the “Default Test”.

The “!!!” Directive

This directive opens an interactive ruby session (irb), in context, so you can play around with the variables. If you run this document, you will be prompted at the following line:

	doctest: Try playing with the 'neato' variable in the irb session
	>> neato = "Oh, I see... that makes sense"

Type ‘exit’ at the irb prompt to continue through the rest of the tests.

Note: You will probably have to test this file using the rubydoctest command, rather than an editor shortcut (such as TextMate’s).

There is a special variable, $rubydoctest, available inside the irb session which you can use to access the ‘current instance’ of the RubyDocTest::Runner object. This is probably only useful for debugging.

The “doctest_require:” Directive

Ruby source files are evaluated once before the RubyDocTest::Runner goes through and evaluates each irb session prompt. This is necessary so that all of the classes, variables, and methods (and so on) that are defined in the file get loaded into memory—i.e. it is necessary so they can be tested.

When writing doctests in a ruby source file, however, you may find that it is necessary to include one or more ruby files before the whole file is evaluated. The “doctest_require” directive is just the tool to use.

Ruby DocTest will first attempt to ‘require’ the specified file relative to the file it is ’require’d from.

	doctest_require: "../my-helper"

Unlike the regular ‘require’ method in ruby, ‘doctest_require’ expects “my-helper.rb” to exist in the directory above the source file’s directory. If it can’t be found there, then the regular ‘require’ rules apply for finding it in other directories around the system.

Advanced Tip: Everything after the ‘doctest_require:’ directive gets evaluated (i.e. it’s not just a string). So if you’d like, you can do other things before the ruby code is eval’ed, too. In addition, if ‘nil’ is the last thing in the directive, then no file is ’require’d. For example:

	doctest_require: $mysql_fixture_file = "test/fixtures/memorypress.sql"


	doctest_require: $mysql_fixture_file = "test/fixtures/memorypress.sql"; nil

assigns a string to a global variable, and then returns nil so that doctest_require does not load/require any files, since eval’ing it returned nil, not a string.


The $rubydoctest variable

If you open an irb session using the !!! special directive, a $rubydoctest global variable will be available to the context. Here is a short list of example uses for this variable:

	puts $rubydoctest.blocks.map{|g| g.lines.join("\n")}.join("\n---\n")