You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2013/05/28 19:47:43 UTC

[lucy-commits] [10/19] git commit: refs/heads/separate-clownfish-wip1 - Move test harness classes to Clownfish::TestHarness

Move test harness classes to Clownfish::TestHarness


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/bfc96f6d
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/bfc96f6d
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/bfc96f6d

Branch: refs/heads/separate-clownfish-wip1
Commit: bfc96f6d879b105e7caede84101cb116316e784c
Parents: 30bb63a
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Mon May 27 22:35:30 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Tue May 28 17:07:28 2013 +0200

----------------------------------------------------------------------
 c/t/test_lucy.c                                    |    2 +-
 core/Clownfish/Test.c                              |    6 +-
 core/Clownfish/Test/TestBatch.c                    |  293 ---------------
 core/Clownfish/Test/TestBatch.cfh                  |  120 ------
 core/Clownfish/Test/TestByteBuf.c                  |    4 +-
 core/Clownfish/Test/TestByteBuf.cfh                |    2 +-
 core/Clownfish/Test/TestCharBuf.c                  |    4 +-
 core/Clownfish/Test/TestCharBuf.cfh                |    2 +-
 core/Clownfish/Test/TestErr.c                      |    2 +-
 core/Clownfish/Test/TestErr.cfh                    |    2 +-
 core/Clownfish/Test/TestFormatter.c                |  184 ---------
 core/Clownfish/Test/TestFormatter.cfh              |  138 -------
 core/Clownfish/Test/TestHash.c                     |    4 +-
 core/Clownfish/Test/TestHash.cfh                   |    2 +-
 core/Clownfish/Test/TestLockFreeRegistry.c         |    2 +-
 core/Clownfish/Test/TestLockFreeRegistry.cfh       |    2 +-
 core/Clownfish/Test/TestNum.c                      |    4 +-
 core/Clownfish/Test/TestNum.cfh                    |    2 +-
 core/Clownfish/Test/TestObj.c                      |    2 +-
 core/Clownfish/Test/TestObj.cfh                    |    2 +-
 core/Clownfish/Test/TestRunner.c                   |   93 -----
 core/Clownfish/Test/TestRunner.cfh                 |   77 ----
 core/Clownfish/Test/TestUtils.c                    |  140 -------
 core/Clownfish/Test/TestUtils.cfh                  |   71 ----
 core/Clownfish/Test/TestVArray.c                   |    4 +-
 core/Clownfish/Test/TestVArray.cfh                 |    2 +-
 core/Clownfish/Test/Util/TestAtomic.c              |    2 +-
 core/Clownfish/Test/Util/TestAtomic.cfh            |    2 +-
 core/Clownfish/Test/Util/TestMemory.c              |    2 +-
 core/Clownfish/Test/Util/TestMemory.cfh            |    2 +-
 core/Clownfish/Test/Util/TestNumberUtils.c         |    4 +-
 core/Clownfish/Test/Util/TestNumberUtils.cfh       |    2 +-
 core/Clownfish/Test/Util/TestStringHelper.c        |    4 +-
 core/Clownfish/Test/Util/TestStringHelper.cfh      |    2 +-
 core/Clownfish/TestHarness/TestBatch.c             |  293 +++++++++++++++
 core/Clownfish/TestHarness/TestBatch.cfh           |  120 ++++++
 core/Clownfish/TestHarness/TestFormatter.c         |  184 +++++++++
 core/Clownfish/TestHarness/TestFormatter.cfh       |  138 +++++++
 core/Clownfish/TestHarness/TestRunner.c            |   93 +++++
 core/Clownfish/TestHarness/TestRunner.cfh          |   77 ++++
 core/Clownfish/TestHarness/TestUtils.c             |  140 +++++++
 core/Clownfish/TestHarness/TestUtils.cfh           |   71 ++++
 core/Lucy/Test.c                                   |    6 +-
 core/Lucy/Test/Analysis/TestAnalyzer.c             |    2 +-
 core/Lucy/Test/Analysis/TestAnalyzer.cfh           |    2 +-
 core/Lucy/Test/Analysis/TestCaseFolder.c           |    2 +-
 core/Lucy/Test/Analysis/TestCaseFolder.cfh         |    2 +-
 core/Lucy/Test/Analysis/TestNormalizer.c           |    2 +-
 core/Lucy/Test/Analysis/TestNormalizer.cfh         |    2 +-
 core/Lucy/Test/Analysis/TestPolyAnalyzer.c         |    2 +-
 core/Lucy/Test/Analysis/TestPolyAnalyzer.cfh       |    2 +-
 core/Lucy/Test/Analysis/TestRegexTokenizer.c       |    2 +-
 core/Lucy/Test/Analysis/TestRegexTokenizer.cfh     |    2 +-
 core/Lucy/Test/Analysis/TestSnowballStemmer.c      |    2 +-
 core/Lucy/Test/Analysis/TestSnowballStemmer.cfh    |    2 +-
 core/Lucy/Test/Analysis/TestSnowballStopFilter.c   |    2 +-
 core/Lucy/Test/Analysis/TestSnowballStopFilter.cfh |    2 +-
 core/Lucy/Test/Analysis/TestStandardTokenizer.c    |    2 +-
 core/Lucy/Test/Analysis/TestStandardTokenizer.cfh  |    2 +-
 core/Lucy/Test/Highlight/TestHeatMap.c             |    2 +-
 core/Lucy/Test/Highlight/TestHeatMap.cfh           |    2 +-
 core/Lucy/Test/Highlight/TestHighlighter.c         |    2 +-
 core/Lucy/Test/Highlight/TestHighlighter.cfh       |    2 +-
 core/Lucy/Test/Index/TestDocWriter.c               |    2 +-
 core/Lucy/Test/Index/TestDocWriter.cfh             |    2 +-
 core/Lucy/Test/Index/TestHighlightWriter.c         |    2 +-
 core/Lucy/Test/Index/TestHighlightWriter.cfh       |    2 +-
 core/Lucy/Test/Index/TestIndexManager.c            |    2 +-
 core/Lucy/Test/Index/TestIndexManager.cfh          |    2 +-
 core/Lucy/Test/Index/TestPolyReader.c              |    2 +-
 core/Lucy/Test/Index/TestPolyReader.cfh            |    2 +-
 core/Lucy/Test/Index/TestPostingListWriter.c       |    2 +-
 core/Lucy/Test/Index/TestPostingListWriter.cfh     |    2 +-
 core/Lucy/Test/Index/TestSegWriter.c               |    2 +-
 core/Lucy/Test/Index/TestSegWriter.cfh             |    2 +-
 core/Lucy/Test/Index/TestSegment.c                 |    2 +-
 core/Lucy/Test/Index/TestSegment.cfh               |    2 +-
 core/Lucy/Test/Index/TestSnapshot.c                |    2 +-
 core/Lucy/Test/Index/TestSnapshot.cfh              |    2 +-
 core/Lucy/Test/Index/TestTermInfo.c                |    2 +-
 core/Lucy/Test/Index/TestTermInfo.cfh              |    2 +-
 core/Lucy/Test/Object/TestBitVector.c              |    2 +-
 core/Lucy/Test/Object/TestBitVector.cfh            |    2 +-
 core/Lucy/Test/Object/TestI32Array.c               |    2 +-
 core/Lucy/Test/Object/TestI32Array.cfh             |    2 +-
 core/Lucy/Test/Plan/TestBlobType.c                 |    2 +-
 core/Lucy/Test/Plan/TestBlobType.cfh               |    2 +-
 core/Lucy/Test/Plan/TestFieldMisc.c                |    2 +-
 core/Lucy/Test/Plan/TestFieldMisc.cfh              |    2 +-
 core/Lucy/Test/Plan/TestFieldType.c                |    2 +-
 core/Lucy/Test/Plan/TestFieldType.cfh              |    2 +-
 core/Lucy/Test/Plan/TestFullTextType.c             |    2 +-
 core/Lucy/Test/Plan/TestFullTextType.cfh           |    2 +-
 core/Lucy/Test/Plan/TestNumericType.c              |    2 +-
 core/Lucy/Test/Plan/TestNumericType.cfh            |    2 +-
 core/Lucy/Test/Search/TestLeafQuery.c              |    2 +-
 core/Lucy/Test/Search/TestLeafQuery.cfh            |    2 +-
 core/Lucy/Test/Search/TestMatchAllQuery.c          |    2 +-
 core/Lucy/Test/Search/TestMatchAllQuery.cfh        |    2 +-
 core/Lucy/Test/Search/TestNOTQuery.c               |    2 +-
 core/Lucy/Test/Search/TestNOTQuery.cfh             |    2 +-
 core/Lucy/Test/Search/TestNoMatchQuery.c           |    2 +-
 core/Lucy/Test/Search/TestNoMatchQuery.cfh         |    2 +-
 core/Lucy/Test/Search/TestPhraseQuery.c            |    2 +-
 core/Lucy/Test/Search/TestPhraseQuery.cfh          |    2 +-
 core/Lucy/Test/Search/TestPolyQuery.c              |    2 +-
 core/Lucy/Test/Search/TestPolyQuery.cfh            |    4 +-
 core/Lucy/Test/Search/TestQueryParserLogic.c       |    2 +-
 core/Lucy/Test/Search/TestQueryParserLogic.cfh     |    2 +-
 core/Lucy/Test/Search/TestQueryParserSyntax.c      |    2 +-
 core/Lucy/Test/Search/TestQueryParserSyntax.cfh    |    2 +-
 core/Lucy/Test/Search/TestRangeQuery.c             |    2 +-
 core/Lucy/Test/Search/TestRangeQuery.cfh           |    2 +-
 core/Lucy/Test/Search/TestReqOptQuery.c            |    2 +-
 core/Lucy/Test/Search/TestReqOptQuery.cfh          |    2 +-
 core/Lucy/Test/Search/TestSeriesMatcher.c          |    2 +-
 core/Lucy/Test/Search/TestSeriesMatcher.cfh        |    2 +-
 core/Lucy/Test/Search/TestSortSpec.c               |    2 +-
 core/Lucy/Test/Search/TestSortSpec.cfh             |    2 +-
 core/Lucy/Test/Search/TestSpan.c                   |    2 +-
 core/Lucy/Test/Search/TestSpan.cfh                 |    2 +-
 core/Lucy/Test/Search/TestTermQuery.c              |    2 +-
 core/Lucy/Test/Search/TestTermQuery.cfh            |    2 +-
 core/Lucy/Test/Store/TestCompoundFileReader.c      |    2 +-
 core/Lucy/Test/Store/TestCompoundFileReader.cfh    |    2 +-
 core/Lucy/Test/Store/TestCompoundFileWriter.c      |    2 +-
 core/Lucy/Test/Store/TestCompoundFileWriter.cfh    |    2 +-
 core/Lucy/Test/Store/TestFSDirHandle.c             |    2 +-
 core/Lucy/Test/Store/TestFSDirHandle.cfh           |    2 +-
 core/Lucy/Test/Store/TestFSFileHandle.c            |    2 +-
 core/Lucy/Test/Store/TestFSFileHandle.cfh          |    2 +-
 core/Lucy/Test/Store/TestFSFolder.c                |    2 +-
 core/Lucy/Test/Store/TestFSFolder.cfh              |    2 +-
 core/Lucy/Test/Store/TestFileHandle.c              |    2 +-
 core/Lucy/Test/Store/TestFileHandle.cfh            |    2 +-
 core/Lucy/Test/Store/TestFolder.c                  |    2 +-
 core/Lucy/Test/Store/TestFolder.cfh                |    2 +-
 core/Lucy/Test/Store/TestFolderCommon.c            |    2 +-
 core/Lucy/Test/Store/TestIOChunks.c                |    2 +-
 core/Lucy/Test/Store/TestIOChunks.cfh              |    2 +-
 core/Lucy/Test/Store/TestIOPrimitives.c            |    2 +-
 core/Lucy/Test/Store/TestIOPrimitives.cfh          |    2 +-
 core/Lucy/Test/Store/TestInStream.c                |    2 +-
 core/Lucy/Test/Store/TestInStream.cfh              |    2 +-
 core/Lucy/Test/Store/TestRAMDirHandle.c            |    2 +-
 core/Lucy/Test/Store/TestRAMDirHandle.cfh          |    2 +-
 core/Lucy/Test/Store/TestRAMFileHandle.c           |    2 +-
 core/Lucy/Test/Store/TestRAMFileHandle.cfh         |    2 +-
 core/Lucy/Test/Store/TestRAMFolder.c               |    2 +-
 core/Lucy/Test/Store/TestRAMFolder.cfh             |    2 +-
 core/Lucy/Test/TestSchema.c                        |    2 +-
 core/Lucy/Test/TestSchema.cfh                      |    2 +-
 core/Lucy/Test/TestUtils.c                         |    2 +-
 core/Lucy/Test/Util/TestIndexFileNames.c           |    2 +-
 core/Lucy/Test/Util/TestIndexFileNames.cfh         |    2 +-
 core/Lucy/Test/Util/TestJson.c                     |    2 +-
 core/Lucy/Test/Util/TestJson.cfh                   |    2 +-
 core/Lucy/Test/Util/TestMemoryPool.c               |    2 +-
 core/Lucy/Test/Util/TestMemoryPool.cfh             |    2 +-
 core/Lucy/Test/Util/TestPriorityQueue.c            |    2 +-
 core/Lucy/Test/Util/TestPriorityQueue.cfh          |    2 +-
 161 files changed, 1273 insertions(+), 1273 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/c/t/test_lucy.c
----------------------------------------------------------------------
diff --git a/c/t/test_lucy.c b/c/t/test_lucy.c
index fc3f81e..808d0f7 100644
--- a/c/t/test_lucy.c
+++ b/c/t/test_lucy.c
@@ -16,7 +16,7 @@
 
 #include <stdlib.h>
 
-#include "Clownfish/Test/TestFormatter.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
 #include "Clownfish/Test.h"
 #include "Lucy/Test.h"
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test.c b/core/Clownfish/Test.c
index d569e55..4d2a9fc 100644
--- a/core/Clownfish/Test.c
+++ b/core/Clownfish/Test.c
@@ -23,9 +23,9 @@
 #include "Clownfish/Test.h"
 
 #include "Clownfish/Err.h"
-#include "Clownfish/Test/TestBatch.h"
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/Test/TestRunner.h"
+#include "Clownfish/TestHarness/TestBatch.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
+#include "Clownfish/TestHarness/TestRunner.h"
 #include "Clownfish/VArray.h"
 
 #include "Clownfish/Test/TestByteBuf.h"

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestBatch.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestBatch.c b/core/Clownfish/Test/TestBatch.c
deleted file mode 100644
index f77a71a..0000000
--- a/core/Clownfish/Test/TestBatch.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <math.h>
-#include <stdio.h>
-#include <string.h>
-
-#define C_CFISH_TESTBATCH
-#define CFISH_USE_SHORT_NAMES
-#define LUCY_USE_SHORT_NAMES
-#include "Clownfish/Test/TestBatch.h"
-#include "Clownfish/CharBuf.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/VArray.h"
-#include "Clownfish/VTable.h"
-
-struct try_run_tests_context {
-    TestBatch *batch;
-};
-
-static void
-S_try_run_tests(void *context);
-
-static bool
-S_vtest_true(TestBatch *self, bool condition, const char *pattern,
-             va_list args);
-
-TestBatch*
-TestBatch_new(uint32_t num_planned, TestFormatter *formatter) {
-    TestBatch *self = (TestBatch*)VTable_Make_Obj(TESTBATCH);
-    return TestBatch_init(self, num_planned, formatter);
-}
-
-TestBatch*
-TestBatch_init(TestBatch *self, uint32_t num_planned,
-               TestFormatter *formatter) {
-    // Assign.
-    self->num_planned = num_planned;
-    self->formatter   = (TestFormatter*)INCREF(formatter);
-
-    // Initialize.
-    self->test_num    = 0;
-    self->num_passed  = 0;
-    self->num_failed  = 0;
-    self->num_skipped = 0;
-
-    return self;
-}
-
-void
-TestBatch_destroy(TestBatch *self) {
-    DECREF(self->formatter);
-    SUPER_DESTROY(self, TESTBATCH);
-}
-
-bool
-TestBatch_run(TestBatch *self) {
-    TestFormatter_Batch_Prologue(self->formatter, self);
-
-    struct try_run_tests_context args;
-    args.batch = self;
-    Err *err = Err_trap(S_try_run_tests, &args);
-
-    bool failed = false;
-    if (err) {
-        failed = true;
-        CharBuf *mess = Err_Get_Mess(err);
-        INCREF(mess);
-        Err_warn_mess(mess);
-    }
-    if (self->num_failed > 0) {
-        failed = true;
-        TestFormatter_batch_comment(self->formatter, "%d/%d tests failed.\n",
-                                    self->num_failed, self->test_num);
-    }
-    if (self->test_num != self->num_planned) {
-        failed = true;
-        TestFormatter_batch_comment(self->formatter,
-                                    "Bad plan: You planned %d tests but ran"
-                                    " %d.\n",
-                                    self->num_planned, self->test_num);
-    }
-
-    return !failed;
-}
-
-static void
-S_try_run_tests(void *context) {
-    struct try_run_tests_context *args
-        = (struct try_run_tests_context*)context;
-    TestBatch_Run_Tests(args->batch);
-}
-
-uint32_t
-TestBatch_get_num_planned(TestBatch *self) {
-    return self->num_planned;
-}
-
-uint32_t
-TestBatch_get_num_tests(TestBatch *self) {
-    return self->test_num;
-}
-
-uint32_t
-TestBatch_get_num_failed(TestBatch *self) {
-    return self->num_failed;
-}
-
-bool
-TestBatch_test_true(void *vself, bool condition, const char *pattern, ...) {
-    va_list args;
-    va_start(args, pattern);
-    bool result = TestBatch_VTest_True((TestBatch*)vself, condition,
-                                         pattern, args);
-    va_end(args);
-    return result;
-}
-
-bool
-TestBatch_test_false(void *vself, bool condition, const char *pattern, ...) {
-    va_list args;
-    va_start(args, pattern);
-    bool result = TestBatch_VTest_False((TestBatch*)vself, condition,
-                                          pattern, args);
-    va_end(args);
-    return result;
-}
-
-bool
-TestBatch_test_int_equals(void *vself, long got, long expected,
-                          const char *pattern, ...) {
-    va_list args;
-    va_start(args, pattern);
-    bool result = TestBatch_VTest_Int_Equals((TestBatch*)vself, got,
-                                               expected, pattern, args);
-    va_end(args);
-    return result;
-}
-
-bool
-TestBatch_test_float_equals(void *vself, double got, double expected,
-                            const char *pattern, ...) {
-    va_list args;
-    va_start(args, pattern);
-    bool result = TestBatch_VTest_Float_Equals((TestBatch*)vself, got,
-                                                 expected, pattern, args);
-    va_end(args);
-    return result;
-}
-
-bool
-TestBatch_test_string_equals(void *vself, const char *got,
-                             const char *expected, const char *pattern, ...) {
-    va_list args;
-    va_start(args, pattern);
-    bool result = TestBatch_VTest_String_Equals((TestBatch*)vself, got,
-                                                  expected, pattern, args);
-    va_end(args);
-    return result;
-}
-
-bool
-TestBatch_pass(void *vself, const char *pattern, ...) {
-    va_list args;
-    va_start(args, pattern);
-    bool result = TestBatch_VPass((TestBatch*)vself, pattern, args);
-    va_end(args);
-    return result;
-}
-
-bool
-TestBatch_fail(void *vself, const char *pattern, ...) {
-    va_list args;
-    va_start(args, pattern);
-    bool result = TestBatch_VFail((TestBatch*)vself, pattern, args);
-    va_end(args);
-    return result;
-}
-
-void
-TestBatch_skip(void *vself, const char *pattern, ...) {
-    va_list args;
-    va_start(args, pattern);
-    TestBatch_VSkip((TestBatch*)vself, pattern, args);
-    va_end(args);
-}
-
-bool
-TestBatch_vtest_true(TestBatch *self, bool condition, const char *pattern,
-                     va_list args) {
-    return S_vtest_true(self, condition, pattern, args);
-}
-
-bool
-TestBatch_vtest_false(TestBatch *self, bool condition,
-                      const char *pattern, va_list args) {
-    return S_vtest_true(self, !condition, pattern, args);
-}
-
-bool
-TestBatch_vtest_int_equals(TestBatch *self, long got, long expected,
-                           const char *pattern, va_list args) {
-    bool pass = (got == expected);
-    S_vtest_true(self, pass, pattern, args);
-    if (!pass) {
-        TestFormatter_test_comment(self->formatter,
-                                   "Expected '%ld', got '%ld'.\n",
-                                   expected, got);
-    }
-    return pass;
-}
-
-bool
-TestBatch_vtest_float_equals(TestBatch *self, double got, double expected,
-                             const char *pattern, va_list args) {
-    double relative_error = got / expected - 1.0;
-    bool   pass           = (fabs(relative_error) < 1e-6);
-    S_vtest_true(self, pass, pattern, args);
-    if (!pass) {
-        TestFormatter_test_comment(self->formatter,
-                                   "Expected '%e', got '%e'.\n",
-                                   expected, got);
-    }
-    return pass;
-}
-
-bool
-TestBatch_vtest_string_equals(TestBatch *self, const char *got,
-                              const char *expected, const char *pattern,
-                              va_list args) {
-    bool pass = (strcmp(got, expected) == 0);
-    S_vtest_true(self, pass, pattern, args);
-    if (!pass) {
-        TestFormatter_test_comment(self->formatter,
-                                   "Expected '%s', got '%s'.\n",
-                                   expected, got);
-    }
-    return pass;
-}
-
-bool
-TestBatch_vpass(TestBatch *self, const char *pattern, va_list args) {
-    return S_vtest_true(self, true, pattern, args);
-}
-
-bool
-TestBatch_vfail(TestBatch *self, const char *pattern, va_list args) {
-    return S_vtest_true(self, false, pattern, args);
-}
-
-void
-TestBatch_vskip(TestBatch *self, const char *pattern, va_list args) {
-    self->test_num++;
-    // TODO: Add a VTest_Skip method to TestFormatter
-    TestFormatter_VTest_Result(self->formatter, true, self->test_num,
-                               pattern, args);
-    self->num_skipped++;
-}
-
-static bool
-S_vtest_true(TestBatch* self, bool condition, const char *pattern,
-             va_list args) {
-    // Increment test number.
-    self->test_num++;
-
-    if (condition) {
-        self->num_passed++;
-    }
-    else {
-        self->num_failed++;
-    }
-
-    TestFormatter_VTest_Result(self->formatter, condition, self->test_num,
-                               pattern, args);
-
-    return condition;
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestBatch.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestBatch.cfh b/core/Clownfish/Test/TestBatch.cfh
deleted file mode 100644
index 01113a0..0000000
--- a/core/Clownfish/Test/TestBatch.cfh
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel Clownfish;
-
-abstract class Clownfish::Test::TestBatch inherits Clownfish::Obj {
-    TestFormatter *formatter;
-    uint32_t       test_num;
-    uint32_t       num_planned;
-    uint32_t       num_passed;
-    uint32_t       num_failed;
-    uint32_t       num_skipped;
-
-    inert incremented TestBatch*
-    new(uint32_t num_planned, TestFormatter *formatter);
-
-    inert TestBatch*
-    init(TestBatch *self, uint32_t num_planned, TestFormatter *formatter);
-
-    public void
-    Destroy(TestBatch *self);
-
-    /** Run the test batch and print test output and diagnosis.
-     *
-     * @return true if the test batch passed.
-     */
-    bool
-    Run(TestBatch *self);
-
-    /** Run the tests of the test batch.
-     */
-    abstract void
-    Run_Tests(TestBatch *self);
-
-    /** Return the number of tests planned.
-     */
-    uint32_t
-    Get_Num_Planned(TestBatch *self);
-
-    /** Return the number of tests run.
-     */
-    uint32_t
-    Get_Num_Tests(TestBatch *self);
-
-    /** Return the number of failed tests.
-     */
-    uint32_t
-    Get_Num_Failed(TestBatch *self);
-
-    inert bool
-    test_true(void *vself, bool condition, const char *pattern, ...);
-
-    inert bool
-    test_false(void *vself, bool condition, const char *pattern, ...);
-
-    inert bool
-    test_int_equals(void *vself, long got, long expected,
-                    const char *pattern, ...);
-
-    inert bool
-    test_float_equals(void *vself, double got, double expected,
-                      const char *pattern, ...);
-
-    inert bool
-    test_string_equals(void *vself, const char *got, const char *expected,
-                       const char *pattern, ...);
-
-    inert bool
-    pass(void *vself, const char *pattern, ...);
-
-    inert bool
-    fail(void *vself, const char *pattern, ...);
-
-    inert void
-    skip(void *vself, const char *pattern, ...);
-
-    bool
-    VTest_True(TestBatch *self, bool condition, const char *pattern,
-               va_list args);
-
-    bool
-    VTest_False(TestBatch *self, bool condition, const char *pattern,
-                va_list args);
-
-    bool
-    VTest_Int_Equals(TestBatch *self, long got, long expected,
-                     const char *pattern, va_list args);
-
-    bool
-    VTest_Float_Equals(TestBatch *self, double got, double expected,
-                       const char *pattern, va_list args);
-
-    bool
-    VTest_String_Equals(TestBatch *self, const char *got, const char *expected,
-                       const char *pattern, va_list args);
-
-    bool
-    VPass(TestBatch *self, const char *pattern, va_list args);
-
-    bool
-    VFail(TestBatch *self, const char *pattern, va_list args);
-
-    void
-    VSkip(TestBatch *self, const char *pattern, va_list args);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestByteBuf.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestByteBuf.c b/core/Clownfish/Test/TestByteBuf.c
index 71329d7..98da9c3 100644
--- a/core/Clownfish/Test/TestByteBuf.c
+++ b/core/Clownfish/Test/TestByteBuf.c
@@ -23,8 +23,8 @@
 
 #include "Clownfish/ByteBuf.h"
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/Test/TestUtils.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
+#include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/VTable.h"
 
 TestByteBuf*

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestByteBuf.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestByteBuf.cfh b/core/Clownfish/Test/TestByteBuf.cfh
index fba607b..6819191 100644
--- a/core/Clownfish/Test/TestByteBuf.cfh
+++ b/core/Clownfish/Test/TestByteBuf.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::TestByteBuf cnick TestBB
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestByteBuf*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestCharBuf.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestCharBuf.c b/core/Clownfish/Test/TestCharBuf.c
index 891731c..bc8a348 100644
--- a/core/Clownfish/Test/TestCharBuf.c
+++ b/core/Clownfish/Test/TestCharBuf.c
@@ -26,8 +26,8 @@
 #include "Clownfish/CharBuf.h"
 #include "Clownfish/Num.h"
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/Test/TestUtils.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
+#include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/VTable.h"
 
 static char smiley[] = { (char)0xE2, (char)0x98, (char)0xBA, 0 };

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestCharBuf.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestCharBuf.cfh b/core/Clownfish/Test/TestCharBuf.cfh
index 1ecedcc..ba27bdb 100644
--- a/core/Clownfish/Test/TestCharBuf.cfh
+++ b/core/Clownfish/Test/TestCharBuf.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::TestCharBuf cnick TestCB
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestCharBuf*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestErr.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestErr.c b/core/Clownfish/Test/TestErr.c
index c6b0869..7839de5 100644
--- a/core/Clownfish/Test/TestErr.c
+++ b/core/Clownfish/Test/TestErr.c
@@ -22,7 +22,7 @@
 #include "Clownfish/CharBuf.h"
 #include "Clownfish/Err.h"
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
 #include "Clownfish/VTable.h"
 
 TestErr*

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestErr.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestErr.cfh b/core/Clownfish/Test/TestErr.cfh
index 1366e7e..4efd467 100644
--- a/core/Clownfish/Test/TestErr.cfh
+++ b/core/Clownfish/Test/TestErr.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::TestErr
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestErr*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestFormatter.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestFormatter.c b/core/Clownfish/Test/TestFormatter.c
deleted file mode 100644
index 5a700a2..0000000
--- a/core/Clownfish/Test/TestFormatter.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-
-#define C_CFISH_TESTFORMATTER
-#define CFISH_USE_SHORT_NAMES
-#define LUCY_USE_SHORT_NAMES
-#define CHY_USE_SHORT_NAMES
-
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/CharBuf.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Test/TestBatch.h"
-#include "Clownfish/Test/TestRunner.h"
-#include "Clownfish/VTable.h"
-
-TestFormatter*
-TestFormatter_init(TestFormatter *self) {
-    ABSTRACT_CLASS_CHECK(self, TESTFORMATTER);
-    return self;
-}
-
-void
-TestFormatter_test_result(void *vself, bool pass, uint32_t test_num,
-                          const char *fmt, ...) {
-    va_list args;
-    va_start(args, fmt);
-    TestFormatter_VTest_Result((TestFormatter*)vself, pass, test_num, fmt,
-                               args);
-    va_end(args);
-}
-
-void
-TestFormatter_test_comment(void *vself, const char *fmt, ...) {
-    va_list args;
-    va_start(args, fmt);
-    TestFormatter_VTest_Comment((TestFormatter*)vself, fmt, args);
-    va_end(args);
-}
-
-void
-TestFormatter_batch_comment(void *vself, const char *fmt, ...) {
-    va_list args;
-    va_start(args, fmt);
-    TestFormatter_VBatch_Comment((TestFormatter*)vself, fmt, args);
-    va_end(args);
-}
-
-TestFormatterCF*
-TestFormatterCF_new() {
-    TestFormatterCF *self
-        = (TestFormatterCF*)VTable_Make_Obj(TESTFORMATTERCF);
-    return TestFormatterCF_init(self);
-}
-
-TestFormatterCF*
-TestFormatterCF_init(TestFormatterCF *self) {
-    return (TestFormatterCF*)TestFormatter_init((TestFormatter*)self);
-}
-
-void
-TestFormatterCF_batch_prologue(TestFormatterCF *self, TestBatch *batch) {
-    UNUSED_VAR(self);
-    CharBuf *class_name = TestBatch_Get_Class_Name(batch);
-    printf("Running %s...\n", CB_Get_Ptr8(class_name));
-}
-
-void
-TestFormatterCF_vtest_result(TestFormatterCF *self, bool pass,
-                             uint32_t test_num, const char *fmt,
-                             va_list args) {
-    UNUSED_VAR(self);
-    if (!pass) {
-        printf("  Failed test %u: ", test_num);
-        vprintf(fmt, args);
-        printf("\n");
-    }
-}
-
-void
-TestFormatterCF_vtest_comment(TestFormatterCF *self, const char *fmt,
-                              va_list args) {
-    UNUSED_VAR(self);
-    printf("    ");
-    vprintf(fmt, args);
-}
-
-void
-TestFormatterCF_vbatch_comment(TestFormatterCF *self, const char *fmt,
-                               va_list args) {
-    UNUSED_VAR(self);
-    printf("  ");
-    vprintf(fmt, args);
-}
-
-void
-TestFormatterCF_summary(TestFormatterCF *self, TestRunner *runner) {
-    UNUSED_VAR(self);
-    uint32_t num_batches        = TestRunner_Get_Num_Batches(runner);
-    uint32_t num_batches_failed = TestRunner_Get_Num_Batches_Failed(runner);
-    uint32_t num_tests          = TestRunner_Get_Num_Tests(runner);
-    uint32_t num_tests_failed   = TestRunner_Get_Num_Tests_Failed(runner);
-
-    if (num_batches == 0) {
-        printf("No tests planned or run.\n");
-    }
-    else if (num_batches_failed == 0) {
-        printf("%u batches passed. %u tests passed.\n", num_batches,
-               num_tests);
-        printf("Result: PASS\n");
-    }
-    else {
-        printf("%u/%u batches failed. %u/%u tests failed.\n",
-               num_batches_failed, num_batches, num_tests_failed, num_tests);
-        printf("Result: FAIL\n");
-    }
-}
-
-TestFormatterTAP*
-TestFormatterTAP_new() {
-    TestFormatterTAP *self
-        = (TestFormatterTAP*)VTable_Make_Obj(TESTFORMATTERTAP);
-    return TestFormatterTAP_init(self);
-}
-
-TestFormatterTAP*
-TestFormatterTAP_init(TestFormatterTAP *self) {
-    return (TestFormatterTAP*)TestFormatter_init((TestFormatter*)self);
-}
-
-void
-TestFormatterTAP_batch_prologue(TestFormatterTAP *self, TestBatch *batch) {
-    UNUSED_VAR(self);
-    printf("1..%u\n", TestBatch_Get_Num_Planned(batch));
-}
-
-void
-TestFormatterTAP_vtest_result(TestFormatterTAP *self, bool pass,
-                              uint32_t test_num, const char *fmt,
-                              va_list args) {
-    UNUSED_VAR(self);
-    const char *result = pass ? "ok" : "not ok";
-    printf("%s %u - ", result, test_num);
-    vprintf(fmt, args);
-    printf("\n");
-}
-
-void
-TestFormatterTAP_vtest_comment(TestFormatterTAP *self, const char *fmt,
-                               va_list args) {
-    UNUSED_VAR(self);
-    printf("#   ");
-    vprintf(fmt, args);
-}
-
-void
-TestFormatterTAP_vbatch_comment(TestFormatterTAP *self, const char *fmt,
-                                va_list args) {
-    UNUSED_VAR(self);
-    printf("# ");
-    vprintf(fmt, args);
-}
-
-void
-TestFormatterTAP_summary(TestFormatterTAP *self, TestRunner *runner) {
-    UNUSED_VAR(self);
-    UNUSED_VAR(runner);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestFormatter.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestFormatter.cfh b/core/Clownfish/Test/TestFormatter.cfh
deleted file mode 100644
index 2ba63bf..0000000
--- a/core/Clownfish/Test/TestFormatter.cfh
+++ /dev/null
@@ -1,138 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel Clownfish;
-
-/**
- * Abstract base class for Clownfish test formatters.
- */
-abstract class Clownfish::Test::TestFormatter inherits Clownfish::Obj {
-    inert TestFormatter*
-    init(TestFormatter *self);
-
-    inert void
-    test_result(void *vself, bool pass, uint32_t test_num, const char *fmt,
-                ...);
-
-    inert void
-    test_comment(void *vself, const char *fmt, ...);
-
-    inert void
-    batch_comment(void *vself, const char *fmt, ...);
-
-    /** Print output at the beginning of a test batch.
-     *
-     * @param batch The test batch.
-     */
-    abstract void
-    Batch_Prologue(TestFormatter *self, TestBatch *batch);
-
-    /** Print the result of a single test.
-     *
-     * @param pass True if the test passed, false otherwise.
-     * @param test_num The sequence number of the test.
-     * @param fmt printf-style format string.
-     * @param args Additional arguments.
-     */
-    abstract void
-    VTest_Result(TestFormatter *self, bool pass, uint32_t test_num,
-                 const char *fmt, va_list args);
-
-    /** Print additional diagnosis for a test.
-     *
-     * @param fmt printf-style format string.
-     * @param args Additional arguments.
-     */
-    abstract void
-    VTest_Comment(TestFormatter *self, const char *fmt, va_list args);
-
-    /** Print additional diagnosis for a test batch.
-     *
-     * @param fmt printf-style format string.
-     * @param args Additional arguments.
-     */
-    abstract void
-    VBatch_Comment(TestFormatter *self, const char *fmt, va_list args);
-
-    /** Print test summary after running all test batches.
-     *
-     * @param runner The test runner.
-     */
-    abstract void
-    Summary(TestFormatter *self, TestRunner *runner);
-}
-
-/**
- * A TestFormatter that produces human-readable output in a custom
- * "Clownfish" format.
- */
-class Clownfish::Test::Formatter::TestFormatterCF
-    inherits Clownfish::Test::TestFormatter {
-
-    inert incremented TestFormatterCF*
-    new();
-
-    inert TestFormatterCF*
-    init(TestFormatterCF *self);
-
-    void
-    Batch_Prologue(TestFormatterCF *self, TestBatch *batch);
-
-    void
-    VTest_Result(TestFormatterCF *self, bool pass, uint32_t test_num,
-                 const char *fmt, va_list args);
-
-    void
-    VTest_Comment(TestFormatterCF *self, const char *fmt, va_list args);
-
-    void
-    VBatch_Comment(TestFormatterCF *self, const char *fmt, va_list args);
-
-    void
-    Summary(TestFormatterCF *self, TestRunner *runner);
-}
-
-/**
- * A TestFormatter that produces TAP output (Test Anything Protocol).
- * See http://testanything.org/
- */
-class Clownfish::Test::Formatter::TestFormatterTAP
-    inherits Clownfish::Test::TestFormatter {
-
-    inert incremented TestFormatterTAP*
-    new();
-
-    inert TestFormatterTAP*
-    init(TestFormatterTAP *self);
-
-    void
-    Batch_Prologue(TestFormatterTAP *self, TestBatch *batch);
-
-    void
-    VTest_Result(TestFormatterTAP *self, bool pass, uint32_t test_num,
-                 const char *fmt, va_list args);
-
-    void
-    VTest_Comment(TestFormatterTAP *self, const char *fmt, va_list args);
-
-    void
-    VBatch_Comment(TestFormatterTAP *self, const char *fmt, va_list args);
-
-    void
-    Summary(TestFormatterTAP *self, TestRunner *runner);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestHash.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestHash.c b/core/Clownfish/Test/TestHash.c
index 773a6f8..6b72ec7 100644
--- a/core/Clownfish/Test/TestHash.c
+++ b/core/Clownfish/Test/TestHash.c
@@ -26,8 +26,8 @@
 #include "Clownfish/Hash.h"
 #include "Clownfish/Num.h"
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/Test/TestUtils.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
+#include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/VArray.h"
 #include "Clownfish/VTable.h"
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestHash.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestHash.cfh b/core/Clownfish/Test/TestHash.cfh
index ed5e548..cc74687 100644
--- a/core/Clownfish/Test/TestHash.cfh
+++ b/core/Clownfish/Test/TestHash.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::TestHash
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestHash*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestLockFreeRegistry.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestLockFreeRegistry.c b/core/Clownfish/Test/TestLockFreeRegistry.c
index 035bd77..dcd5e8b 100644
--- a/core/Clownfish/Test/TestLockFreeRegistry.c
+++ b/core/Clownfish/Test/TestLockFreeRegistry.c
@@ -24,7 +24,7 @@
 
 #include "Clownfish/LockFreeRegistry.h"
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
 #include "Clownfish/VTable.h"
 
 TestLockFreeRegistry*

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestLockFreeRegistry.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestLockFreeRegistry.cfh b/core/Clownfish/Test/TestLockFreeRegistry.cfh
index b2c7d36..376fbe2 100644
--- a/core/Clownfish/Test/TestLockFreeRegistry.cfh
+++ b/core/Clownfish/Test/TestLockFreeRegistry.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::TestLockFreeRegistry cnick TestLFReg
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestLockFreeRegistry*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestNum.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestNum.c b/core/Clownfish/Test/TestNum.c
index 1f01a61..add9a65 100644
--- a/core/Clownfish/Test/TestNum.c
+++ b/core/Clownfish/Test/TestNum.c
@@ -22,8 +22,8 @@
 #include "Clownfish/CharBuf.h"
 #include "Clownfish/Num.h"
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/Test/TestUtils.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
+#include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/VTable.h"
 
 TestNum*

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestNum.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestNum.cfh b/core/Clownfish/Test/TestNum.cfh
index b6d1035..9176210 100644
--- a/core/Clownfish/Test/TestNum.cfh
+++ b/core/Clownfish/Test/TestNum.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::TestNum
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestNum*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestObj.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestObj.c b/core/Clownfish/Test/TestObj.c
index fa0a80b..63d81f7 100644
--- a/core/Clownfish/Test/TestObj.c
+++ b/core/Clownfish/Test/TestObj.c
@@ -25,7 +25,7 @@
 #include "Clownfish/CharBuf.h"
 #include "Clownfish/Err.h"
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
 #include "Clownfish/VTable.h"
 
 TestObj*

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestObj.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestObj.cfh b/core/Clownfish/Test/TestObj.cfh
index 3c41f2b..3cca164 100644
--- a/core/Clownfish/Test/TestObj.cfh
+++ b/core/Clownfish/Test/TestObj.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::TestObj
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestObj*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestRunner.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestRunner.c b/core/Clownfish/Test/TestRunner.c
deleted file mode 100644
index 8091c36..0000000
--- a/core/Clownfish/Test/TestRunner.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define C_CFISH_TESTRUNNER
-#define CFISH_USE_SHORT_NAMES
-#define LUCY_USE_SHORT_NAMES
-#define CHY_USE_SHORT_NAMES
-
-#include "Clownfish/Test/TestRunner.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Test/TestBatch.h"
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/VTable.h"
-
-TestRunner*
-TestRunner_new(TestFormatter *formatter) {
-    TestRunner *self = (TestRunner*)VTable_Make_Obj(TESTRUNNER);
-    return TestRunner_init(self, formatter);
-}
-
-TestRunner*
-TestRunner_init(TestRunner *self, TestFormatter *formatter) {
-    self->formatter          = (TestFormatter*)INCREF(formatter);
-    self->num_tests          = 0;
-    self->num_tests_failed   = 0;
-    self->num_batches        = 0;
-    self->num_batches_failed = 0;
-
-    return self;
-}
-
-void
-TestRunner_destroy(TestRunner *self) {
-    DECREF(self->formatter);
-    SUPER_DESTROY(self, TESTRUNNER);
-}
-
-bool
-TestRunner_run_batch(TestRunner *self, TestBatch *batch) {
-    bool success = TestBatch_Run(batch);
-
-    self->num_tests        += TestBatch_Get_Num_Tests(batch);
-    self->num_tests_failed += TestBatch_Get_Num_Failed(batch);
-    self->num_batches      += 1;
-
-    if (!success) {
-        self->num_batches_failed += 1;
-    }
-
-    return success;
-}
-
-bool
-TestRunner_finish(TestRunner *self) {
-    TestFormatter_Summary(self->formatter, self);
-
-    return self->num_batches != 0 && self->num_batches_failed == 0;
-}
-
-uint32_t
-TestRunner_get_num_tests(TestRunner *self) {
-    return self->num_tests;
-}
-
-uint32_t
-TestRunner_get_num_tests_failed(TestRunner *self) {
-    return self->num_tests_failed;
-}
-
-uint32_t
-TestRunner_get_num_batches(TestRunner *self) {
-    return self->num_batches;
-}
-
-uint32_t
-TestRunner_get_num_batches_failed(TestRunner *self) {
-    return self->num_batches_failed;
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestRunner.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestRunner.cfh b/core/Clownfish/Test/TestRunner.cfh
deleted file mode 100644
index a59010a..0000000
--- a/core/Clownfish/Test/TestRunner.cfh
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel Clownfish;
-
-/**
- * Run multiple test batches and collect statistics.
- */
-class Clownfish::Test::TestRunner inherits Clownfish::Obj {
-    TestFormatter *formatter;
-    uint32_t       num_tests;
-    uint32_t       num_tests_failed;
-    uint32_t       num_batches;
-    uint32_t       num_batches_failed;
-
-    inert incremented TestRunner*
-    new(TestFormatter *formatter);
-
-    /**
-     * @param formatter The test formatter to format the test output.
-     */
-    inert TestRunner*
-    init(TestRunner *self, TestFormatter *formatter);
-
-    public void
-    Destroy(TestRunner *self);
-
-    /** Run a test batch and collect statistics.
-     *
-     * @param batch The test batch.
-     * @return true if the test batch passed.
-     */
-    bool
-    Run_Batch(TestRunner *self, TestBatch *batch);
-
-    /** Print a summary after running all test batches.
-     *
-     * @return true if any tests were run and all test batches passed.
-     */
-    bool
-    Finish(TestRunner *self);
-
-    /** Return the number of tests run.
-     */
-    uint32_t
-    Get_Num_Tests(TestRunner *self);
-
-    /** Return the number of failed tests.
-     */
-    uint32_t
-    Get_Num_Tests_Failed(TestRunner *self);
-
-    /** Return the number of test batches run.
-     */
-    uint32_t
-    Get_Num_Batches(TestRunner *self);
-
-    /** Return the number of failed test batches.
-     */
-    uint32_t
-    Get_Num_Batches_Failed(TestRunner *self);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestUtils.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestUtils.c b/core/Clownfish/Test/TestUtils.c
deleted file mode 100644
index 0f7b72a..0000000
--- a/core/Clownfish/Test/TestUtils.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#define CHY_USE_SHORT_NAMES
-#define CFISH_USE_SHORT_NAMES
-#define LUCY_USE_SHORT_NAMES
-
-#include "Clownfish/Test/TestUtils.h"
-
-#include "Clownfish/CharBuf.h"
-#include "Clownfish/Util/Memory.h"
-#include "Lucy/Store/InStream.h"
-#include "Lucy/Store/OutStream.h"
-#include "Lucy/Store/RAMFile.h"
-#include "Lucy/Util/Freezer.h"
-
-uint64_t
-TestUtils_random_u64() {
-    uint64_t num = ((uint64_t)(rand()   & 0x7FFF) << 60)
-                   | ((uint64_t)(rand() & 0x7FFF) << 45)
-                   | ((uint64_t)(rand() & 0x7FFF) << 30)
-                   | ((uint64_t)(rand() & 0x7FFF) << 15)
-                   | ((uint64_t)(rand() & 0x7FFF) << 0);
-    return num;
-}
-
-int64_t*
-TestUtils_random_i64s(int64_t *buf, size_t count, int64_t min,
-                      int64_t limit) {
-    uint64_t  range = min < limit ? limit - min : 0;
-    int64_t *ints = buf ? buf : (int64_t*)CALLOCATE(count, sizeof(int64_t));
-    for (size_t i = 0; i < count; i++) {
-        ints[i] = min + TestUtils_random_u64() % range;
-    }
-    return ints;
-}
-
-uint64_t*
-TestUtils_random_u64s(uint64_t *buf, size_t count, uint64_t min,
-                      uint64_t limit) {
-    uint64_t  range = min < limit ? limit - min : 0;
-    uint64_t *ints = buf ? buf : (uint64_t*)CALLOCATE(count, sizeof(uint64_t));
-    for (size_t i = 0; i < count; i++) {
-        ints[i] = min + TestUtils_random_u64() % range;
-    }
-    return ints;
-}
-
-double*
-TestUtils_random_f64s(double *buf, size_t count) {
-    double *f64s = buf ? buf : (double*)CALLOCATE(count, sizeof(double));
-    for (size_t i = 0; i < count; i++) {
-        uint64_t num = TestUtils_random_u64();
-        f64s[i] = U64_TO_DOUBLE(num) / UINT64_MAX;
-    }
-    return f64s;
-}
-
-static uint32_t
-S_random_code_point(void) {
-    uint32_t code_point = 0;
-    while (1) {
-        uint8_t chance = (rand() % 9) + 1;
-        switch (chance) {
-            case 1: case 2: case 3:
-                code_point = rand() % 0x80;
-                break;
-            case 4: case 5: case 6:
-                code_point = (rand() % (0x0800  - 0x0080)) + 0x0080;
-                break;
-            case 7: case 8:
-                code_point = (rand() % (0x10000 - 0x0800)) + 0x0800;
-                break;
-            case 9: {
-                    uint64_t num = TestUtils_random_u64();
-                    code_point = (num % (0x10FFFF - 0x10000)) + 0x10000;
-                }
-        }
-        if (code_point > 0x10FFFF) {
-            continue; // Too high.
-        }
-        if (code_point > 0xD7FF && code_point < 0xE000) {
-            continue; // UTF-16 surrogate.
-        }
-        break;
-    }
-    return code_point;
-}
-
-CharBuf*
-TestUtils_random_string(size_t length) {
-    CharBuf *string = CB_new(length);
-    while (length--) {
-        CB_Cat_Char(string, S_random_code_point());
-    }
-    return string;
-}
-
-CharBuf*
-TestUtils_get_cb(const char *ptr) {
-    return CB_new_from_utf8(ptr, strlen(ptr));
-}
-
-Obj*
-TestUtils_freeze_thaw(Obj *object) {
-    if (object) {
-        RAMFile *ram_file = RAMFile_new(NULL, false);
-        OutStream *outstream = OutStream_open((Obj*)ram_file);
-        FREEZE(object, outstream);
-        OutStream_Close(outstream);
-        DECREF(outstream);
-
-        InStream *instream = InStream_open((Obj*)ram_file);
-        Obj *retval = THAW(instream);
-        DECREF(instream);
-        DECREF(ram_file);
-        return retval;
-    }
-    else {
-        return NULL;
-    }
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestUtils.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestUtils.cfh b/core/Clownfish/Test/TestUtils.cfh
deleted file mode 100644
index 5c88ec4..0000000
--- a/core/Clownfish/Test/TestUtils.cfh
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-parcel Clownfish;
-
-inert class Clownfish::Test::TestUtils  {
-
-    /** Testing-only CharBuf factory which uses strlen().
-     */
-    inert incremented CharBuf*
-    get_cb(const char *utf8);
-
-    /** Return a random unsigned 64-bit integer.
-     */
-    inert uint64_t
-    random_u64();
-
-    /** Return an array of <code>count</code> random 64-bit integers where
-     * <code>min <= n < limit</code>.
-     *
-     * If <code>buf</code> is NULL, it will be allocated, otherwise it will
-     * be used.
-     */
-    inert int64_t*
-    random_i64s(int64_t *buf, size_t count, int64_t min, int64_t limit);
-
-    /** Return an array of <code>count</code> random unsigned, 64-bit integers
-     * where <code>min <= n < limit</code>.
-     *
-     * If <code>buf</code> is NULL, it will be allocated, otherwise it will
-     * be used.
-     */
-    inert uint64_t*
-    random_u64s(uint64_t *buf, size_t count, uint64_t min, uint64_t limit);
-
-    /** Return an array of <code>count</code> random double-precision floating
-     * point numbers between 0 and 1.
-     *
-     * If <code>buf</code> is NULL, it will be allocated, otherwise it will
-     * be used.
-     */
-    inert double*
-    random_f64s(double *buf, size_t count);
-
-    /** Return a string with a random (legal) sequence of code points.
-     * @param length Length of the string in code points.
-     */
-    inert incremented CharBuf*
-    random_string(size_t length);
-
-    /** Return the result of round-tripping the object through FREEZE and
-     * THAW.
-     */
-    inert incremented Obj*
-    freeze_thaw(Obj *object);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestVArray.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestVArray.c b/core/Clownfish/Test/TestVArray.c
index 99b5918..110c01b 100644
--- a/core/Clownfish/Test/TestVArray.c
+++ b/core/Clownfish/Test/TestVArray.c
@@ -25,8 +25,8 @@
 #include "Clownfish/Err.h"
 #include "Clownfish/Num.h"
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/Test/TestUtils.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
+#include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/VArray.h"
 #include "Clownfish/VTable.h"
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/TestVArray.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/TestVArray.cfh b/core/Clownfish/Test/TestVArray.cfh
index 481dbb4..478127a 100644
--- a/core/Clownfish/Test/TestVArray.cfh
+++ b/core/Clownfish/Test/TestVArray.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::TestVArray
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestVArray*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/Util/TestAtomic.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/Util/TestAtomic.c b/core/Clownfish/Test/Util/TestAtomic.c
index 3610f7d..6187198 100644
--- a/core/Clownfish/Test/Util/TestAtomic.c
+++ b/core/Clownfish/Test/Util/TestAtomic.c
@@ -20,7 +20,7 @@
 #include "Clownfish/Test/Util/TestAtomic.h"
 
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
 #include "Clownfish/Util/Atomic.h"
 #include "Clownfish/VTable.h"
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/Util/TestAtomic.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/Util/TestAtomic.cfh b/core/Clownfish/Test/Util/TestAtomic.cfh
index 90d905e..576eec9 100644
--- a/core/Clownfish/Test/Util/TestAtomic.cfh
+++ b/core/Clownfish/Test/Util/TestAtomic.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::Util::TestAtomic
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestAtomic*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/Util/TestMemory.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/Util/TestMemory.c b/core/Clownfish/Test/Util/TestMemory.c
index a3ac538..0c58b99 100644
--- a/core/Clownfish/Test/Util/TestMemory.c
+++ b/core/Clownfish/Test/Util/TestMemory.c
@@ -21,7 +21,7 @@
 #include "Clownfish/Test/Util/TestMemory.h"
 
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
 #include "Clownfish/Util/Memory.h"
 #include "Clownfish/VTable.h"
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/Util/TestMemory.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/Util/TestMemory.cfh b/core/Clownfish/Test/Util/TestMemory.cfh
index 23252c2..6426935 100644
--- a/core/Clownfish/Test/Util/TestMemory.cfh
+++ b/core/Clownfish/Test/Util/TestMemory.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::Util::TestMemory
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestMemory*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/Util/TestNumberUtils.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/Util/TestNumberUtils.c b/core/Clownfish/Test/Util/TestNumberUtils.c
index b524818..04c79f0 100644
--- a/core/Clownfish/Test/Util/TestNumberUtils.c
+++ b/core/Clownfish/Test/Util/TestNumberUtils.c
@@ -24,8 +24,8 @@
 
 #include "Clownfish/Err.h"
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/Test/TestUtils.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
+#include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/Util/Memory.h"
 #include "Clownfish/Util/NumberUtils.h"
 #include "Clownfish/VTable.h"

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/Util/TestNumberUtils.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/Util/TestNumberUtils.cfh b/core/Clownfish/Test/Util/TestNumberUtils.cfh
index 1c6659e..1e4bacc 100644
--- a/core/Clownfish/Test/Util/TestNumberUtils.cfh
+++ b/core/Clownfish/Test/Util/TestNumberUtils.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::Util::TestNumberUtils cnick TestNumUtil
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestNumberUtils*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/Util/TestStringHelper.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/Util/TestStringHelper.c b/core/Clownfish/Test/Util/TestStringHelper.c
index 18cc4db..0ca46e9 100644
--- a/core/Clownfish/Test/Util/TestStringHelper.c
+++ b/core/Clownfish/Test/Util/TestStringHelper.c
@@ -24,8 +24,8 @@
 #include "Clownfish/CharBuf.h"
 #include "Clownfish/Err.h"
 #include "Clownfish/Test.h"
-#include "Clownfish/Test/TestFormatter.h"
-#include "Clownfish/Test/TestUtils.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
+#include "Clownfish/TestHarness/TestUtils.h"
 #include "Clownfish/Util/StringHelper.h"
 #include "Clownfish/VTable.h"
 #include "Lucy/Util/Json.h"

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/Test/Util/TestStringHelper.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/Test/Util/TestStringHelper.cfh b/core/Clownfish/Test/Util/TestStringHelper.cfh
index 1c33ea5..219ec81 100644
--- a/core/Clownfish/Test/Util/TestStringHelper.cfh
+++ b/core/Clownfish/Test/Util/TestStringHelper.cfh
@@ -17,7 +17,7 @@
 parcel TestClownfish;
 
 class Clownfish::Test::Util::TestStringHelper cnick TestStrHelp
-    inherits Clownfish::Test::TestBatch {
+    inherits Clownfish::TestHarness::TestBatch {
 
     inert incremented TestStringHelper*
     new(TestFormatter *formatter);

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/TestHarness/TestBatch.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/TestHarness/TestBatch.c b/core/Clownfish/TestHarness/TestBatch.c
new file mode 100644
index 0000000..486e967
--- /dev/null
+++ b/core/Clownfish/TestHarness/TestBatch.c
@@ -0,0 +1,293 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#define C_CFISH_TESTBATCH
+#define CFISH_USE_SHORT_NAMES
+#define LUCY_USE_SHORT_NAMES
+#include "Clownfish/TestHarness/TestBatch.h"
+#include "Clownfish/CharBuf.h"
+#include "Clownfish/Err.h"
+#include "Clownfish/TestHarness/TestFormatter.h"
+#include "Clownfish/VArray.h"
+#include "Clownfish/VTable.h"
+
+struct try_run_tests_context {
+    TestBatch *batch;
+};
+
+static void
+S_try_run_tests(void *context);
+
+static bool
+S_vtest_true(TestBatch *self, bool condition, const char *pattern,
+             va_list args);
+
+TestBatch*
+TestBatch_new(uint32_t num_planned, TestFormatter *formatter) {
+    TestBatch *self = (TestBatch*)VTable_Make_Obj(TESTBATCH);
+    return TestBatch_init(self, num_planned, formatter);
+}
+
+TestBatch*
+TestBatch_init(TestBatch *self, uint32_t num_planned,
+               TestFormatter *formatter) {
+    // Assign.
+    self->num_planned = num_planned;
+    self->formatter   = (TestFormatter*)INCREF(formatter);
+
+    // Initialize.
+    self->test_num    = 0;
+    self->num_passed  = 0;
+    self->num_failed  = 0;
+    self->num_skipped = 0;
+
+    return self;
+}
+
+void
+TestBatch_destroy(TestBatch *self) {
+    DECREF(self->formatter);
+    SUPER_DESTROY(self, TESTBATCH);
+}
+
+bool
+TestBatch_run(TestBatch *self) {
+    TestFormatter_Batch_Prologue(self->formatter, self);
+
+    struct try_run_tests_context args;
+    args.batch = self;
+    Err *err = Err_trap(S_try_run_tests, &args);
+
+    bool failed = false;
+    if (err) {
+        failed = true;
+        CharBuf *mess = Err_Get_Mess(err);
+        INCREF(mess);
+        Err_warn_mess(mess);
+    }
+    if (self->num_failed > 0) {
+        failed = true;
+        TestFormatter_batch_comment(self->formatter, "%d/%d tests failed.\n",
+                                    self->num_failed, self->test_num);
+    }
+    if (self->test_num != self->num_planned) {
+        failed = true;
+        TestFormatter_batch_comment(self->formatter,
+                                    "Bad plan: You planned %d tests but ran"
+                                    " %d.\n",
+                                    self->num_planned, self->test_num);
+    }
+
+    return !failed;
+}
+
+static void
+S_try_run_tests(void *context) {
+    struct try_run_tests_context *args
+        = (struct try_run_tests_context*)context;
+    TestBatch_Run_Tests(args->batch);
+}
+
+uint32_t
+TestBatch_get_num_planned(TestBatch *self) {
+    return self->num_planned;
+}
+
+uint32_t
+TestBatch_get_num_tests(TestBatch *self) {
+    return self->test_num;
+}
+
+uint32_t
+TestBatch_get_num_failed(TestBatch *self) {
+    return self->num_failed;
+}
+
+bool
+TestBatch_test_true(void *vself, bool condition, const char *pattern, ...) {
+    va_list args;
+    va_start(args, pattern);
+    bool result = TestBatch_VTest_True((TestBatch*)vself, condition,
+                                         pattern, args);
+    va_end(args);
+    return result;
+}
+
+bool
+TestBatch_test_false(void *vself, bool condition, const char *pattern, ...) {
+    va_list args;
+    va_start(args, pattern);
+    bool result = TestBatch_VTest_False((TestBatch*)vself, condition,
+                                          pattern, args);
+    va_end(args);
+    return result;
+}
+
+bool
+TestBatch_test_int_equals(void *vself, long got, long expected,
+                          const char *pattern, ...) {
+    va_list args;
+    va_start(args, pattern);
+    bool result = TestBatch_VTest_Int_Equals((TestBatch*)vself, got,
+                                               expected, pattern, args);
+    va_end(args);
+    return result;
+}
+
+bool
+TestBatch_test_float_equals(void *vself, double got, double expected,
+                            const char *pattern, ...) {
+    va_list args;
+    va_start(args, pattern);
+    bool result = TestBatch_VTest_Float_Equals((TestBatch*)vself, got,
+                                                 expected, pattern, args);
+    va_end(args);
+    return result;
+}
+
+bool
+TestBatch_test_string_equals(void *vself, const char *got,
+                             const char *expected, const char *pattern, ...) {
+    va_list args;
+    va_start(args, pattern);
+    bool result = TestBatch_VTest_String_Equals((TestBatch*)vself, got,
+                                                  expected, pattern, args);
+    va_end(args);
+    return result;
+}
+
+bool
+TestBatch_pass(void *vself, const char *pattern, ...) {
+    va_list args;
+    va_start(args, pattern);
+    bool result = TestBatch_VPass((TestBatch*)vself, pattern, args);
+    va_end(args);
+    return result;
+}
+
+bool
+TestBatch_fail(void *vself, const char *pattern, ...) {
+    va_list args;
+    va_start(args, pattern);
+    bool result = TestBatch_VFail((TestBatch*)vself, pattern, args);
+    va_end(args);
+    return result;
+}
+
+void
+TestBatch_skip(void *vself, const char *pattern, ...) {
+    va_list args;
+    va_start(args, pattern);
+    TestBatch_VSkip((TestBatch*)vself, pattern, args);
+    va_end(args);
+}
+
+bool
+TestBatch_vtest_true(TestBatch *self, bool condition, const char *pattern,
+                     va_list args) {
+    return S_vtest_true(self, condition, pattern, args);
+}
+
+bool
+TestBatch_vtest_false(TestBatch *self, bool condition,
+                      const char *pattern, va_list args) {
+    return S_vtest_true(self, !condition, pattern, args);
+}
+
+bool
+TestBatch_vtest_int_equals(TestBatch *self, long got, long expected,
+                           const char *pattern, va_list args) {
+    bool pass = (got == expected);
+    S_vtest_true(self, pass, pattern, args);
+    if (!pass) {
+        TestFormatter_test_comment(self->formatter,
+                                   "Expected '%ld', got '%ld'.\n",
+                                   expected, got);
+    }
+    return pass;
+}
+
+bool
+TestBatch_vtest_float_equals(TestBatch *self, double got, double expected,
+                             const char *pattern, va_list args) {
+    double relative_error = got / expected - 1.0;
+    bool   pass           = (fabs(relative_error) < 1e-6);
+    S_vtest_true(self, pass, pattern, args);
+    if (!pass) {
+        TestFormatter_test_comment(self->formatter,
+                                   "Expected '%e', got '%e'.\n",
+                                   expected, got);
+    }
+    return pass;
+}
+
+bool
+TestBatch_vtest_string_equals(TestBatch *self, const char *got,
+                              const char *expected, const char *pattern,
+                              va_list args) {
+    bool pass = (strcmp(got, expected) == 0);
+    S_vtest_true(self, pass, pattern, args);
+    if (!pass) {
+        TestFormatter_test_comment(self->formatter,
+                                   "Expected '%s', got '%s'.\n",
+                                   expected, got);
+    }
+    return pass;
+}
+
+bool
+TestBatch_vpass(TestBatch *self, const char *pattern, va_list args) {
+    return S_vtest_true(self, true, pattern, args);
+}
+
+bool
+TestBatch_vfail(TestBatch *self, const char *pattern, va_list args) {
+    return S_vtest_true(self, false, pattern, args);
+}
+
+void
+TestBatch_vskip(TestBatch *self, const char *pattern, va_list args) {
+    self->test_num++;
+    // TODO: Add a VTest_Skip method to TestFormatter
+    TestFormatter_VTest_Result(self->formatter, true, self->test_num,
+                               pattern, args);
+    self->num_skipped++;
+}
+
+static bool
+S_vtest_true(TestBatch* self, bool condition, const char *pattern,
+             va_list args) {
+    // Increment test number.
+    self->test_num++;
+
+    if (condition) {
+        self->num_passed++;
+    }
+    else {
+        self->num_failed++;
+    }
+
+    TestFormatter_VTest_Result(self->formatter, condition, self->test_num,
+                               pattern, args);
+
+    return condition;
+}
+
+

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/TestHarness/TestBatch.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/TestHarness/TestBatch.cfh b/core/Clownfish/TestHarness/TestBatch.cfh
new file mode 100644
index 0000000..cf82286
--- /dev/null
+++ b/core/Clownfish/TestHarness/TestBatch.cfh
@@ -0,0 +1,120 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+parcel Clownfish;
+
+abstract class Clownfish::TestHarness::TestBatch inherits Clownfish::Obj {
+    TestFormatter *formatter;
+    uint32_t       test_num;
+    uint32_t       num_planned;
+    uint32_t       num_passed;
+    uint32_t       num_failed;
+    uint32_t       num_skipped;
+
+    inert incremented TestBatch*
+    new(uint32_t num_planned, TestFormatter *formatter);
+
+    inert TestBatch*
+    init(TestBatch *self, uint32_t num_planned, TestFormatter *formatter);
+
+    public void
+    Destroy(TestBatch *self);
+
+    /** Run the test batch and print test output and diagnosis.
+     *
+     * @return true if the test batch passed.
+     */
+    bool
+    Run(TestBatch *self);
+
+    /** Run the tests of the test batch.
+     */
+    abstract void
+    Run_Tests(TestBatch *self);
+
+    /** Return the number of tests planned.
+     */
+    uint32_t
+    Get_Num_Planned(TestBatch *self);
+
+    /** Return the number of tests run.
+     */
+    uint32_t
+    Get_Num_Tests(TestBatch *self);
+
+    /** Return the number of failed tests.
+     */
+    uint32_t
+    Get_Num_Failed(TestBatch *self);
+
+    inert bool
+    test_true(void *vself, bool condition, const char *pattern, ...);
+
+    inert bool
+    test_false(void *vself, bool condition, const char *pattern, ...);
+
+    inert bool
+    test_int_equals(void *vself, long got, long expected,
+                    const char *pattern, ...);
+
+    inert bool
+    test_float_equals(void *vself, double got, double expected,
+                      const char *pattern, ...);
+
+    inert bool
+    test_string_equals(void *vself, const char *got, const char *expected,
+                       const char *pattern, ...);
+
+    inert bool
+    pass(void *vself, const char *pattern, ...);
+
+    inert bool
+    fail(void *vself, const char *pattern, ...);
+
+    inert void
+    skip(void *vself, const char *pattern, ...);
+
+    bool
+    VTest_True(TestBatch *self, bool condition, const char *pattern,
+               va_list args);
+
+    bool
+    VTest_False(TestBatch *self, bool condition, const char *pattern,
+                va_list args);
+
+    bool
+    VTest_Int_Equals(TestBatch *self, long got, long expected,
+                     const char *pattern, va_list args);
+
+    bool
+    VTest_Float_Equals(TestBatch *self, double got, double expected,
+                       const char *pattern, va_list args);
+
+    bool
+    VTest_String_Equals(TestBatch *self, const char *got, const char *expected,
+                       const char *pattern, va_list args);
+
+    bool
+    VPass(TestBatch *self, const char *pattern, va_list args);
+
+    bool
+    VFail(TestBatch *self, const char *pattern, va_list args);
+
+    void
+    VSkip(TestBatch *self, const char *pattern, va_list args);
+}
+
+

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/TestHarness/TestFormatter.c
----------------------------------------------------------------------
diff --git a/core/Clownfish/TestHarness/TestFormatter.c b/core/Clownfish/TestHarness/TestFormatter.c
new file mode 100644
index 0000000..b6f0ac0
--- /dev/null
+++ b/core/Clownfish/TestHarness/TestFormatter.c
@@ -0,0 +1,184 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+
+#define C_CFISH_TESTFORMATTER
+#define CFISH_USE_SHORT_NAMES
+#define LUCY_USE_SHORT_NAMES
+#define CHY_USE_SHORT_NAMES
+
+#include "Clownfish/TestHarness/TestFormatter.h"
+#include "Clownfish/CharBuf.h"
+#include "Clownfish/Err.h"
+#include "Clownfish/TestHarness/TestBatch.h"
+#include "Clownfish/TestHarness/TestRunner.h"
+#include "Clownfish/VTable.h"
+
+TestFormatter*
+TestFormatter_init(TestFormatter *self) {
+    ABSTRACT_CLASS_CHECK(self, TESTFORMATTER);
+    return self;
+}
+
+void
+TestFormatter_test_result(void *vself, bool pass, uint32_t test_num,
+                          const char *fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    TestFormatter_VTest_Result((TestFormatter*)vself, pass, test_num, fmt,
+                               args);
+    va_end(args);
+}
+
+void
+TestFormatter_test_comment(void *vself, const char *fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    TestFormatter_VTest_Comment((TestFormatter*)vself, fmt, args);
+    va_end(args);
+}
+
+void
+TestFormatter_batch_comment(void *vself, const char *fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    TestFormatter_VBatch_Comment((TestFormatter*)vself, fmt, args);
+    va_end(args);
+}
+
+TestFormatterCF*
+TestFormatterCF_new() {
+    TestFormatterCF *self
+        = (TestFormatterCF*)VTable_Make_Obj(TESTFORMATTERCF);
+    return TestFormatterCF_init(self);
+}
+
+TestFormatterCF*
+TestFormatterCF_init(TestFormatterCF *self) {
+    return (TestFormatterCF*)TestFormatter_init((TestFormatter*)self);
+}
+
+void
+TestFormatterCF_batch_prologue(TestFormatterCF *self, TestBatch *batch) {
+    UNUSED_VAR(self);
+    CharBuf *class_name = TestBatch_Get_Class_Name(batch);
+    printf("Running %s...\n", CB_Get_Ptr8(class_name));
+}
+
+void
+TestFormatterCF_vtest_result(TestFormatterCF *self, bool pass,
+                             uint32_t test_num, const char *fmt,
+                             va_list args) {
+    UNUSED_VAR(self);
+    if (!pass) {
+        printf("  Failed test %u: ", test_num);
+        vprintf(fmt, args);
+        printf("\n");
+    }
+}
+
+void
+TestFormatterCF_vtest_comment(TestFormatterCF *self, const char *fmt,
+                              va_list args) {
+    UNUSED_VAR(self);
+    printf("    ");
+    vprintf(fmt, args);
+}
+
+void
+TestFormatterCF_vbatch_comment(TestFormatterCF *self, const char *fmt,
+                               va_list args) {
+    UNUSED_VAR(self);
+    printf("  ");
+    vprintf(fmt, args);
+}
+
+void
+TestFormatterCF_summary(TestFormatterCF *self, TestRunner *runner) {
+    UNUSED_VAR(self);
+    uint32_t num_batches        = TestRunner_Get_Num_Batches(runner);
+    uint32_t num_batches_failed = TestRunner_Get_Num_Batches_Failed(runner);
+    uint32_t num_tests          = TestRunner_Get_Num_Tests(runner);
+    uint32_t num_tests_failed   = TestRunner_Get_Num_Tests_Failed(runner);
+
+    if (num_batches == 0) {
+        printf("No tests planned or run.\n");
+    }
+    else if (num_batches_failed == 0) {
+        printf("%u batches passed. %u tests passed.\n", num_batches,
+               num_tests);
+        printf("Result: PASS\n");
+    }
+    else {
+        printf("%u/%u batches failed. %u/%u tests failed.\n",
+               num_batches_failed, num_batches, num_tests_failed, num_tests);
+        printf("Result: FAIL\n");
+    }
+}
+
+TestFormatterTAP*
+TestFormatterTAP_new() {
+    TestFormatterTAP *self
+        = (TestFormatterTAP*)VTable_Make_Obj(TESTFORMATTERTAP);
+    return TestFormatterTAP_init(self);
+}
+
+TestFormatterTAP*
+TestFormatterTAP_init(TestFormatterTAP *self) {
+    return (TestFormatterTAP*)TestFormatter_init((TestFormatter*)self);
+}
+
+void
+TestFormatterTAP_batch_prologue(TestFormatterTAP *self, TestBatch *batch) {
+    UNUSED_VAR(self);
+    printf("1..%u\n", TestBatch_Get_Num_Planned(batch));
+}
+
+void
+TestFormatterTAP_vtest_result(TestFormatterTAP *self, bool pass,
+                              uint32_t test_num, const char *fmt,
+                              va_list args) {
+    UNUSED_VAR(self);
+    const char *result = pass ? "ok" : "not ok";
+    printf("%s %u - ", result, test_num);
+    vprintf(fmt, args);
+    printf("\n");
+}
+
+void
+TestFormatterTAP_vtest_comment(TestFormatterTAP *self, const char *fmt,
+                               va_list args) {
+    UNUSED_VAR(self);
+    printf("#   ");
+    vprintf(fmt, args);
+}
+
+void
+TestFormatterTAP_vbatch_comment(TestFormatterTAP *self, const char *fmt,
+                                va_list args) {
+    UNUSED_VAR(self);
+    printf("# ");
+    vprintf(fmt, args);
+}
+
+void
+TestFormatterTAP_summary(TestFormatterTAP *self, TestRunner *runner) {
+    UNUSED_VAR(self);
+    UNUSED_VAR(runner);
+}
+
+

http://git-wip-us.apache.org/repos/asf/lucy/blob/bfc96f6d/core/Clownfish/TestHarness/TestFormatter.cfh
----------------------------------------------------------------------
diff --git a/core/Clownfish/TestHarness/TestFormatter.cfh b/core/Clownfish/TestHarness/TestFormatter.cfh
new file mode 100644
index 0000000..06402d2
--- /dev/null
+++ b/core/Clownfish/TestHarness/TestFormatter.cfh
@@ -0,0 +1,138 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+parcel Clownfish;
+
+/**
+ * Abstract base class for Clownfish test formatters.
+ */
+abstract class Clownfish::TestHarness::TestFormatter inherits Clownfish::Obj {
+    inert TestFormatter*
+    init(TestFormatter *self);
+
+    inert void
+    test_result(void *vself, bool pass, uint32_t test_num, const char *fmt,
+                ...);
+
+    inert void
+    test_comment(void *vself, const char *fmt, ...);
+
+    inert void
+    batch_comment(void *vself, const char *fmt, ...);
+
+    /** Print output at the beginning of a test batch.
+     *
+     * @param batch The test batch.
+     */
+    abstract void
+    Batch_Prologue(TestFormatter *self, TestBatch *batch);
+
+    /** Print the result of a single test.
+     *
+     * @param pass True if the test passed, false otherwise.
+     * @param test_num The sequence number of the test.
+     * @param fmt printf-style format string.
+     * @param args Additional arguments.
+     */
+    abstract void
+    VTest_Result(TestFormatter *self, bool pass, uint32_t test_num,
+                 const char *fmt, va_list args);
+
+    /** Print additional diagnosis for a test.
+     *
+     * @param fmt printf-style format string.
+     * @param args Additional arguments.
+     */
+    abstract void
+    VTest_Comment(TestFormatter *self, const char *fmt, va_list args);
+
+    /** Print additional diagnosis for a test batch.
+     *
+     * @param fmt printf-style format string.
+     * @param args Additional arguments.
+     */
+    abstract void
+    VBatch_Comment(TestFormatter *self, const char *fmt, va_list args);
+
+    /** Print test summary after running all test batches.
+     *
+     * @param runner The test runner.
+     */
+    abstract void
+    Summary(TestFormatter *self, TestRunner *runner);
+}
+
+/**
+ * A TestFormatter that produces human-readable output in a custom
+ * "Clownfish" format.
+ */
+class Clownfish::Test::Formatter::TestFormatterCF
+    inherits Clownfish::TestHarness::TestFormatter {
+
+    inert incremented TestFormatterCF*
+    new();
+
+    inert TestFormatterCF*
+    init(TestFormatterCF *self);
+
+    void
+    Batch_Prologue(TestFormatterCF *self, TestBatch *batch);
+
+    void
+    VTest_Result(TestFormatterCF *self, bool pass, uint32_t test_num,
+                 const char *fmt, va_list args);
+
+    void
+    VTest_Comment(TestFormatterCF *self, const char *fmt, va_list args);
+
+    void
+    VBatch_Comment(TestFormatterCF *self, const char *fmt, va_list args);
+
+    void
+    Summary(TestFormatterCF *self, TestRunner *runner);
+}
+
+/**
+ * A TestFormatter that produces TAP output (Test Anything Protocol).
+ * See http://testanything.org/
+ */
+class Clownfish::Test::Formatter::TestFormatterTAP
+    inherits Clownfish::TestHarness::TestFormatter {
+
+    inert incremented TestFormatterTAP*
+    new();
+
+    inert TestFormatterTAP*
+    init(TestFormatterTAP *self);
+
+    void
+    Batch_Prologue(TestFormatterTAP *self, TestBatch *batch);
+
+    void
+    VTest_Result(TestFormatterTAP *self, bool pass, uint32_t test_num,
+                 const char *fmt, va_list args);
+
+    void
+    VTest_Comment(TestFormatterTAP *self, const char *fmt, va_list args);
+
+    void
+    VBatch_Comment(TestFormatterTAP *self, const char *fmt, va_list args);
+
+    void
+    Summary(TestFormatterTAP *self, TestRunner *runner);
+}
+
+