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 2016/07/11 11:25:41 UTC

[08/14] lucy-clownfish git commit: Move tests to separate directory

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestHost.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestHost.c b/runtime/core/Clownfish/Test/TestHost.c
deleted file mode 100644
index 6da0efa..0000000
--- a/runtime/core/Clownfish/Test/TestHost.c
+++ /dev/null
@@ -1,125 +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 CFISH_USE_SHORT_NAMES
-#define TESTCFISH_USE_SHORT_NAMES
-
-#include "Clownfish/Test/TestHost.h"
-#include "Clownfish/Class.h"
-#include "Clownfish/String.h"
-
-TestHost*
-TestHost_new() {
-    return (TestHost*)Class_Make_Obj(TESTHOST);
-}
-
-Obj*
-TestHost_Test_Obj_Pos_Arg_IMP(TestHost *self, Obj *arg) {
-    UNUSED_VAR(self);
-    return arg;
-}
-
-Obj*
-TestHost_Test_Obj_Pos_Arg_Def_IMP(TestHost *self, Obj *arg) {
-    UNUSED_VAR(self);
-    return arg;
-}
-
-Obj*
-TestHost_Test_Obj_Label_Arg_IMP(TestHost *self, Obj *arg, bool unused) {
-    UNUSED_VAR(self);
-    UNUSED_VAR(unused);
-    return arg;
-}
-
-Obj*
-TestHost_Test_Obj_Label_Arg_Def_IMP(TestHost *self, Obj *arg, bool unused) {
-    UNUSED_VAR(self);
-    UNUSED_VAR(unused);
-    return arg;
-}
-
-int32_t
-TestHost_Test_Int32_Pos_Arg_IMP(TestHost *self, int32_t arg) {
-    UNUSED_VAR(self);
-    return arg;
-}
-
-int32_t
-TestHost_Test_Int32_Pos_Arg_Def_IMP(TestHost *self, int32_t arg) {
-    UNUSED_VAR(self);
-    return arg;
-}
-
-int32_t
-TestHost_Test_Int32_Label_Arg_IMP(TestHost *self, int32_t arg, bool unused) {
-    UNUSED_VAR(self);
-    UNUSED_VAR(unused);
-    return arg;
-}
-
-int32_t
-TestHost_Test_Int32_Label_Arg_Def_IMP(TestHost *self, int32_t arg,
-                                      bool unused) {
-    UNUSED_VAR(self);
-    UNUSED_VAR(unused);
-    return arg;
-}
-
-bool
-TestHost_Test_Bool_Pos_Arg_IMP(TestHost *self, bool arg) {
-    UNUSED_VAR(self);
-    return arg;
-}
-
-bool
-TestHost_Test_Bool_Pos_Arg_Def_IMP(TestHost *self, bool arg) {
-    UNUSED_VAR(self);
-    return arg;
-}
-
-bool
-TestHost_Test_Bool_Label_Arg_IMP(TestHost *self, bool arg, bool unused) {
-    UNUSED_VAR(self);
-    UNUSED_VAR(unused);
-    return arg;
-}
-
-bool
-TestHost_Test_Bool_Label_Arg_Def_IMP(TestHost *self, bool arg, bool unused) {
-    UNUSED_VAR(self);
-    UNUSED_VAR(unused);
-    return arg;
-}
-
-void
-TestHost_Invoke_Invalid_Callback_From_C_IMP(TestHost *self) {
-    TestHost_Invalid_Callback(self);
-}
-
-String*
-TestHost_Aliased_IMP(TestHost *self) {
-    UNUSED_VAR(self);
-    return Str_newf("C");
-}
-
-String*
-TestHost_Invoke_Aliased_From_C_IMP(TestHost *self) {
-    UNUSED_VAR(self);
-    return TestHost_Aliased(self);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestHost.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestHost.cfh b/runtime/core/Clownfish/Test/TestHost.cfh
deleted file mode 100644
index 92bc272..0000000
--- a/runtime/core/Clownfish/Test/TestHost.cfh
+++ /dev/null
@@ -1,81 +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 TestClownfish;
-
-/** Clownfish test suite.
- */
-class Clownfish::Test::TestHost {
-    inert incremented TestHost*
-    new();
-
-    Obj*
-    Test_Obj_Pos_Arg(TestHost *self, Obj *arg);
-
-    Obj*
-    Test_Obj_Pos_Arg_Def(TestHost *self, nullable Obj *arg = NULL);
-
-    Obj*
-    Test_Obj_Label_Arg(TestHost *self, Obj *arg, bool unused = false);
-
-    Obj*
-    Test_Obj_Label_Arg_Def(TestHost *self, nullable Obj *arg = NULL,
-                           bool unused = false);
-
-    int32_t
-    Test_Int32_Pos_Arg(TestHost *self, int32_t arg);
-
-    int32_t
-    Test_Int32_Pos_Arg_Def(TestHost *self, int32_t arg = 101);
-
-    int32_t
-    Test_Int32_Label_Arg(TestHost *self, int32_t arg, bool unused = false);
-
-    int32_t
-    Test_Int32_Label_Arg_Def(TestHost *self, int32_t arg = 101,
-                             bool unused = false);
-
-    bool
-    Test_Bool_Pos_Arg(TestHost *self, bool arg);
-
-    bool
-    Test_Bool_Pos_Arg_Def(TestHost *self, bool arg = true);
-
-    bool
-    Test_Bool_Label_Arg(TestHost *self, bool arg, bool unused = false);
-
-    bool
-    Test_Bool_Label_Arg_Def(TestHost *self, bool arg = true,
-                            bool unused = false);
-
-    /** A method that can't be overridden from the host language.
-     */
-    abstract void*
-    Invalid_Callback(TestHost *self);
-
-    void
-    Invoke_Invalid_Callback_From_C(TestHost *self);
-
-    /** A method with a custom host language alias.
-     */
-    incremented String*
-    Aliased(TestHost *self);
-
-    incremented String*
-    Invoke_Aliased_From_C(TestHost* self);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestLockFreeRegistry.c b/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
deleted file mode 100644
index b70ff1f..0000000
--- a/runtime/core/Clownfish/Test/TestLockFreeRegistry.c
+++ /dev/null
@@ -1,168 +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 CFISH_USE_SHORT_NAMES
-#define TESTCFISH_USE_SHORT_NAMES
-
-#include "Clownfish/Test/TestLockFreeRegistry.h"
-
-#include "Clownfish/Class.h"
-#include "Clownfish/LockFreeRegistry.h"
-#include "Clownfish/String.h"
-#include "Clownfish/Test.h"
-#include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/TestHarness/TestUtils.h"
-#include "Clownfish/Util/Memory.h"
-
-#define NUM_THREADS 5
-
-typedef struct ThreadArgs {
-    LockFreeRegistry *registry;
-    uint32_t         *nums;
-    uint32_t          num_objs;
-    uint64_t          target_time;
-    uint32_t          succeeded;
-} ThreadArgs;
-
-TestLockFreeRegistry*
-TestLFReg_new() {
-    return (TestLockFreeRegistry*)Class_Make_Obj(TESTLOCKFREEREGISTRY);
-}
-
-static void
-test_all(TestBatchRunner *runner) {
-    LockFreeRegistry *registry = LFReg_new(1);
-    String *foo = Str_newf("foo");
-    String *bar = Str_newf("bar");
-    String *baz = Str_newf("baz");
-    String *foo_dupe = Str_newf("foo");
-
-    TEST_TRUE(runner, LFReg_register(registry, foo, (Obj*)foo),
-              "Register() returns true on success");
-    TEST_FALSE(runner,
-               LFReg_register(registry, foo_dupe, (Obj*)foo_dupe),
-               "Can't Register() keys that test equal");
-
-    TEST_TRUE(runner, LFReg_register(registry, bar, (Obj*)bar),
-              "Register() key with the same Hash_Sum but that isn't Equal");
-
-    TEST_TRUE(runner, LFReg_fetch(registry, foo_dupe) == (Obj*)foo,
-              "Fetch()");
-    TEST_TRUE(runner, LFReg_fetch(registry, bar) == (Obj*)bar,
-              "Fetch() again");
-    TEST_TRUE(runner, LFReg_fetch(registry, baz) == NULL,
-              "Fetch() non-existent key returns NULL");
-
-    DECREF(foo_dupe);
-    DECREF(baz);
-    DECREF(bar);
-    DECREF(foo);
-    LFReg_destroy(registry);
-}
-
-static void
-S_register_many(void *varg) {
-    ThreadArgs *args = (ThreadArgs*)varg;
-
-    // Encourage contention, so that all threads try to register at the same
-    // time.
-
-    // Sleep until target_time.
-    uint64_t time = TestUtils_time();
-    if (args->target_time > time) {
-        TestUtils_usleep(args->target_time - time);
-    }
-
-    TestUtils_thread_yield();
-
-    uint32_t succeeded = 0;
-    for (uint32_t i = 0; i < args->num_objs; i++) {
-        String *obj = Str_newf("%u32", args->nums[i]);
-        if (LFReg_register(args->registry, obj, (Obj*)obj)) {
-            succeeded++;
-        }
-        DECREF(obj);
-    }
-
-    args->succeeded = succeeded;
-}
-
-static void
-test_threads(TestBatchRunner *runner) {
-    if (!TestUtils_has_threads) {
-        SKIP(runner, 1, "No thread support");
-        return;
-    }
-
-    LockFreeRegistry *registry = LFReg_new(32);
-    ThreadArgs thread_args[NUM_THREADS];
-    uint32_t num_objs = 10000;
-
-    for (uint32_t i = 0; i < NUM_THREADS; i++) {
-        uint32_t *nums = (uint32_t*)MALLOCATE(num_objs * sizeof(uint32_t));
-
-        for (uint32_t j = 0; j < num_objs; j++) {
-            nums[j] = j;
-        }
-
-        // Fisher-Yates shuffle.
-        for (uint32_t j = num_objs - 1; j > 0; j--) {
-            uint32_t r = (uint32_t)TestUtils_random_u64() % (j + 1);
-            uint32_t tmp = nums[j];
-            nums[j] = nums[r];
-            nums[r] = tmp;
-        }
-
-        thread_args[i].registry = registry;
-        thread_args[i].nums     = nums;
-        thread_args[i].num_objs = num_objs;
-    }
-
-    Thread *threads[NUM_THREADS];
-    uint64_t target_time = TestUtils_time() + 200 * 1000;
-
-    for (uint32_t i = 0; i < NUM_THREADS; i++) {
-        thread_args[i].target_time = target_time;
-        threads[i]
-            = TestUtils_thread_create(S_register_many, &thread_args[i], NULL);
-    }
-
-    uint32_t total_succeeded = 0;
-
-    for (uint32_t i = 0; i < NUM_THREADS; i++) {
-        TestUtils_thread_join(threads[i]);
-        total_succeeded += thread_args[i].succeeded;
-        FREEMEM(thread_args[i].nums);
-    }
-
-    TEST_INT_EQ(runner, total_succeeded, num_objs,
-                "registered exactly the right number of entries across all"
-                " threads");
-
-    LFReg_destroy(registry);
-}
-
-void
-TestLFReg_Run_IMP(TestLockFreeRegistry *self, TestBatchRunner *runner) {
-    TestBatchRunner_Plan(runner, (TestBatch*)self, 7);
-    test_all(runner);
-    test_threads(runner);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestLockFreeRegistry.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestLockFreeRegistry.cfh b/runtime/core/Clownfish/Test/TestLockFreeRegistry.cfh
deleted file mode 100644
index 784f745..0000000
--- a/runtime/core/Clownfish/Test/TestLockFreeRegistry.cfh
+++ /dev/null
@@ -1,29 +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 TestClownfish;
-
-class Clownfish::Test::TestLockFreeRegistry nickname TestLFReg
-    inherits Clownfish::TestHarness::TestBatch {
-
-    inert incremented TestLockFreeRegistry*
-    new();
-
-    void
-    Run(TestLockFreeRegistry *self, TestBatchRunner *runner);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestMethod.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestMethod.c b/runtime/core/Clownfish/Test/TestMethod.c
deleted file mode 100644
index 7c39759..0000000
--- a/runtime/core/Clownfish/Test/TestMethod.c
+++ /dev/null
@@ -1,91 +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 CFISH_USE_SHORT_NAMES
-#define TESTCFISH_USE_SHORT_NAMES
-
-#include "Clownfish/Test/TestMethod.h"
-
-#include "Clownfish/Err.h"
-#include "Clownfish/Method.h"
-#include "Clownfish/String.h"
-#include "Clownfish/TestHarness/TestBatchRunner.h"
-
-TestMethod*
-TestMethod_new() {
-    return (TestMethod*)Class_Make_Obj(TESTMETHOD);
-}
-
-static void
-S_set_host_alias(void *context) {
-    Method *method = (Method*)context;
-    Method_Set_Host_Alias(method, SSTR_WRAP_C("foo"));
-}
-
-static void
-test_accessors(TestBatchRunner *runner) {
-    String *name = SSTR_WRAP_C("Frobnicate_Widget");
-    Method *method = Method_new(name, NULL, 0);
-
-    TEST_TRUE(runner, Str_Equals(Method_Get_Name(method), (Obj*)name),
-              "Get_Name");
-
-    String *alias = SSTR_WRAP_C("host_frob");
-    Method_Set_Host_Alias(method, alias);
-    TEST_TRUE(runner, Str_Equals(Method_Get_Host_Alias(method), (Obj*)alias),
-              "Set_Host_Alias");
-    Err *error = Err_trap(S_set_host_alias, method);
-    TEST_TRUE(runner, error != NULL,
-              "Set_Host_Alias can't be called more than once");
-    DECREF(error);
-
-    TEST_FALSE(runner, Method_Is_Excluded_From_Host(method),
-               "Is_Excluded_From_Host");
-
-    Method_Destroy(method);
-}
-
-static void
-test_lower_snake_alias(TestBatchRunner *runner) {
-    String *name = SSTR_WRAP_C("Frobnicate_Widget");
-    Method *method = Method_new(name, NULL, 0);
-
-    {
-        String *alias = Method_lower_snake_alias(method);
-        TEST_TRUE(runner, Str_Equals_Utf8(alias, "frobnicate_widget", 17),
-                  "lower_snake_alias without explicit alias");
-        DECREF(alias);
-    }
-
-    {
-        String *new_alias = SSTR_WRAP_C("host_frob");
-        Method_Set_Host_Alias(method, new_alias);
-        String *alias = Method_lower_snake_alias(method);
-        TEST_TRUE(runner, Str_Equals(alias, (Obj*)new_alias),
-                  "lower_snake_alias with explicit alias");
-        DECREF(alias);
-    }
-
-    Method_Destroy(method);
-}
-
-void
-TestMethod_Run_IMP(TestMethod *self, TestBatchRunner *runner) {
-    TestBatchRunner_Plan(runner, (TestBatch*)self, 6);
-    test_accessors(runner);
-    test_lower_snake_alias(runner);
-}
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestMethod.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestMethod.cfh b/runtime/core/Clownfish/Test/TestMethod.cfh
deleted file mode 100644
index 76b9558..0000000
--- a/runtime/core/Clownfish/Test/TestMethod.cfh
+++ /dev/null
@@ -1,28 +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 TestClownfish;
-
-class Clownfish::Test::TestMethod
-    inherits Clownfish::TestHarness::TestBatch {
-
-    inert incremented TestMethod*
-    new();
-
-    void
-    Run(TestMethod *self, TestBatchRunner *runner);
-}
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestNum.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestNum.c b/runtime/core/Clownfish/Test/TestNum.c
deleted file mode 100644
index dfa6769..0000000
--- a/runtime/core/Clownfish/Test/TestNum.c
+++ /dev/null
@@ -1,278 +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 CFISH_USE_SHORT_NAMES
-#define TESTCFISH_USE_SHORT_NAMES
-
-#include <math.h>
-
-#include "charmony.h"
-
-#include "Clownfish/Test/TestNum.h"
-
-#include "Clownfish/Err.h"
-#include "Clownfish/String.h"
-#include "Clownfish/Num.h"
-#include "Clownfish/Test.h"
-#include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/TestHarness/TestUtils.h"
-#include "Clownfish/Class.h"
-
-TestNum*
-TestNum_new() {
-    return (TestNum*)Class_Make_Obj(TESTNUM);
-}
-
-static void
-test_To_String(TestBatchRunner *runner) {
-    Float   *f64 = Float_new(1.33);
-    Integer *i64 = Int_new(INT64_MAX);
-    String *f64_string = Float_To_String(f64);
-    String *i64_string = Int_To_String(i64);
-
-    TEST_TRUE(runner, Str_Starts_With_Utf8(f64_string, "1.3", 3),
-              "Float_To_String");
-    TEST_TRUE(runner, Str_Equals_Utf8(i64_string, "9223372036854775807", 19),
-              "Int_To_String");
-
-    DECREF(i64_string);
-    DECREF(f64_string);
-    DECREF(i64);
-    DECREF(f64);
-}
-
-static void
-S_float_to_i64(void *context) {
-    Float *f = (Float*)context;
-    Float_To_I64(f);
-}
-
-static void
-test_accessors(TestBatchRunner *runner) {
-    Float   *f64 = Float_new(1.33);
-    Integer *i64 = Int_new(INT64_MIN);
-    double wanted64 = 1.33;
-    double got64;
-
-    got64 = Float_Get_Value(f64);
-    TEST_TRUE(runner, *(int64_t*)&got64 == *(int64_t*)&wanted64,
-              "F64 Get_Value");
-    TEST_TRUE(runner, Float_To_I64(f64) == 1, "Float_To_I64");
-
-    {
-        Float *huge = Float_new(1e40);
-        Err *error = Err_trap(S_float_to_i64, huge);
-        TEST_TRUE(runner, error != NULL,
-                  "Float_To_I64 throws when out of range (+)");
-        DECREF(error);
-        DECREF(huge);
-    }
-
-    {
-        Float *huge = Float_new(-1e40);
-        Err *error = Err_trap(S_float_to_i64, huge);
-        TEST_TRUE(runner, error != NULL,
-                  "Float_To_I64 throws when out of range (-)");
-        DECREF(error);
-        DECREF(huge);
-    }
-
-    TEST_TRUE(runner, Int_Get_Value(i64) == INT64_MIN, "I64 Get_Value");
-    TEST_TRUE(runner, Int_To_F64(i64) == -9223372036854775808.0, "Int_To_F64");
-
-    DECREF(i64);
-    DECREF(f64);
-}
-
-static void
-S_test_compare_float_int(TestBatchRunner *runner, double f64_val,
-                         int64_t i64_val, int32_t result) {
-    Float *f64;
-    Integer *i64;
-
-    f64 = Float_new(f64_val);
-    i64 = Int_new(i64_val);
-    TEST_INT_EQ(runner, Float_Compare_To(f64, (Obj*)i64), result,
-                "Float_Compare_To %f %" PRId64, f64_val, i64_val);
-    TEST_INT_EQ(runner, Int_Compare_To(i64, (Obj*)f64), -result,
-                "Int_Compare_To %" PRId64" %f", i64_val, f64_val);
-    TEST_INT_EQ(runner, Float_Equals(f64, (Obj*)i64), result == 0,
-                "Float_Equals %f %" PRId64, f64_val, i64_val);
-    TEST_INT_EQ(runner, Int_Equals(i64, (Obj*)f64), result == 0,
-                "Int_Equals %" PRId64 " %f", i64_val, f64_val);
-    DECREF(f64);
-    DECREF(i64);
-
-    if (i64_val == INT64_MIN) { return; }
-
-    f64 = Float_new(-f64_val);
-    i64 = Int_new(-i64_val);
-    TEST_INT_EQ(runner, Float_Compare_To(f64, (Obj*)i64), -result,
-                "Float_Compare_To %f %" PRId64, -f64_val, -i64_val);
-    TEST_INT_EQ(runner, Int_Compare_To(i64, (Obj*)f64), result,
-                "Int_Compare_To %" PRId64" %f", -i64_val, -f64_val);
-    TEST_INT_EQ(runner, Float_Equals(f64, (Obj*)i64), result == 0,
-                "Float_Equals %f %" PRId64, -f64_val, -i64_val);
-    TEST_INT_EQ(runner, Int_Equals(i64, (Obj*)f64), result == 0,
-                "Int_Equals %" PRId64 " %f", -i64_val, -f64_val);
-    DECREF(f64);
-    DECREF(i64);
-}
-
-static void
-S_float_compare_to(void *context) {
-    Float *f = (Float*)context;
-    Float_Compare_To(f, (Obj*)OBJ);
-}
-
-static void
-S_int_compare_to(void *context) {
-    Integer *i = (Integer*)context;
-    Int_Compare_To(i, (Obj*)OBJ);
-}
-
-static void
-test_Equals_and_Compare_To(TestBatchRunner *runner) {
-    {
-        Float *f1 = Float_new(1.0);
-        Float *f2 = Float_new(1.0);
-        TEST_TRUE(runner, Float_Compare_To(f1, (Obj*)f2) == 0,
-                  "Float_Compare_To equal");
-        TEST_TRUE(runner, Float_Equals(f1, (Obj*)f2),
-                  "Float_Equals equal");
-        DECREF(f1);
-        DECREF(f2);
-    }
-
-    {
-        Float *f1 = Float_new(1.0);
-        Float *f2 = Float_new(2.0);
-        TEST_TRUE(runner, Float_Compare_To(f1, (Obj*)f2) < 0,
-                  "Float_Compare_To less than");
-        TEST_FALSE(runner, Float_Equals(f1, (Obj*)f2),
-                   "Float_Equals less than");
-        DECREF(f1);
-        DECREF(f2);
-    }
-
-    {
-        Float *f1 = Float_new(1.0);
-        Float *f2 = Float_new(0.0);
-        TEST_TRUE(runner, Float_Compare_To(f1, (Obj*)f2) > 0,
-                  "Float_Compare_To greater than");
-        TEST_FALSE(runner, Float_Equals(f1, (Obj*)f2),
-                   "Float_Equals greater than");
-        DECREF(f1);
-        DECREF(f2);
-    }
-
-    {
-        Float *f = Float_new(1.0);
-        Err *error = Err_trap(S_float_compare_to, f);
-        TEST_TRUE(runner, error != NULL,
-                  "Float_Compare_To with invalid type throws");
-        TEST_FALSE(runner, Float_Equals(f, (Obj*)OBJ),
-                   "Float_Equals with different type");
-        DECREF(error);
-        DECREF(f);
-    }
-
-    {
-        Integer *i1 = Int_new(INT64_C(0x6666666666666666));
-        Integer *i2 = Int_new(INT64_C(0x6666666666666666));
-        TEST_TRUE(runner, Int_Compare_To(i1, (Obj*)i2) == 0,
-                  "Int_Compare_To equal");
-        TEST_TRUE(runner, Int_Equals(i1, (Obj*)i2),
-                  "Int_Equals equal");
-        DECREF(i1);
-        DECREF(i2);
-    }
-
-    {
-        Integer *i1 = Int_new(INT64_C(0x6666666666666666));
-        Integer *i2 = Int_new(INT64_C(0x6666666666666667));
-        TEST_TRUE(runner, Int_Compare_To(i1, (Obj*)i2) < 0,
-                  "Int_Compare_To less than");
-        TEST_FALSE(runner, Int_Equals(i1, (Obj*)i2),
-                   "Int_Equals less than");
-        DECREF(i1);
-        DECREF(i2);
-    }
-
-    {
-        Integer *i1 = Int_new(INT64_C(0x6666666666666666));
-        Integer *i2 = Int_new(INT64_C(0x6666666666666665));
-        TEST_TRUE(runner, Int_Compare_To(i1, (Obj*)i2) > 0,
-                  "Int_Compare_To greater than");
-        TEST_FALSE(runner, Int_Equals(i1, (Obj*)i2),
-                   "Int_Equals greater than");
-        DECREF(i1);
-        DECREF(i2);
-    }
-
-    {
-        Integer *i = Int_new(0);
-        Err *error = Err_trap(S_int_compare_to, i);
-        TEST_TRUE(runner, error != NULL,
-                  "Int_Compare_To with invalid type throws");
-        TEST_FALSE(runner, Int_Equals(i, (Obj*)OBJ),
-                   "Int_Equals with different type");
-        DECREF(error);
-        DECREF(i);
-    }
-
-    // NOTICE: When running these tests on x86/x64, it's best to compile
-    // with -ffloat-store to avoid excess FPU precision which can hide
-    // implementation bugs.
-    S_test_compare_float_int(runner, (double)INT64_MAX * 2.0, INT64_MAX, 1);
-    S_test_compare_float_int(runner, pow(2.0, 60.0), INT64_C(1) << 60, 0);
-    S_test_compare_float_int(runner, pow(2.0, 60.0), (INT64_C(1) << 60) - 1,
-                             1);
-    S_test_compare_float_int(runner, pow(2.0, 60.0), (INT64_C(1) << 60) + 1,
-                             -1);
-    S_test_compare_float_int(runner, pow(2.0, 63.0), INT64_MAX, 1);
-    S_test_compare_float_int(runner, -pow(2.0, 63.0), INT64_MIN, 0);
-    // -9223372036854777856.0 == nextafter(-pow(2, 63), -INFINITY)
-    S_test_compare_float_int(runner, -9223372036854777856.0, INT64_MIN, -1);
-    S_test_compare_float_int(runner, 1.0, 2, -1);
-}
-
-static void
-test_Clone(TestBatchRunner *runner) {
-    Float   *f64 = Float_new(1.33);
-    Integer *i64 = Int_new(INT64_MAX);
-    Float   *f64_dupe = Float_Clone(f64);
-    Integer *i64_dupe = Int_Clone(i64);
-    TEST_TRUE(runner, Float_Equals(f64, (Obj*)f64_dupe),
-              "Float Clone");
-    TEST_TRUE(runner, Int_Equals(i64, (Obj*)i64_dupe),
-              "Integer Clone");
-    DECREF(i64_dupe);
-    DECREF(f64_dupe);
-    DECREF(i64);
-    DECREF(f64);
-}
-
-void
-TestNum_Run_IMP(TestNum *self, TestBatchRunner *runner) {
-    TestBatchRunner_Plan(runner, (TestBatch*)self, 82);
-    test_To_String(runner);
-    test_accessors(runner);
-    test_Equals_and_Compare_To(runner);
-    test_Clone(runner);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestNum.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestNum.cfh b/runtime/core/Clownfish/Test/TestNum.cfh
deleted file mode 100644
index 6d1f663..0000000
--- a/runtime/core/Clownfish/Test/TestNum.cfh
+++ /dev/null
@@ -1,29 +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 TestClownfish;
-
-class Clownfish::Test::TestNum
-    inherits Clownfish::TestHarness::TestBatch {
-
-    inert incremented TestNum*
-    new();
-
-    void
-    Run(TestNum *self, TestBatchRunner *runner);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestObj.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestObj.c b/runtime/core/Clownfish/Test/TestObj.c
deleted file mode 100644
index c4cdafe..0000000
--- a/runtime/core/Clownfish/Test/TestObj.c
+++ /dev/null
@@ -1,152 +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 CFISH_USE_SHORT_NAMES
-#define TESTCFISH_USE_SHORT_NAMES
-
-#include "charmony.h"
-
-#include "Clownfish/Test/TestObj.h"
-
-#include "Clownfish/String.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Test.h"
-#include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/Class.h"
-
-TestObj*
-TestObj_new() {
-    return (TestObj*)Class_Make_Obj(TESTOBJ);
-}
-
-static Obj*
-S_new_testobj() {
-    String *class_name = SSTR_WRAP_C("TestObj");
-    Obj *obj;
-    Class *klass = Class_fetch_class(class_name);
-    if (!klass) {
-        klass = Class_singleton(class_name, OBJ);
-    }
-    obj = Class_Make_Obj(klass);
-    return Obj_init(obj);
-}
-
-static void
-test_refcounts(TestBatchRunner *runner) {
-    Obj *obj = S_new_testobj();
-
-    TEST_INT_EQ(runner, CFISH_REFCOUNT_NN(obj), 1,
-                "Correct starting refcount");
-
-    obj = CFISH_INCREF_NN(obj);
-    TEST_INT_EQ(runner, CFISH_REFCOUNT_NN(obj), 2, "INCREF_NN");
-
-    CFISH_DECREF_NN(obj);
-    TEST_INT_EQ(runner, CFISH_REFCOUNT_NN(obj), 1, "DECREF_NN");
-
-    DECREF(obj);
-}
-
-static void
-test_To_String(TestBatchRunner *runner) {
-    Obj *testobj = S_new_testobj();
-    String *string = Obj_To_String(testobj);
-    TEST_TRUE(runner, Str_Contains_Utf8(string, "TestObj", 7), "To_String");
-    DECREF(string);
-    DECREF(testobj);
-}
-
-static void
-test_Equals(TestBatchRunner *runner) {
-    Obj *testobj = S_new_testobj();
-    Obj *other   = S_new_testobj();
-
-    TEST_TRUE(runner, Obj_Equals(testobj, testobj),
-              "Equals is true for the same object");
-    TEST_FALSE(runner, Obj_Equals(testobj, other),
-               "Distinct objects are not equal");
-
-    DECREF(testobj);
-    DECREF(other);
-}
-
-static void
-test_is_a(TestBatchRunner *runner) {
-    String *string     = Str_new_from_trusted_utf8("", 0);
-    Class  *str_class  = Str_get_class(string);
-    String *class_name = Str_get_class_name(string);
-
-    TEST_TRUE(runner, Str_is_a(string, STRING), "String is_a String.");
-    TEST_TRUE(runner, Str_is_a(string, OBJ), "String is_a Obj.");
-    TEST_TRUE(runner, str_class == STRING, "get_class");
-    TEST_TRUE(runner, Str_Equals(Class_Get_Name(STRING), (Obj*)class_name),
-              "get_class_name");
-    TEST_FALSE(runner, Obj_is_a(NULL, OBJ), "NULL is not an Obj");
-
-    DECREF(string);
-}
-
-static void
-S_attempt_init(void *context) {
-    Obj_init((Obj*)context);
-}
-
-static void
-S_attempt_Clone(void *context) {
-    Obj_Clone((Obj*)context);
-}
-
-static void
-S_attempt_Compare_To(void *context) {
-    Obj_Compare_To((Obj*)context, (Obj*)context);
-}
-
-static void
-S_verify_abstract_error(TestBatchRunner *runner, Err_Attempt_t routine,
-                        void *context, const char *name) {
-    char message[100];
-    sprintf(message, "%s() is abstract", name);
-    Err *error = Err_trap(routine, context);
-    TEST_TRUE(runner, error != NULL
-              && Err_is_a(error, ERR)
-              && Str_Contains_Utf8(Err_Get_Mess(error), "bstract", 7),
-              message);
-    DECREF(error);
-}
-
-static void
-test_abstract_routines(TestBatchRunner *runner) {
-    Obj *blank = Class_Make_Obj(OBJ);
-    S_verify_abstract_error(runner, S_attempt_init, blank, "init");
-
-    Obj *obj = S_new_testobj();
-    S_verify_abstract_error(runner, S_attempt_Clone,      obj, "Clone");
-    S_verify_abstract_error(runner, S_attempt_Compare_To, obj, "Compare_To");
-    DECREF(obj);
-}
-
-void
-TestObj_Run_IMP(TestObj *self, TestBatchRunner *runner) {
-    TestBatchRunner_Plan(runner, (TestBatch*)self, 14);
-    test_refcounts(runner);
-    test_To_String(runner);
-    test_Equals(runner);
-    test_is_a(runner);
-    test_abstract_routines(runner);
-}
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestObj.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestObj.cfh b/runtime/core/Clownfish/Test/TestObj.cfh
deleted file mode 100644
index c5cc401..0000000
--- a/runtime/core/Clownfish/Test/TestObj.cfh
+++ /dev/null
@@ -1,28 +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 TestClownfish;
-
-class Clownfish::Test::TestObj
-    inherits Clownfish::TestHarness::TestBatch {
-
-    inert incremented TestObj*
-    new();
-
-    void
-    Run(TestObj *self, TestBatchRunner *runner);
-}
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestPtrHash.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestPtrHash.c b/runtime/core/Clownfish/Test/TestPtrHash.c
deleted file mode 100644
index 3bf7003..0000000
--- a/runtime/core/Clownfish/Test/TestPtrHash.c
+++ /dev/null
@@ -1,108 +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 CFISH_USE_SHORT_NAMES
-#define TESTCFISH_USE_SHORT_NAMES
-
-#include <stdlib.h>
-#include <time.h>
-
-#include "Clownfish/Test/TestPtrHash.h"
-#include "Clownfish/Class.h"
-#include "Clownfish/PtrHash.h"
-#include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/TestHarness/TestUtils.h"
-#include "Clownfish/Util/Memory.h"
-
-TestPtrHash*
-TestPtrHash_new() {
-    return (TestPtrHash*)Class_Make_Obj(TESTPTRHASH);
-}
-
-static void
-test_Store_and_Fetch(TestBatchRunner *runner) {
-    PtrHash *hash = PtrHash_new(100);
-    char dummy[100];
-
-    for (int i = 0; i < 100; i++) {
-        void *key = &dummy[i];
-        PtrHash_Store(hash, key, key);
-    }
-
-    bool all_equal = true;
-    for (int i = 0; i < 100; i++) {
-        void *key = &dummy[i];
-        void *value = PtrHash_Fetch(hash, key);
-        if (value != key) {
-            all_equal = false;
-            break;
-        }
-    }
-    TEST_TRUE(runner, all_equal, "basic Store and Fetch");
-
-    TEST_TRUE(runner, PtrHash_Fetch(hash, &dummy[100]) == NULL,
-              "Fetch against non-existent key returns NULL");
-
-    PtrHash_Store(hash, &dummy[50], dummy);
-    TEST_TRUE(runner, PtrHash_Fetch(hash, &dummy[50]) == dummy,
-              "Store replaces existing value");
-
-    PtrHash_Destroy(hash);
-}
-
-static void
-test_stress(TestBatchRunner *runner) {
-    PtrHash *hash = PtrHash_new(0); // trigger multiple rebuilds.
-    size_t num_elems = 200000;
-    void **keys = (void**)MALLOCATE(num_elems * sizeof(void*));
-
-    for (size_t i = 0; i < num_elems; i++) {
-        size_t index = (size_t)(TestUtils_random_u64() % num_elems);
-        void *key = &keys[index];
-        PtrHash_Store(hash, key, key);
-        keys[i] = key;
-    }
-
-    // Overwrite for good measure.
-    for (size_t i = 0; i < num_elems; i++) {
-        void *key = keys[i];
-        PtrHash_Store(hash, key, key);
-    }
-
-    bool all_equal = true;
-    for (size_t i = 0; i < num_elems; i++) {
-        void *key = keys[i];
-        void *got = PtrHash_Fetch(hash, key);
-        if (got != key) {
-            all_equal = false;
-            break;
-        }
-    }
-    TEST_TRUE(runner, all_equal, "stress test");
-
-    FREEMEM(keys);
-    PtrHash_Destroy(hash);
-}
-
-void
-TestPtrHash_Run_IMP(TestPtrHash *self, TestBatchRunner *runner) {
-    TestBatchRunner_Plan(runner, (TestBatch*)self, 4);
-    srand((unsigned int)time(NULL));
-    test_Store_and_Fetch(runner);
-    test_stress(runner);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestPtrHash.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestPtrHash.cfh b/runtime/core/Clownfish/Test/TestPtrHash.cfh
deleted file mode 100644
index 83589cb..0000000
--- a/runtime/core/Clownfish/Test/TestPtrHash.cfh
+++ /dev/null
@@ -1,29 +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 TestClownfish;
-
-class Clownfish::Test::TestPtrHash
-    inherits Clownfish::TestHarness::TestBatch {
-
-    inert incremented TestPtrHash*
-    new();
-
-    void
-    Run(TestPtrHash *self, TestBatchRunner *runner);
-}
-
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestString.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestString.c b/runtime/core/Clownfish/Test/TestString.c
deleted file mode 100644
index d89b5fe..0000000
--- a/runtime/core/Clownfish/Test/TestString.c
+++ /dev/null
@@ -1,848 +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 <string.h>
-#include <stdio.h>
-
-#define CFISH_USE_SHORT_NAMES
-#define TESTCFISH_USE_SHORT_NAMES
-
-#include "Clownfish/Test/TestString.h"
-
-#include "Clownfish/String.h"
-#include "Clownfish/Boolean.h"
-#include "Clownfish/ByteBuf.h"
-#include "Clownfish/CharBuf.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Test.h"
-#include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/TestHarness/TestUtils.h"
-#include "Clownfish/Util/Memory.h"
-#include "Clownfish/Class.h"
-
-#define SMILEY "\xE2\x98\xBA"
-static char smiley[] = { (char)0xE2, (char)0x98, (char)0xBA, 0 };
-static uint32_t smiley_len = 3;
-static int32_t smiley_cp  = 0x263A;
-
-TestString*
-TestStr_new() {
-    return (TestString*)Class_Make_Obj(TESTSTRING);
-}
-
-static String*
-S_get_str(const char *string) {
-    return Str_new_from_utf8(string, strlen(string));
-}
-
-// Surround a smiley with lots of whitespace.
-static String*
-S_smiley_with_whitespace(size_t *num_spaces_ptr) {
-    int32_t spaces[] = {
-        ' ',    '\t',   '\r',   '\n',   0x000B, 0x000C, 0x000D, 0x0085,
-        0x00A0, 0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,
-        0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x2028, 0x2029, 0x202F,
-        0x205F, 0x3000
-    };
-    size_t num_spaces = sizeof(spaces) / sizeof(uint32_t);
-
-    CharBuf *buf = CB_new(0);
-    for (size_t i = 0; i < num_spaces; i++) { CB_Cat_Char(buf, spaces[i]); }
-    CB_Cat_Char(buf, smiley_cp);
-    for (size_t i = 0; i < num_spaces; i++) { CB_Cat_Char(buf, spaces[i]); }
-
-    String *retval = CB_To_String(buf);
-    if (num_spaces_ptr) { *num_spaces_ptr = num_spaces; }
-
-    DECREF(buf);
-    return retval;
-}
-
-static void
-test_new(TestBatchRunner *runner) {
-    static char chars[] = "A string " SMILEY " with a smile.";
-
-    {
-        char *buffer = (char*)MALLOCATE(sizeof(chars));
-        strcpy(buffer, chars);
-        String *thief = Str_new_steal_utf8(buffer, sizeof(chars) - 1);
-        TEST_TRUE(runner, Str_Equals_Utf8(thief, chars, sizeof(chars) - 1),
-                  "Str_new_steal_utf8");
-        DECREF(thief);
-    }
-
-    {
-        char *buffer = (char*)MALLOCATE(sizeof(chars));
-        strcpy(buffer, chars);
-        String *thief
-            = Str_new_steal_trusted_utf8(buffer, sizeof(chars) - 1);
-        TEST_TRUE(runner, Str_Equals_Utf8(thief, chars, sizeof(chars) - 1),
-                  "Str_new_steal_trusted_utf8");
-        DECREF(thief);
-    }
-
-    {
-        String *wrapper = Str_new_wrap_utf8(chars, sizeof(chars) - 1);
-        TEST_TRUE(runner, Str_Equals_Utf8(wrapper, chars, sizeof(chars) - 1),
-                  "Str_new_wrap_utf8");
-        DECREF(wrapper);
-    }
-
-    {
-        String *wrapper = Str_new_wrap_trusted_utf8(chars, sizeof(chars) - 1);
-        TEST_TRUE(runner, Str_Equals_Utf8(wrapper, chars, sizeof(chars) - 1),
-                  "Str_new_wrap_trusted_utf8");
-        DECREF(wrapper);
-    }
-
-    {
-        String *smiley_str = Str_new_from_char(smiley_cp);
-        TEST_TRUE(runner, Str_Equals_Utf8(smiley_str, smiley, smiley_len),
-                  "Str_new_from_char");
-        DECREF(smiley_str);
-    }
-}
-
-static void
-test_Cat(TestBatchRunner *runner) {
-    String *wanted = Str_newf("a%s", smiley);
-    String *source;
-    String *got;
-
-    source = S_get_str("");
-    got = Str_Cat(source, wanted);
-    TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Cat");
-    DECREF(got);
-    DECREF(source);
-
-    source = S_get_str("a");
-    got = Str_Cat_Utf8(source, smiley, smiley_len);
-    TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Cat_Utf8");
-    DECREF(got);
-    DECREF(source);
-
-    source = S_get_str("a");
-    got = Str_Cat_Trusted_Utf8(source, smiley, smiley_len);
-    TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Cat_Trusted_Utf8");
-    DECREF(got);
-    DECREF(source);
-
-    DECREF(wanted);
-}
-
-static void
-test_Clone(TestBatchRunner *runner) {
-    String *wanted = S_get_str("foo");
-    String *got    = Str_Clone(wanted);
-    TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "Clone");
-    DECREF(got);
-    DECREF(wanted);
-}
-
-static int64_t
-S_find(String *string, String *substring) {
-    StringIterator *iter = Str_Find(string, substring);
-    if (iter == NULL) { return -1; }
-    size_t tick = StrIter_Recede(iter, SIZE_MAX);
-    DECREF(iter);
-    return (int64_t)tick;
-}
-
-static void
-test_Contains_and_Find(TestBatchRunner *runner) {
-    String *string;
-    String *substring = S_get_str("foo");
-    String *empty     = S_get_str("");
-
-    TEST_FALSE(runner, Str_Contains(empty, substring),
-               "Not contained in empty string");
-    TEST_INT_EQ(runner, S_find(empty, substring), -1,
-                "Not found in empty string");
-
-    string = S_get_str("foo");
-    TEST_TRUE(runner, Str_Contains(string, substring),
-              "Contains complete string");
-    TEST_INT_EQ(runner, S_find(string, substring), 0, "Find complete string");
-    TEST_TRUE(runner, Str_Contains(string, empty),
-              "Contains empty string");
-    TEST_INT_EQ(runner, S_find(string, empty), 0, "Find empty string");
-    DECREF(string);
-
-    string = S_get_str("afoo");
-    TEST_TRUE(runner, Str_Contains(string, substring),
-              "Contained after first");
-    TEST_INT_EQ(runner, S_find(string, substring), 1, "Find after first");
-    String *prefix = Str_SubString(string, 0, 3);
-    TEST_FALSE(runner, Str_Contains(prefix, substring), "Don't overrun");
-    DECREF(prefix);
-    DECREF(string);
-
-    string = S_get_str("afood");
-    TEST_TRUE(runner, Str_Contains(string, substring), "Contained in middle");
-    TEST_INT_EQ(runner, S_find(string, substring), 1, "Find in middle");
-    DECREF(string);
-
-    DECREF(empty);
-    DECREF(substring);
-}
-
-static void
-test_Code_Point_At_and_From(TestBatchRunner *runner) {
-    int32_t code_points[] = {
-        'a', smiley_cp, smiley_cp, 'b', smiley_cp, 'c'
-    };
-    uint32_t num_code_points = sizeof(code_points) / sizeof(int32_t);
-    String *string = Str_newf("a%s%sb%sc", smiley, smiley, smiley);
-    uint32_t i;
-
-    for (i = 0; i < num_code_points; i++) {
-        uint32_t from = num_code_points - i;
-        TEST_INT_EQ(runner, Str_Code_Point_At(string, i), code_points[i],
-                    "Code_Point_At %ld", (long)i);
-        TEST_INT_EQ(runner, Str_Code_Point_From(string, from),
-                    code_points[i], "Code_Point_From %ld", (long)from);
-    }
-
-    TEST_INT_EQ(runner, Str_Code_Point_At(string, num_code_points), STR_OOB,
-                "Code_Point_At %ld", (long)num_code_points);
-    TEST_INT_EQ(runner, Str_Code_Point_From(string, 0), STR_OOB,
-                "Code_Point_From 0");
-    TEST_INT_EQ(runner, Str_Code_Point_From(string, num_code_points + 1),
-                STR_OOB, "Code_Point_From %ld", (long)(num_code_points + 1));
-
-    DECREF(string);
-}
-
-static void
-test_SubString(TestBatchRunner *runner) {
-    {
-        String *string = Str_newf("a%s%sb%sc", smiley, smiley, smiley);
-        String *wanted = Str_newf("%sb%s", smiley, smiley);
-        String *got = Str_SubString(string, 2, 3);
-        TEST_TRUE(runner, Str_Equals(wanted, (Obj*)got), "SubString");
-        DECREF(string);
-        DECREF(wanted);
-        DECREF(got);
-    }
-
-    {
-        static const char chars[] = "A string.";
-        String *wrapper = Str_new_wrap_utf8(chars, sizeof(chars) - 1);
-        String *wanted  = Str_newf("string");
-        String *got     = Str_SubString(wrapper, 2, 6);
-        TEST_TRUE(runner, Str_Equals(got, (Obj*)wanted),
-                  "SubString with wrapped buffer");
-        DECREF(wrapper);
-        DECREF(wanted);
-        DECREF(got);
-    }
-}
-
-static void
-test_Trim(TestBatchRunner *runner) {
-    String *ws_smiley = S_smiley_with_whitespace(NULL);
-    String *ws_foo    = S_get_str("  foo  ");
-    String *ws_only   = S_get_str("  \t  \r\n");
-    String *trimmed   = S_get_str("a     b");
-    String *got;
-
-    got = Str_Trim(ws_smiley);
-    TEST_TRUE(runner, Str_Equals_Utf8(got, smiley, smiley_len), "Trim");
-    DECREF(got);
-
-    got = Str_Trim_Top(ws_foo);
-    TEST_TRUE(runner, Str_Equals_Utf8(got, "foo  ", 5), "Trim_Top");
-    DECREF(got);
-
-    got = Str_Trim_Tail(ws_foo);
-    TEST_TRUE(runner, Str_Equals_Utf8(got, "  foo", 5), "Trim_Tail");
-    DECREF(got);
-
-    got = Str_Trim(ws_only);
-    TEST_TRUE(runner, Str_Equals_Utf8(got, "", 0), "Trim with only whitespace");
-    DECREF(got);
-
-    got = Str_Trim_Top(ws_only);
-    TEST_TRUE(runner, Str_Equals_Utf8(got, "", 0),
-              "Trim_Top with only whitespace");
-    DECREF(got);
-
-    got = Str_Trim_Tail(ws_only);
-    TEST_TRUE(runner, Str_Equals_Utf8(got, "", 0),
-              "Trim_Tail with only whitespace");
-    DECREF(got);
-
-    got = Str_Trim(trimmed);
-    TEST_TRUE(runner, Str_Equals(got, (Obj*)trimmed),
-              "Trim doesn't change trimmed string");
-    DECREF(got);
-
-    got = Str_Trim_Top(trimmed);
-    TEST_TRUE(runner, Str_Equals(got, (Obj*)trimmed),
-              "Trim_Top doesn't change trimmed string");
-    DECREF(got);
-
-    got = Str_Trim_Tail(trimmed);
-    TEST_TRUE(runner, Str_Equals(got, (Obj*)trimmed),
-              "Trim_Tail doesn't change trimmed string");
-    DECREF(got);
-
-    DECREF(trimmed);
-    DECREF(ws_only);
-    DECREF(ws_foo);
-    DECREF(ws_smiley);
-}
-
-static void
-test_To_F64(TestBatchRunner *runner) {
-    String *string;
-
-    string = S_get_str("1.5");
-    double difference = 1.5 - Str_To_F64(string);
-    if (difference < 0) { difference = 0 - difference; }
-    TEST_TRUE(runner, difference < 0.001, "To_F64");
-    DECREF(string);
-
-    string = S_get_str("-1.5");
-    difference = 1.5 + Str_To_F64(string);
-    if (difference < 0) { difference = 0 - difference; }
-    TEST_TRUE(runner, difference < 0.001, "To_F64 negative");
-    DECREF(string);
-
-    // TODO: Enable this test when we have real substrings.
-    /*string = S_get_str("1.59");
-    double value_full = Str_To_F64(string);
-    Str_Set_Size(string, 3);
-    double value_short = Str_To_F64(string);
-    TEST_TRUE(runner, value_short < value_full,
-              "TO_F64 doesn't run past end of string");
-    DECREF(string);*/
-}
-
-static void
-test_To_I64(TestBatchRunner *runner) {
-    String *string;
-
-    string = S_get_str("10");
-    TEST_INT_EQ(runner, Str_To_I64(string), 10, "To_I64");
-    DECREF(string);
-
-    string = S_get_str("-10");
-    TEST_INT_EQ(runner, Str_To_I64(string), -10, "To_I64 negative");
-    DECREF(string);
-
-    string = S_get_str("10.");
-    TEST_INT_EQ(runner, Str_To_I64(string), 10, "To_I64 stops at non-digits");
-    DECREF(string);
-
-    string = S_get_str("10" SMILEY);
-    TEST_INT_EQ(runner, Str_To_I64(string), 10, "To_I64 stops at non-ASCII");
-    DECREF(string);
-
-    string = S_get_str("10A");
-    TEST_INT_EQ(runner, Str_To_I64(string), 10,
-              "To_I64 stops at out-of-range digits");
-    DECREF(string);
-}
-
-static void
-test_BaseX_To_I64(TestBatchRunner *runner) {
-    String *string;
-
-    string = S_get_str("-JJ");
-    TEST_INT_EQ(runner, Str_BaseX_To_I64(string, 20), -399,
-              "BaseX_To_I64 base 20");
-    DECREF(string);
-}
-
-static void
-test_To_String(TestBatchRunner *runner) {
-    String *string = Str_newf("Test");
-    String *copy   = Str_To_String(string);
-    TEST_TRUE(runner, Str_Equals(copy, (Obj*)string), "To_String");
-    DECREF(string);
-    DECREF(copy);
-}
-
-static void
-test_To_Utf8(TestBatchRunner *runner) {
-    String *string = Str_newf("a%s%sb%sc", smiley, smiley, smiley);
-    char *buf = Str_To_Utf8(string);
-    TEST_TRUE(runner, strcmp(buf, "a" SMILEY SMILEY "b" SMILEY "c") == 0,
-              "To_Utf8");
-    FREEMEM(buf);
-    DECREF(string);
-}
-
-static void
-test_To_ByteBuf(TestBatchRunner *runner) {
-    String     *string = Str_newf("foo");
-    ByteBuf    *bb     = Str_To_ByteBuf(string);
-    TEST_TRUE(runner, BB_Equals_Bytes(bb, "foo", 3), "To_ByteBuf");
-    DECREF(bb);
-    DECREF(string);
-}
-
-static void
-test_Length(TestBatchRunner *runner) {
-    String *string = Str_newf("a%s%sb%sc", smiley, smiley, smiley);
-    TEST_UINT_EQ(runner, Str_Length(string), 6, "Length");
-    DECREF(string);
-}
-
-static void
-test_Compare_To(TestBatchRunner *runner) {
-    String *abc = Str_newf("a%s%sb%sc", smiley, smiley, smiley);
-    String *ab  = Str_newf("a%s%sb", smiley, smiley);
-    String *ac  = Str_newf("a%s%sc", smiley, smiley);
-
-    TEST_TRUE(runner, Str_Compare_To(abc, (Obj*)abc) == 0,
-              "Compare_To abc abc");
-    TEST_TRUE(runner, Str_Compare_To(ab, (Obj*)abc) < 0,
-              "Compare_To ab abc");
-    TEST_TRUE(runner, Str_Compare_To(abc, (Obj*)ab) > 0,
-              "Compare_To abc ab");
-    TEST_TRUE(runner, Str_Compare_To(ab, (Obj*)ac) < 0,
-              "Compare_To ab ac");
-    TEST_TRUE(runner, Str_Compare_To(ac, (Obj*)ab) > 0,
-              "Compare_To ac ab");
-
-    DECREF(ac);
-    DECREF(ab);
-    DECREF(abc);
-}
-
-static void
-test_Starts_Ends_With(TestBatchRunner *runner) {
-    String *prefix = S_get_str("pre" SMILEY "fix_");
-    String *suffix = S_get_str("_post" SMILEY "fix");
-    String *empty  = S_get_str("");
-
-    TEST_TRUE(runner, Str_Starts_With(suffix, suffix),
-              "Starts_With self returns true");
-    TEST_TRUE(runner, Str_Ends_With(prefix, prefix),
-              "Ends_With self returns true");
-
-    TEST_TRUE(runner, Str_Starts_With(suffix, empty),
-              "Starts_With empty string returns true");
-    TEST_TRUE(runner, Str_Ends_With(prefix, empty),
-              "Ends_With empty string returns true");
-    TEST_FALSE(runner, Str_Starts_With(empty, suffix),
-              "Empty string Starts_With returns false");
-    TEST_FALSE(runner, Str_Ends_With(empty, prefix),
-              "Empty string Ends_With returns false");
-
-    {
-        String *string
-            = S_get_str("pre" SMILEY "fix_string_post" SMILEY "fix");
-        TEST_TRUE(runner, Str_Starts_With(string, prefix),
-                  "Starts_With returns true");
-        TEST_TRUE(runner, Str_Ends_With(string, suffix),
-                  "Ends_With returns true");
-        DECREF(string);
-    }
-
-    {
-        String *string
-            = S_get_str("pre" SMILEY "fix:string:post" SMILEY "fix");
-        TEST_FALSE(runner, Str_Starts_With(string, prefix),
-                   "Starts_With returns false");
-        TEST_FALSE(runner, Str_Ends_With(string, suffix),
-                   "Ends_With returns false");
-        DECREF(string);
-    }
-
-    DECREF(prefix);
-    DECREF(suffix);
-    DECREF(empty);
-}
-
-static void
-test_Starts_Ends_With_Utf8(TestBatchRunner *runner) {
-    String *str = S_get_str("pre" SMILEY "post");
-
-    static const char prefix[] = "pre" SMILEY;
-    static const char postfix[] = SMILEY "post";
-    static const size_t prefix_size = sizeof(prefix) - 1;
-    static const size_t postfix_size = sizeof(postfix) - 1;
-    TEST_TRUE(runner, Str_Starts_With_Utf8(str, prefix, prefix_size),
-              "Starts_With_Utf8 returns true");
-    TEST_TRUE(runner, Str_Ends_With_Utf8(str, postfix, postfix_size),
-              "Ends_With_Utf8 returns true");
-    TEST_FALSE(runner, Str_Starts_With_Utf8(str, postfix, postfix_size),
-              "Starts_With_Utf8 returns false");
-    TEST_FALSE(runner, Str_Ends_With_Utf8(str, prefix, prefix_size),
-              "Ends_With_Utf8 returns false");
-
-    static const char longer[] = "12345678901234567890";
-    static const size_t longer_size = sizeof(longer) - 1;
-    TEST_FALSE(runner, Str_Starts_With_Utf8(str, longer, longer_size),
-              "Starts_With_Utf8 longer str returns false");
-    TEST_FALSE(runner, Str_Ends_With_Utf8(str, longer, longer_size),
-               "Ends_With_Utf8 longer str returns false");
-
-    DECREF(str);
-}
-
-static void
-test_Get_Ptr8(TestBatchRunner *runner) {
-    String *string = S_get_str("Banana");
-
-    const char *ptr8 = Str_Get_Ptr8(string);
-    TEST_TRUE(runner, strcmp(ptr8, "Banana") == 0, "Get_Ptr8");
-
-    size_t size = Str_Get_Size(string);
-    TEST_UINT_EQ(runner, size, 6, "Get_Size");
-
-    DECREF(string);
-}
-
-static void
-test_iterator(TestBatchRunner *runner) {
-    static const int32_t code_points[] = {
-        0x41,
-        0x7F,
-        0x80,
-        0x7FF,
-        0x800,
-        0xFFFF,
-        0x10000,
-        0x10FFFF
-    };
-    static size_t num_code_points
-        = sizeof(code_points) / sizeof(code_points[0]);
-
-    CharBuf *buf = CB_new(0);
-    for (size_t i = 0; i < num_code_points; ++i) {
-        CB_Cat_Char(buf, code_points[i]);
-    }
-    String *string = CB_To_String(buf);
-
-    {
-        StringIterator *iter = Str_Top(string);
-
-        TEST_TRUE(runner, StrIter_Equals(iter, (Obj*)iter),
-                  "StringIterator equal to self");
-        TEST_FALSE(runner, StrIter_Equals(iter, (Obj*)CFISH_TRUE),
-                   "StringIterator not equal non-iterators");
-
-        DECREF(iter);
-    }
-
-    {
-        StringIterator *top  = Str_Top(string);
-        StringIterator *tail = Str_Tail(string);
-
-        TEST_FALSE(runner, StrIter_Equals(top, (Obj*)tail),
-                   "StrIter_Equals returns false");
-
-        TEST_INT_EQ(runner, StrIter_Compare_To(top, (Obj*)tail), -1,
-                    "Compare_To top < tail");
-        TEST_INT_EQ(runner, StrIter_Compare_To(tail, (Obj*)top), 1,
-                    "Compare_To tail > top");
-        TEST_INT_EQ(runner, StrIter_Compare_To(top, (Obj*)top), 0,
-                    "Compare_To top == top");
-
-        StringIterator *clone = StrIter_Clone(top);
-        TEST_TRUE(runner, StrIter_Equals(clone, (Obj*)top), "Clone");
-
-        StrIter_Assign(clone, tail);
-        TEST_TRUE(runner, StrIter_Equals(clone, (Obj*)tail), "Assign");
-
-        String *other = Str_newf("Other string");
-        StringIterator *other_iter = Str_Top(other);
-        TEST_FALSE(runner, StrIter_Equals(other_iter, (Obj*)tail),
-                   "Equals returns false for different strings");
-        StrIter_Assign(clone, other_iter);
-        TEST_TRUE(runner, StrIter_Equals(clone, (Obj*)other_iter),
-                  "Assign iterator with different string");
-
-        DECREF(other);
-        DECREF(other_iter);
-        DECREF(clone);
-        DECREF(top);
-        DECREF(tail);
-    }
-
-    {
-        StringIterator *iter = Str_Top(string);
-
-        for (size_t i = 0; i < num_code_points; ++i) {
-            TEST_TRUE(runner, StrIter_Has_Next(iter), "Has_Next %d", i);
-            int32_t code_point = StrIter_Next(iter);
-            TEST_INT_EQ(runner, code_point, code_points[i], "Next %d", i);
-        }
-
-        TEST_TRUE(runner, !StrIter_Has_Next(iter),
-                  "Has_Next at end of string");
-        TEST_INT_EQ(runner, StrIter_Next(iter), STR_OOB,
-                    "Next at end of string");
-
-        StringIterator *tail = Str_Tail(string);
-        TEST_TRUE(runner, StrIter_Equals(iter, (Obj*)tail), "Equals tail");
-
-        DECREF(tail);
-        DECREF(iter);
-    }
-
-    {
-        StringIterator *iter = Str_Tail(string);
-
-        for (size_t i = num_code_points; i--;) {
-            TEST_TRUE(runner, StrIter_Has_Prev(iter), "Has_Prev %d", i);
-            int32_t code_point = StrIter_Prev(iter);
-            TEST_INT_EQ(runner, code_point, code_points[i], "Prev %d", i);
-        }
-
-        TEST_TRUE(runner, !StrIter_Has_Prev(iter),
-                  "Has_Prev at end of string");
-        TEST_INT_EQ(runner, StrIter_Prev(iter), STR_OOB,
-                    "Prev at start of string");
-
-        StringIterator *top = Str_Top(string);
-        TEST_TRUE(runner, StrIter_Equals(iter, (Obj*)top), "Equals top");
-
-        DECREF(top);
-        DECREF(iter);
-    }
-
-    {
-        StringIterator *iter = Str_Top(string);
-
-        StrIter_Next(iter);
-        TEST_UINT_EQ(runner, StrIter_Advance(iter, 2), 2,
-                     "Advance returns number of code points");
-        TEST_INT_EQ(runner, StrIter_Next(iter), code_points[3],
-                    "Advance works");
-        TEST_UINT_EQ(runner,
-                     StrIter_Advance(iter, 1000000), num_code_points - 4,
-                     "Advance past end of string");
-
-        StrIter_Prev(iter);
-        TEST_UINT_EQ(runner, StrIter_Recede(iter, 2), 2,
-                     "Recede returns number of code points");
-        TEST_INT_EQ(runner, StrIter_Prev(iter), code_points[num_code_points-4],
-                    "Recede works");
-        TEST_UINT_EQ(runner, StrIter_Recede(iter, 1000000), num_code_points - 4,
-                     "Recede past start of string");
-
-        DECREF(iter);
-    }
-
-    DECREF(string);
-    DECREF(buf);
-}
-
-static void
-test_iterator_whitespace(TestBatchRunner *runner) {
-    size_t num_spaces;
-    String *ws_smiley = S_smiley_with_whitespace(&num_spaces);
-
-    {
-        StringIterator *iter = Str_Top(ws_smiley);
-        TEST_UINT_EQ(runner, StrIter_Skip_Whitespace(iter), num_spaces,
-                     "Skip_Whitespace");
-        TEST_UINT_EQ(runner, StrIter_Skip_Whitespace(iter), 0,
-                     "Skip_Whitespace without whitespace");
-        DECREF(iter);
-    }
-
-    {
-        StringIterator *iter = Str_Tail(ws_smiley);
-        TEST_UINT_EQ(runner, StrIter_Skip_Whitespace_Back(iter), num_spaces,
-                     "Skip_Whitespace_Back");
-        TEST_UINT_EQ(runner, StrIter_Skip_Whitespace_Back(iter), 0,
-                     "Skip_Whitespace_Back without whitespace");
-        DECREF(iter);
-    }
-
-    DECREF(ws_smiley);
-}
-
-typedef struct {
-    StringIterator *top;
-    StringIterator *tail;
-} StrIterCropContext;
-
-static void
-S_striter_crop(void *vcontext) {
-    StrIterCropContext *context = (StrIterCropContext*)vcontext;
-    StrIter_crop(context->top, context->tail);
-}
-
-static void
-test_iterator_substring(TestBatchRunner *runner) {
-    String *string = Str_newf("a%sb%sc%sd", smiley, smiley, smiley);
-
-    StringIterator *start = Str_Top(string);
-    StringIterator *end = Str_Tail(string);
-
-    {
-        String *substring = StrIter_crop(start, end);
-        TEST_TRUE(runner, Str_Equals(substring, (Obj*)string),
-                  "StrIter_crop whole string");
-        DECREF(substring);
-    }
-
-    StrIter_Advance(start, 2);
-    StrIter_Recede(end, 2);
-
-    {
-        String *substring = StrIter_crop(start, end);
-        static const char wanted_buf[] = "b" SMILEY "c";
-        static const size_t wanted_size = sizeof(wanted_buf) - 1;
-        String *wanted = Str_new_from_utf8(wanted_buf, wanted_size);
-        TEST_TRUE(runner, Str_Equals(substring, (Obj*)wanted),
-                  "StrIter_crop");
-
-        TEST_TRUE(runner, StrIter_Starts_With(start, wanted),
-                  "Starts_With returns true");
-        TEST_TRUE(runner, StrIter_Ends_With(end, wanted),
-                  "Ends_With returns true");
-        TEST_TRUE(runner,
-                  StrIter_Starts_With_Utf8(start, wanted_buf, wanted_size),
-                  "Starts_With_Utf8 returns true");
-        TEST_TRUE(runner,
-                  StrIter_Ends_With_Utf8(end, wanted_buf, wanted_size),
-                  "Ends_With_Utf8 returns true");
-
-        DECREF(wanted);
-        DECREF(substring);
-    }
-
-    {
-        static const char short_buf[] = "b" SMILEY "x";
-        static const size_t short_size = sizeof(short_buf) - 1;
-        String *short_str = Str_new_from_utf8(short_buf, short_size);
-        TEST_FALSE(runner, StrIter_Starts_With(start, short_str),
-                   "Starts_With returns false");
-        TEST_FALSE(runner, StrIter_Ends_With(start, short_str),
-                   "Ends_With returns false");
-        TEST_FALSE(runner,
-                   StrIter_Starts_With_Utf8(start, short_buf, short_size),
-                   "Starts_With_Utf8 returns false");
-        TEST_FALSE(runner,
-                   StrIter_Ends_With_Utf8(start, short_buf, short_size),
-                   "Ends_With_Utf8 returns false");
-
-        static const char long_buf[] = "b" SMILEY "xxxxxxxxxxxx" SMILEY "c";
-        static const size_t long_size = sizeof(long_buf) - 1;
-        String *long_str = Str_new_from_utf8(long_buf, long_size);
-        TEST_FALSE(runner, StrIter_Starts_With(start, long_str),
-                   "Starts_With long string returns false");
-        TEST_FALSE(runner, StrIter_Ends_With(end, long_str),
-                   "Ends_With long string returns false");
-        TEST_FALSE(runner,
-                   StrIter_Starts_With_Utf8(start, long_buf, long_size),
-                   "Starts_With_Utf8 long string returns false");
-        TEST_FALSE(runner,
-                   StrIter_Ends_With_Utf8(end, long_buf, long_size),
-                   "Ends_With_Utf8 long string returns false");
-
-        DECREF(short_str);
-        DECREF(long_str);
-    }
-
-    {
-        String *substring = StrIter_crop(end, NULL);
-        String *wanted = Str_newf("%sd", smiley);
-        TEST_TRUE(runner, Str_Equals(substring, (Obj*)wanted),
-                  "StrIter_crop with NULL tail");
-        DECREF(wanted);
-        DECREF(substring);
-    }
-
-    {
-        String *substring = StrIter_crop(NULL, start);
-        String *wanted = Str_newf("a%s", smiley);
-        TEST_TRUE(runner, Str_Equals(substring, (Obj*)wanted),
-                  "StrIter_crop with NULL top");
-        DECREF(wanted);
-        DECREF(substring);
-    }
-
-    {
-        StrIterCropContext context;
-        context.top  = NULL;
-        context.tail = NULL;
-        Err *error = Err_trap(S_striter_crop, &context);
-        TEST_TRUE(runner, error != NULL,
-                  "StrIter_crop throws if top and tail are NULL");
-        DECREF(error);
-    }
-
-    {
-        String *other = SSTR_WRAP_C("other");
-        StrIterCropContext context;
-        context.top  = start;
-        context.tail = Str_Tail(other);
-        Err *error = Err_trap(S_striter_crop, &context);
-        TEST_TRUE(runner, error != NULL,
-                  "StrIter_crop throws if string don't match");
-        DECREF(error);
-        DECREF(context.tail);
-    }
-
-    {
-        StrIterCropContext context;
-        context.top  = end;
-        context.tail = start;
-        Err *error = Err_trap(S_striter_crop, &context);
-        TEST_TRUE(runner, error != NULL,
-                  "StrIter_crop throws if top is behind tail");
-        DECREF(error);
-    }
-
-    DECREF(start);
-    DECREF(end);
-    DECREF(string);
-}
-
-void
-TestStr_Run_IMP(TestString *self, TestBatchRunner *runner) {
-    TestBatchRunner_Plan(runner, (TestBatch*)self, 158);
-    test_new(runner);
-    test_Cat(runner);
-    test_Clone(runner);
-    test_Code_Point_At_and_From(runner);
-    test_Contains_and_Find(runner);
-    test_SubString(runner);
-    test_Trim(runner);
-    test_To_F64(runner);
-    test_To_I64(runner);
-    test_BaseX_To_I64(runner);
-    test_To_String(runner);
-    test_To_Utf8(runner);
-    test_To_ByteBuf(runner);
-    test_Length(runner);
-    test_Compare_To(runner);
-    test_Starts_Ends_With(runner);
-    test_Starts_Ends_With_Utf8(runner);
-    test_Get_Ptr8(runner);
-    test_iterator(runner);
-    test_iterator_whitespace(runner);
-    test_iterator_substring(runner);
-}
-
-/*************************** StringCallbackTest ***************************/
-
-bool
-StrCbTest_Unchanged_By_Callback_IMP(StringCallbackTest *self, String *str) {
-    String *before = Str_Clone(str);
-    StrCbTest_Callback(self);
-    return Str_Equals(str, (Obj*)before);
-}
-

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestString.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestString.cfh b/runtime/core/Clownfish/Test/TestString.cfh
deleted file mode 100644
index 88e43c9..0000000
--- a/runtime/core/Clownfish/Test/TestString.cfh
+++ /dev/null
@@ -1,36 +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 TestClownfish;
-
-class Clownfish::Test::TestString nickname TestStr
-    inherits Clownfish::TestHarness::TestBatch {
-
-    inert incremented TestString*
-    new();
-
-    void
-    Run(TestString *self, TestBatchRunner *runner);
-}
-
-abstract class Clownfish::Test::StringCallbackTest nickname StrCbTest {
-    bool
-    Unchanged_By_Callback(StringCallbackTest *self, String *str);
-
-    abstract void
-    Callback(StringCallbackTest *self);
-}
-