summaryrefslogtreecommitdiff
path: root/src/test/lily-test.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/lily-test.h')
-rw-r--r--src/test/lily-test.h263
1 files changed, 263 insertions, 0 deletions
diff --git a/src/test/lily-test.h b/src/test/lily-test.h
new file mode 100644
index 0000000..b5f380c
--- /dev/null
+++ b/src/test/lily-test.h
@@ -0,0 +1,263 @@
+/****************************************************************
+ *
+ * ======== lily-test ========
+ *
+ * a midsize C unit testing library
+ * copyright (c) 2022 kate swanson (sanine)
+ *
+ * This is anti-capitalist software, released for free use by individuals and
+ * organizations that do not operate by capitalist principles.
+ *
+ * Permission is hereby granted, free of charge, to any person or
+ * organization (the "User") obtaining a copy of this software and associated
+ * documentation files (the "Software"), to use, copy, modify, merge,
+ * distribute, and/or sell copies of the Software, subject to the following conditions:
+ *
+ * 1. The above copyright notice and this permission notice shall be included
+ * in all copies or modified versions of the Software.
+ *
+ * 2. The User is one of the following:
+ * a. An individual person, laboring for themselves
+ * b. A non-profit organization
+ * c. An educational institution
+ * d. An organization that seeks shared profit for all of its members, and
+ * allows non-members to set the cost of their labor
+ *
+ * 3. If the User is an organization with owners, then all owners are workers
+ * and all workers are owners with equal equity and/or equal vote.
+ *
+ * 4. If the User is an organization, then the User is not law enforcement or
+ * military, or working for or under either.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT EXPRESS OR IMPLIED WARRANTY OF
+ * ANY KIND, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://anticapitalist.software/
+ * https://sanine.net
+ *
+ ****************************************************************/
+
+
+#ifndef LILY_TEST_H
+#define LILY_TEST_H
+
+#define LILY_VERSION_MAJOR 1
+#define LILY_VERSION_MINOR 0
+#define LILY_VERSION_PATCH 0
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+
+#define STR_IMP(x) #x
+#define STR(x) STR_IMP(x)
+/* define SOURCE_PATH_SIZE to strip away the
+ leading parts of the full compilation path */
+#ifndef SOURCE_PATH_SIZE
+#define LILY_LOCATION (__FILE__ ":" STR(__LINE__))
+#else
+#define LILY_LOCATION ((__FILE__ ":" STR(__LINE__)) + SOURCE_PATH_SIZE)
+#endif
+
+/** a few nasty globals that make everything clean for the end user */
+struct lily_globals_t {
+ jmp_buf env;
+ size_t error_msg_len;
+ char *error_msg;
+ const char *error_location;
+};
+extern struct lily_globals_t _lily_globals;
+
+typedef void (*lily_test_t)(void);
+
+/** run a single test */
+#define lily_run_test(test) _lily_run_test(#test, test)
+void _lily_run_test(const char *name, lily_test_t test);
+
+/** run a suite */
+#define lily_run_suite(suite) _lily_run_suite(#suite, suite)
+void _lily_run_suite(const char *name, lily_test_t suite);
+
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * assertions
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+/** basic assertion function, mostly used by the other assertions */
+void lily_assert_msg(bool statement, const char *location,
+ const char *format_string, ...);
+
+#define lily_assert_true(statement) _lily_assert_true(#statement, statement, LILY_LOCATION)
+void _lily_assert_true(const char *statement, bool value, const char *location);
+
+
+#define lily_assert_false(statement) _lily_assert_false(#statement, statement, LILY_LOCATION)
+void _lily_assert_false(const char *statement, bool value, const char *location);
+
+
+#define lily_assert_not_null(ptr) _lily_assert_not_null(#ptr, ptr, LILY_LOCATION)
+void _lily_assert_not_null(const char *name, void *ptr, const char *location);
+
+
+#define lily_assert_null(ptr) _lily_assert_null(#ptr, ptr, LILY_LOCATION)
+void _lily_assert_null(const char *name, void *ptr, const char *location);
+
+
+#define lily_assert_ptr_equal(a, b) _lily_assert_ptr_equal(#a, #b, a, b, LILY_LOCATION)
+void _lily_assert_ptr_equal(const char *name_a, const char *name_b,
+ void *a, void *b, const char *location);
+
+
+#define lily_assert_ptr_not_equal(a, b) _lily_assert_ptr_not_equal(#a, #b, a, b, LILY_LOCATION)
+void _lily_assert_ptr_not_equal(const char *name_a, const char *name_b,
+ void *a, void *b, const char *location);
+
+
+#define lily_assert_int_equal(a, b) _lily_assert_int_equal(#a, #b, a, b, LILY_LOCATION)
+void _lily_assert_int_equal(const char *name_a, const char *name_b,
+ intmax_t a, intmax_t b, const char *location);
+
+
+#define lily_assert_int_not_equal(a, b) _lily_assert_int_not_equal(#a, #b, a, b, LILY_LOCATION)
+void _lily_assert_int_not_equal(const char *name_a, const char *name_b,
+ intmax_t a, intmax_t b, const char *location);
+
+
+#define lily_assert_float_equal(a, b, epsilon) \
+ _lily_assert_float_equal(#a, #b, a, b, epsilon, LILY_LOCATION)
+void _lily_assert_float_equal(const char *name_a, const char *name_b,
+ double a, double b, double epsilon, const char *location);
+
+
+#define lily_assert_float_not_equal(a, b, epsilon) \
+ _lily_assert_float_not_equal(#a, #b, a, b, epsilon, LILY_LOCATION)
+void _lily_assert_float_not_equal(const char *name_a, const char *name_b,
+ double a, double b, double epsilon, const char *location);
+
+
+#define lily_assert_string_equal(a, b) _lily_assert_string_equal(#a, #b, a, b, LILY_LOCATION)
+void _lily_assert_string_equal(const char *name_a, const char *name_b,
+ char *a, char *b, const char *location);
+
+
+#define lily_assert_string_not_equal(a, b) _lily_assert_string_not_equal(#a, #b, a, b, LILY_LOCATION)
+void _lily_assert_string_not_equal(const char *name_a, const char *name_b,
+ char *a, char *b, const char *location);
+
+
+#define lily_assert_memory_equal(a, b, size) \
+ _lily_assert_memory_equal(#a, #b, a, b, size, LILY_LOCATION)
+void _lily_assert_memory_equal(const char *name_a, const char *name_b,
+ void *a, void *b, size_t size, const char *location);
+
+
+#define lily_assert_memory_not_equal(a, b, size) \
+ _lily_assert_memory_not_equal(#a, #b, a, b, size, LILY_LOCATION)
+void _lily_assert_memory_not_equal(const char *name_a, const char *name_b,
+ void *a, void *b, size_t size, const char *location);
+
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * mocks
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+
+/** queue structure capable of containing arbitrary data */
+typedef struct lily_queue_t {
+ size_t buf_size;
+ uint8_t *buf;
+ uint8_t *front, *back;
+} lily_queue_t;
+
+
+/** create a queue */
+lily_queue_t* lily_queue_create();
+
+/** destroy a queue */
+void lily_queue_destroy(lily_queue_t *q);
+
+
+/** enqueue a value
+ *
+ * q - the queue to append to
+ * type - the type of the value to append
+ * value - the value to append
+ */
+#define lily_enqueue(q, type, value) \
+ do { \
+ type _var = value; \
+ _lily_enqueue(q, sizeof(type), (uint8_t*)(&_var)); \
+ } while(0)
+void _lily_enqueue(lily_queue_t *q, size_t size, uint8_t *data);
+
+
+/** pop a value from the queue
+ *
+ * q - the queue to pop from
+ * type - the type of the value to pop
+ * ptr - the location to store the popped value
+ */
+#define lily_dequeue(q, type, ptr) \
+ _lily_dequeue(q, sizeof(type), (uint8_t*) ptr)
+void _lily_dequeue(lily_queue_t *q, size_t size, uint8_t *ptr);
+
+
+struct lily_mock_arg_t {
+ size_t size;
+ void *var;
+};
+
+#define LILY_NARGS(args) (sizeof(args)/sizeof(struct lily_mock_arg_t))
+
+/** structure to store data for mock functions */
+typedef struct lily_mock_t {
+ unsigned int n_calls;
+ lily_queue_t *arguments;
+ lily_queue_t *values;
+} lily_mock_t;
+
+/** setup mock function storage */
+lily_mock_t * lily_mock_create();
+/** tear down mock function storage */
+void lily_mock_destroy(lily_mock_t *m);
+/** automatically re-create mock function storage */
+void lily_mock_use(lily_mock_t **m);
+
+/** store a call to a mock function */
+#define lily_mock_store_call(m, args) \
+ _lily_mock_call(m, args, LILY_NARGS(args))
+/* lily_mock_call is deprecated!! do not use it in new programs */
+#define lily_mock_call(m, args) \
+ _lily_mock_call(m, args, LILY_NARGS(args))
+void _lily_mock_call(lily_mock_t *m, struct lily_mock_arg_t *args, size_t n_args);
+
+/** retrieve a call to a mock function */
+#define lily_mock_get_call(m, args, call_num) \
+ _lily_get_call(m, args, LILY_NARGS(args), call_num)
+/* lily_get_call is deprecated!! do not use it in new programs */
+#define lily_get_call(m, args, call_num) \
+ _lily_get_call(m, args, LILY_NARGS(args), call_num)
+void _lily_get_call(lily_mock_t *m,
+ struct lily_mock_arg_t *args,
+ size_t n_args,
+ unsigned int call_num);
+
+/** store a value in a mock structure */
+#define lily_store_value(m, type, value) \
+ lily_enqueue(m->values, type, value)
+/** retrieve a value from a mock structure */
+#define lily_get_value(m, type, ptr) \
+ lily_dequeue(m->values, type, ptr)
+
+#endif