annotate src/serd-0.18.2/tests/serd_test.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents c7265573341e
children
rev   line source
Chris@0 1 /*
Chris@0 2 Copyright 2011-2012 David Robillard <http://drobilla.net>
Chris@0 3
Chris@0 4 Permission to use, copy, modify, and/or distribute this software for any
Chris@0 5 purpose with or without fee is hereby granted, provided that the above
Chris@0 6 copyright notice and this permission notice appear in all copies.
Chris@0 7
Chris@0 8 THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
Chris@0 9 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
Chris@0 10 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
Chris@0 11 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
Chris@0 12 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
Chris@0 13 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Chris@0 14 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Chris@0 15 */
Chris@0 16
Chris@0 17 #include <float.h>
Chris@0 18 #include <math.h>
Chris@0 19 #include <stdarg.h>
Chris@0 20 #include <stdio.h>
Chris@0 21 #include <stdlib.h>
Chris@0 22 #include <string.h>
Chris@0 23
Chris@0 24 #include "serd/serd.h"
Chris@0 25
Chris@0 26 #define USTR(s) ((const uint8_t*)(s))
Chris@0 27
Chris@0 28 #ifdef _WIN32
Chris@0 29 # define INFINITY (DBL_MAX + DBL_MAX)
Chris@0 30 # define NAN (INFINITY - INFINITY)
Chris@0 31 #endif
Chris@0 32
Chris@0 33 static int
Chris@0 34 failure(const char* fmt, ...)
Chris@0 35 {
Chris@0 36 va_list args;
Chris@0 37 va_start(args, fmt);
Chris@0 38 fprintf(stderr, "error: ");
Chris@0 39 vfprintf(stderr, fmt, args);
Chris@0 40 va_end(args);
Chris@0 41 return 1;
Chris@0 42 }
Chris@0 43
Chris@0 44 static bool
Chris@0 45 test_strtod(double dbl, double max_delta)
Chris@0 46 {
Chris@0 47 char buf[1024];
Chris@0 48 snprintf(buf, sizeof(buf), "%lf", dbl);
Chris@0 49
Chris@0 50 char* endptr = NULL;
Chris@0 51 const double out = serd_strtod(buf, &endptr);
Chris@0 52
Chris@0 53 const double diff = fabs(out - dbl);
Chris@0 54 if (diff > max_delta) {
Chris@0 55 return !failure("Parsed %lf != %lf (delta %lf)\n", dbl, out, diff);
Chris@0 56 }
Chris@0 57 return true;
Chris@0 58 }
Chris@0 59
Chris@0 60 static SerdStatus
Chris@0 61 count_prefixes(void* handle, const SerdNode* name, const SerdNode* uri)
Chris@0 62 {
Chris@0 63 ++*(int*)handle;
Chris@0 64 return SERD_SUCCESS;
Chris@0 65 }
Chris@0 66
Chris@0 67 typedef struct {
Chris@0 68 int n_statements;
Chris@0 69 const SerdNode* graph;
Chris@0 70 } ReaderTest;
Chris@0 71
Chris@0 72 static SerdStatus
Chris@0 73 test_sink(void* handle,
Chris@0 74 SerdStatementFlags flags,
Chris@0 75 const SerdNode* graph,
Chris@0 76 const SerdNode* subject,
Chris@0 77 const SerdNode* predicate,
Chris@0 78 const SerdNode* object,
Chris@0 79 const SerdNode* object_datatype,
Chris@0 80 const SerdNode* object_lang)
Chris@0 81 {
Chris@0 82 ReaderTest* rt = (ReaderTest*)handle;
Chris@0 83 ++rt->n_statements;
Chris@0 84 rt->graph = graph;
Chris@0 85 return SERD_SUCCESS;
Chris@0 86 }
Chris@0 87
Chris@0 88 int
Chris@0 89 main(void)
Chris@0 90 {
Chris@0 91 #define MAX 1000000
Chris@0 92 #define NUM_TESTS 1000
Chris@0 93 for (int i = 0; i < NUM_TESTS; ++i) {
Chris@0 94 double dbl = rand() % MAX;
Chris@0 95 dbl += (rand() % MAX) / (double)MAX;
Chris@0 96
Chris@0 97 if (!test_strtod(dbl, 1 / (double)MAX)) {
Chris@0 98 return 1;
Chris@0 99 }
Chris@0 100 }
Chris@0 101
Chris@0 102 const double expt_test_nums[] = {
Chris@0 103 2.0E18, -5e19, +8e20, 2e+34, -5e-5, 8e0, 9e-0, 2e+0
Chris@0 104 };
Chris@0 105
Chris@0 106 const char* expt_test_strs[] = {
Chris@0 107 "02e18", "-5e019", "+8e20", "2E+34", "-5E-5", "8E0", "9e-0", " 2e+0"
Chris@0 108 };
Chris@0 109
Chris@0 110 for (unsigned i = 0; i < sizeof(expt_test_nums) / sizeof(double); ++i) {
Chris@0 111 const double num = serd_strtod(expt_test_strs[i], NULL);
Chris@0 112 const double delta = fabs(num - expt_test_nums[i]);
Chris@0 113 if (delta > DBL_EPSILON) {
Chris@0 114 return failure("Parsed `%s' %lf != %lf (delta %lf)\n",
Chris@0 115 expt_test_strs[i], num, expt_test_nums[i], delta);
Chris@0 116 }
Chris@0 117 }
Chris@0 118
Chris@0 119 // Test serd_node_new_decimal
Chris@0 120
Chris@0 121 const double dbl_test_nums[] = {
Chris@0 122 0.0, 9.0, 10.0, .01, 2.05, -16.00001, 5.000000005, 0.0000000001, NAN, INFINITY
Chris@0 123 };
Chris@0 124
Chris@0 125 const char* dbl_test_strs[] = {
Chris@0 126 "0.0", "9.0", "10.0", "0.01", "2.05", "-16.00001", "5.00000001", "0.0", NULL, NULL
Chris@0 127 };
Chris@0 128
Chris@0 129 for (unsigned i = 0; i < sizeof(dbl_test_nums) / sizeof(double); ++i) {
Chris@0 130 SerdNode node = serd_node_new_decimal(dbl_test_nums[i], 8);
Chris@0 131 const bool pass = (node.buf && dbl_test_strs[i])
Chris@0 132 ? !strcmp((const char*)node.buf, (const char*)dbl_test_strs[i])
Chris@0 133 : ((const char*)node.buf == dbl_test_strs[i]);
Chris@0 134 if (!pass) {
Chris@0 135 return failure("Serialised `%s' != %s\n",
Chris@0 136 node.buf, dbl_test_strs[i]);
Chris@0 137 }
Chris@0 138 const size_t len = node.buf ? strlen((const char*)node.buf) : 0;
Chris@0 139 if (node.n_bytes != len || node.n_chars != len) {
Chris@0 140 return failure("Length %zu,%zu != %zu\n",
Chris@0 141 node.n_bytes, node.n_chars, len);
Chris@0 142 }
Chris@0 143 serd_node_free(&node);
Chris@0 144 }
Chris@0 145
Chris@0 146 // Test serd_node_new_integer
Chris@0 147
Chris@0 148 const long int_test_nums[] = {
Chris@0 149 0, -0, -23, 23, -12340, 1000, -1000
Chris@0 150 };
Chris@0 151
Chris@0 152 const char* int_test_strs[] = {
Chris@0 153 "0", "0", "-23", "23", "-12340", "1000", "-1000"
Chris@0 154 };
Chris@0 155
Chris@0 156 for (unsigned i = 0; i < sizeof(int_test_nums) / sizeof(double); ++i) {
Chris@0 157 SerdNode node = serd_node_new_integer(int_test_nums[i]);
Chris@0 158 if (strcmp((const char*)node.buf, (const char*)int_test_strs[i])) {
Chris@0 159 return failure("Serialised `%s' != %s\n",
Chris@0 160 node.buf, int_test_strs[i]);
Chris@0 161 }
Chris@0 162 const size_t len = strlen((const char*)node.buf);
Chris@0 163 if (node.n_bytes != len || node.n_chars != len) {
Chris@0 164 return failure("Length %zu,%zu != %zu\n",
Chris@0 165 node.n_bytes, node.n_chars, len);
Chris@0 166 }
Chris@0 167 serd_node_free(&node);
Chris@0 168 }
Chris@0 169
Chris@0 170 // Test serd_node_new_blob
Chris@0 171 for (size_t size = 0; size < 256; ++size) {
Chris@0 172 uint8_t* data = (uint8_t*)malloc(size);
Chris@0 173 for (size_t i = 0; i < size; ++i) {
Chris@0 174 data[i] = (uint8_t)(rand() % 256);
Chris@0 175 }
Chris@0 176
Chris@0 177 SerdNode blob = serd_node_new_blob(data, size, size % 5);
Chris@0 178
Chris@0 179 if (blob.n_bytes != blob.n_chars) {
Chris@0 180 return failure("Blob %zu bytes != %zu chars\n",
Chris@0 181 blob.n_bytes, blob.n_chars);
Chris@0 182 }
Chris@0 183
Chris@0 184 size_t out_size;
Chris@0 185 uint8_t* out = (uint8_t*)serd_base64_decode(
Chris@0 186 blob.buf, blob.n_bytes, &out_size);
Chris@0 187 if (out_size != size) {
Chris@0 188 return failure("Blob size %zu != %zu\n", out_size, size);
Chris@0 189 }
Chris@0 190
Chris@0 191 for (size_t i = 0; i < size; ++i) {
Chris@0 192 if (out[i] != data[i]) {
Chris@0 193 return failure("Corrupt blob at byte %zu\n", i);
Chris@0 194 }
Chris@0 195 }
Chris@0 196
Chris@0 197 serd_node_free(&blob);
Chris@0 198 free(out);
Chris@0 199 free(data);
Chris@0 200 }
Chris@0 201
Chris@0 202 // Test serd_strlen
Chris@0 203
Chris@0 204 const uint8_t str[] = { '"', '5', 0xE2, 0x82, 0xAC, '"', '\n', 0 };
Chris@0 205
Chris@0 206 size_t n_bytes;
Chris@0 207 SerdNodeFlags flags;
Chris@0 208 size_t len = serd_strlen(str, &n_bytes, &flags);
Chris@0 209 if (len != 5 || n_bytes != 7
Chris@0 210 || flags != (SERD_HAS_QUOTE|SERD_HAS_NEWLINE)) {
Chris@0 211 return failure("Bad serd_strlen(%s) len=%zu n_bytes=%zu flags=%u\n",
Chris@0 212 str, len, n_bytes, flags);
Chris@0 213 }
Chris@0 214 len = serd_strlen(str, NULL, &flags);
Chris@0 215 if (len != 5) {
Chris@0 216 return failure("Bad serd_strlen(%s) len=%zu flags=%u\n",
Chris@0 217 str, len, flags);
Chris@0 218 }
Chris@0 219
Chris@0 220 // Test serd_strerror
Chris@0 221
Chris@0 222 const uint8_t* msg = NULL;
Chris@0 223 if (strcmp((const char*)(msg = serd_strerror(SERD_SUCCESS)), "Success")) {
Chris@0 224 return failure("Bad message `%s' for SERD_SUCCESS\n", msg);
Chris@0 225 }
Chris@0 226 for (int i = SERD_FAILURE; i <= SERD_ERR_INTERNAL; ++i) {
Chris@0 227 msg = serd_strerror((SerdStatus)i);
Chris@0 228 if (!strcmp((const char*)msg, "Success")) {
Chris@0 229 return failure("Bad message `%s' for (SerdStatus)%d\n", msg, i);
Chris@0 230 }
Chris@0 231 }
Chris@0 232 msg = serd_strerror((SerdStatus)-1);
Chris@0 233
Chris@0 234 // Test serd_uri_to_path
Chris@0 235
Chris@0 236 const uint8_t* uri = (const uint8_t*)"file:///home/user/foo.ttl";
Chris@0 237 if (strcmp((const char*)serd_uri_to_path(uri), "/home/user/foo.ttl")) {
Chris@0 238 return failure("Bad path %s for %s\n", serd_uri_to_path(uri), uri);
Chris@0 239 }
Chris@0 240 uri = (const uint8_t*)"file://localhost/home/user/foo.ttl";
Chris@0 241 if (strcmp((const char*)serd_uri_to_path(uri), "/home/user/foo.ttl")) {
Chris@0 242 return failure("Bad path %s for %s\n", serd_uri_to_path(uri), uri);
Chris@0 243 }
Chris@0 244 uri = (const uint8_t*)"file:illegal/file/uri";
Chris@0 245 if (serd_uri_to_path(uri)) {
Chris@0 246 return failure("Converted invalid URI `%s' to path `%s'\n",
Chris@0 247 uri, serd_uri_to_path(uri));
Chris@0 248 }
Chris@0 249 uri = (const uint8_t*)"file:///c:/awful/system";
Chris@0 250 if (strcmp((const char*)serd_uri_to_path(uri), "c:/awful/system")) {
Chris@0 251 return failure("Bad path %s for %s\n", serd_uri_to_path(uri), uri);
Chris@0 252 }
Chris@0 253 uri = (const uint8_t*)"file:///c:awful/system";
Chris@0 254 if (strcmp((const char*)serd_uri_to_path(uri), "/c:awful/system")) {
Chris@0 255 return failure("Bad path %s for %s\n", serd_uri_to_path(uri), uri);
Chris@0 256 }
Chris@0 257 uri = (const uint8_t*)"file:///0/1";
Chris@0 258 if (strcmp((const char*)serd_uri_to_path(uri), "/0/1")) {
Chris@0 259 return failure("Bad path %s for %s\n", serd_uri_to_path(uri), uri);
Chris@0 260 }
Chris@0 261 uri = (const uint8_t*)"C:\\Windows\\Sucks";
Chris@0 262 if (strcmp((const char*)serd_uri_to_path(uri), "C:\\Windows\\Sucks")) {
Chris@0 263 return failure("Bad path %s for %s\n", serd_uri_to_path(uri), uri);
Chris@0 264 }
Chris@0 265 uri = (const uint8_t*)"C|/Windows/Sucks";
Chris@0 266 if (strcmp((const char*)serd_uri_to_path(uri), "C|/Windows/Sucks")) {
Chris@0 267 return failure("Bad path %s for %s\n", serd_uri_to_path(uri), uri);
Chris@0 268 }
Chris@0 269
Chris@0 270 // Test serd_node_new_file_uri and serd_file_uri_parse
Chris@0 271 SerdURI furi;
Chris@0 272 const uint8_t* path_str = USTR("C:/My 100%");
Chris@0 273 SerdNode file_node = serd_node_new_file_uri(path_str, 0, &furi, true);
Chris@0 274 uint8_t* hostname = NULL;
Chris@0 275 uint8_t* out_path = serd_file_uri_parse(file_node.buf, &hostname);
Chris@0 276 if (strcmp((const char*)file_node.buf, "file:///C:/My%20100%%")) {
Chris@0 277 return failure("Bad URI %s\n", file_node.buf);
Chris@0 278 } else if (hostname) {
Chris@0 279 return failure("hostname `%s' shouldn't exist\n", hostname);
Chris@0 280 } else if (strcmp((const char*)path_str, (const char*)out_path)) {
Chris@0 281 return failure("path=>URI=>path failure %s => %s => %s\n",
Chris@0 282 path_str, file_node.buf, out_path);
Chris@0 283 }
Chris@0 284 free(out_path);
Chris@0 285 serd_node_free(&file_node);
Chris@0 286
Chris@0 287 path_str = USTR("C:\\Pointless Space");
Chris@0 288 file_node = serd_node_new_file_uri(path_str, USTR("pwned"), 0, true);
Chris@0 289 hostname = NULL;
Chris@0 290 out_path = serd_file_uri_parse(file_node.buf, &hostname);
Chris@0 291 if (strcmp((const char*)file_node.buf, "file://pwned/C:/Pointless%20Space")) {
Chris@0 292 return failure("Bad URI %s\n", file_node.buf);
Chris@0 293 } else if (!hostname || strcmp((const char*)hostname, "pwned")) {
Chris@0 294 return failure("Bad hostname `%s'\n", hostname);
Chris@0 295 } else if (strcmp((const char*)out_path, "C:/Pointless Space")) {
Chris@0 296 return failure("path=>URI=>path failure %s => %s => %s\n",
Chris@0 297 path_str, file_node.buf, out_path);
Chris@0 298 }
Chris@0 299 free(hostname);
Chris@0 300 free(out_path);
Chris@0 301 serd_node_free(&file_node);
Chris@0 302
Chris@0 303 path_str = USTR("/foo/bar");
Chris@0 304 file_node = serd_node_new_file_uri(path_str, 0, 0, true);
Chris@0 305 hostname = NULL;
Chris@0 306 out_path = serd_file_uri_parse(file_node.buf, &hostname);
Chris@0 307 if (strcmp((const char*)file_node.buf, "file:///foo/bar")) {
Chris@0 308 return failure("Bad URI %s\n", file_node.buf);
Chris@0 309 } else if (hostname) {
Chris@0 310 return failure("hostname `%s' shouldn't exist\n", hostname);
Chris@0 311 } else if (strcmp((const char*)path_str, (const char*)out_path)) {
Chris@0 312 return failure("path=>URI=>path failure %s => %s => %s\n",
Chris@0 313 path_str, file_node.buf, out_path);
Chris@0 314 }
Chris@0 315 free(out_path);
Chris@0 316 serd_node_free(&file_node);
Chris@0 317
Chris@0 318 path_str = USTR("/foo/bar");
Chris@0 319 file_node = serd_node_new_file_uri(path_str, USTR("localhost"), 0, true);
Chris@0 320 out_path = serd_file_uri_parse(file_node.buf, &hostname);
Chris@0 321 if (strcmp((const char*)file_node.buf, "file://localhost/foo/bar")) {
Chris@0 322 return failure("Bad URI %s\n", file_node.buf);
Chris@0 323 } else if (strcmp((const char*)hostname, "localhost")) {
Chris@0 324 return failure("incorrect hostname `%s'\n", hostname);
Chris@0 325 } else if (strcmp((const char*)path_str, (const char*)out_path)) {
Chris@0 326 return failure("path=>URI=>path failure %s => %s => %s\n",
Chris@0 327 path_str, file_node.buf, out_path);
Chris@0 328 }
Chris@0 329 free(hostname);
Chris@0 330 free(out_path);
Chris@0 331 serd_node_free(&file_node);
Chris@0 332
Chris@0 333 path_str = USTR("a/relative path");
Chris@0 334 file_node = serd_node_new_file_uri(path_str, 0, 0, false);
Chris@0 335 out_path = serd_file_uri_parse(file_node.buf, &hostname);
Chris@0 336 if (strcmp((const char*)file_node.buf, "a/relative path")) {
Chris@0 337 return failure("Bad URI %s\n", file_node.buf);
Chris@0 338 } else if (hostname) {
Chris@0 339 return failure("hostname `%s' shouldn't exist\n", hostname);
Chris@0 340 } else if (strcmp((const char*)path_str, (const char*)out_path)) {
Chris@0 341 return failure("path=>URI=>path failure %s => %s => %s\n",
Chris@0 342 path_str, file_node.buf, out_path);
Chris@0 343 }
Chris@0 344 free(hostname);
Chris@0 345 free(out_path);
Chris@0 346 serd_node_free(&file_node);
Chris@0 347
Chris@0 348 if (serd_file_uri_parse(USTR("file://invalid"), NULL)) {
Chris@0 349 return failure("successfully parsed bogus URI <file://invalid>\n");
Chris@0 350 }
Chris@0 351
Chris@0 352 out_path = serd_file_uri_parse(USTR("file://host/foo/%XYbar"), NULL);
Chris@0 353 if (strcmp((const char*)out_path, "/foo/bar")) {
Chris@0 354 return failure("bad tolerance of junk escape: `%s'\n", out_path);
Chris@0 355 }
Chris@0 356 free(out_path);
Chris@0 357 out_path = serd_file_uri_parse(USTR("file://host/foo/%0Abar"), NULL);
Chris@0 358 if (strcmp((const char*)out_path, "/foo/bar")) {
Chris@0 359 return failure("bad tolerance of junk escape: `%s'\n", out_path);
Chris@0 360 }
Chris@0 361 free(out_path);
Chris@0 362
Chris@0 363 // Test serd_node_equals
Chris@0 364
Chris@0 365 const uint8_t replacement_char_str[] = { 0xEF, 0xBF, 0xBD, 0 };
Chris@0 366 SerdNode lhs = serd_node_from_string(SERD_LITERAL, replacement_char_str);
Chris@0 367 SerdNode rhs = serd_node_from_string(SERD_LITERAL, USTR("123"));
Chris@0 368 if (serd_node_equals(&lhs, &rhs)) {
Chris@0 369 return failure("%s == %s\n", lhs.buf, rhs.buf);
Chris@0 370 }
Chris@0 371
Chris@0 372 SerdNode qnode = serd_node_from_string(SERD_CURIE, USTR("foo:bar"));
Chris@0 373 if (serd_node_equals(&lhs, &qnode)) {
Chris@0 374 return failure("%s == %s\n", lhs.buf, qnode.buf);
Chris@0 375 }
Chris@0 376
Chris@0 377 if (!serd_node_equals(&lhs, &lhs)) {
Chris@0 378 return failure("%s != %s\n", lhs.buf, lhs.buf);
Chris@0 379 }
Chris@0 380
Chris@0 381 // Test serd_node_from_string
Chris@0 382
Chris@0 383 SerdNode node = serd_node_from_string(SERD_LITERAL, (const uint8_t*)"hello\"");
Chris@0 384 if (node.n_bytes != 6 || node.n_chars != 6 || node.flags != SERD_HAS_QUOTE
Chris@0 385 || strcmp((const char*)node.buf, "hello\"")) {
Chris@0 386 return failure("Bad node %s %zu %zu %d %d\n",
Chris@0 387 node.buf, node.n_bytes, node.n_chars, node.flags, node.type);
Chris@0 388 }
Chris@0 389
Chris@0 390 node = serd_node_from_string(SERD_URI, NULL);
Chris@0 391 if (!serd_node_equals(&node, &SERD_NODE_NULL)) {
Chris@0 392 return failure("Creating node from NULL string failed\n");
Chris@0 393 }
Chris@0 394
Chris@0 395 // Test serd_node_new_uri_from_string
Chris@0 396
Chris@0 397 SerdURI base_uri;
Chris@0 398 SerdNode base = serd_node_new_uri_from_string(USTR("http://example.org/"),
Chris@0 399 NULL, &base_uri);
Chris@0 400 SerdNode nil = serd_node_new_uri_from_string(NULL, &base_uri, NULL);
Chris@0 401 if (nil.type != SERD_URI || strcmp((const char*)nil.buf, (const char*)base.buf)) {
Chris@0 402 return failure("URI %s != base %s\n", nil.buf, base.buf);
Chris@0 403 }
Chris@0 404 serd_node_free(&base);
Chris@0 405 serd_node_free(&nil);
Chris@0 406
Chris@0 407 // Test SerdEnv
Chris@0 408
Chris@0 409 SerdNode u = serd_node_from_string(SERD_URI, USTR("http://example.org/foo"));
Chris@0 410 SerdNode b = serd_node_from_string(SERD_CURIE, USTR("invalid"));
Chris@0 411 SerdNode c = serd_node_from_string(SERD_CURIE, USTR("eg.2:b"));
Chris@0 412 SerdEnv* env = serd_env_new(NULL);
Chris@0 413 serd_env_set_prefix_from_strings(env, USTR("eg.2"), USTR("http://example.org/"));
Chris@0 414
Chris@0 415 if (!serd_env_set_base_uri(env, &node)) {
Chris@0 416 return failure("Set base URI to %s\n", node.buf);
Chris@0 417 }
Chris@0 418
Chris@0 419 SerdChunk prefix, suffix;
Chris@0 420 if (!serd_env_expand(env, &b, &prefix, &suffix)) {
Chris@0 421 return failure("Expanded invalid curie %s\n", b.buf);
Chris@0 422 }
Chris@0 423
Chris@0 424 SerdNode xnode = serd_env_expand_node(env, &node);
Chris@0 425 if (!serd_node_equals(&xnode, &SERD_NODE_NULL)) {
Chris@0 426 return failure("Expanded %s to %s\n", c.buf, xnode.buf);
Chris@0 427 }
Chris@0 428
Chris@0 429 SerdNode xu = serd_env_expand_node(env, &u);
Chris@0 430 if (strcmp((const char*)xu.buf, "http://example.org/foo")) {
Chris@0 431 return failure("Expanded %s to %s\n", c.buf, xu.buf);
Chris@0 432 }
Chris@0 433 serd_node_free(&xu);
Chris@0 434
Chris@0 435 SerdNode badpre = serd_node_from_string(SERD_CURIE, USTR("hm:what"));
Chris@0 436 SerdNode xbadpre = serd_env_expand_node(env, &badpre);
Chris@0 437 if (!serd_node_equals(&xbadpre, &SERD_NODE_NULL)) {
Chris@0 438 return failure("Expanded invalid curie %s\n", badpre.buf);
Chris@0 439 }
Chris@0 440
Chris@0 441 SerdNode xc = serd_env_expand_node(env, &c);
Chris@0 442 if (strcmp((const char*)xc.buf, "http://example.org/b")) {
Chris@0 443 return failure("Expanded %s to %s\n", c.buf, xc.buf);
Chris@0 444 }
Chris@0 445 serd_node_free(&xc);
Chris@0 446
Chris@0 447 if (!serd_env_set_prefix(env, &SERD_NODE_NULL, &SERD_NODE_NULL)) {
Chris@0 448 return failure("Set NULL prefix\n");
Chris@0 449 }
Chris@0 450
Chris@0 451 const SerdNode lit = serd_node_from_string(SERD_LITERAL, USTR("hello"));
Chris@0 452 if (!serd_env_set_prefix(env, &b, &lit)) {
Chris@0 453 return failure("Set prefix to literal\n");
Chris@0 454 }
Chris@0 455
Chris@0 456 int n_prefixes = 0;
Chris@0 457 serd_env_set_prefix_from_strings(env, USTR("eg.2"), USTR("http://example.org/"));
Chris@0 458 serd_env_foreach(env, count_prefixes, &n_prefixes);
Chris@0 459 if (n_prefixes != 1) {
Chris@0 460 return failure("Bad prefix count %d\n", n_prefixes);
Chris@0 461 }
Chris@0 462
Chris@0 463 SerdNode shorter_uri = serd_node_from_string(SERD_URI, USTR("urn:foo"));
Chris@0 464 SerdNode prefix_name;
Chris@0 465 if (serd_env_qualify(env, &shorter_uri, &prefix_name, &suffix)) {
Chris@0 466 return failure("Qualified %s\n", shorter_uri.buf);
Chris@0 467 }
Chris@0 468
Chris@0 469 // Test SerdReader and SerdWriter
Chris@0 470
Chris@0 471 const char* path = "serd_test.ttl";
Chris@0 472 FILE* fd = fopen(path, "w");
Chris@0 473 if (!fd) {
Chris@0 474 return failure("Failed to open file %s\n", path);
Chris@0 475 }
Chris@0 476
Chris@0 477 SerdWriter* writer = serd_writer_new(
Chris@0 478 SERD_TURTLE, (SerdStyle)0, env, NULL, serd_file_sink, fd);
Chris@0 479 if (!writer) {
Chris@0 480 return failure("Failed to create writer\n");
Chris@0 481 }
Chris@0 482
Chris@0 483 serd_writer_chop_blank_prefix(writer, USTR("tmp"));
Chris@0 484 serd_writer_chop_blank_prefix(writer, NULL);
Chris@0 485
Chris@0 486 if (!serd_writer_set_base_uri(writer, &lit)) {
Chris@0 487 return failure("Set base URI to %s\n", lit.buf);
Chris@0 488 }
Chris@0 489
Chris@0 490 if (!serd_writer_set_prefix(writer, &lit, &lit)) {
Chris@0 491 return failure("Set prefix %s to %s\n", lit.buf, lit.buf);
Chris@0 492 }
Chris@0 493
Chris@0 494 if (!serd_writer_end_anon(writer, NULL)) {
Chris@0 495 return failure("Ended non-existent anonymous node\n");
Chris@0 496 }
Chris@0 497
Chris@0 498 if (serd_writer_get_env(writer) != env) {
Chris@0 499 return failure("Writer has incorrect env\n");
Chris@0 500 }
Chris@0 501
Chris@0 502 uint8_t buf[] = { 0x80, 0, 0, 0, 0 };
Chris@0 503 SerdNode s = serd_node_from_string(SERD_URI, USTR(""));
Chris@0 504 SerdNode p = serd_node_from_string(SERD_URI, USTR("http://example.org/pred"));
Chris@0 505 SerdNode o = serd_node_from_string(SERD_LITERAL, buf);
Chris@0 506
Chris@0 507 // Write 3 invalid statements (should write nothing)
Chris@0 508 const SerdNode* junk[][5] = { { &s, &p, NULL, NULL, NULL },
Chris@0 509 { &s, NULL, &o, NULL, NULL },
Chris@0 510 { NULL, &p, &o, NULL, NULL },
Chris@0 511 { &s, &p, &SERD_NODE_NULL, NULL, NULL },
Chris@0 512 { &s, &SERD_NODE_NULL, &o, NULL, NULL },
Chris@0 513 { &SERD_NODE_NULL, &p, &o, NULL, NULL },
Chris@0 514 { &s, &o, &o, NULL, NULL },
Chris@0 515 { &o, &p, &o, NULL, NULL },
Chris@0 516 { NULL, NULL, NULL, NULL, NULL } };
Chris@0 517 for (unsigned i = 0; i < sizeof(junk) / (sizeof(SerdNode*) * 5); ++i) {
Chris@0 518 if (!serd_writer_write_statement(
Chris@0 519 writer, 0, NULL,
Chris@0 520 junk[i][0], junk[i][1], junk[i][2], junk[i][3], junk[i][4])) {
Chris@0 521 return failure("Successfully wrote junk statement %d\n", i);
Chris@0 522 }
Chris@0 523 }
Chris@0 524
Chris@0 525 const SerdNode t = serd_node_from_string(SERD_URI, USTR("urn:Type"));
Chris@0 526 const SerdNode l = serd_node_from_string(SERD_LITERAL, USTR("en"));
Chris@0 527 const SerdNode* good[][5] = { { &s, &p, &o, NULL, NULL },
Chris@0 528 { &s, &p, &o, &SERD_NODE_NULL, &SERD_NODE_NULL },
Chris@0 529 { &s, &p, &o, &t, NULL },
Chris@0 530 { &s, &p, &o, NULL, &l },
Chris@0 531 { &s, &p, &o, &t, &l },
Chris@0 532 { &s, &p, &o, &t, &SERD_NODE_NULL },
Chris@0 533 { &s, &p, &o, &SERD_NODE_NULL, &l },
Chris@0 534 { &s, &p, &o, NULL, &SERD_NODE_NULL },
Chris@0 535 { &s, &p, &o, &SERD_NODE_NULL, NULL },
Chris@0 536 { &s, &p, &o, &SERD_NODE_NULL, NULL } };
Chris@0 537 for (unsigned i = 0; i < sizeof(good) / (sizeof(SerdNode*) * 5); ++i) {
Chris@0 538 if (serd_writer_write_statement(
Chris@0 539 writer, 0, NULL,
Chris@0 540 good[i][0], good[i][1], good[i][2], good[i][3], good[i][4])) {
Chris@0 541 return failure("Failed to write good statement %d\n", i);
Chris@0 542 }
Chris@0 543 }
Chris@0 544
Chris@0 545 // Write 1 statement with bad UTF-8 (should be replaced)
Chris@0 546 if (serd_writer_write_statement(writer, 0, NULL,
Chris@0 547 &s, &p, &o, NULL, NULL)) {
Chris@0 548 return failure("Failed to write junk UTF-8\n");
Chris@0 549 }
Chris@0 550
Chris@0 551 // Write 1 valid statement
Chris@0 552 o = serd_node_from_string(SERD_LITERAL, USTR("hello"));
Chris@0 553 if (serd_writer_write_statement(writer, 0, NULL,
Chris@0 554 &s, &p, &o, NULL, NULL)) {
Chris@0 555 return failure("Failed to write valid statement\n");
Chris@0 556 }
Chris@0 557
Chris@0 558 serd_writer_free(writer);
Chris@0 559
Chris@0 560 // Test chunk sink
Chris@0 561 SerdChunk chunk = { NULL, 0 };
Chris@0 562 writer = serd_writer_new(
Chris@0 563 SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk);
Chris@0 564
Chris@0 565 o = serd_node_from_string(SERD_URI, USTR("http://example.org/base"));
Chris@0 566 if (serd_writer_set_base_uri(writer, &o)) {
Chris@0 567 return failure("Failed to write to chunk sink\n");
Chris@0 568 }
Chris@0 569
Chris@0 570 serd_writer_free(writer);
Chris@0 571 uint8_t* out = serd_chunk_sink_finish(&chunk);
Chris@0 572
Chris@0 573 if (strcmp((const char*)out, "@base <http://example.org/base> .\n")) {
Chris@0 574 return failure("Incorrect chunk output:\n%s\n", chunk.buf);
Chris@0 575 }
Chris@0 576
Chris@0 577 free(out);
Chris@0 578
Chris@0 579 // Rewind and test reader
Chris@0 580 fseek(fd, 0, SEEK_SET);
Chris@0 581
Chris@0 582 ReaderTest* rt = (ReaderTest*)malloc(sizeof(ReaderTest));
Chris@0 583 rt->n_statements = 0;
Chris@0 584 rt->graph = NULL;
Chris@0 585
Chris@0 586 SerdReader* reader = serd_reader_new(
Chris@0 587 SERD_TURTLE, rt, free,
Chris@0 588 NULL, NULL, test_sink, NULL);
Chris@0 589 if (!reader) {
Chris@0 590 return failure("Failed to create reader\n");
Chris@0 591 }
Chris@0 592 if (serd_reader_get_handle(reader) != rt) {
Chris@0 593 return failure("Corrupt reader handle\n");
Chris@0 594 }
Chris@0 595
Chris@0 596 SerdNode g = serd_node_from_string(SERD_URI, USTR("http://example.org/"));
Chris@0 597 serd_reader_set_default_graph(reader, &g);
Chris@0 598 serd_reader_add_blank_prefix(reader, USTR("tmp"));
Chris@0 599 serd_reader_add_blank_prefix(reader, NULL);
Chris@0 600
Chris@0 601 if (!serd_reader_read_file(reader, USTR("http://notafile"))) {
Chris@0 602 return failure("Apparently read an http URI\n");
Chris@0 603 }
Chris@0 604 if (!serd_reader_read_file(reader, USTR("file:///better/not/exist"))) {
Chris@0 605 return failure("Apprently read a non-existent file\n");
Chris@0 606 }
Chris@0 607 SerdStatus st = serd_reader_read_file(reader, USTR(path));
Chris@0 608 if (st) {
Chris@0 609 return failure("Error reading file (%s)\n", serd_strerror(st));
Chris@0 610 }
Chris@0 611
Chris@0 612 if (rt->n_statements != 12) {
Chris@0 613 return failure("Bad statement count %d\n", rt->n_statements);
Chris@0 614 } else if (!rt->graph || !rt->graph->buf ||
Chris@0 615 strcmp((const char*)rt->graph->buf, "http://example.org/")) {
Chris@0 616 return failure("Bad graph %p\n", rt->graph);
Chris@0 617 }
Chris@0 618
Chris@0 619 if (!serd_reader_read_string(reader, USTR("This isn't Turtle at all."))) {
Chris@0 620 return failure("Parsed invalid string successfully.\n");
Chris@0 621 }
Chris@0 622
Chris@0 623 serd_reader_free(reader);
Chris@0 624 fclose(fd);
Chris@0 625
Chris@0 626 serd_env_free(env);
Chris@0 627
Chris@0 628 printf("Success\n");
Chris@0 629 return 0;
Chris@0 630 }