aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_node.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_node.c')
-rw-r--r--test/test_node.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/test/test_node.c b/test/test_node.c
new file mode 100644
index 00000000..1d6ad2c5
--- /dev/null
+++ b/test/test_node.c
@@ -0,0 +1,203 @@
+/*
+ Copyright 2011-2020 David Robillard <http://drobilla.net>
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#undef NDEBUG
+
+#include "serd/serd.h"
+
+#include <assert.h>
+#include <float.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define USTR(s) ((const uint8_t*)(s))
+
+#ifndef INFINITY
+# define INFINITY (DBL_MAX + DBL_MAX)
+#endif
+#ifndef NAN
+# define NAN (INFINITY - INFINITY)
+#endif
+
+static void
+test_strtod(double dbl, double max_delta)
+{
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "%f", dbl);
+
+ char* endptr = NULL;
+ const double out = serd_strtod(buf, &endptr);
+
+ const double diff = fabs(out - dbl);
+ assert(diff <= max_delta);
+}
+
+static void
+test_string_to_double(void)
+{
+ const double expt_test_nums[] = {
+ 2.0E18, -5e19, +8e20, 2e+24, -5e-5, 8e0, 9e-0, 2e+0
+ };
+
+ const char* expt_test_strs[] = {
+ "02e18", "-5e019", "+8e20", "2E+24", "-5E-5", "8E0", "9e-0", " 2e+0"
+ };
+
+ for (size_t i = 0; i < sizeof(expt_test_nums) / sizeof(double); ++i) {
+ const double num = serd_strtod(expt_test_strs[i], NULL);
+ const double delta = fabs(num - expt_test_nums[i]);
+ assert(delta <= DBL_EPSILON);
+
+ test_strtod(expt_test_nums[i], DBL_EPSILON);
+ }
+}
+
+static void
+test_double_to_node(void)
+{
+ const double dbl_test_nums[] = {
+ 0.0, 9.0, 10.0, .01, 2.05, -16.00001, 5.000000005, 0.0000000001, NAN, INFINITY
+ };
+
+ const char* dbl_test_strs[] = {
+ "0.0", "9.0", "10.0", "0.01", "2.05", "-16.00001", "5.00000001", "0.0", NULL, NULL
+ };
+
+ for (size_t i = 0; i < sizeof(dbl_test_nums) / sizeof(double); ++i) {
+ SerdNode node = serd_node_new_decimal(dbl_test_nums[i], 8);
+ const bool pass = (node.buf && dbl_test_strs[i])
+ ? !strcmp((const char*)node.buf, dbl_test_strs[i])
+ : ((const char*)node.buf == dbl_test_strs[i]);
+ assert(pass);
+ const size_t len = node.buf ? strlen((const char*)node.buf) : 0;
+ assert(node.n_bytes == len && node.n_chars == len);
+ serd_node_free(&node);
+ }
+}
+
+static void
+test_integer_to_node(void)
+{
+ const long int_test_nums[] = {
+ 0, -0, -23, 23, -12340, 1000, -1000
+ };
+
+ const char* int_test_strs[] = {
+ "0", "0", "-23", "23", "-12340", "1000", "-1000"
+ };
+
+ for (size_t i = 0; i < sizeof(int_test_nums) / sizeof(double); ++i) {
+ SerdNode node = serd_node_new_integer(int_test_nums[i]);
+ assert(!strcmp((const char*)node.buf, (const char*)int_test_strs[i]));
+ const size_t len = strlen((const char*)node.buf);
+ assert(node.n_bytes == len && node.n_chars == len);
+ serd_node_free(&node);
+ }
+}
+
+static void
+test_blob_to_node(void)
+{
+ for (size_t size = 0; size < 256; ++size) {
+ uint8_t* data = size > 0 ? (uint8_t*)malloc(size) : NULL;
+ for (size_t i = 0; i < size; ++i) {
+ data[i] = (uint8_t)((size + i) % 256);
+ }
+
+ SerdNode blob = serd_node_new_blob(data, size, size % 5);
+
+ assert(blob.n_bytes == blob.n_chars);
+ assert(blob.n_bytes == strlen((const char*)blob.buf));
+
+ size_t out_size = 0;
+ uint8_t* out = (uint8_t*)serd_base64_decode(
+ blob.buf, blob.n_bytes, &out_size);
+ assert(out_size == size);
+
+ for (size_t i = 0; i < size; ++i) {
+ assert(out[i] == data[i]);
+ }
+
+ serd_node_free(&blob);
+ serd_free(out);
+ free(data);
+ }
+}
+
+static void
+test_node_equals(void)
+{
+ const uint8_t replacement_char_str[] = { 0xEF, 0xBF, 0xBD, 0 };
+ SerdNode lhs = serd_node_from_string(SERD_LITERAL, replacement_char_str);
+ SerdNode rhs = serd_node_from_string(SERD_LITERAL, USTR("123"));
+ assert(!serd_node_equals(&lhs, &rhs));
+
+ SerdNode qnode = serd_node_from_string(SERD_CURIE, USTR("foo:bar"));
+ assert(!serd_node_equals(&lhs, &qnode));
+ assert(serd_node_equals(&lhs, &lhs));
+
+ SerdNode null_copy = serd_node_copy(&SERD_NODE_NULL);
+ assert(serd_node_equals(&SERD_NODE_NULL, &null_copy));
+}
+
+static void
+test_node_from_string(void)
+{
+ SerdNode node = serd_node_from_string(SERD_LITERAL, (const uint8_t*)"hello\"");
+ assert(node.n_bytes == 6 && node.n_chars == 6 &&
+ node.flags == SERD_HAS_QUOTE &&
+ !strcmp((const char*)node.buf, "hello\""));
+
+ node = serd_node_from_string(SERD_URI, NULL);
+ assert(serd_node_equals(&node, &SERD_NODE_NULL));
+}
+
+static void
+test_node_from_substring(void)
+{
+ SerdNode empty = serd_node_from_substring(SERD_LITERAL, NULL, 32);
+ assert(!empty.buf && !empty.n_bytes && !empty.n_chars && !empty.flags &&
+ !empty.type);
+
+ SerdNode a_b = serd_node_from_substring(SERD_LITERAL, USTR("a\"bc"), 3);
+ assert(a_b.n_bytes == 3 && a_b.n_chars == 3 &&
+ a_b.flags == SERD_HAS_QUOTE &&
+ !strncmp((const char*)a_b.buf, "a\"b", 3));
+
+ a_b = serd_node_from_substring(SERD_LITERAL, USTR("a\"bc"), 10);
+ assert(a_b.n_bytes == 4 && a_b.n_chars == 4 &&
+ a_b.flags == SERD_HAS_QUOTE &&
+ !strncmp((const char*)a_b.buf, "a\"bc", 4));
+}
+
+int
+main(void)
+{
+ test_string_to_double();
+ test_double_to_node();
+ test_integer_to_node();
+ test_blob_to_node();
+ test_node_equals();
+ test_node_from_string();
+ test_node_from_substring();
+
+ printf("Success\n");
+ return 0;
+}