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:40 UTC
[07/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/TestVector.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestVector.c b/runtime/core/Clownfish/Test/TestVector.c
deleted file mode 100644
index 17a7f98..0000000
--- a/runtime/core/Clownfish/Test/TestVector.c
+++ /dev/null
@@ -1,572 +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 <stdlib.h>
-
-#define C_CFISH_VECTOR
-#define CFISH_USE_SHORT_NAMES
-#define TESTCFISH_USE_SHORT_NAMES
-
-#define MAX_VECTOR_SIZE (SIZE_MAX / sizeof(Obj*))
-
-#include "Clownfish/Test/TestVector.h"
-
-#include "Clownfish/String.h"
-#include "Clownfish/Boolean.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Num.h"
-#include "Clownfish/Test.h"
-#include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/TestHarness/TestUtils.h"
-#include "Clownfish/Vector.h"
-#include "Clownfish/Class.h"
-
-TestVector*
-TestVector_new() {
- return (TestVector*)Class_Make_Obj(TESTVECTOR);
-}
-
-// Return an array of size 10 with 30 garbage pointers behind.
-static Vector*
-S_array_with_garbage() {
- Vector *array = Vec_new(100);
-
- for (int i = 0; i < 40; i++) {
- Vec_Push(array, (Obj*)CFISH_TRUE);
- }
-
- // Remove elements using different methods.
- Vec_Excise(array, 10, 10);
- for (int i = 0; i < 10; i++) { Vec_Pop(array); }
- Vec_Resize(array, 10);
-
- return array;
-}
-
-static void
-test_Equals(TestBatchRunner *runner) {
- Vector *array = Vec_new(0);
- Vector *other = Vec_new(0);
- String *stuff = SSTR_WRAP_C("stuff");
-
- TEST_TRUE(runner, Vec_Equals(array, (Obj*)array),
- "Array equal to self");
-
- TEST_FALSE(runner, Vec_Equals(array, (Obj*)CFISH_TRUE),
- "Array not equal to non-array");
-
- TEST_TRUE(runner, Vec_Equals(array, (Obj*)other),
- "Empty arrays are equal");
-
- Vec_Push(array, (Obj*)CFISH_TRUE);
- TEST_FALSE(runner, Vec_Equals(array, (Obj*)other),
- "Add one elem and Equals returns false");
-
- Vec_Push(other, (Obj*)CFISH_TRUE);
- TEST_TRUE(runner, Vec_Equals(array, (Obj*)other),
- "Add a matching elem and Equals returns true");
-
- Vec_Store(array, 2, (Obj*)CFISH_TRUE);
- TEST_FALSE(runner, Vec_Equals(array, (Obj*)other),
- "Add elem after a NULL and Equals returns false");
-
- Vec_Store(other, 2, (Obj*)CFISH_TRUE);
- TEST_TRUE(runner, Vec_Equals(array, (Obj*)other),
- "Empty elems don't spoil Equals");
-
- Vec_Store(other, 2, INCREF(stuff));
- TEST_FALSE(runner, Vec_Equals(array, (Obj*)other),
- "Non-matching value spoils Equals");
-
- Vec_Store(other, 2, NULL);
- TEST_FALSE(runner, Vec_Equals(array, (Obj*)other),
- "NULL value spoils Equals");
- TEST_FALSE(runner, Vec_Equals(other, (Obj*)array),
- "NULL value spoils Equals (reversed)");
-
- Vec_Excise(array, 1, 2); // removes empty elems
- DECREF(Vec_Delete(other, 1)); // leaves NULL in place of deleted elem
- DECREF(Vec_Delete(other, 2));
- TEST_FALSE(runner, Vec_Equals(array, (Obj*)other),
- "Empty trailing elements spoil Equals");
-
- DECREF(array);
- DECREF(other);
-}
-
-static void
-test_Store_Fetch(TestBatchRunner *runner) {
- Vector *array = Vec_new(0);
- String *elem;
-
- TEST_TRUE(runner, Vec_Fetch(array, 2) == NULL, "Fetch beyond end");
-
- Vec_Store(array, 2, (Obj*)Str_newf("foo"));
- elem = (String*)CERTIFY(Vec_Fetch(array, 2), STRING);
- TEST_UINT_EQ(runner, 3, Vec_Get_Size(array), "Store updates size");
- TEST_TRUE(runner, Str_Equals_Utf8(elem, "foo", 3), "Store");
-
- elem = (String*)INCREF(elem);
- TEST_INT_EQ(runner, 2, CFISH_REFCOUNT_NN(elem),
- "start with refcount of 2");
- Vec_Store(array, 2, (Obj*)Str_newf("bar"));
- TEST_INT_EQ(runner, 1, CFISH_REFCOUNT_NN(elem),
- "Displacing elem via Store updates refcount");
- DECREF(elem);
- elem = (String*)CERTIFY(Vec_Fetch(array, 2), STRING);
- TEST_TRUE(runner, Str_Equals_Utf8(elem, "bar", 3), "Store displacement");
-
- DECREF(array);
-
- array = S_array_with_garbage();
- Vec_Store(array, 40, (Obj*)CFISH_TRUE);
- bool all_null = true;
- for (size_t i = 10; i < 40; i++) {
- if (Vec_Fetch(array, i) != NULL) { all_null = false; }
- }
- TEST_TRUE(runner, all_null, "Out-of-bounds Store clears excised elements");
- DECREF(array);
-}
-
-static void
-test_Push_Pop_Insert(TestBatchRunner *runner) {
- Vector *array = Vec_new(0);
- String *elem;
-
- TEST_UINT_EQ(runner, Vec_Get_Size(array), 0, "size starts at 0");
- TEST_TRUE(runner, Vec_Pop(array) == NULL,
- "Pop from empty array returns NULL");
-
- Vec_Push(array, (Obj*)Str_newf("a"));
- Vec_Push(array, (Obj*)Str_newf("b"));
- Vec_Push(array, (Obj*)Str_newf("c"));
-
- TEST_UINT_EQ(runner, Vec_Get_Size(array), 3, "size after Push");
- TEST_TRUE(runner, NULL != CERTIFY(Vec_Fetch(array, 2), STRING), "Push");
-
- elem = (String*)CERTIFY(Vec_Pop(array), STRING);
- TEST_TRUE(runner, Str_Equals_Utf8(elem, "c", 1), "Pop");
- TEST_UINT_EQ(runner, Vec_Get_Size(array), 2, "size after Pop");
- DECREF(elem);
-
- Vec_Insert(array, 0, (Obj*)Str_newf("foo"));
- elem = (String*)CERTIFY(Vec_Fetch(array, 0), STRING);
- TEST_TRUE(runner, Str_Equals_Utf8(elem, "foo", 3), "Insert");
- TEST_UINT_EQ(runner, Vec_Get_Size(array), 3, "size after Insert");
-
- for (int i = 0; i < 256; ++i) {
- Vec_Push(array, (Obj*)Str_newf("flotsam"));
- }
- for (size_t i = 0; i < 512; ++i) {
- Vec_Insert(array, i, (Obj*)Str_newf("jetsam"));
- }
- TEST_UINT_EQ(runner, Vec_Get_Size(array), 3 + 256 + 512,
- "size after exercising Push and Insert");
-
- DECREF(array);
-}
-
-static void
-test_Insert_All(TestBatchRunner *runner) {
- int64_t i;
-
- {
- Vector *dst = Vec_new(20);
- Vector *src = Vec_new(10);
- Vector *wanted = Vec_new(30);
-
- for (i = 0; i < 10; i++) { Vec_Push(dst, (Obj*)Int_new(i)); }
- for (i = 0; i < 10; i++) { Vec_Push(dst, (Obj*)Int_new(i + 20)); }
- for (i = 0; i < 10; i++) { Vec_Push(src, (Obj*)Int_new(i + 10)); }
- for (i = 0; i < 30; i++) { Vec_Push(wanted, (Obj*)Int_new(i)); }
-
- Vec_Insert_All(dst, 10, src);
- TEST_TRUE(runner, Vec_Equals(dst, (Obj*)wanted), "Insert_All between");
-
- DECREF(wanted);
- DECREF(src);
- DECREF(dst);
- }
-
- {
- Vector *dst = Vec_new(10);
- Vector *src = Vec_new(10);
- Vector *wanted = Vec_new(30);
-
- for (i = 0; i < 10; i++) { Vec_Push(dst, (Obj*)Int_new(i)); }
- for (i = 0; i < 10; i++) { Vec_Push(src, (Obj*)Int_new(i + 20)); }
- for (i = 0; i < 10; i++) { Vec_Push(wanted, (Obj*)Int_new(i)); }
- for (i = 0; i < 10; i++) {
- Vec_Store(wanted, (size_t)i + 20, (Obj*)Int_new(i + 20));
- }
-
- Vec_Insert_All(dst, 20, src);
- TEST_TRUE(runner, Vec_Equals(dst, (Obj*)wanted), "Insert_All after");
-
- DECREF(wanted);
- DECREF(src);
- DECREF(dst);
- }
-}
-
-static void
-test_Delete(TestBatchRunner *runner) {
- Vector *wanted = Vec_new(5);
- Vector *got = Vec_new(5);
- uint32_t i;
-
- for (i = 0; i < 5; i++) { Vec_Push(got, (Obj*)Str_newf("%u32", i)); }
- Vec_Store(wanted, 0, (Obj*)Str_newf("0", i));
- Vec_Store(wanted, 1, (Obj*)Str_newf("1", i));
- Vec_Store(wanted, 4, (Obj*)Str_newf("4", i));
- DECREF(Vec_Delete(got, 2));
- DECREF(Vec_Delete(got, 3));
- TEST_TRUE(runner, Vec_Equals(wanted, (Obj*)got), "Delete");
-
- TEST_TRUE(runner, Vec_Delete(got, 25000) == NULL,
- "Delete beyond array size returns NULL");
-
- DECREF(wanted);
- DECREF(got);
-}
-
-static void
-test_Resize(TestBatchRunner *runner) {
- Vector *array = Vec_new(3);
- uint32_t i;
-
- for (i = 0; i < 2; i++) { Vec_Push(array, (Obj*)Str_newf("%u32", i)); }
- TEST_UINT_EQ(runner, Vec_Get_Capacity(array), 3, "Start with capacity 3");
-
- Vec_Resize(array, 4);
- TEST_UINT_EQ(runner, Vec_Get_Size(array), 4, "Resize up");
- TEST_UINT_EQ(runner, Vec_Get_Capacity(array), 4,
- "Resize changes capacity");
-
- Vec_Resize(array, 2);
- TEST_UINT_EQ(runner, Vec_Get_Size(array), 2, "Resize down");
- TEST_TRUE(runner, Vec_Fetch(array, 2) == NULL, "Resize down zaps elem");
-
- Vec_Resize(array, 2);
- TEST_UINT_EQ(runner, Vec_Get_Size(array), 2, "Resize to same size");
-
- DECREF(array);
-
- array = S_array_with_garbage();
- Vec_Resize(array, 40);
- bool all_null = true;
- for (size_t i = 10; i < 40; i++) {
- if (Vec_Fetch(array, i) != NULL) { all_null = false; }
- }
- TEST_TRUE(runner, all_null, "Resize clears excised elements");
- DECREF(array);
-}
-
-static void
-test_Excise(TestBatchRunner *runner) {
- Vector *wanted = Vec_new(5);
- Vector *got = Vec_new(5);
-
- for (uint32_t i = 0; i < 5; i++) {
- Vec_Push(wanted, (Obj*)Str_newf("%u32", i));
- Vec_Push(got, (Obj*)Str_newf("%u32", i));
- }
-
- Vec_Excise(got, 7, 1);
- TEST_TRUE(runner, Vec_Equals(wanted, (Obj*)got),
- "Excise outside of range is no-op");
-
- Vec_Excise(got, 2, 2);
- DECREF(Vec_Delete(wanted, 2));
- DECREF(Vec_Delete(wanted, 3));
- Vec_Store(wanted, 2, Vec_Delete(wanted, 4));
- Vec_Resize(wanted, 3);
- TEST_TRUE(runner, Vec_Equals(wanted, (Obj*)got),
- "Excise multiple elems");
-
- Vec_Excise(got, 2, 2);
- Vec_Resize(wanted, 2);
- TEST_TRUE(runner, Vec_Equals(wanted, (Obj*)got),
- "Splicing too many elems truncates");
-
- Vec_Excise(got, 0, 1);
- Vec_Store(wanted, 0, Vec_Delete(wanted, 1));
- Vec_Resize(wanted, 1);
- TEST_TRUE(runner, Vec_Equals(wanted, (Obj*)got),
- "Excise first elem");
-
- DECREF(got);
- DECREF(wanted);
-}
-
-static void
-test_Push_All(TestBatchRunner *runner) {
- Vector *wanted = Vec_new(0);
- Vector *got = Vec_new(0);
- Vector *scratch = Vec_new(0);
- Vector *empty = Vec_new(0);
- uint32_t i;
-
- for (i = 0; i < 40; i++) { Vec_Push(wanted, (Obj*)Str_newf("%u32", i)); }
- Vec_Push(wanted, NULL);
- for (i = 0; i < 20; i++) { Vec_Push(got, (Obj*)Str_newf("%u32", i)); }
- for (i = 20; i < 40; i++) { Vec_Push(scratch, (Obj*)Str_newf("%u32", i)); }
- Vec_Push(scratch, NULL);
-
- Vec_Push_All(got, scratch);
- TEST_TRUE(runner, Vec_Equals(wanted, (Obj*)got), "Push_All");
-
- Vec_Push_All(got, empty);
- TEST_TRUE(runner, Vec_Equals(wanted, (Obj*)got),
- "Push_All with empty array");
-
- DECREF(wanted);
- DECREF(got);
- DECREF(scratch);
- DECREF(empty);
-}
-
-static void
-test_Slice(TestBatchRunner *runner) {
- Vector *array = Vec_new(0);
- for (uint32_t i = 0; i < 10; i++) { Vec_Push(array, (Obj*)Str_newf("%u32", i)); }
- {
- Vector *slice = Vec_Slice(array, 0, 10);
- TEST_TRUE(runner, Vec_Equals(array, (Obj*)slice), "Slice entire array");
- DECREF(slice);
- }
- {
- Vector *slice = Vec_Slice(array, 0, 11);
- TEST_TRUE(runner, Vec_Equals(array, (Obj*)slice),
- "Exceed length");
- DECREF(slice);
- }
- {
- Vector *wanted = Vec_new(0);
- Vec_Push(wanted, (Obj*)Str_newf("9"));
- Vector *slice = Vec_Slice(array, 9, 11);
- TEST_TRUE(runner, Vec_Equals(slice, (Obj*)wanted),
- "Exceed length, start near end");
- DECREF(slice);
- DECREF(wanted);
- }
- {
- Vector *slice = Vec_Slice(array, 0, 0);
- TEST_TRUE(runner, Vec_Get_Size(slice) == 0, "empty slice");
- DECREF(slice);
- }
- {
- Vector *slice = Vec_Slice(array, 20, 1);
- TEST_TRUE(runner, Vec_Get_Size(slice) == 0, "exceed offset");
- DECREF(slice);
- }
- {
- Vector *wanted = Vec_new(0);
- Vec_Push(wanted, (Obj*)Str_newf("9"));
- Vector *slice = Vec_Slice(array, 9, SIZE_MAX - 1);
- TEST_TRUE(runner, Vec_Get_Size(slice) == 1, "guard against overflow");
- DECREF(slice);
- DECREF(wanted);
- }
- DECREF(array);
-}
-
-static void
-test_Clone(TestBatchRunner *runner) {
- Vector *array = Vec_new(0);
- Vector *twin;
- uint32_t i;
-
- for (i = 0; i < 10; i++) {
- Vec_Push(array, (Obj*)Int_new(i));
- }
- Vec_Push(array, NULL);
- twin = Vec_Clone(array);
- TEST_TRUE(runner, Vec_Equals(array, (Obj*)twin), "Clone");
- TEST_TRUE(runner, Vec_Fetch(array, 1) == Vec_Fetch(twin, 1),
- "Clone doesn't clone elements");
-
- DECREF(array);
- DECREF(twin);
-}
-
-static void
-S_push(void *context) {
- Vector *vec = (Vector*)context;
- Vec_Push(vec, (Obj*)CFISH_TRUE);
-}
-
-static void
-S_insert_at_size_max(void *context) {
- Vector *vec = (Vector*)context;
- Vec_Insert(vec, SIZE_MAX, (Obj*)CFISH_TRUE);
-}
-
-static void
-S_store_at_size_max(void *context) {
- Vector *vec = (Vector*)context;
- Vec_Store(vec, SIZE_MAX, (Obj*)CFISH_TRUE);
-}
-
-typedef struct {
- Vector *vec;
- Vector *other;
-} VectorPair;
-
-static void
-S_push_all(void *vcontext) {
- VectorPair *context = (VectorPair*)vcontext;
- Vec_Push_All(context->vec, context->other);
-}
-
-static void
-S_insert_all_at_size_max(void *vcontext) {
- VectorPair *context = (VectorPair*)vcontext;
- Vec_Insert_All(context->vec, SIZE_MAX, context->other);
-}
-
-static void
-S_test_exception(TestBatchRunner *runner, Err_Attempt_t func, void *context,
- const char *test_name) {
- Err *error = Err_trap(func, context);
- TEST_TRUE(runner, error != NULL, test_name);
- DECREF(error);
-}
-
-static void
-test_exceptions(TestBatchRunner *runner) {
- {
- Vector *vec = Vec_new(0);
- vec->cap = MAX_VECTOR_SIZE;
- vec->size = vec->cap;
- S_test_exception(runner, S_push, vec, "Push throws on overflow");
- vec->size = 0;
- DECREF(vec);
- }
-
- {
- Vector *vec = Vec_new(0);
- S_test_exception(runner, S_insert_at_size_max, vec,
- "Insert throws on overflow");
- DECREF(vec);
- }
-
- {
- Vector *vec = Vec_new(0);
- S_test_exception(runner, S_store_at_size_max, vec,
- "Store throws on overflow");
- DECREF(vec);
- }
-
- {
- VectorPair context;
- context.vec = Vec_new(0);
- context.vec->cap = 1000000000;
- context.vec->size = context.vec->cap;
- context.other = Vec_new(0);
- context.other->cap = MAX_VECTOR_SIZE - context.vec->cap + 1;
- context.other->size = context.other->cap;
- S_test_exception(runner, S_push_all, &context,
- "Push_All throws on overflow");
- context.vec->size = 0;
- context.other->size = 0;
- DECREF(context.other);
- DECREF(context.vec);
- }
-
- {
- VectorPair context;
- context.vec = Vec_new(0);
- context.other = Vec_new(0);
- S_test_exception(runner, S_insert_all_at_size_max, &context,
- "Insert_All throws on overflow");
- DECREF(context.other);
- DECREF(context.vec);
- }
-}
-
-static void
-test_Sort(TestBatchRunner *runner) {
- Vector *array = Vec_new(8);
- Vector *wanted = Vec_new(8);
-
- Vec_Push(array, NULL);
- Vec_Push(array, (Obj*)Str_newf("aaab"));
- Vec_Push(array, (Obj*)Str_newf("ab"));
- Vec_Push(array, NULL);
- Vec_Push(array, NULL);
- Vec_Push(array, (Obj*)Str_newf("aab"));
- Vec_Push(array, (Obj*)Str_newf("b"));
-
- Vec_Push(wanted, (Obj*)Str_newf("aaab"));
- Vec_Push(wanted, (Obj*)Str_newf("aab"));
- Vec_Push(wanted, (Obj*)Str_newf("ab"));
- Vec_Push(wanted, (Obj*)Str_newf("b"));
- Vec_Push(wanted, NULL);
- Vec_Push(wanted, NULL);
- Vec_Push(wanted, NULL);
-
- Vec_Sort(array);
- TEST_TRUE(runner, Vec_Equals(array, (Obj*)wanted), "Sort with NULLs");
-
- DECREF(array);
- DECREF(wanted);
-}
-
-static void
-test_Grow(TestBatchRunner *runner) {
- Vector *array = Vec_new(500);
- size_t cap;
-
- cap = Vec_Get_Capacity(array);
- TEST_TRUE(runner, cap >= 500, "Array is created with minimum capacity");
-
- Vec_Grow(array, 2000);
- cap = Vec_Get_Capacity(array);
- TEST_TRUE(runner, cap >= 2000, "Grow to larger capacity");
-
- size_t old_cap = cap;
- Vec_Grow(array, old_cap);
- cap = Vec_Get_Capacity(array);
- TEST_TRUE(runner, cap >= old_cap, "Grow to same capacity");
-
- Vec_Grow(array, 1000);
- cap = Vec_Get_Capacity(array);
- TEST_TRUE(runner, cap >= 1000, "Grow to smaller capacity");
-
- DECREF(array);
-}
-
-void
-TestVector_Run_IMP(TestVector *self, TestBatchRunner *runner) {
- TestBatchRunner_Plan(runner, (TestBatch*)self, 62);
- test_Equals(runner);
- test_Store_Fetch(runner);
- test_Push_Pop_Insert(runner);
- test_Insert_All(runner);
- test_Delete(runner);
- test_Resize(runner);
- test_Excise(runner);
- test_Push_All(runner);
- test_Slice(runner);
- test_Clone(runner);
- test_exceptions(runner);
- test_Sort(runner);
- test_Grow(runner);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/TestVector.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/TestVector.cfh b/runtime/core/Clownfish/Test/TestVector.cfh
deleted file mode 100644
index 090b8b9..0000000
--- a/runtime/core/Clownfish/Test/TestVector.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::TestVector
- inherits Clownfish::TestHarness::TestBatch {
-
- inert incremented TestVector*
- new();
-
- void
- Run(TestVector *self, TestBatchRunner *runner);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/Util/TestAtomic.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/Util/TestAtomic.c b/runtime/core/Clownfish/Test/Util/TestAtomic.c
deleted file mode 100644
index f87279a..0000000
--- a/runtime/core/Clownfish/Test/Util/TestAtomic.c
+++ /dev/null
@@ -1,65 +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/Util/TestAtomic.h"
-
-#include "Clownfish/Test.h"
-#include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/Util/Atomic.h"
-#include "Clownfish/Class.h"
-
-TestAtomic*
-TestAtomic_new() {
- return (TestAtomic*)Class_Make_Obj(TESTATOMIC);
-}
-
-static void
-test_cas_ptr(TestBatchRunner *runner) {
- int foo = 1;
- int bar = 2;
- int *foo_pointer = &foo;
- int *bar_pointer = &bar;
- int *target = NULL;
-
- TEST_TRUE(runner,
- Atomic_cas_ptr((void**)&target, NULL, foo_pointer),
- "cas_ptr returns true on success");
- TEST_TRUE(runner, target == foo_pointer, "cas_ptr sets target");
-
- target = NULL;
- TEST_FALSE(runner,
- Atomic_cas_ptr((void**)&target, bar_pointer, foo_pointer),
- "cas_ptr returns false when it old_value doesn't match");
- TEST_TRUE(runner, target == NULL,
- "cas_ptr doesn't do anything to target when old_value doesn't match");
-
- target = foo_pointer;
- TEST_TRUE(runner,
- Atomic_cas_ptr((void**)&target, foo_pointer, bar_pointer),
- "cas_ptr from one value to another");
- TEST_TRUE(runner, target == bar_pointer, "cas_ptr sets target");
-}
-
-void
-TestAtomic_Run_IMP(TestAtomic *self, TestBatchRunner *runner) {
- TestBatchRunner_Plan(runner, (TestBatch*)self, 6);
- test_cas_ptr(runner);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/Util/TestAtomic.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/Util/TestAtomic.cfh b/runtime/core/Clownfish/Test/Util/TestAtomic.cfh
deleted file mode 100644
index 2788342..0000000
--- a/runtime/core/Clownfish/Test/Util/TestAtomic.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::Util::TestAtomic
- inherits Clownfish::TestHarness::TestBatch {
-
- inert incremented TestAtomic*
- new();
-
- void
- Run(TestAtomic *self, TestBatchRunner *runner);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/Util/TestMemory.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/Util/TestMemory.c b/runtime/core/Clownfish/Test/Util/TestMemory.c
deleted file mode 100644
index 8151c72..0000000
--- a/runtime/core/Clownfish/Test/Util/TestMemory.c
+++ /dev/null
@@ -1,119 +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 "charmony.h"
-
-#include "Clownfish/Test/Util/TestMemory.h"
-
-#include "Clownfish/Test.h"
-#include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/Util/Memory.h"
-#include "Clownfish/Class.h"
-
-TestMemory*
-TestMemory_new() {
- return (TestMemory*)Class_Make_Obj(TESTMEMORY);
-}
-
-static void
-test_oversize__growth_rate(TestBatchRunner *runner) {
- bool success = true;
- uint64_t size = 0;
- double growth_count = 0;
- double average_growth_rate = 0.0;
-
- while (size < SIZE_MAX) {
- uint64_t next_size = Memory_oversize((size_t)size + 1, sizeof(void*));
- if (next_size < size) {
- success = false;
- FAIL(runner, "Asked for %" PRId64 ", got smaller amount %" PRId64,
- size + 1, next_size);
- break;
- }
- if (size > 0) {
- growth_count += 1;
- double growth_rate = CHY_U64_TO_DOUBLE(next_size) /
- CHY_U64_TO_DOUBLE(size);
- double sum = growth_rate + (growth_count - 1) * average_growth_rate;
- average_growth_rate = sum / growth_count;
- if (average_growth_rate < 1.1) {
- FAIL(runner, "Average growth rate dropped below 1.1x: %f",
- average_growth_rate);
- success = false;
- break;
- }
- }
- size = next_size;
- }
- TEST_TRUE(runner, growth_count > 0, "Grew %f times", growth_count);
- if (success) {
- TEST_TRUE(runner, average_growth_rate > 1.1,
- "Growth rate of oversize() averages above 1.1: %.3f",
- average_growth_rate);
- }
-
- for (size_t minimum = 1; minimum < 8; minimum++) {
- uint64_t next_size = Memory_oversize(minimum, sizeof(void*));
- double growth_rate = CHY_U64_TO_DOUBLE(next_size) / (double)minimum;
- TEST_TRUE(runner, growth_rate > 1.2,
- "Growth rate is higher for smaller arrays (%u, %.3f)",
- (unsigned)minimum, growth_rate);
- }
-}
-
-static void
-test_oversize__ceiling(TestBatchRunner *runner) {
- for (unsigned width = 0; width < 10; width++) {
- size_t size = Memory_oversize(SIZE_MAX, width);
- TEST_TRUE(runner, size == SIZE_MAX,
- "Memory_oversize hits ceiling at SIZE_MAX (width %u)", width);
- size = Memory_oversize(SIZE_MAX - 1, width);
- TEST_TRUE(runner, size == SIZE_MAX,
- "Memory_oversize hits ceiling at SIZE_MAX (width %u)", width);
- }
-}
-
-static void
-test_oversize__rounding(TestBatchRunner *runner) {
- unsigned widths[] = { 1, 2, 4, 0 };
-
- for (int width_tick = 0; widths[width_tick] != 0; width_tick++) {
- unsigned width = widths[width_tick];
- for (unsigned i = 0; i < 25; i++) {
- size_t size = Memory_oversize(i, width);
- size_t bytes = size * width;
- if (bytes % sizeof(size_t) != 0) {
- FAIL(runner, "Rounding failure for %u, width %u",
- i, width);
- return;
- }
- }
- }
- PASS(runner, "Round allocations up to the size of a pointer");
-}
-
-void
-TestMemory_Run_IMP(TestMemory *self, TestBatchRunner *runner) {
- TestBatchRunner_Plan(runner, (TestBatch*)self, 30);
- test_oversize__growth_rate(runner);
- test_oversize__ceiling(runner);
- test_oversize__rounding(runner);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/Util/TestMemory.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/Util/TestMemory.cfh b/runtime/core/Clownfish/Test/Util/TestMemory.cfh
deleted file mode 100644
index d0b5803..0000000
--- a/runtime/core/Clownfish/Test/Util/TestMemory.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::Util::TestMemory
- inherits Clownfish::TestHarness::TestBatch {
-
- inert incremented TestMemory*
- new();
-
- void
- Run(TestMemory *self, TestBatchRunner *runner);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/Util/TestStringHelper.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/Util/TestStringHelper.c b/runtime/core/Clownfish/Test/Util/TestStringHelper.c
deleted file mode 100644
index 2a873fd..0000000
--- a/runtime/core/Clownfish/Test/Util/TestStringHelper.c
+++ /dev/null
@@ -1,373 +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>
-
-#define CFISH_USE_SHORT_NAMES
-#define TESTCFISH_USE_SHORT_NAMES
-
-#include "Clownfish/Test/Util/TestStringHelper.h"
-
-#include "Clownfish/String.h"
-#include "Clownfish/Err.h"
-#include "Clownfish/Test.h"
-#include "Clownfish/TestHarness/TestBatchRunner.h"
-#include "Clownfish/Util/StringHelper.h"
-#include "Clownfish/Class.h"
-
-/* This alternative implementation of utf8_valid() is (presumably) slower, but
- * it implements the standard in a more linear, easy-to-grok way.
- */
-#define TRAIL_OK(n) (n >= 0x80 && n <= 0xBF)
-TestStringHelper*
-TestStrHelp_new() {
- return (TestStringHelper*)Class_Make_Obj(TESTSTRINGHELPER);
-}
-
-static bool
-S_utf8_valid_alt(const char *maybe_utf8, size_t size) {
- const uint8_t *string = (const uint8_t*)maybe_utf8;
- const uint8_t *const end = string + size;
- while (string < end) {
- int count = StrHelp_UTF8_COUNT[*string];
- bool valid = false;
- if (count == 1) {
- if (string[0] <= 0x7F) {
- valid = true;
- }
- }
- else if (count == 2) {
- if (string[0] >= 0xC2 && string[0] <= 0xDF) {
- if (TRAIL_OK(string[1])) {
- valid = true;
- }
- }
- }
- else if (count == 3) {
- if (string[0] == 0xE0) {
- if (string[1] >= 0xA0 && string[1] <= 0xBF
- && TRAIL_OK(string[2])
- ) {
- valid = true;
- }
- }
- else if (string[0] >= 0xE1 && string[0] <= 0xEC) {
- if (TRAIL_OK(string[1])
- && TRAIL_OK(string[2])
- ) {
- valid = true;
- }
- }
- else if (string[0] == 0xED) {
- if (string[1] >= 0x80 && string[1] <= 0x9F
- && TRAIL_OK(string[2])
- ) {
- valid = true;
- }
- }
- else if (string[0] >= 0xEE && string[0] <= 0xEF) {
- if (TRAIL_OK(string[1])
- && TRAIL_OK(string[2])
- ) {
- valid = true;
- }
- }
- }
- else if (count == 4) {
- if (string[0] == 0xF0) {
- if (string[1] >= 0x90 && string[1] <= 0xBF
- && TRAIL_OK(string[2])
- && TRAIL_OK(string[3])
- ) {
- valid = true;
- }
- }
- else if (string[0] >= 0xF1 && string[0] <= 0xF3) {
- if (TRAIL_OK(string[1])
- && TRAIL_OK(string[2])
- && TRAIL_OK(string[3])
- ) {
- valid = true;
- }
- }
- else if (string[0] == 0xF4) {
- if (string[1] >= 0x80 && string[1] <= 0x8F
- && TRAIL_OK(string[2])
- && TRAIL_OK(string[3])
- ) {
- valid = true;
- }
- }
- }
-
- if (!valid) {
- return false;
- }
- string += count;
- }
-
- if (string != end) {
- return false;
- }
-
- return true;
-}
-
-static void
-test_overlap(TestBatchRunner *runner) {
- size_t result;
- result = StrHelp_overlap("", "", 0, 0);
- TEST_UINT_EQ(runner, result, 0, "two empty strings");
- result = StrHelp_overlap("", "foo", 0, 3);
- TEST_UINT_EQ(runner, result, 0, "first string is empty");
- result = StrHelp_overlap("foo", "", 3, 0);
- TEST_UINT_EQ(runner, result, 0, "second string is empty");
- result = StrHelp_overlap("foo", "foo", 3, 3);
- TEST_UINT_EQ(runner, result, 3, "equal strings");
- result = StrHelp_overlap("foo bar", "foo", 7, 3);
- TEST_UINT_EQ(runner, result, 3, "first string is longer");
- result = StrHelp_overlap("foo", "foo bar", 3, 7);
- TEST_UINT_EQ(runner, result, 3, "second string is longer");
- result = StrHelp_overlap("bar", "baz", 3, 3);
- TEST_UINT_EQ(runner, result, 2, "different byte");
-}
-
-
-static void
-test_to_base36(TestBatchRunner *runner) {
- char buffer[StrHelp_MAX_BASE36_BYTES];
- StrHelp_to_base36(UINT64_MAX, buffer);
- TEST_STR_EQ(runner, "3w5e11264sgsf", buffer, "base36 UINT64_MAX");
- StrHelp_to_base36(1, buffer);
- TEST_STR_EQ(runner, "1", buffer, "base36 1");
- TEST_INT_EQ(runner, buffer[1], 0, "base36 NULL termination");
-}
-
-static void
-test_utf8_round_trip(TestBatchRunner *runner) {
- int32_t code_point;
- for (code_point = 0; code_point <= 0x10FFFF; code_point++) {
- char buffer[4];
- uint32_t size = StrHelp_encode_utf8_char(code_point, buffer);
- char *start = buffer;
- char *end = start + size;
-
- // Verify length returned by encode_utf8_char().
- if (size != StrHelp_UTF8_COUNT[(unsigned char)buffer[0]]) {
- break;
- }
- // Verify that utf8_valid() agrees with alternate implementation.
- if (!!StrHelp_utf8_valid(start, size)
- != !!S_utf8_valid_alt(start, size)
- ) {
- break;
- }
-
- // Verify back_utf8_char().
- if (StrHelp_back_utf8_char(end, start) != start) {
- break;
- }
-
- // Verify round trip of encode/decode.
- if (StrHelp_decode_utf8_char(buffer) != code_point) {
- break;
- }
- }
- if (code_point == 0x110000) {
- PASS(runner, "Successfully round tripped 0 - 0x10FFFF");
- }
- else {
- FAIL(runner, "Failed round trip at 0x%.1X", (unsigned)code_point);
- }
-}
-
-static void
-S_test_validity(TestBatchRunner *runner, const char *content, size_t size,
- bool expected, const char *description) {
- bool sane = StrHelp_utf8_valid(content, size);
- bool double_check = S_utf8_valid_alt(content, size);
- if (sane != double_check) {
- FAIL(runner, "Disagreement: %s", description);
- }
- else {
- TEST_TRUE(runner, sane == expected, "%s", description);
- }
-}
-
-static void
-test_utf8_valid(TestBatchRunner *runner) {
- // Musical symbol G clef:
- // Code point: U+1D11E
- // UTF-16: 0xD834 0xDD1E
- // UTF-8 0xF0 0x9D 0x84 0x9E
- S_test_validity(runner, "\xF0\x9D\x84\x9E", 4, true,
- "Musical symbol G clef");
- S_test_validity(runner, "\xED\xA0\xB4\xED\xB4\x9E", 6, false,
- "G clef as UTF-8 encoded UTF-16 surrogates");
- S_test_validity(runner, ".\xED\xA0\xB4.", 5, false,
- "Isolated high surrogate");
- S_test_validity(runner, ".\xED\xB4\x9E.", 5, false,
- "Isolated low surrogate");
-
- // Shortest form.
- S_test_validity(runner, ".\xC1\x9C.", 4, false,
- "Non-shortest form ASCII backslash");
- S_test_validity(runner, ".\xC0\xAF.", 4, false,
- "Non-shortest form ASCII slash");
- S_test_validity(runner, ".\xC0\x80.", 4, false,
- "Non-shortest form ASCII NUL character");
- S_test_validity(runner, ".\xE0\x9F\xBF.", 5, false,
- "Non-shortest form three byte sequence");
- S_test_validity(runner, ".\xF0\x8F\xBF\xBF.", 6, false,
- "Non-shortest form four byte sequence");
-
- // Range.
- S_test_validity(runner, "\xF8\x88\x80\x80\x80", 5, false, "5-byte UTF-8");
- S_test_validity(runner, "\xF4\x8F\xBF\xBF", 4, true,
- "Code point 0x10FFFF");
- S_test_validity(runner, "\xF4\x90\x80\x80", 4, false,
- "Code point 0x110000 too large");
- S_test_validity(runner, "\xF5\x80\x80\x80", 4, false,
- "Sequence starting with 0xF5");
-
- // Truncated sequences.
- S_test_validity(runner, "\xC2", 1, false,
- "Truncated two byte sequence");
- S_test_validity(runner, "\xE2\x98", 2, false,
- "Truncated three byte sequence");
- S_test_validity(runner, "\xF0\x9D\x84", 3, false,
- "Truncated four byte sequence");
-
- // Bad continuations.
- S_test_validity(runner, "\xE2\x98\xBA\xE2\x98\xBA", 6, true,
- "SmileySmiley");
- S_test_validity(runner, "\xE2\xBA\xE2\x98\xBA", 5, false,
- "missing first continuation byte");
- S_test_validity(runner, "\xE2\x98\xE2\x98\xBA", 5, false,
- "missing second continuation byte");
- S_test_validity(runner, "\xE2\xE2\x98\xBA", 4, false,
- "missing both continuation bytes");
- S_test_validity(runner, "\xBA\xE2\x98\xBA\xE2\xBA", 5, false,
- "missing first continuation byte (end)");
- S_test_validity(runner, "\xE2\x98\xBA\xE2\x98", 5, false,
- "missing second continuation byte (end)");
- S_test_validity(runner, "\xE2\x98\xBA\xE2", 4, false,
- "missing both continuation bytes (end)");
- S_test_validity(runner, "\xBA\xE2\x98\xBA", 4, false,
- "isolated continuation byte 0xBA");
- S_test_validity(runner, "\x98\xE2\x98\xBA", 4, false,
- "isolated continuation byte 0x98");
- S_test_validity(runner, "\xE2\x98\xBA\xBA", 4, false,
- "isolated continuation byte 0xBA (end)");
- S_test_validity(runner, "\xE2\x98\xBA\x98", 4, false,
- "isolated continuation byte 0x98 (end)");
- S_test_validity(runner, "\xF0xxxx", 5, false,
- "missing continuation byte 2/4");
- S_test_validity(runner, "\xF0\x9Dxxxx", 5, false,
- "missing continuation byte 3/4");
- S_test_validity(runner, "\xF0\x9D\x84xx", 5, false,
- "missing continuation byte 4/4");
-}
-
-static void
-S_validate_utf8(void *context) {
- const char *text = (const char*)context;
- StrHelp_validate_utf8(text, strlen(text), "src.c", 17, "fn");
-}
-
-static void
-test_validate_utf8(TestBatchRunner *runner) {
- {
- Err *error = Err_trap(S_validate_utf8, "Sigma\xC1\x9C.");
- TEST_TRUE(runner, error != NULL, "validate_utf8 throws");
- String *mess = Err_Get_Mess(error);
- const char *expected = "Invalid UTF-8 after 'Sigma': C1 9C 2E\n";
- bool ok = Str_Starts_With_Utf8(mess, expected, strlen(expected));
- TEST_TRUE(runner, ok, "validate_utf8 throws correct error message");
- DECREF(error);
- }
-
- {
- Err *error = Err_trap(S_validate_utf8,
- "xxx123456789\xE2\x93\xAA"
- "1234567890\xC1\x9C.");
- String *mess = Err_Get_Mess(error);
- const char *expected =
- "Invalid UTF-8 after '123456789\xE2\x93\xAA"
- "1234567890': C1 9C 2E\n";
- bool ok = Str_Starts_With_Utf8(mess, expected, strlen(expected));
- TEST_TRUE(runner, ok, "validate_utf8 truncates long prefix");
- DECREF(error);
- }
-}
-
-static void
-test_is_whitespace(TestBatchRunner *runner) {
- TEST_TRUE(runner, StrHelp_is_whitespace(' '), "space is whitespace");
- TEST_TRUE(runner, StrHelp_is_whitespace('\n'), "newline is whitespace");
- TEST_TRUE(runner, StrHelp_is_whitespace('\t'), "tab is whitespace");
- TEST_TRUE(runner, StrHelp_is_whitespace('\v'),
- "vertical tab is whitespace");
- TEST_FALSE(runner, StrHelp_is_whitespace('a'), "'a' isn't whitespace");
- TEST_FALSE(runner, StrHelp_is_whitespace(0), "NULL isn't whitespace");
- TEST_FALSE(runner, StrHelp_is_whitespace(0x263A),
- "Smiley isn't whitespace");
-}
-
-static void
-S_encode_utf8_char(void *context) {
- int32_t *code_point_ptr = (int32_t*)context;
- char buffer[4];
- StrHelp_encode_utf8_char(*code_point_ptr, buffer);
-}
-
-static void
-test_encode_utf8_char(TestBatchRunner *runner) {
- int32_t code_point = 0x110000;
- Err *error = Err_trap(S_encode_utf8_char, &code_point);
- TEST_TRUE(runner, error != NULL, "Encode code point 0x110000 throws");
- DECREF(error);
-}
-
-static void
-test_back_utf8_char(TestBatchRunner *runner) {
- char buffer[4];
- char *buf = buffer + 1;
- uint32_t len = StrHelp_encode_utf8_char(0x263A, buffer);
- char *end = buffer + len;
- TEST_TRUE(runner, StrHelp_back_utf8_char(end, buffer) == buffer,
- "back_utf8_char");
- TEST_TRUE(runner, StrHelp_back_utf8_char(end, buf) == NULL,
- "back_utf8_char returns NULL rather than back up beyond start");
- TEST_TRUE(runner, StrHelp_back_utf8_char(buffer, buffer) == NULL,
- "back_utf8_char returns NULL when end == start");
-}
-
-void
-TestStrHelp_Run_IMP(TestStringHelper *self, TestBatchRunner *runner) {
- TestBatchRunner_Plan(runner, (TestBatch*)self, 55);
- test_overlap(runner);
- test_to_base36(runner);
- test_utf8_round_trip(runner);
- test_utf8_valid(runner);
- test_validate_utf8(runner);
- test_is_whitespace(runner);
- test_encode_utf8_char(runner);
- test_back_utf8_char(runner);
-}
-
-
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/Clownfish/Test/Util/TestStringHelper.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Test/Util/TestStringHelper.cfh b/runtime/core/Clownfish/Test/Util/TestStringHelper.cfh
deleted file mode 100644
index 752c553..0000000
--- a/runtime/core/Clownfish/Test/Util/TestStringHelper.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::Util::TestStringHelper nickname TestStrHelp
- inherits Clownfish::TestHarness::TestBatch {
-
- inert incremented TestStringHelper*
- new();
-
- void
- Run(TestStringHelper *self, TestBatchRunner *runner);
-}
-
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/TestClownfish.c
----------------------------------------------------------------------
diff --git a/runtime/core/TestClownfish.c b/runtime/core/TestClownfish.c
deleted file mode 100644
index e9ec7a3..0000000
--- a/runtime/core/TestClownfish.c
+++ /dev/null
@@ -1,22 +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 "testcfish_parcel.h"
-
-void
-testcfish_init_parcel() {
-}
-
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/core/TestClownfish.cfp
----------------------------------------------------------------------
diff --git a/runtime/core/TestClownfish.cfp b/runtime/core/TestClownfish.cfp
deleted file mode 100644
index 6db4b4a..0000000
--- a/runtime/core/TestClownfish.cfp
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "name": "TestClownfish",
- "nickname": "TestCfish",
- "version": "v0.5.0",
- "prerequisites": {
- "Clownfish": "v0.5.0"
- }
-}
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/go/build.go
----------------------------------------------------------------------
diff --git a/runtime/go/build.go b/runtime/go/build.go
index 6b0b0be..c6eb9e3 100644
--- a/runtime/go/build.go
+++ b/runtime/go/build.go
@@ -119,6 +119,7 @@ func configure() {
func runCFC() {
hierarchy := cfc.NewHierarchy("autogen")
hierarchy.AddSourceDir("../core")
+ hierarchy.AddSourceDir("../test")
hierarchy.Build()
autogenHeader := "Auto-generated by build.go.\n"
coreBinding := cfc.NewBindCore(hierarchy, autogenHeader, "")
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/perl/buildlib/Clownfish/Build.pm
----------------------------------------------------------------------
diff --git a/runtime/perl/buildlib/Clownfish/Build.pm b/runtime/perl/buildlib/Clownfish/Build.pm
index 9506662..81b5fbf 100644
--- a/runtime/perl/buildlib/Clownfish/Build.pm
+++ b/runtime/perl/buildlib/Clownfish/Build.pm
@@ -54,13 +54,16 @@ my $XS_SOURCE_DIR = 'xs';
my $CFC_BUILD = catfile( $CFC_DIR, 'Build' );
my $LIB_DIR = 'lib';
my $CORE_SOURCE_DIR;
+my $TEST_SOURCE_DIR;
my $CHARMONIZER_C;
if ($IS_CPAN_DIST) {
$CORE_SOURCE_DIR = 'cfcore';
+ $TEST_SOURCE_DIR = 'cftest';
$CHARMONIZER_C = 'charmonizer.c';
}
else {
$CORE_SOURCE_DIR = catdir( @BASE_PATH, 'core' );
+ $TEST_SOURCE_DIR = catdir( @BASE_PATH, 'test' );
$CHARMONIZER_C = catfile( $COMMON_SOURCE_DIR, 'charmonizer.c' );
}
@@ -70,7 +73,7 @@ sub new {
$args{clownfish_params} = {
autogen_header => _autogen_header(),
include => [], # Don't use default includes.
- source => [ $CORE_SOURCE_DIR ],
+ source => [ $CORE_SOURCE_DIR, $TEST_SOURCE_DIR ],
modules => [
{
name => 'Clownfish',
@@ -317,6 +320,7 @@ sub ACTION_dist {
'../../NOTICE' => 'NOTICE',
'../../README.md' => 'README.md',
$CORE_SOURCE_DIR => 'cfcore',
+ $TEST_SOURCE_DIR => 'cftest',
$CHARMONIZER_C => 'charmonizer.c',
);
print "Copying files...\n";
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/python/setup.py
----------------------------------------------------------------------
diff --git a/runtime/python/setup.py b/runtime/python/setup.py
index fa184ef..717ce50 100644
--- a/runtime/python/setup.py
+++ b/runtime/python/setup.py
@@ -51,6 +51,7 @@ make_command = "make" # TODO portability
BASE_DIR = os.path.abspath(os.path.join(os.pardir, os.pardir))
PARENT_DIR = os.path.abspath(os.pardir)
CORE_SOURCE_DIR = os.path.join(PARENT_DIR, 'core')
+TEST_SOURCE_DIR = os.path.join(PARENT_DIR, 'test')
CFEXT_DIR = 'cfext'
COMMON_SOURCE_DIR = os.path.join(PARENT_DIR, 'common')
CHARMONIZER_C = os.path.join(COMMON_SOURCE_DIR, 'charmonizer.c')
@@ -133,6 +134,7 @@ class libclownfish(_Command):
import cfc
hierarchy = cfc.model.Hierarchy(dest="autogen")
hierarchy.add_source_dir(CORE_SOURCE_DIR)
+ hierarchy.add_source_dir(TEST_SOURCE_DIR)
hierarchy.build()
header = "Autogenerated by setup.py"
core_binding = cfc.binding.BindCore(hierarchy=hierarchy, header=header)
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/test/Clownfish/Test.c
----------------------------------------------------------------------
diff --git a/runtime/test/Clownfish/Test.c b/runtime/test/Clownfish/Test.c
new file mode 100644
index 0000000..4ae6163
--- /dev/null
+++ b/runtime/test/Clownfish/Test.c
@@ -0,0 +1,70 @@
+/* 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.h"
+
+#include "Clownfish/TestHarness/TestBatch.h"
+#include "Clownfish/TestHarness/TestSuite.h"
+
+#include "Clownfish/Test/TestBlob.h"
+#include "Clownfish/Test/TestBoolean.h"
+#include "Clownfish/Test/TestByteBuf.h"
+#include "Clownfish/Test/TestString.h"
+#include "Clownfish/Test/TestCharBuf.h"
+#include "Clownfish/Test/TestClass.h"
+#include "Clownfish/Test/TestErr.h"
+#include "Clownfish/Test/TestHash.h"
+#include "Clownfish/Test/TestHashIterator.h"
+#include "Clownfish/Test/TestLockFreeRegistry.h"
+#include "Clownfish/Test/TestMethod.h"
+#include "Clownfish/Test/TestNum.h"
+#include "Clownfish/Test/TestObj.h"
+#include "Clownfish/Test/TestPtrHash.h"
+#include "Clownfish/Test/TestVector.h"
+#include "Clownfish/Test/Util/TestAtomic.h"
+#include "Clownfish/Test/Util/TestMemory.h"
+#include "Clownfish/Test/Util/TestStringHelper.h"
+
+TestSuite*
+Test_create_test_suite() {
+ TestSuite *suite = TestSuite_new();
+
+ TestSuite_Add_Batch(suite, (TestBatch*)TestClass_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestMethod_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestVector_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestHash_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestHashIterator_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestObj_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestErr_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestBlob_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestBB_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestStr_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestCB_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestBoolean_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestNum_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestStrHelp_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestAtomic_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestLFReg_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestMemory_new());
+ TestSuite_Add_Batch(suite, (TestBatch*)TestPtrHash_new());
+
+ return suite;
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/test/Clownfish/Test.cfh
----------------------------------------------------------------------
diff --git a/runtime/test/Clownfish/Test.cfh b/runtime/test/Clownfish/Test.cfh
new file mode 100644
index 0000000..68dc8bc
--- /dev/null
+++ b/runtime/test/Clownfish/Test.cfh
@@ -0,0 +1,26 @@
+/* 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.
+ */
+inert class Clownfish::Test {
+ inert incremented TestSuite*
+ create_test_suite();
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/test/Clownfish/Test/TestBlob.c
----------------------------------------------------------------------
diff --git a/runtime/test/Clownfish/Test/TestBlob.c b/runtime/test/Clownfish/Test/TestBlob.c
new file mode 100644
index 0000000..5776f47
--- /dev/null
+++ b/runtime/test/Clownfish/Test/TestBlob.c
@@ -0,0 +1,147 @@
+/* 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/TestBlob.h"
+
+#include "Clownfish/Blob.h"
+#include "Clownfish/Test.h"
+#include "Clownfish/TestHarness/TestBatchRunner.h"
+#include "Clownfish/TestHarness/TestUtils.h"
+#include "Clownfish/Class.h"
+#include "Clownfish/Util/Memory.h"
+
+#include <string.h>
+
+TestBlob*
+TestBlob_new() {
+ return (TestBlob*)Class_Make_Obj(TESTBLOB);
+}
+
+static void
+test_new_steal(TestBatchRunner *runner) {
+ size_t size = 4;
+ char *buf = (char*)MALLOCATE(size);
+ memset(buf, 'x', size);
+ Blob *blob = Blob_new_steal(buf, size);
+ TEST_TRUE(runner, Blob_Get_Buf(blob) == buf, "new_steal steals buf");
+ TEST_TRUE(runner, Blob_Equals_Bytes(blob, "xxxx", 4),
+ "new_steal doesn't change buf");
+ DECREF(blob);
+}
+
+static void
+test_new_wrap(TestBatchRunner *runner) {
+ static const char buf[] = "xxxx";
+ Blob *blob = Blob_new_wrap(buf, 4);
+ TEST_TRUE(runner, Blob_Get_Buf(blob) == buf, "new_wrap wraps buf");
+ TEST_TRUE(runner, Blob_Equals_Bytes(blob, "xxxx", 4),
+ "new_wrap doesn't change buf");
+ DECREF(blob);
+}
+
+static void
+test_Equals(TestBatchRunner *runner) {
+ Blob *blob = Blob_new("foo", 4); // Include terminating NULL.
+
+ {
+ Blob *other = Blob_new("foo", 4);
+ TEST_TRUE(runner, Blob_Equals(blob, (Obj*)other), "Equals");
+ DECREF(other);
+ }
+
+ {
+ Blob *other = Blob_new("foo", 3);
+ TEST_FALSE(runner, Blob_Equals(blob, (Obj*)other),
+ "Different size spoils Equals");
+ DECREF(other);
+ }
+
+ {
+ Blob *other = Blob_new("bar", 4);
+ TEST_UINT_EQ(runner, Blob_Get_Size(blob), Blob_Get_Size(other),
+ "same length");
+ TEST_FALSE(runner, Blob_Equals(blob, (Obj*)other),
+ "Different content spoils Equals");
+ DECREF(other);
+ }
+
+ TEST_FALSE(runner, Blob_Equals(blob, (Obj*)BLOB),
+ "Different type spoils Equals");
+
+ TEST_TRUE(runner, Blob_Equals_Bytes(blob, "foo", 4), "Equals_Bytes");
+ TEST_FALSE(runner, Blob_Equals_Bytes(blob, "foo", 3),
+ "Equals_Bytes spoiled by different size");
+ TEST_FALSE(runner, Blob_Equals_Bytes(blob, "bar", 4),
+ "Equals_Bytes spoiled by different content");
+
+ DECREF(blob);
+}
+
+static void
+test_Clone(TestBatchRunner *runner) {
+ Blob *blob = Blob_new("foo", 3);
+ Blob *twin = Blob_Clone(blob);
+ TEST_TRUE(runner, Blob_Equals(blob, (Obj*)twin), "Clone");
+ DECREF(blob);
+ DECREF(twin);
+}
+
+static void
+test_Compare_To(TestBatchRunner *runner) {
+ {
+ Blob *a = Blob_new("foo", 4);
+ Blob *b = Blob_new("foo", 4);
+ TEST_INT_EQ(runner, Blob_Compare_To(a, (Obj*)b), 0,
+ "Compare_To returns 0 for equal Blobs");
+ DECREF(a);
+ DECREF(b);
+ }
+
+ {
+ Blob *a = Blob_new("foo", 3);
+ Blob *b = Blob_new("foo\0b", 5);
+ TEST_TRUE(runner, Blob_Compare_To(a, (Obj*)b) < 0,
+ "shorter Blob sorts first");
+ TEST_TRUE(runner, Blob_Compare_To(b, (Obj*)a) > 0,
+ "longer Blob sorts last");
+ DECREF(a);
+ DECREF(b);
+ }
+
+ {
+ Blob *a = Blob_new("foo\0a", 5);
+ Blob *b = Blob_new("foo\0b", 5);
+ TEST_TRUE(runner, Blob_Compare_To(a, (Obj*)b) < 0,
+ "NULL doesn't interfere with Compare_To");
+ DECREF(a);
+ DECREF(b);
+ }
+}
+
+void
+TestBlob_Run_IMP(TestBlob *self, TestBatchRunner *runner) {
+ TestBatchRunner_Plan(runner, (TestBatch*)self, 17);
+ test_new_steal(runner);
+ test_new_wrap(runner);
+ test_Equals(runner);
+ test_Clone(runner);
+ test_Compare_To(runner);
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/test/Clownfish/Test/TestBlob.cfh
----------------------------------------------------------------------
diff --git a/runtime/test/Clownfish/Test/TestBlob.cfh b/runtime/test/Clownfish/Test/TestBlob.cfh
new file mode 100644
index 0000000..4d3d4b6
--- /dev/null
+++ b/runtime/test/Clownfish/Test/TestBlob.cfh
@@ -0,0 +1,28 @@
+/* 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::TestBlob inherits Clownfish::TestHarness::TestBatch {
+
+ inert incremented TestBlob*
+ new();
+
+ void
+ Run(TestBlob *self, TestBatchRunner *runner);
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/test/Clownfish/Test/TestBoolean.c
----------------------------------------------------------------------
diff --git a/runtime/test/Clownfish/Test/TestBoolean.c b/runtime/test/Clownfish/Test/TestBoolean.c
new file mode 100644
index 0000000..8835fe1
--- /dev/null
+++ b/runtime/test/Clownfish/Test/TestBoolean.c
@@ -0,0 +1,99 @@
+/* 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/TestBoolean.h"
+
+#include "Clownfish/String.h"
+#include "Clownfish/Boolean.h"
+#include "Clownfish/Test.h"
+#include "Clownfish/TestHarness/TestBatchRunner.h"
+#include "Clownfish/TestHarness/TestUtils.h"
+#include "Clownfish/Class.h"
+
+TestBoolean*
+TestBoolean_new() {
+ return (TestBoolean*)Class_Make_Obj(TESTBOOLEAN);
+}
+
+static void
+test_singleton(TestBatchRunner *runner) {
+ TEST_TRUE(runner, Bool_singleton(true) == CFISH_TRUE,
+ "Bool_singleton true");
+ TEST_TRUE(runner, Bool_singleton(false) == CFISH_FALSE,
+ "Bool_singleton false");
+}
+
+static void
+test_To_String(TestBatchRunner *runner) {
+ String *true_string = Bool_To_String(CFISH_TRUE);
+ String *false_string = Bool_To_String(CFISH_FALSE);
+
+ TEST_TRUE(runner, Str_Equals_Utf8(true_string, "true", 4),
+ "Bool_To_String [true]");
+ TEST_TRUE(runner, Str_Equals_Utf8(false_string, "false", 5),
+ "Bool_To_String [false]");
+
+ DECREF(false_string);
+ DECREF(true_string);
+}
+
+static void
+test_accessors(TestBatchRunner *runner) {
+ TEST_INT_EQ(runner, Bool_Get_Value(CFISH_TRUE), true,
+ "Bool_Get_Value [true]");
+ TEST_INT_EQ(runner, Bool_Get_Value(CFISH_FALSE), false,
+ "Bool_Get_Value [false]");
+}
+
+static void
+test_Equals_and_Compare_To(TestBatchRunner *runner) {
+ TEST_TRUE(runner, Bool_Equals(CFISH_TRUE, (Obj*)CFISH_TRUE),
+ "CFISH_TRUE Equals itself");
+ TEST_TRUE(runner, Bool_Equals(CFISH_FALSE, (Obj*)CFISH_FALSE),
+ "CFISH_FALSE Equals itself");
+ TEST_FALSE(runner, Bool_Equals(CFISH_FALSE, (Obj*)CFISH_TRUE),
+ "CFISH_FALSE not Equals CFISH_TRUE ");
+ TEST_FALSE(runner, Bool_Equals(CFISH_TRUE, (Obj*)CFISH_FALSE),
+ "CFISH_TRUE not Equals CFISH_FALSE ");
+ TEST_FALSE(runner, Bool_Equals(CFISH_TRUE, (Obj*)STRING),
+ "CFISH_TRUE not Equals random other object ");
+}
+
+static void
+test_Clone(TestBatchRunner *runner) {
+ TEST_TRUE(runner, Bool_Equals(CFISH_TRUE, (Obj*)Bool_Clone(CFISH_TRUE)),
+ "Boolean Clone");
+}
+
+void
+TestBoolean_Run_IMP(TestBoolean *self, TestBatchRunner *runner) {
+ TestBatchRunner_Plan(runner, (TestBatch*)self, 12);
+
+ // Destroying the singletons should have no effect.
+ Bool_Destroy(CFISH_TRUE);
+ Bool_Destroy(CFISH_FALSE);
+
+ test_singleton(runner);
+ 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/test/Clownfish/Test/TestBoolean.cfh
----------------------------------------------------------------------
diff --git a/runtime/test/Clownfish/Test/TestBoolean.cfh b/runtime/test/Clownfish/Test/TestBoolean.cfh
new file mode 100644
index 0000000..43702db
--- /dev/null
+++ b/runtime/test/Clownfish/Test/TestBoolean.cfh
@@ -0,0 +1,29 @@
+/* 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::TestBoolean
+ inherits Clownfish::TestHarness::TestBatch {
+
+ inert incremented TestBoolean*
+ new();
+
+ void
+ Run(TestBoolean *self, TestBatchRunner *runner);
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/test/Clownfish/Test/TestByteBuf.c
----------------------------------------------------------------------
diff --git a/runtime/test/Clownfish/Test/TestByteBuf.c b/runtime/test/Clownfish/Test/TestByteBuf.c
new file mode 100644
index 0000000..7f8fc50
--- /dev/null
+++ b/runtime/test/Clownfish/Test/TestByteBuf.c
@@ -0,0 +1,218 @@
+/* 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>
+
+#define CFISH_USE_SHORT_NAMES
+#define TESTCFISH_USE_SHORT_NAMES
+
+#include "Clownfish/Test/TestByteBuf.h"
+
+#include "Clownfish/ByteBuf.h"
+#include "Clownfish/Test.h"
+#include "Clownfish/TestHarness/TestBatchRunner.h"
+#include "Clownfish/TestHarness/TestUtils.h"
+#include "Clownfish/Blob.h"
+#include "Clownfish/Class.h"
+#include "Clownfish/Err.h"
+#include "Clownfish/String.h"
+#include "Clownfish/Util/Memory.h"
+
+#include <string.h>
+
+TestByteBuf*
+TestBB_new() {
+ return (TestByteBuf*)Class_Make_Obj(TESTBYTEBUF);
+}
+
+static void
+test_new_steal_bytes(TestBatchRunner *runner) {
+ char *buf = (char*)MALLOCATE(10);
+ memset(buf, 'x', 10);
+ ByteBuf *bb = BB_new_steal_bytes(buf, 5, 10);
+ TEST_TRUE(runner, BB_Get_Buf(bb) == buf, "new_steal_bytes steals buffer");
+ TEST_TRUE(runner, BB_Equals_Bytes(bb, "xxxxx", 5),
+ "new_steal_bytes sets correct size");
+ BB_Set_Size(bb, 10);
+ TEST_TRUE(runner, BB_Equals_Bytes(bb, "xxxxxxxxxx", 10),
+ "new_steal_bytes sets correct capacity");
+ DECREF(bb);
+}
+
+static void
+test_Equals(TestBatchRunner *runner) {
+ ByteBuf *bb = BB_new_bytes("foo", 4); // Include terminating NULL.
+
+ TEST_TRUE(runner, BB_Equals(bb, (Obj*)bb), "Equals self");
+ TEST_FALSE(runner, BB_Equals(bb, (Obj*)BYTEBUF),
+ "Equals spoiled by different type");
+
+ {
+ ByteBuf *other = BB_new_bytes("foo", 4);
+ TEST_TRUE(runner, BB_Equals(bb, (Obj*)other), "Equals");
+ DECREF(other);
+ }
+
+ TEST_TRUE(runner, BB_Equals_Bytes(bb, "foo", 4), "Equals_Bytes");
+ TEST_FALSE(runner, BB_Equals_Bytes(bb, "foo", 3),
+ "Equals_Bytes spoiled by different size");
+ TEST_FALSE(runner, BB_Equals_Bytes(bb, "bar", 4),
+ "Equals_Bytes spoiled by different content");
+
+ {
+ ByteBuf *other = BB_new_bytes("foo", 3);
+ TEST_FALSE(runner, BB_Equals(bb, (Obj*)other),
+ "Different size spoils Equals");
+ DECREF(other);
+ }
+
+ {
+ ByteBuf *other = BB_new_bytes("bar", 4);
+ TEST_UINT_EQ(runner, BB_Get_Size(bb), BB_Get_Size(other),
+ "same length");
+ TEST_FALSE(runner, BB_Equals(bb, (Obj*)other),
+ "Different content spoils Equals");
+ DECREF(other);
+ }
+
+ DECREF(bb);
+}
+
+static void
+test_Grow(TestBatchRunner *runner) {
+ ByteBuf *bb = BB_new(1);
+ TEST_UINT_EQ(runner, BB_Get_Capacity(bb), 8,
+ "Allocate in 8-byte increments");
+ BB_Grow(bb, 9);
+ TEST_UINT_EQ(runner, BB_Get_Capacity(bb), 16,
+ "Grow in 8-byte increments");
+ BB_Grow(bb, 16);
+ TEST_UINT_EQ(runner, BB_Get_Capacity(bb), 16,
+ "Grow to same capacity has no effect");
+ DECREF(bb);
+}
+
+static void
+test_Clone(TestBatchRunner *runner) {
+ ByteBuf *bb = BB_new_bytes("foo", 3);
+ ByteBuf *twin = BB_Clone(bb);
+ TEST_TRUE(runner, BB_Equals(bb, (Obj*)twin), "Clone");
+ DECREF(bb);
+ DECREF(twin);
+}
+
+static void
+test_Compare_To(TestBatchRunner *runner) {
+ ByteBuf *a = BB_new_bytes("foo\0a", 5);
+ ByteBuf *b = BB_new_bytes("foo\0b", 5);
+
+ BB_Set_Size(a, 4);
+ BB_Set_Size(b, 4);
+ TEST_INT_EQ(runner, BB_Compare_To(a, (Obj*)b), 0,
+ "Compare_To returns 0 for equal ByteBufs");
+
+ BB_Set_Size(a, 3);
+ TEST_TRUE(runner, BB_Compare_To(a, (Obj*)b) < 0,
+ "shorter ByteBuf sorts first");
+ TEST_TRUE(runner, BB_Compare_To(b, (Obj*)a) > 0,
+ "longer ByteBuf sorts last");
+
+ BB_Set_Size(a, 5);
+ BB_Set_Size(b, 5);
+ TEST_TRUE(runner, BB_Compare_To(a, (Obj*)b) < 0,
+ "NULL doesn't interfere with Compare_To");
+
+ DECREF(a);
+ DECREF(b);
+}
+
+static void
+test_Cat(TestBatchRunner *runner) {
+ ByteBuf *bb = BB_new_bytes("foo", 3);
+
+ {
+ Blob *blob = Blob_new("bar", 3);
+ BB_Cat(bb, blob);
+ TEST_TRUE(runner, BB_Equals_Bytes(bb, "foobar", 6), "Cat");
+ DECREF(blob);
+ }
+
+ BB_Cat_Bytes(bb, "baz", 3);
+ TEST_TRUE(runner, BB_Equals_Bytes(bb, "foobarbaz", 9), "Cat_Bytes");
+
+ DECREF(bb);
+}
+
+static void
+test_Utf8_To_String(TestBatchRunner *runner) {
+ ByteBuf *bb = BB_new_bytes("foo", 3);
+
+ {
+ String *string = BB_Utf8_To_String(bb);
+ TEST_TRUE(runner, Str_Equals_Utf8(string, "foo", 3), "Utf8_To_String");
+ DECREF(string);
+ }
+
+ {
+ String *string = BB_Trusted_Utf8_To_String(bb);
+ TEST_TRUE(runner, Str_Equals_Utf8(string, "foo", 3),
+ "Trusted_Utf8_To_String");
+ DECREF(string);
+ }
+
+ DECREF(bb);
+}
+
+static void
+S_set_wrong_size(void *context) {
+ ByteBuf *bb = (ByteBuf*)context;
+ BB_Set_Size(bb, BB_Get_Capacity(bb) + 1);
+}
+
+static void
+test_Set_Size(TestBatchRunner *runner) {
+ ByteBuf *bb = BB_new(10);
+ Err *error = Err_trap(S_set_wrong_size, bb);
+ TEST_TRUE(runner, error != NULL, "Setting size beyond capacity throws");
+ DECREF(error);
+ DECREF(bb);
+}
+
+static void
+test_Yield_Blob(TestBatchRunner *runner) {
+ ByteBuf *bb = BB_new_bytes("alpha", 5);
+ Blob *blob = BB_Yield_Blob(bb);
+ TEST_TRUE(runner, Blob_Equals_Bytes(blob, "alpha", 5), "Yield_Blob");
+ TEST_UINT_EQ(runner, BB_Get_Size(bb), 0, "Yield_Blob clears buf");
+ DECREF(blob);
+ DECREF(bb);
+}
+
+void
+TestBB_Run_IMP(TestByteBuf *self, TestBatchRunner *runner) {
+ TestBatchRunner_Plan(runner, (TestBatch*)self, 27);
+ test_new_steal_bytes(runner);
+ test_Equals(runner);
+ test_Grow(runner);
+ test_Clone(runner);
+ test_Compare_To(runner);
+ test_Cat(runner);
+ test_Utf8_To_String(runner);
+ test_Set_Size(runner);
+ test_Yield_Blob(runner);
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/test/Clownfish/Test/TestByteBuf.cfh
----------------------------------------------------------------------
diff --git a/runtime/test/Clownfish/Test/TestByteBuf.cfh b/runtime/test/Clownfish/Test/TestByteBuf.cfh
new file mode 100644
index 0000000..d27e715
--- /dev/null
+++ b/runtime/test/Clownfish/Test/TestByteBuf.cfh
@@ -0,0 +1,29 @@
+/* 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::TestByteBuf nickname TestBB
+ inherits Clownfish::TestHarness::TestBatch {
+
+ inert incremented TestByteBuf*
+ new();
+
+ void
+ Run(TestByteBuf *self, TestBatchRunner *runner);
+}
+
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/test/Clownfish/Test/TestCharBuf.c
----------------------------------------------------------------------
diff --git a/runtime/test/Clownfish/Test/TestCharBuf.c b/runtime/test/Clownfish/Test/TestCharBuf.c
new file mode 100644
index 0000000..4329987
--- /dev/null
+++ b/runtime/test/Clownfish/Test/TestCharBuf.c
@@ -0,0 +1,394 @@
+/* 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
+#define C_CFISH_CHARBUF
+
+#include "charmony.h"
+
+#include "Clownfish/Test/TestCharBuf.h"
+
+#include "Clownfish/CharBuf.h"
+#include "Clownfish/Err.h"
+#include "Clownfish/Num.h"
+#include "Clownfish/String.h"
+#include "Clownfish/Test.h"
+#include "Clownfish/TestHarness/TestBatchRunner.h"
+#include "Clownfish/TestHarness/TestUtils.h"
+#include "Clownfish/Class.h"
+
+static char smiley[] = { (char)0xE2, (char)0x98, (char)0xBA, 0 };
+static uint32_t smiley_len = 3;
+
+TestCharBuf*
+TestCB_new() {
+ return (TestCharBuf*)Class_Make_Obj(TESTCHARBUF);
+}
+
+static CharBuf*
+S_get_cb(const char *string) {
+ CharBuf *cb = CB_new(0);
+ CB_Cat_Utf8(cb, string, strlen(string));
+ return cb;
+}
+
+static String*
+S_get_str(const char *string) {
+ return Str_new_from_utf8(string, strlen(string));
+}
+
+static bool
+S_cb_equals(CharBuf *cb, String *other) {
+ String *string = CB_To_String(cb);
+ bool retval = Str_Equals(string, (Obj*)other);
+ DECREF(string);
+ return retval;
+}
+
+static void
+S_cat_invalid_utf8(void *context) {
+ CharBuf *cb = (CharBuf*)context;
+ CB_Cat_Utf8(cb, "\xF0" "a", 2);
+}
+
+static void
+test_Cat(TestBatchRunner *runner) {
+ String *wanted = Str_newf("a%s", smiley);
+ CharBuf *got = S_get_cb("");
+
+ CB_Cat(got, wanted);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "Cat");
+ DECREF(got);
+
+ got = S_get_cb("a");
+ CB_Cat_Char(got, 0x263A);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "Cat_Char");
+ DECREF(got);
+
+ got = S_get_cb("a");
+ CB_Cat_Utf8(got, smiley, smiley_len);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "Cat_Utf8");
+ DECREF(got);
+
+ got = S_get_cb("a");
+ Err *error = Err_trap(S_cat_invalid_utf8, got);
+ TEST_TRUE(runner, error != NULL, "Cat_Utf8 throws with invalid UTF-8");
+ DECREF(error);
+ DECREF(got);
+
+ got = S_get_cb("a");
+ CB_Cat_Trusted_Utf8(got, smiley, smiley_len);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "Cat_Trusted_Utf8");
+ DECREF(got);
+
+ DECREF(wanted);
+}
+
+static void
+test_Clone(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo");
+ CharBuf *wanted_cb = S_get_cb("foo");
+ CharBuf *got = CB_Clone(wanted_cb);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "Clone");
+ DECREF(got);
+ DECREF(wanted);
+ DECREF(wanted_cb);
+}
+
+static void
+test_vcatf_percent(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo % bar");
+ CharBuf *got = S_get_cb("foo");
+ CB_catf(got, " %% bar");
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%%%");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_s(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo bar bizzle baz");
+ CharBuf *got = S_get_cb("foo ");
+ CB_catf(got, "bar %s baz", "bizzle");
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%s");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+S_catf_s_invalid_utf8(void *context) {
+ CharBuf *buf = (CharBuf*)context;
+ CB_catf(buf, "bar %s baz", "\x82" "abcd");
+}
+
+static void
+test_vcatf_s_invalid_utf8(TestBatchRunner *runner) {
+ CharBuf *buf = S_get_cb("foo ");
+ Err *error = Err_trap(S_catf_s_invalid_utf8, buf);
+ TEST_TRUE(runner, error != NULL, "%%s with invalid UTF-8");
+ DECREF(error);
+ DECREF(buf);
+}
+
+static void
+test_vcatf_null_string(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo bar [NULL] baz");
+ CharBuf *got = S_get_cb("foo ");
+ CB_catf(got, "bar %s baz", NULL);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%s NULL");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_str(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo bar ZEKE baz");
+ String *catworthy = S_get_str("ZEKE");
+ CharBuf *got = S_get_cb("foo ");
+ CB_catf(got, "bar %o baz", catworthy);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%o CharBuf");
+ DECREF(catworthy);
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_obj(TestBatchRunner *runner) {
+ String *wanted = S_get_str("ooga 20 booga");
+ Integer *i64 = Int_new(20);
+ CharBuf *got = S_get_cb("ooga");
+ CB_catf(got, " %o booga", i64);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%o Obj");
+ DECREF(i64);
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_null_obj(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo bar [NULL] baz");
+ CharBuf *got = S_get_cb("foo ");
+ CB_catf(got, "bar %o baz", NULL);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%o NULL");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_i8(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo bar -3 baz");
+ int8_t num = -3;
+ CharBuf *got = S_get_cb("foo ");
+ CB_catf(got, "bar %i8 baz", num);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%i8");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_i32(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo bar -100000 baz");
+ int32_t num = -100000;
+ CharBuf *got = S_get_cb("foo ");
+ CB_catf(got, "bar %i32 baz", num);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%i32");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_i64(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo bar -5000000000 baz");
+ int64_t num = INT64_C(-5000000000);
+ CharBuf *got = S_get_cb("foo ");
+ CB_catf(got, "bar %i64 baz", num);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%i64");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_u8(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo bar 3 baz");
+ uint8_t num = 3;
+ CharBuf *got = S_get_cb("foo ");
+ CB_catf(got, "bar %u8 baz", num);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%u8");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_u32(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo bar 100000 baz");
+ uint32_t num = 100000;
+ CharBuf *got = S_get_cb("foo ");
+ CB_catf(got, "bar %u32 baz", num);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%u32");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_u64(TestBatchRunner *runner) {
+ String *wanted = S_get_str("foo bar 5000000000 baz");
+ uint64_t num = UINT64_C(5000000000);
+ CharBuf *got = S_get_cb("foo ");
+ CB_catf(got, "bar %u64 baz", num);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%u64");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_f64(TestBatchRunner *runner) {
+ String *wanted;
+ char buf[64];
+ float num = 1.3f;
+ CharBuf *got = S_get_cb("foo ");
+ sprintf(buf, "foo bar %g baz", num);
+ wanted = Str_new_from_trusted_utf8(buf, strlen(buf));
+ CB_catf(got, "bar %f64 baz", num);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%f64");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+static void
+test_vcatf_x32(TestBatchRunner *runner) {
+ String *wanted;
+ char buf[64];
+ unsigned long num = INT32_MAX;
+ CharBuf *got = S_get_cb("foo ");
+#if (CHY_SIZEOF_LONG == 4)
+ sprintf(buf, "foo bar %.8lx baz", num);
+#elif (CHY_SIZEOF_INT == 4)
+ sprintf(buf, "foo bar %.8x baz", (unsigned)num);
+#endif
+ wanted = Str_new_from_trusted_utf8(buf, strlen(buf));
+ CB_catf(got, "bar %x32 baz", (uint32_t)num);
+ TEST_TRUE(runner, S_cb_equals(got, wanted), "%%x32");
+ DECREF(wanted);
+ DECREF(got);
+}
+
+typedef struct {
+ CharBuf *charbuf;
+ const char *pattern;
+} CatfContext;
+
+static void
+S_catf_invalid_pattern(void *vcontext) {
+ CatfContext *context = (CatfContext*)vcontext;
+ CB_catf(context->charbuf, context->pattern, 0);
+}
+
+static void
+test_vcatf_invalid(TestBatchRunner *runner) {
+ CatfContext context;
+ context.charbuf = S_get_cb("foo ");
+
+ static const char *const patterns[] = {
+ "bar %z baz",
+ "bar %i baz",
+ "bar %i1 baz",
+ "bar %i33 baz",
+ "bar %i65 baz",
+ "bar %u baz",
+ "bar %u9 baz",
+ "bar %u33 baz",
+ "bar %u65 baz",
+ "bar %x baz",
+ "bar %x9 baz",
+ "bar %x33 baz",
+ "bar %f baz",
+ "bar %f9 baz",
+ "bar %f65 baz",
+ "bar \xC2 baz"
+ };
+ static const size_t num_patterns = sizeof(patterns) / sizeof(patterns[0]);
+
+ for (size_t i = 0; i < num_patterns; i++) {
+ context.pattern = patterns[i];
+ Err *error = Err_trap(S_catf_invalid_pattern, &context);
+ TEST_TRUE(runner, error != NULL,
+ "catf throws with invalid pattern '%s'", patterns[i]);
+ DECREF(error);
+ }
+
+ DECREF(context.charbuf);
+}
+
+static void
+test_Clear(TestBatchRunner *runner) {
+ CharBuf *cb = S_get_cb("foo");
+ CB_Clear(cb);
+ CB_Cat_Utf8(cb, "bar", 3);
+ String *string = CB_Yield_String(cb);
+ TEST_TRUE(runner, Str_Equals_Utf8(string, "bar", 3), "Clear");
+ DECREF(string);
+ DECREF(cb);
+}
+
+static void
+test_Grow(TestBatchRunner *runner) {
+ CharBuf *cb = S_get_cb("omega");
+ CB_Grow(cb, 100);
+ size_t cap = cb->cap;
+ TEST_TRUE(runner, cap >= 100, "Grow");
+ CB_Grow(cb, 100);
+ TEST_UINT_EQ(runner, cb->cap, cap, "Grow to same size has no effect");
+ DECREF(cb);
+}
+
+static void
+test_Get_Size(TestBatchRunner *runner) {
+ CharBuf *got = S_get_cb("a");
+ CB_Cat_Utf8(got, smiley, smiley_len);
+ TEST_UINT_EQ(runner, CB_Get_Size(got), smiley_len + 1, "Get_Size");
+ DECREF(got);
+}
+
+void
+TestCB_Run_IMP(TestCharBuf *self, TestBatchRunner *runner) {
+ TestBatchRunner_Plan(runner, (TestBatch*)self, 41);
+ test_vcatf_percent(runner);
+ test_vcatf_s(runner);
+ test_vcatf_s_invalid_utf8(runner);
+ test_vcatf_null_string(runner);
+ test_vcatf_str(runner);
+ test_vcatf_obj(runner);
+ test_vcatf_null_obj(runner);
+ test_vcatf_i8(runner);
+ test_vcatf_i32(runner);
+ test_vcatf_i64(runner);
+ test_vcatf_u8(runner);
+ test_vcatf_u32(runner);
+ test_vcatf_u64(runner);
+ test_vcatf_f64(runner);
+ test_vcatf_x32(runner);
+ test_vcatf_invalid(runner);
+ test_Cat(runner);
+ test_Clone(runner);
+ test_Clear(runner);
+ test_Grow(runner);
+ test_Get_Size(runner);
+}
+
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/8ba4e619/runtime/test/Clownfish/Test/TestCharBuf.cfh
----------------------------------------------------------------------
diff --git a/runtime/test/Clownfish/Test/TestCharBuf.cfh b/runtime/test/Clownfish/Test/TestCharBuf.cfh
new file mode 100644
index 0000000..d568c14
--- /dev/null
+++ b/runtime/test/Clownfish/Test/TestCharBuf.cfh
@@ -0,0 +1,29 @@
+/* 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::TestCharBuf nickname TestCB
+ inherits Clownfish::TestHarness::TestBatch {
+
+ inert incremented TestCharBuf*
+ new();
+
+ void
+ Run(TestCharBuf *self, TestBatchRunner *runner);
+}
+
+