aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--serd/serd.h6
-rw-r--r--src/env.c30
-rw-r--r--tests/env_test.c186
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*
diff --git a/src/env.c b/src/env.c
index f7b1b452..a9753069 100644
--- a/src/env.c
+++ b/src/env.c
@@ -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;