/*
 * Run the tests in the introductory comments to a region.
 *
 * The region marked at the time of invocation will be tested. It should
 * be suitable for calling as a rexx function, and return a string value.
 * It must start with a comment that contains lines describing the tests
 * to be run, the comment ending with a single line having a comment end
 * string on it (with optional whitespace).
 *
 * The format for a test line is:
 * <whatever> test: <expected result> (<argument strings>) <actual result>
 *
 * <whatever> will be ignored.
 *
 * <argument strings> are the arguments to be passed to the region, formatted
 * for use by rexx-do-region. Note that if there are no arguments, then
 * the argument list should be ( 0 ). If there are arguments, then the
 * first thing in the argument list should be the negative of the number of
 * arguments, i.e.: ( -3 "This is" a "\^c" ).
 *
 * <expected results> is the value that it is expected that the function will
 * return when the marked region is started via
 * 'rexx-do-region' argument strings
 *
 * <actual results> are placed by this code. If they match the expected
 * results, they are left blank. Otherwise, it is changed to the actual
 * result. If there was some problem with the result (for example, it
 * occupied more than one line), then the results will be assumed to have
 * been "****".
 */

/* Canonical mg prefix. */
options results
options failat 2
signal on failure

/* Constants for this invocation */
bufname = "*Rexx-Test*"
flag =  "****"

/* Clean out the test buffer, and copy the region to it */
'switch-to-buffer "'bufname'"'
'beginning-of-buffer'
'end-of-buffer'
'kill-region'
'switch-to-buffer ""'	/* Null string -> goes to previous buffer */
'copy-region-as-kill'
'switch-to-buffer ""'
'yank'

/* Find and store all the tests, including the line number the test is on */
i = 1
'beginning-of-buffer'

do until rc ~= 0
	'rexx-point pnt'
	if pnt.3 = '*/' then break
	parse value pnt.3 with 'test:' exp '(' args ')'
	if exp ~= "" then do
		test.i.argstring = args
		test.i.expected = exp
		test.i.line = pnt.1
		i = i + 1
		end
	'next-line'
	end
numtests = i - 1

/* If there aren't any tests, we can stop here */
if numtests < 1 then do
	'rexx-display "No tests to run."'
	exit 0
	end

/* Now run each test, and stash the result */
do i = 1 to numtests
	'end-of-buffer'
	'beginning-of-buffer'
	signal off failure
	'rexx-do-region' test.i.argstring
	signal on failure
	'beginning-of-buffer'
	'rexx-region region'
	if region.0 = 1 then test.i.value = region.1
	else do
		test.i.value = flag
		iterate
		end
	'kill-region'
	end

/*
 * Finally, go check each test against the expected result, and insert the
 * appropriate thing in the buffer.
 */
'switch-to-buffer ""'
do i = 1 to numtests
	'goto-line' test.i.line
	'search-forward )'
	'rexx-insert "\tx"'
	'backward-char'
	'kill-line'
	if test.i.value ~= test.i.expected then
		'rexx-insert 'slashquote(test.i.value, '\')
	end

/* And, since all's well that ends well, exit */
exit 0

/* Come here if some command has serious problems */
failure:
	'rexx-display "something died!"'
	exit 1
