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); +} + +
