From 9223af7a696efad4f47b639ffaa23a01feab2278 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 4 Mar 2013 15:42:26 -0600 Subject: docs for TestBuilder --- .../scala/org/perl8/test/tap/TestBuilder.scala | 69 ++++++++++++++++++---- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/src/main/scala/org/perl8/test/tap/TestBuilder.scala b/src/main/scala/org/perl8/test/tap/TestBuilder.scala index 15305d1..3ee4706 100644 --- a/src/main/scala/org/perl8/test/tap/TestBuilder.scala +++ b/src/main/scala/org/perl8/test/tap/TestBuilder.scala @@ -2,6 +2,13 @@ package org.perl8.test.tap import org.perl8.test._ +/** This class provides a convenient yet low level API for generating TAP + * streams. Each instance of this class handles a single TAP stream, and + * keeps track of things like the current test number for you. All + * TAP-producing methods write the TAP lines to `Console.out` or + * `Console.err`, so you can override those (via `Console.withOut` or + * `Console.withErr`). + */ class TestBuilder private ( plan: Plan, indent: String, @@ -12,51 +19,86 @@ class TestBuilder private ( case p => outLine(Producer.plan(p)) } + /** Creates a new builder instance, and emits the corresponding plan line, + * unless the plan is not given. + * + * @param plan [[org.perl8.test.Plan plan]] for this test. + * @param terminalInUse Whether this test is being run from a harness which + * will not just be writing directly to the output. + * This will make things written to `Console.err` have + * a newline prepended, so that they always start on + * an empty line. + */ def this (plan: Plan = NoPlan, terminalInUse: Boolean = false) = this(plan, "", terminalInUse) + /** Create a new TestBuilder instance, to be used to run a subtest. This new + * instance will have all of its lines prefixed by an additional level of + * indentation. This instance will still need to have `doneTesting` + * called on it, and the result of the subtest will still need to be + * reported as a separate test result through `ok`. + */ def cloneForSubtest (newPlan: Plan): TestBuilder = new TestBuilder(newPlan, indent + " ", terminalInUse) + /** Reports a single test result to `Console.out`. */ def ok (test: Boolean) { state.ok(test) outLine(Producer.result(test, state.currentTest)) } + /** Reports a single test result with description to `Console.out`. */ def ok (test: Boolean, description: String) { state.ok(test) outLine(Producer.result(test, state.currentTest, description)) } + /** Reports a single TODO test result to `Console.out`. */ def todo (todo: String, test: Boolean) { state.ok(true) outLine(Producer.todoResult(test, state.currentTest, todo)) } + /** Reports a single TODO test result with description to `Console.out`. */ def todo (todo: String, test: Boolean, description: String) { state.ok(true) outLine(Producer.todoResult(test, state.currentTest, description, todo)) } + /** Reports a single skipped test result to `Console.out`. */ def skip (reason: String) { state.ok(true) outLine(Producer.skip(state.currentTest, reason)) } + /** Writes a comment line to `Console.err`. This will allow it to be + * visible in most summarizing harnesses (which consume and parse + * everything that goes to `Console.out`). + */ def diag (message: String) { errLine(Producer.comment(message)) } + /** Write a comment line to `Console.out`. This will typically only be + * visible in the raw TAP stream. + */ def note (message: String) { outLine(Producer.comment(message)) } + /** Abort the current test, with a message. */ def bailOut (message: String) { val bailOutMessage = Producer.bailOut(message) outLine(bailOutMessage) throw new BailOutException(bailOutMessage) } + /** Finalize the current builder instance. This writes the auto-calculated + * plan to `Console.out` if the plan type was `NoPlan` and reports a + * summary of the test results as a comment to `Console.err`. + * + * @return whether or not the test class as a whole passed. + */ def doneTesting: Boolean = { plan match { case NumericPlan(_) => printErrors @@ -69,6 +111,22 @@ class TestBuilder private ( state.isPassing } + /** The exit code to use, in harnesses that run a single test. Passing tests + * return 0, invalid tests (such as running a different number of tests + * than planned) return 255, and all others return the number of failed + * tests. + */ + def exitCode: Int = + if (state.isPassing) { + 0 + } + else if (!state.matchesPlan || state.currentTest == 0) { + 255 + } + else { + state.failCount + } + private def printErrors { if (!state.matchesPlan) { val planCount = (plan match { @@ -93,17 +151,6 @@ class TestBuilder private ( } } - def exitCode: Int = - if (state.isPassing) { - 0 - } - else if (!state.matchesPlan || state.currentTest == 0) { - 255 - } - else { - state.failCount - } - private val state = new TestState private def outLine (str: String) { -- cgit v1.2.3