From ec688b4723a041044226358bcd4dd6e2da39da49 Mon Sep 17 00:00:00 2001 From: Luca Muscariello Date: Thu, 23 Feb 2017 17:01:02 +0100 Subject: Initial commit: cframework. Longbow and Libparc Change-Id: I90378dbd30da6033b20fb1f829b3b822cf366c59 Signed-off-by: Luca Muscariello --- libparc/parc/testing/parc_MemoryTesting.c | 44 ++ libparc/parc/testing/parc_MemoryTesting.h | 47 ++ libparc/parc/testing/parc_ObjectTesting.c | 266 ++++++++++ libparc/parc/testing/parc_ObjectTesting.h | 253 ++++++++++ libparc/parc/testing/test/.gitignore | 2 + libparc/parc/testing/test/CMakeLists.txt | 12 + .../parc/testing/test/test_parc_MemoryTesting.c | 86 ++++ .../parc/testing/test/test_parc_ObjectTesting.c | 543 +++++++++++++++++++++ 8 files changed, 1253 insertions(+) create mode 100755 libparc/parc/testing/parc_MemoryTesting.c create mode 100755 libparc/parc/testing/parc_MemoryTesting.h create mode 100644 libparc/parc/testing/parc_ObjectTesting.c create mode 100644 libparc/parc/testing/parc_ObjectTesting.h create mode 100644 libparc/parc/testing/test/.gitignore create mode 100644 libparc/parc/testing/test/CMakeLists.txt create mode 100755 libparc/parc/testing/test/test_parc_MemoryTesting.c create mode 100755 libparc/parc/testing/test/test_parc_ObjectTesting.c (limited to 'libparc/parc/testing') diff --git a/libparc/parc/testing/parc_MemoryTesting.c b/libparc/parc/testing/parc_MemoryTesting.c new file mode 100755 index 00000000..9a7b49fa --- /dev/null +++ b/libparc/parc/testing/parc_MemoryTesting.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed 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 + +#include +#include +#include + +bool +parcMemoryTesting_ExpectedOutstanding(const uint32_t expected, const char *format, ...) +{ + bool result = true; + + int allocationsLeaked = parcMemory_Outstanding() - expected; + if (allocationsLeaked != 0) { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + if (allocationsLeaked < 0) { + printf(" (%d more allocations deallocated than allocated)\n", -allocationsLeaked); + } else { + printf(" (%d allocations not deallocated)\n", allocationsLeaked); + } + result = false; + } + + return result; +} diff --git a/libparc/parc/testing/parc_MemoryTesting.h b/libparc/parc/testing/parc_MemoryTesting.h new file mode 100755 index 00000000..32b139db --- /dev/null +++ b/libparc/parc/testing/parc_MemoryTesting.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed 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. + */ + +/** + * @file parc_TestingMemory.h + * @brief <#Brief Description#> + * + * <#Detailed Description#> + * + */ + +#ifndef PARC_Library_parc_TestingMemory_h +#define PARC_Library_parc_TestingMemory_h + +#include +#include +#include +#include + +/** + * Determine if the current number of memory allocations is equal to the specified number. + * + * @param [in] expected The expected number of outstanding allocations. + * + * @return true The expected number of outstanding allocations is equal to the actual outstanding allocations. + * + * Example: + * @code + * { + * parcMemoryTesting_ExpectedOutstanding(0, "%s memory leak", __func__); + * } + * @endcode + */ +bool parcMemoryTesting_ExpectedOutstanding(const uint32_t expected, const char *format, ...); +#endif diff --git a/libparc/parc/testing/parc_ObjectTesting.c b/libparc/parc/testing/parc_ObjectTesting.c new file mode 100644 index 00000000..03fe2222 --- /dev/null +++ b/libparc/parc/testing/parc_ObjectTesting.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed 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 +#include +#include + +#include +#include +#include + +void +parcObjectTesting_AssertAcquireReleaseContractImpl(void *(acquireFunction)(const PARCObject *), const PARCObject *instance) +{ + void *reference = acquireFunction(instance); + assertTrue(reference == instance, "Expected the acquire function to return the same instance pointer."); + parcObject_Release(&reference); + parcObjectTesting_AssertAcquireReleaseImpl(instance); +} + +void +parcObjectTesting_AssertAcquireReleaseImpl(const PARCObject *instance) +{ + PARCReferenceCount originalReferences = parcObject_GetReferenceCount(instance); + + PARCObject *newReference = parcObject_Acquire(instance); + + assertTrue(newReference == instance, "Expected the acquire function to return the same instance pointer."); + + PARCReferenceCount currentReferences = parcObject_GetReferenceCount(instance); + assertTrue(currentReferences == (originalReferences + 1), + "Expected references to be %" PRIu64 ", actual %" PRIu64, (originalReferences + 1), currentReferences); + + parcObject_Release(&newReference); + currentReferences = parcObject_GetReferenceCount(instance); + assertTrue(currentReferences == originalReferences, + "Expected references to be %" PRIu64 ", actual %" PRIu64, originalReferences, currentReferences); +} + +static void +_parcObjectTesting_AssertEquals(bool (*equalsFunction)(const void *a, const void *b), const void *x, const void *y, const void *z, va_list ap) +{ + assertNotNull(x, "The value of x cannot be NULL."); + assertNotNull(y, "The value of y cannot be NULL."); + assertNotNull(z, "The value of z cannot be NULL."); + + assertFalse(x == y, "The value x cannot be the same as y"); + assertFalse(x == z, "The value x cannot be the same as z"); + assertFalse(y == z, "The value y cannot be the same as z"); + + assertTrue(equalsFunction(NULL, NULL), "Equality failed: Equals(NULL, NULL) must be true"); + + assertFalse(equalsFunction(x, NULL), "Equality failed: The value of x must not be Equal to NULL."); + assertFalse(equalsFunction(NULL, x), "Equality failed: NULL must not be equal to the value of x."); + + assertTrue(equalsFunction(x, x), "Reflexive failed: for any non-null reference value x, equals(x, x) must return true."); + + assertTrue(equalsFunction(x, y), "Equality failed: The values of x and y must be Equal."); + assertTrue(equalsFunction(x, z), "Equality failed: The values of x and z must be Equal."); + + assertTrue(equalsFunction(x, y) == equalsFunction(y, x), "Symmetric equality failed: equals(x, y) == equals(y, x) must true."); + + assertTrue((equalsFunction(x, y) == equalsFunction(y, z)) == equalsFunction(z, x), + "Transitive equality failed: equals(x, y) == equals(y, z) == equals(z, x) must true."); + + int index = 0; + for (void *value = va_arg(ap, void *); value != 0; value = va_arg(ap, void *)) { + assertFalse(equalsFunction(x, value), "Value %d (@%p) must not be equal to x", index, value); + assertTrue(equalsFunction(x, value) == equalsFunction(value, x), + "Symmetric equality failed: equals(x, value) == equals(value, x) must true."); + index++; + } +} + +void +parcObjectTesting_AssertEquals(const PARCObject *x, const void *y, const void *z, ...) +{ + va_list ap; + va_start(ap, z); + + _parcObjectTesting_AssertEquals((bool (*)(const void *, const void *))parcObject_Equals, x, y, z, ap); + + assertTrue(parcObject_HashCode(x) == parcObject_HashCode(y), + "HashCode of x and y must be equal"); + assertTrue(parcObject_HashCode(x) == parcObject_HashCode(z), + "HashCode of x and z must be equal"); + + va_end(ap); +} + +void +parcObjectTesting_AssertEqualsFunctionImpl(bool (*equalsFunction)(const void *a, const void *b), const void *x, const void *y, const void *z, ...) +{ + va_list ap; + va_start(ap, z); + _parcObjectTesting_AssertEquals(equalsFunction, x, y, z, ap); + + va_end(ap); +} + +bool +parcObjectTesting_AssertCompareToImpl(int (*compareTo)(const void *a, const void *b), + const void *exemplar, + const void **equivalent, + const void **lesser, + const void **greater) +{ + assertNotNull(exemplar, "Parameter exemplar must not be NULL"); + assertNotNull(equivalent, "Parameter equivalent must not be NULL"); + assertNotNull(lesser, "Parameter less must not be NULL"); + assertNotNull(greater, "Parameter greater must not be NULL"); + + assertTrue(compareTo(NULL, NULL) == 0, "Comparison of null values must be 0."); + + assertTrue(compareTo(exemplar, NULL) > 0, "Comparison of a non-null value to a null value must be > 0."); + + assertTrue(compareTo(NULL, exemplar) < 0, "Comparison of null value to a non-null value must be < 0."); + + assertTrue(compareTo(exemplar, exemplar) == 0, "Comparison of a value to itself must == 0"); + + for (int i = 0; equivalent[i] != NULL; i++) { + assertTrue(compareTo(exemplar, equivalent[i]) == 0, + "Comparison of the value to equivalent[%d] must == 0", i); + assertTrue(compareTo(exemplar, equivalent[i]) == -compareTo(equivalent[i], exemplar), + "Requires sgn(compareTo(value, equivalent[%d])) == -sgn(equivalent[%d], value)", i, i); + } + for (int i = 0; lesser[i] != NULL; i++) { + assertTrue(compareTo(exemplar, lesser[i]) > 0, + "Compare of value to lesser[%d] must be > 0", i); + assertTrue(compareTo(exemplar, lesser[i]) == -compareTo(lesser[i], exemplar), + "Requires signum(compareTo(value, lesser[%d])) == -signum(lesser[%d], value)", i, i); + } + for (int i = 0; greater[i] != NULL; i++) { + assertTrue(compareTo(exemplar, greater[i]) < 0, "Compare to greater[%d] must be > 0", i); + assertTrue(compareTo(exemplar, greater[i]) == -compareTo(greater[i], exemplar), + "Requires compareTo(value, greater[%d]) == -compareTo(greater[%d], value)", i, i); + } + + return true; +} + +void +parcObjectTesting_AssertHashCode(const PARCObject *x, const void *y) +{ + assertFalse(x == y, "The parameters x and y cannot be the same value."); + assertTrue(parcObject_Equals(x, y), "The parameters x and y must be equal"); + + PARCHashCode xCode = parcObject_HashCode(x); + PARCHashCode yCode = parcObject_HashCode(y); + + assertTrue(xCode == yCode, "Expected the HashCode of two equal objects to be equal."); +} + +void +parcObjectTesting_AssertHashCodeImpl(PARCHashCode (*hashCode)(const void *a), void *a) +{ + PARCHashCode code1 = hashCode(a); + PARCHashCode code2 = hashCode(a); + assertTrue(code1 == code2, "HashCode function does not consistently return the same value."); +} + +static void +_parcObjectTesting_AssertCopy(const PARCObject *instance) +{ + PARCObject *copy = parcObject_Copy(instance); + if (copy == instance) { + parcObject_Release(©); + assertFalse(true, "Copy should not be the same object"); + } + if (!parcObject_Equals(instance, copy)) { + parcObject_Release(©); + assertTrue(false, "Object fails Copy Test"); + } + + parcObject_Release(©); +} + +static void +_parcObjectTesting_AssertEqualsWrapper(const PARCObject *a, + const PARCObject *b, + const PARCObject *c, + ...) +{ + va_list ap; + va_start(ap, c); + + _parcObjectTesting_AssertEquals((bool (*)(const void *, const void *))parcObject_Equals, a, b, c, ap); + + va_end(ap); +} + +static void +_parcObjectTesting_AssertToJSON(const PARCObject *instance) +{ + PARCJSON *json = parcObject_ToJSON(instance); + char *result = parcJSON_ToString(json); + assertNotNull(result, "Something should be returned"); + parcMemory_Deallocate(&result); + parcJSON_Release(&json); +} + +static void +_parcObjectTesting_AssertToString(const PARCObject *instance) +{ + char *result = parcObject_ToString(instance); + assertNotNull(result, "Something should be returned"); + parcMemory_Deallocate(&result); +} + +void +parcObjectTesting_AssertObjectConformance(const PARCObject *inst1, + const PARCObject *inst2, + const PARCObject *inst3, + const PARCObject *lesser, + const PARCObject *greater) +{ + assertNotNull(inst1, "The value of x cannot be NULL."); + assertNotNull(inst2, "The value of y cannot be NULL."); + assertNotNull(inst3, "The value of z cannot be NULL."); + assertNotNull(lesser, "The value of z cannot be NULL."); + assertNotNull(greater, "The value of z cannot be NULL."); + + parcObject_AssertValid(inst1); + parcObject_AssertValid(inst2); + parcObject_AssertValid(inst3); + parcObject_AssertValid(lesser); + parcObject_AssertValid(greater); + + // Acquire/Release + parcObjectTesting_AssertAcquireReleaseImpl(inst1); + + // Equals + _parcObjectTesting_AssertEqualsWrapper(inst1, inst2, inst3, lesser, greater, NULL); + + // Copy + _parcObjectTesting_AssertCopy(inst1); + + // Compare + const void *equals[] = { inst1, inst2, NULL }; + const void *lessThan[] = { lesser, NULL }; + const void *greaterThan[] = { greater, NULL }; + parcObjectTesting_AssertCompareToImpl(parcObject_Compare, inst1, equals, lessThan, greaterThan); + + // HashCode + parcObjectTesting_AssertHashCode(inst1, inst2); + + // ToJSON + _parcObjectTesting_AssertToJSON(inst1); + + // ToString + _parcObjectTesting_AssertToString(inst1); +} diff --git a/libparc/parc/testing/parc_ObjectTesting.h b/libparc/parc/testing/parc_ObjectTesting.h new file mode 100644 index 00000000..557fee10 --- /dev/null +++ b/libparc/parc/testing/parc_ObjectTesting.h @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed 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. + */ + +/** + * @file parc_ObjectTesting.h + * @brief Support for LongBow runtime and unit testing of PARCObject implementations. + * + */ +#ifndef PARC_Library_parc_ObjectTest_h +#define PARC_Library_parc_ObjectTest_h + +#include +#include + +#include +#include + +/** + * Test if a PARCObject subclass behaves well as a PARCObject when passed to the various PARCObject functions. + * + * @param [in] inst1 A pointer to an instance that will be used as the base comparison for remaining parameters. + * @param [in] inst2 A pointer to an instance that is known to be equal to @p inst1, but is not @p inst1. + * @param [in] inst3 A pointer to an instance that is known to be equal to @p inst1 & @p inst2, but is not @p inst1 or @p inst2. + * @param [in] lesser A pointer to and instance that are known to be lesser than @p inst1. + * @param [in] greater A pointer to and instance that are known to be greater than @p inst1. + * + * @see parcObjectTesting_AssertEqualsFunction + * @see parcObjectTesting_AssertCompareTo + * @see parcObjectTesting_AssertAcquire + * @see parcObjectTesting_AssertHashCode + */ + +void parcObjectTesting_AssertObjectConformance(const PARCObject *inst1, + const PARCObject *inst2, + const PARCObject *inst3, + const PARCObject *lesser, + const PARCObject *greater); + +/** + * Ensure that a function implements the Equals contract. + * + * The equality function must implement the following equivalence relations on non-null instances: + * + * * It is reflexive: for any non-null reference value x, equals(x, x) must return true. + * + * * It is symmetric: for any non-null reference values x and y, equals(x, y) must return true if and only if + * equals(y x) returns true. + * + * * It is transitive: for any non-null reference values x, y, and z, if + * equals(x, y) returns true and + * equals(y, z) returns true, + * then equals(x, z) must return true. + * + * * It is consistent: for any non-null reference values x and y, multiple invocations of equals(x, y) + * consistently return true or consistently return false. + * + * * For any non-null reference value x, equals(x, NULL)) must return false. + * + * @param [in] _function_ A pointer to a function that will be called to determine if it conforms to the Equals contract. + * @param [in] _x_ A pointer to a value that will be used as the base comparison for remaining parameters. + * @param [in] _y_ A pointer to a value that is known to be equal to @p x, but is not @p x. + * @param [in] _z_ A pointer to a value that is known to be equal to @p x and to @p y, but is neither @p x nor @p y. + * @param [in] ... A list of pointers to values that are known to be not equal to @p x, @p y, or @p z. + * @see parcObjectTesting_AssertEqualsImpl + */ +#define parcObjectTesting_AssertEqualsFunction(_function_, _x_, _y_, _z_, ...) \ + parcObjectTesting_AssertEqualsFunctionImpl((bool (*)(const void *, const void *))_function_, _x_, _y_, _z_, __VA_ARGS__, NULL) + +/** + * Compares instance a known set of other instances for order. + * + * The comparison function that this evaluates sgn(a - b) required to return a negative integer, + * zero, or a positive integer as a is less than, + * equal to, or greater than b. + * + * The function must ensure that: + *
    + *
  • sgn(compareTo(a, b)) == -sgn(b, a) for all values of a and b.
  • + *
  • the relation is transitive: (compareTo(x, y)>0 && compareTo(y, z)>0) implies compareTo(x, z)>0.
  • + *
  • compareTo(x, y)== 0 implies that sgn(compareTo(x, z)) == sgn(compareTo(y, z)), for all values of z.
  • + *
+ * + * This also stipulates that + * compareTo(NULL, NULL)) == 0, + * compareTo(not-NULL, NULL)) > 0, + * compareTo(NULL, not-NULL)) < 0. + * + * It is strongly recommended, but not strictly required that relation(compareTo(x, y)==0) == equals(x, y)) is true. + * Any module that implements the compareTo function and violates this condition + * should clearly indicate this fact. + * For example, "Note: this implementation has a natural ordering that is inconsistent with equals." + * + * @param [in] compareTo A pointer to a function implementing the CompareTo function signature. + * @param [in] exemplar The pivotal value under test. + * @param [in] equivalent A NULL terminated array of values that are all equivalent to value. + * @param [in] lesser A NULL terminated array of values that are all less than value. + * @param [in] greater A NULL terminated array of values that are all greater than value. + * @see parcObjectTesting_AssertCompareTo + */ +#define parcObjectTesting_AssertCompareTo(function, value, equality, lesser, greater) \ + parcObjectTesting_AssertCompareToImpl((int (*)(const void *, const void *))function, (void *) value, (void *) equality, (void *) lesser, (void *) greater) + +#define parcObjectTesting_AssertAcquireReleaseContract(_function_, _instance_) \ + parcObjectTesting_AssertAcquireReleaseContractImpl((void *(*)(const PARCObject *))_function_, _instance_) +/** + * Assert the acquire/release contract given the Acquire function of a PARCObject implementation. + * + * Paragraphs Of Explanation + * + * @param [in] acquireFunction A pointer to the acquireFunction to invoke. + * @param [in] instance A pointer to a PARCObject implementation that will be used to acquire and release references. + */ +void parcObjectTesting_AssertAcquireReleaseContractImpl(void *(acquireFunction)(const PARCObject *), + const PARCObject *instance); + + +#define parcObjectTesting_AssertAcquire(_instance_) \ + parcObjectTesting_AssertAcquireReleaseImpl((const PARCObject *) _instance_) + +/** + * Assert that the given PARCObject's Acquire/Release contract is correct. + * + * @param [in] instance A pointer to a PARCObject instance. + */ +void parcObjectTesting_AssertAcquireReleaseImpl(const PARCObject *instance); + +/** + * Ensure that a function implements the Equals contract. + * + * The equality function must implement the following equivalence relations on non-null instances: + * + * * It is reflexive: for any non-null reference value x, equals(x, x) must return true. + * + * * It is symmetric: for any non-null reference values x and y, equals(x, y) must return true if and only if + * equals(y x) returns true. + * + * * It is transitive: for any non-null reference values x, y, and z, if + * equals(x, y) returns true and + * equals(y, z) returns true, + * then equals(x, z) must return true. + * + * * It is consistent: for any non-null reference values x and y, multiple invocations of equals(x, y) + * consistently return true or consistently return false. + * + * * For any non-null reference value x, equals(x, NULL)) must return false. + * + * @param [in] equalsFunction A pointer to a function that will be called to determine if it conforms to the Equals contract. + * @param [in] x A pointer to a value that will be used as the base comparison for remaining parameters. + * @param [in] y A pointer to a value that is known to be equal to @p x, but is not @p x. + * @param [in] z A pointer to a value that is known to be equal to @p x and to @p y, but is neither @p x nor @p y. + * @param [in] ... A NULL terminated variable number of parameters consisting of pointers to values that are known to be not equal to @p x, @p y, or @p z. + * @see parcObjectTesting_AssertEquals + */ +void parcObjectTesting_AssertEqualsFunctionImpl(bool (*equalsFunction)(const void *a, const void *b), const void *x, const void *y, const void *z, ...); + +/** + * Ensure that a PARCObject implements the Equals contract. + * + * The PARCObject's `Equals()` function must implement the following equivalence relations on non-null instances: + * + * * It is reflexive: for any non-null reference value x, equals(x, x) must return true. + * + * * It is symmetric: for any non-null reference values x and y, equals(x, y) must return true if and only if + * equals(y x) returns true. + * + * * It is transitive: for any non-null reference values x, y, and z, if + * equals(x, y) returns true and + * equals(y, z) returns true, + * then equals(x, z) must return true. + * + * * It is consistent: for any non-null reference values x and y, multiple invocations of equals(x, y) + * consistently return true or consistently return false. + * + * * For any non-null reference value x, equals(x, NULL)) must return false. + * + * @param [in] object A pointer to a valid PARCObject instance. + * @param [in] y A pointer to a value that is known to be equal to @p object, but is not the same as @p object. + * @param [in] z A pointer to a value that is known to be equal to @p object and to @p y, but is neither the same as @p object nor @p y. + * @param [in] ... A NULL terminated variable number of parameters consisting of pointers to values that are known to be not equal to @p object, @p y, or @p z. + */ +void parcObjectTesting_AssertEquals(const PARCObject *object, const void *y, const void *z, ...); + +/** + * Compares instance a with instance b for order. + * + * The comparison function that this evaluates sgn(a - b) required to return a negative integer, + * zero, or a positive integer as a is less than, + * equal to, or greater than b. + * + * The function must ensure that: + *
    + *
  • sgn(compareTo(a, b)) == -sgn(b, a) for all values of a and b.
  • + *
  • the relation is transitive: (compareTo(x, y)>0 && compareTo(y, z)>0) implies compareTo(x, z)>0.
  • + *
  • compareTo(x, y)== 0 implies that sgn(compareTo(x, z)) == sgn(compareTo(y, z)), for all values of z.
  • + *
+ * + * This also stipulates that + * compareTo(NULL, NULL)) == 0, + * compareTo(not-NULL, NULL)) > 0, + * compareTo(NULL, not-NULL)) < 0. + * + * It is strongly recommended, but not strictly required that relation(compareTo(x, y)==0) == equals(x, y)) is true. + * Any module that implements the compareTo function and violates this condition + * should clearly indicate this fact. + * For example, "Note: this implementation has a natural ordering that is inconsistent with equals." + * + * @param [in] compareTo A pointer to a function implementing the CompareTo function signature. + * @param [in] exemplar The pivotal value under test. + * @param [in] equivalent A NULL terminated array of values that are all equivalent to value. + * @param [in] lesser A NULL terminated array of values that are all less than value. + * @param [in] greater A NULL terminated array of values that are all greater than value. + * @see parcObjectTesting_AssertCompareTo + */ +bool parcObjectTesting_AssertCompareToImpl(int (*compareTo)(const void *a, const void *b), + const void *exemplar, + const void **equivalent, + const void **lesser, + const void **greater); + +/** + * Assert the HashCode contract on a PARCObject. + * + * @param [in] x A pointer to a valid PARCObject. + * @param [in] y A pointer to a valid PARCObject, that must be equal to @p x, but not the same. + * + * Example: + * @code + * { + * <#example#> + * } + * @endcode + */ +void parcObjectTesting_AssertHashCode(const PARCObject *x, const void *y); + +/** + * Assert the HashCode function contract. + * + * @param [in] hashCode A pointer to a function implementing the hash code function. + */ +void parcObjectTesting_AssertHashCodeImpl(PARCHashCode (*hashCode)(const void *a), void *a); +#endif diff --git a/libparc/parc/testing/test/.gitignore b/libparc/parc/testing/test/.gitignore new file mode 100644 index 00000000..3b3dc64d --- /dev/null +++ b/libparc/parc/testing/test/.gitignore @@ -0,0 +1,2 @@ +test_parc_MemoryTesting +test_parc_ObjectTesting diff --git a/libparc/parc/testing/test/CMakeLists.txt b/libparc/parc/testing/test/CMakeLists.txt new file mode 100644 index 00000000..1de2e89d --- /dev/null +++ b/libparc/parc/testing/test/CMakeLists.txt @@ -0,0 +1,12 @@ +set(TestsExpectedToPass + test_parc_MemoryTesting + test_parc_ObjectTesting + ) + +# Enable gcov output for the tests +add_definitions(--coverage) +set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage") + +foreach(test ${TestsExpectedToPass}) + AddTest(${test}) +endforeach() diff --git a/libparc/parc/testing/test/test_parc_MemoryTesting.c b/libparc/parc/testing/test/test_parc_MemoryTesting.c new file mode 100755 index 00000000..d24e79d4 --- /dev/null +++ b/libparc/parc/testing/test/test_parc_MemoryTesting.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed 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 the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../parc_MemoryTesting.c" + +#include +#include + +#include + +LONGBOW_TEST_RUNNER(test_parc_MemoryTest) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(test_parc_MemoryTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(test_parc_MemoryTest) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, parcMemoryTesting_ExpectedOutstanding); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, parcMemoryTesting_ExpectedOutstanding) +{ + void *memory = parcMemory_Allocate(4); + + assertTrue(parcMemoryTesting_ExpectedOutstanding(1, "Expected 1 outstanding allocation"), + "Failed 1 expected allocation"); + + parcMemory_Deallocate(&memory); + assertTrue(parcMemoryTesting_ExpectedOutstanding(0, "Expected 0 outstanding allocations"), + "Failed 0 expected allocations"); + + assertFalse(parcMemoryTesting_ExpectedOutstanding(1, "Expected 1 outstanding allocations"), + "Failed 1 expected llocations"); + assertFalse(parcMemoryTesting_ExpectedOutstanding(-1, "Expected -1 outstanding allocations"), + "Failed -1 expected allocations"); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_parc_MemoryTest); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} diff --git a/libparc/parc/testing/test/test_parc_ObjectTesting.c b/libparc/parc/testing/test/test_parc_ObjectTesting.c new file mode 100755 index 00000000..9d70b68c --- /dev/null +++ b/libparc/parc/testing/test/test_parc_ObjectTesting.c @@ -0,0 +1,543 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed 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 the file(s) containing the functions to be tested. +// This permits internal static functions to be visible to this Test Framework. +#include "../parc_ObjectTesting.c" +#include +#include + +#include +#include +#include + +#include +#include +#include + +LONGBOW_TEST_RUNNER(test_parc_ObjectTesting) +{ + // The following Test Fixtures will run their corresponding Test Cases. + // Test Fixtures are run in the order specified, but all tests should be idempotent. + // Never rely on the execution order of tests or share state between them. + LONGBOW_RUN_TEST_FIXTURE(Static); + LONGBOW_RUN_TEST_FIXTURE(CompareTo); + LONGBOW_RUN_TEST_FIXTURE(Equals); + LONGBOW_RUN_TEST_FIXTURE(AcquireRelease); + LONGBOW_RUN_TEST_FIXTURE(Conformance); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(test_parc_ObjectTesting) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(test_parc_ObjectTesting) +{ + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestRunner_GetName(testRunner), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + + return LONGBOW_STATUS_SUCCEEDED; +} + +static bool +_equalsFunction(const void *x, const void *y) +{ + if (x == y) { + return true; + } + if (x == NULL || y == NULL) { + return false; + } + + return (strcmp(x, y) == 0); +} + +static bool +_equalsFunction_NotReflexive(const void *x, const void *y) +{ + if (x == y) { + return true; + } + if (x == NULL || y == NULL) { + return false; + } + if (x < y) { + return true; + } else { + return false; + } +} + +LONGBOW_TEST_FIXTURE(Equals) +{ + LONGBOW_RUN_TEST_CASE(Equals, parcObjectTesting_AssertEquals); + + LONGBOW_RUN_TEST_CASE(Equals, parcObjectTesting_AssertEqualsFunctionImpl); + LONGBOW_RUN_TEST_CASE(Equals, parcObjectTesting_AssertEqualsFunctionImpl_FailXYsame); + LONGBOW_RUN_TEST_CASE(Equals, parcObjectTesting_AssertEqualsFunctionImpl_FailXZsame); + LONGBOW_RUN_TEST_CASE(Equals, parcObjectTesting_AssertEqualsFunctionImpl_FailXnotequalZ); + LONGBOW_RUN_TEST_CASE(Equals, parcObjectTesting_AssertEqualsFunctionImpl_FailXnotequalY); + LONGBOW_RUN_TEST_CASE(Equals, parcObjectTesting_AssertEqualsFunctionImpl_FailNotSymmetric); +} + +static uint32_t _longBowGlobal_Global_outstanding; + +LONGBOW_TEST_FIXTURE_SETUP(Equals) +{ + _longBowGlobal_Global_outstanding = parcMemory_Outstanding(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Equals) +{ + LongBowStatus result = LONGBOW_STATUS_SUCCEEDED; + + if (parcMemoryTesting_ExpectedOutstanding(_longBowGlobal_Global_outstanding, longBowTestCase_GetName(testCase)) == false) { + parcSafeMemory_ReportAllocation(STDERR_FILENO); + result = LONGBOW_STATUS_MEMORYLEAK; + } + + return result; +} + +LONGBOW_TEST_CASE(Equals, parcObjectTesting_AssertEquals) +{ + PARCBuffer *x = parcBuffer_Allocate(sizeof(uint64_t)); + PARCBuffer *y = parcBuffer_Allocate(sizeof(uint64_t)); + PARCBuffer *z = parcBuffer_Allocate(sizeof(uint64_t)); + PARCBuffer *u1 = parcBuffer_Allocate(sizeof(uint64_t)); + PARCBuffer *u2 = parcBuffer_Allocate(sizeof(uint64_t)); + parcBuffer_Flip(parcBuffer_PutUint64(x, 1)); + parcBuffer_Flip(parcBuffer_PutUint64(y, 1)); + parcBuffer_Flip(parcBuffer_PutUint64(z, 1)); + parcBuffer_Flip(parcBuffer_PutUint64(u1, 2)); + parcBuffer_Flip(parcBuffer_PutUint64(u2, 3)); + + parcObjectTesting_AssertEquals(x, y, z, u1, u2, NULL); + parcBuffer_Release(&x); + parcBuffer_Release(&y); + parcBuffer_Release(&z); + parcBuffer_Release(&u1); + parcBuffer_Release(&u2); +} + +LONGBOW_TEST_CASE(Equals, parcObjectTesting_AssertEqualsFunctionImpl) +{ + void *x = strdup("1"); + void *y = strdup("1"); + void *z = strdup("1"); + void *u1 = "a"; + void *u2 = "b"; + + parcObjectTesting_AssertEqualsFunctionImpl(_equalsFunction, x, y, z, u1, u2, NULL); + free(x); + free(y); + free(z); +} + +LONGBOW_TEST_CASE_EXPECTS(Equals, parcObjectTesting_AssertEqualsFunctionImpl_FailXYsame, .event = &LongBowAssertEvent) +{ + void *x = strdup("1"); + void *y = x; + void *z = strdup("1"); + void *u1 = "a"; + void *u2 = "b"; + + parcObjectTesting_AssertEqualsFunctionImpl(_equalsFunction, x, y, z, u1, u2, NULL); + free(x); + free(y); + free(z); +} + +LONGBOW_TEST_CASE_EXPECTS(Equals, parcObjectTesting_AssertEqualsFunctionImpl_FailXZsame, .event = &LongBowAssertEvent) +{ + void *x = strdup("1"); + void *y = strdup("1"); + void *z = x; + void *u1 = "a"; + void *u2 = "b"; + + parcObjectTesting_AssertEqualsFunctionImpl(_equalsFunction, x, y, z, u1, u2, NULL); + free(x); + free(y); + free(z); +} + +LONGBOW_TEST_CASE_EXPECTS(Equals, parcObjectTesting_AssertEqualsFunctionImpl_FailXnotequalY, .event = &LongBowAssertEvent) +{ + void *x = strdup("1"); + void *y = strdup("xyzzy"); + void *z = strdup("1"); + void *u1 = "a"; + void *u2 = "b"; + + parcObjectTesting_AssertEqualsFunctionImpl(_equalsFunction, x, y, z, u1, u2, NULL); + free(x); + free(y); + free(z); +} + +LONGBOW_TEST_CASE_EXPECTS(Equals, parcObjectTesting_AssertEqualsFunctionImpl_FailXnotequalZ, .event = &LongBowAssertEvent) +{ + void *x = strdup("1"); + void *y = strdup("1"); + void *z = strdup("xyzzy"); + void *u1 = "a"; + void *u2 = "b"; + + parcObjectTesting_AssertEqualsFunctionImpl(_equalsFunction, x, y, z, u1, u2, NULL); + free(x); + free(y); + free(z); +} + +LONGBOW_TEST_CASE_EXPECTS(Equals, parcObjectTesting_AssertEqualsFunctionImpl_FailNotSymmetric, .event = &LongBowAssertEvent) +{ + void *x = strdup("1"); + void *y = strdup("1"); + void *z = strdup("1"); + void *u1 = "a"; + void *u2 = "b"; + + parcObjectTesting_AssertEqualsFunctionImpl(_equalsFunction_NotReflexive, x, y, z, u1, u2, NULL); + free(x); + free(y); + free(z); +} + +LONGBOW_TEST_FIXTURE(AcquireRelease) +{ + LONGBOW_RUN_TEST_CASE(AcquireRelease, parcObjectTesting_AssertAcquire); +} + +LONGBOW_TEST_FIXTURE_SETUP(AcquireRelease) +{ + _longBowGlobal_Global_outstanding = parcMemory_Outstanding(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(AcquireRelease) +{ + LongBowStatus result = LONGBOW_STATUS_SUCCEEDED; + + if (parcMemoryTesting_ExpectedOutstanding(_longBowGlobal_Global_outstanding, longBowTestCase_GetName(testCase)) == false) { + parcSafeMemory_ReportAllocation(STDERR_FILENO); + result = LONGBOW_STATUS_MEMORYLEAK; + } + + return result; +} + +LONGBOW_TEST_CASE(AcquireRelease, parcObjectTesting_AssertAcquire) +{ + PARCBuffer *buffer = parcBuffer_Allocate(10); + parcObjectTesting_AssertAcquireReleaseImpl(buffer); + parcBuffer_Release(&buffer); +} + + +LONGBOW_TEST_FIXTURE(CompareTo) +{ + LONGBOW_RUN_TEST_CASE(CompareTo, parcObjectTesting_AssertCompareTo); +} + +LONGBOW_TEST_FIXTURE_SETUP(CompareTo) +{ + _longBowGlobal_Global_outstanding = parcMemory_Outstanding(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(CompareTo) +{ + LongBowStatus result = LONGBOW_STATUS_SUCCEEDED; + + if (parcMemoryTesting_ExpectedOutstanding(_longBowGlobal_Global_outstanding, longBowTestCase_GetName(testCase)) == false) { + parcSafeMemory_ReportAllocation(STDERR_FILENO); + result = LONGBOW_STATUS_MEMORYLEAK; + } + + return result; +} + +LONGBOW_TEST_CASE(CompareTo, parcObjectTesting_AssertCompareTo) +{ + PARCBuffer *x = parcBuffer_Wrap((uint8_t [10]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 10, 0, 10); + PARCBuffer *y = parcBuffer_Wrap((uint8_t [10]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 10, 0, 10); + + PARCBuffer *equivalent[] = { + x, + y, + NULL + }; + PARCBuffer *lesser[] = { + parcBuffer_Wrap((uint8_t [10]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8 }, 10, 0, 10), + parcBuffer_Wrap((uint8_t [9]) { 0, 1, 2, 3, 4, 5, 5, 7, 8, }, 9, 0, 9), + NULL + }; + PARCBuffer *greater[] = { + parcBuffer_Wrap((uint8_t [10]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10 }, 10, 0, 10), + parcBuffer_Wrap((uint8_t [11]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 11, 0, 11), + NULL + }; + + parcObjectTesting_AssertCompareTo(parcBuffer_Compare, x, equivalent, lesser, greater); + + parcBuffer_Release(&x); + parcBuffer_Release(&y); + + for (int i = 0; lesser[i] != NULL; i++) { + parcBuffer_Release(&lesser[i]); + } + for (int i = 0; greater[i] != NULL; i++) { + parcBuffer_Release(&greater[i]); + } +} + +LONGBOW_TEST_FIXTURE(Static) +{ +} + +LONGBOW_TEST_FIXTURE_SETUP(Static) +{ + _longBowGlobal_Global_outstanding = parcMemory_Outstanding(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Static) +{ + LongBowStatus result = LONGBOW_STATUS_SUCCEEDED; + + size_t allocationsLeaked = parcMemory_Outstanding() - _longBowGlobal_Global_outstanding; + + if (allocationsLeaked) { + printf("%s leaks memory by %zd allocations\n", longBowTestCase_GetName(testCase), allocationsLeaked); + parcSafeMemory_ReportAllocation(STDERR_FILENO); + result = LONGBOW_STATUS_MEMORYLEAK; + } + return result; +} + +LONGBOW_TEST_FIXTURE(Conformance) +{ + LONGBOW_RUN_TEST_CASE(Conformance, parcObjectTesting_AssertObjectConformance_succeed); + + LONGBOW_RUN_TEST_CASE(Conformance, parcObjectTesting_AssertObjectConformance_fail_non_object); + LONGBOW_RUN_TEST_CASE(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_equals); + LONGBOW_RUN_TEST_CASE(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_compare); + LONGBOW_RUN_TEST_CASE(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_copy_junk); + LONGBOW_RUN_TEST_CASE(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_copy_same); + LONGBOW_RUN_TEST_CASE(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_hash); + LONGBOW_RUN_TEST_CASE(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_toString); + LONGBOW_RUN_TEST_CASE(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_toJSON); +} + + +typedef struct { + PARCBuffer *inst1; + PARCBuffer *inst2; + PARCBuffer *inst3; + PARCBuffer *lesser; + PARCBuffer *greater; + PARCObjectDescriptor *descriptor; +} TestData_t; + +static const PARCObjectDescriptor * +_copyDescriptor(const PARCObjectDescriptor *orig) +{ + return parcObjectDescriptor_Create("Name", + orig->objectSize, + orig->objectAlignment, + orig->isLockable, + orig->destructor, + orig->release, orig->copy, + orig->toString, orig->equals, + orig->compare, orig->hashCode, + orig->toJSON, orig->display, + orig->super, orig->typeState); +} + +LONGBOW_TEST_FIXTURE_SETUP(Conformance) +{ + TestData_t *data = parcMemory_AllocateAndClear(sizeof(TestData_t)); + assertNotNull(data, "parcMemory_AllocateAndClear(%zu) returned NULL", sizeof(TestData_t)); + + data->inst1 = parcBuffer_Flip(parcBuffer_CreateFromArray((uint8_t [10]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 10)); + data->inst2 = parcBuffer_Flip(parcBuffer_CreateFromArray((uint8_t [10]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 10)); + data->inst3 = parcBuffer_Flip(parcBuffer_CreateFromArray((uint8_t [10]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 10)); + data->lesser = parcBuffer_Flip(parcBuffer_CreateFromArray((uint8_t [10]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8 }, 10)); + data->greater = parcBuffer_Flip(parcBuffer_CreateFromArray((uint8_t [10]) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10 }, 10)); + + PARCObjectDescriptor *d = (PARCObjectDescriptor *) parcObject_GetDescriptor(data->inst1); + data->descriptor = (PARCObjectDescriptor *) _copyDescriptor(d); + + longBowTestCase_SetClipBoardData(testCase, data); + + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Conformance) +{ + TestData_t *data = longBowTestCase_GetClipBoardData(testCase); + + parcBuffer_Release(&data->inst1); + parcBuffer_Release(&data->inst2); + parcBuffer_Release(&data->inst3); + parcBuffer_Release(&data->lesser); + parcBuffer_Release(&data->greater); + + parcObjectDescriptor_Destroy(&data->descriptor); + + parcMemory_Deallocate(&data); + + uint32_t outstandingAllocations = parcSafeMemory_ReportAllocation(STDERR_FILENO); + if (outstandingAllocations != 0) { + printf("%s leaks memory by %d allocations\n", longBowTestCase_GetName(testCase), outstandingAllocations); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Conformance, parcObjectTesting_AssertObjectConformance_succeed) +{ + TestData_t *data = longBowTestCase_GetClipBoardData(testCase); + + parcObjectTesting_AssertObjectConformance(data->inst1, data->inst2, data->inst3, data->lesser, data->greater); +} + +LONGBOW_TEST_CASE_EXPECTS(Conformance, parcObjectTesting_AssertObjectConformance_fail_non_object, .event = &LongBowAssertEvent) +{ + char *inst1 = "not an object"; + char *inst2 = "not an object"; + char *inst3 = "not an object"; + + parcObjectTesting_AssertObjectConformance(inst1, inst2, inst3, NULL, NULL); +} + +LONGBOW_TEST_CASE_EXPECTS(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_equals, .event = &LongBowAssertEvent) +{ + TestData_t *data = longBowTestCase_GetClipBoardData(testCase); + PARCBuffer *inst1 = data->inst1; + PARCBuffer *inst2 = inst1; + PARCBuffer *inst3 = inst1; + + parcObjectTesting_AssertObjectConformance(inst1, inst2, inst3, data->lesser, data->greater); +} + +LONGBOW_TEST_CASE_EXPECTS(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_compare, .event = &LongBowAssertEvent) +{ + TestData_t *data = longBowTestCase_GetClipBoardData(testCase); + + parcObjectTesting_AssertObjectConformance(data->inst1, data->inst2, data->inst3, data->greater, data->lesser); +} + +__attribute__ ((noinline)) +static PARCObject * +badCopyJunk(const PARCObject *instance) +{ + return parcBuffer_Allocate(10); +} + +LONGBOW_TEST_CASE_EXPECTS(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_copy_junk, .event = &LongBowAssertEvent) +{ + TestData_t *data = longBowTestCase_GetClipBoardData(testCase); + + data->descriptor->copy = badCopyJunk; + parcObject_SetDescriptor(data->inst1, data->descriptor); + + parcObjectTesting_AssertObjectConformance(data->inst1, data->inst2, data->inst3, data->greater, data->lesser); +} + +static PARCObject * +badCopySame(const PARCObject *instance) +{ + return parcObject_Acquire(instance); +} + +LONGBOW_TEST_CASE_EXPECTS(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_copy_same, .event = &LongBowAssertEvent) +{ + TestData_t *data = longBowTestCase_GetClipBoardData(testCase); + + data->descriptor->copy = badCopySame; + parcObject_SetDescriptor(data->inst1, data->descriptor); + + parcObjectTesting_AssertObjectConformance(data->inst1, data->inst2, data->inst3, data->greater, data->lesser); +} + +static PARCHashCode +badHash(const PARCObject *instance) +{ + return (PARCHashCode) instance; +} + +LONGBOW_TEST_CASE_EXPECTS(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_hash, .event = &LongBowAssertEvent) +{ + TestData_t *data = longBowTestCase_GetClipBoardData(testCase); + + data->descriptor->hashCode = badHash; + parcObject_SetDescriptor(data->inst1, data->descriptor); + + parcObjectTesting_AssertObjectConformance(data->inst1, data->inst2, data->inst3, data->greater, data->lesser); +} + +static PARCJSON * +badToJSON(const PARCObject *instance) +{ + return NULL; +} + +LONGBOW_TEST_CASE_EXPECTS(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_toJSON, .event = &LongBowAssertEvent) +{ + TestData_t *data = longBowTestCase_GetClipBoardData(testCase); + + data->descriptor->toJSON = badToJSON; + parcObject_SetDescriptor(data->inst1, data->descriptor); + + parcObjectTesting_AssertObjectConformance(data->inst1, data->inst2, data->inst3, data->greater, data->lesser); +} + +static char * +badToString(const PARCObject *instance) +{ + return NULL; +} + +LONGBOW_TEST_CASE_EXPECTS(Conformance, parcObjectTesting_AssertObjectConformance_fail_object_toString, .event = &LongBowAssertEvent) +{ + TestData_t *data = longBowTestCase_GetClipBoardData(testCase); + + data->descriptor->toString = badToString; + parcObject_SetDescriptor(data->inst1, data->descriptor); + + parcObjectTesting_AssertObjectConformance(data->inst1, data->inst2, data->inst3, data->greater, data->lesser); +} + +int +main(int argc, char *argv[argc]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(test_parc_ObjectTesting); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} -- cgit 1.2.3-korg