diff options
-rw-r--r-- | serd/serd.h | 6 | ||||
-rw-r--r-- | src/env.c | 30 | ||||
-rw-r--r-- | tests/env_test.c | 186 |
3 files changed, 176 insertions, 46 deletions
diff --git a/serd/serd.h b/serd/serd.h index 4dd7e7bd..d57dc00c 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -1123,11 +1123,13 @@ SerdNode* serd_env_qualify(const SerdEnv* env, const SerdNode* uri); /** - Expand `node`, transforming CURIEs into URIs + Expand `node`, transforming CURIEs and URI references into absolute URIs. If `node` is a literal, its datatype is expanded if necessary. - Returns null if `node` can not be expanded. + For simple nodes that do not require expansion, a copy is returned. Null is + returned if `node` is/contains a CURIE or relative URI that can not be + expanded. */ SERD_API SerdNode* @@ -295,23 +295,33 @@ expand_literal(const SerdEnv* env, const SerdNode* node) assert(serd_node_type(node) == SERD_LITERAL); const SerdNode* const datatype = serd_node_datatype(node); - if (datatype && serd_node_type(datatype) == SERD_CURIE) { + if (!datatype) { + return serd_node_copy(node); + } + + if (serd_node_type(datatype) == SERD_CURIE) { SerdStringView prefix; SerdStringView suffix; - if (!serd_env_expand_in_place(env, datatype, &prefix, &suffix)) { - return serd_new_typed_literal_expanded(serd_node_string(node), - serd_node_length(node), - serd_node_flags(node), - SERD_URI, - prefix, - suffix); + if (serd_env_expand_in_place(env, datatype, &prefix, &suffix)) { + return NULL; } - } else if (datatype && serd_node_type(datatype) == SERD_URI) { + + return serd_new_typed_literal_expanded(serd_node_string(node), + serd_node_length(node), + serd_node_flags(node), + SERD_URI, + prefix, + suffix); + + } else if (serd_node_type(datatype) == SERD_URI) { SerdURI datatype_uri; serd_uri_parse(serd_node_string(datatype), &datatype_uri); SerdURI abs_datatype_uri; serd_uri_resolve(&datatype_uri, &env->base_uri, &abs_datatype_uri); + if (abs_datatype_uri.scheme.len == 0) { + return NULL; + } return serd_new_typed_literal_uri(serd_node_string(node), serd_node_length(node), @@ -361,7 +371,7 @@ serd_env_expand(const SerdEnv* env, const SerdNode* node) case SERD_CURIE: return expand_curie(env, node); case SERD_BLANK: - return NULL; + return serd_node_copy(node); } } diff --git a/tests/env_test.c b/tests/env_test.c index 1d8b612f..bf222d14 100644 --- a/tests/env_test.c +++ b/tests/env_test.c @@ -120,36 +120,27 @@ test_set_prefix(void) } static void -test_expand(void) -{ - SerdNode* const name = serd_new_string("eg.1"); - SerdNode* const eg = serd_new_uri(NS_EG); - SerdNode* const blank = serd_new_blank("b1"); - SerdNode* const rel = serd_new_uri("rel"); - SerdNode* const base = serd_new_uri("http://example.org/b/"); - SerdNode* const c1 = serd_new_curie("eg.1:foo"); - SerdNode* const c1_full = serd_new_uri("http://example.org/foo"); - SerdNode* const c2 = serd_new_curie("hm:what"); - SerdNode* const type = serd_new_uri("Type"); - SerdNode* const typed = serd_new_typed_literal("data", type); - SerdEnv* const env = serd_env_new(base); - - assert(!serd_env_set_prefix(env, name, eg)); +test_expand_untyped_literal(void) +{ + SerdNode* const untyped = serd_new_string("data"); + SerdEnv* const env = serd_env_new(NULL); - assert(!serd_env_expand(env, name)); - assert(!serd_env_expand(env, blank)); + SerdNode* const untyped_out = serd_env_expand(env, untyped); + assert(serd_node_equals(untyped_out, untyped)); + serd_node_free(untyped_out); - // Expand CURIE - SerdNode* const c1_out = serd_env_expand(env, c1); - assert(serd_node_equals(c1_out, c1_full)); - serd_node_free(c1_out); + serd_env_free(env); + serd_node_free(untyped); +} - // Expand relative URI - SerdNode* const rel_out = serd_env_expand(env, rel); - assert(!strcmp(serd_node_string(rel_out), "http://example.org/b/rel")); - serd_node_free(rel_out); +static void +test_expand_uri_datatype(void) +{ + SerdNode* const base = serd_new_uri("http://example.org/b/"); + SerdNode* const type = serd_new_uri("Type"); + SerdNode* const typed = serd_new_typed_literal("data", type); + SerdEnv* const env = serd_env_new(base); - // Expand literal with URI datatype SerdNode* const typed_out = serd_env_expand(env, typed); assert(typed_out); assert(!strcmp(serd_node_string(typed_out), "data")); @@ -158,22 +149,142 @@ test_expand(void) "http://example.org/b/Type")); serd_node_free(typed_out); - assert(!serd_env_expand(env, c2)); + serd_env_free(env); + serd_node_free(typed); + serd_node_free(type); + serd_node_free(base); +} + +static void +test_expand_bad_uri_datatype(void) +{ + SerdNode* const type = serd_new_uri("Type"); + SerdNode* const typed = serd_new_typed_literal("data", type); + SerdEnv* const env = serd_env_new(NULL); + + assert(!serd_env_expand(env, typed)); serd_env_free(env); serd_node_free(typed); serd_node_free(type); - serd_node_free(c2); - serd_node_free(c1_full); - serd_node_free(c1); +} + +static void +test_expand_curie_datatype(void) +{ + SerdNode* const name = serd_new_string("eg"); + SerdNode* const eg = serd_new_uri(NS_EG); + SerdNode* const type = serd_new_curie("eg:Type"); + SerdNode* const typed = serd_new_typed_literal("data", type); + SerdEnv* const env = serd_env_new(NULL); + + assert(!serd_env_set_prefix(env, name, eg)); + + SerdNode* const typed_out = serd_env_expand(env, typed); + assert(typed_out); + assert(!strcmp(serd_node_string(typed_out), "data")); + assert(serd_node_datatype(typed_out)); + assert(!strcmp(serd_node_string(serd_node_datatype(typed_out)), + "http://example.org/Type")); + serd_node_free(typed_out); + + serd_env_free(env); + serd_node_free(typed); + serd_node_free(type); + serd_node_free(eg); + serd_node_free(name); +} + +static void +test_expand_bad_curie_datatype(void) +{ + SerdNode* const type = serd_new_curie("eg:Type"); + SerdNode* const typed = serd_new_typed_literal("data", type); + SerdEnv* const env = serd_env_new(NULL); + + assert(!serd_env_expand(env, typed)); + + serd_env_free(env); + serd_node_free(typed); + serd_node_free(type); +} + +static void +test_expand_uri(void) +{ + SerdNode* const rel = serd_new_uri("rel"); + SerdNode* const base = serd_new_uri("http://example.org/b/"); + SerdEnv* const env = serd_env_new(base); + + SerdNode* const rel_out = serd_env_expand(env, rel); + assert(!strcmp(serd_node_string(rel_out), "http://example.org/b/rel")); + serd_node_free(rel_out); + + serd_env_free(env); serd_node_free(base); serd_node_free(rel); - serd_node_free(blank); +} + +static void +test_expand_bad_uri(void) +{ + SerdNode* const bad_uri = serd_new_uri("rel"); + SerdEnv* const env = serd_env_new(NULL); + + assert(!serd_env_expand(env, bad_uri)); + + serd_env_free(env); + serd_node_free(bad_uri); +} + +static void +test_expand_curie(void) +{ + SerdNode* const name = serd_new_string("eg.1"); + SerdNode* const eg = serd_new_uri(NS_EG); + SerdNode* const curie = serd_new_curie("eg.1:foo"); + SerdEnv* const env = serd_env_new(NULL); + + assert(!serd_env_set_prefix(env, name, eg)); + + SerdNode* const curie_out = serd_env_expand(env, curie); + assert(curie_out); + assert(!strcmp(serd_node_string(curie_out), "http://example.org/foo")); + serd_node_free(curie_out); + + serd_env_free(env); + serd_node_free(curie); serd_node_free(eg); serd_node_free(name); } static void +test_expand_bad_curie(void) +{ + SerdNode* const curie = serd_new_curie("eg.1:foo"); + SerdEnv* const env = serd_env_new(NULL); + + assert(!serd_env_expand(env, curie)); + + serd_env_free(env); + serd_node_free(curie); +} + +static void +test_expand_blank(void) +{ + SerdNode* const blank = serd_new_blank("b1"); + SerdEnv* const env = serd_env_new(NULL); + + SerdNode* const blank_out = serd_env_expand(env, blank); + assert(serd_node_equals(blank_out, blank)); + serd_node_free(blank_out); + + serd_env_free(env); + serd_node_free(blank); +} + +static void test_qualify(void) { SerdNode* const name = serd_new_string("eg"); @@ -185,8 +296,6 @@ test_qualify(void) assert(!serd_env_set_prefix(env, name, eg)); - assert(!serd_env_expand(env, name)); - SerdNode* const u1_out = serd_env_qualify(env, u1); assert(serd_node_equals(u1_out, c1)); serd_node_free(u1_out); @@ -243,7 +352,16 @@ main(void) test_null(); test_base_uri(); test_set_prefix(); - test_expand(); + test_expand_untyped_literal(); + test_expand_uri_datatype(); + test_expand_bad_uri_datatype(); + test_expand_curie_datatype(); + test_expand_bad_curie_datatype(); + test_expand_uri(); + test_expand_bad_uri(); + test_expand_curie(); + test_expand_bad_curie(); + test_expand_blank(); test_qualify(); test_equals(); return 0; |