aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/serd/serd.h6
-rw-r--r--src/env.c31
-rw-r--r--src/uri.c3
-rw-r--r--test/test_env.c191
4 files changed, 190 insertions, 41 deletions
diff --git a/include/serd/serd.h b/include/serd/serd.h
index cfdc8693..a2e767ff 100644
--- a/include/serd/serd.h
+++ b/include/serd/serd.h
@@ -1062,13 +1062,15 @@ serd_env_qualify(const SerdEnv* SERD_NULLABLE env,
const SerdNode* SERD_NONNULL uri);
/**
- Expand `node`, transforming CURIEs into URIs.
+ Expand `node`, transforming CURIEs and URI references into absolute URIs.
If `node` is a relative URI reference, it is expanded to a full URI if
possible. If `node` is a literal, its datatype is expanded if necessary.
If `node` is a CURIE, it is expanded to a full URI if possible.
- 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* SERD_ALLOCATED
diff --git a/src/env.c b/src/env.c
index 21dbb45d..55901e26 100644
--- a/src/env.c
+++ b/src/env.c
@@ -278,15 +278,34 @@ 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_view(node), serd_node_flags(node), SERD_URI, prefix, suffix);
+ if (serd_env_expand_in_place(env, datatype, &prefix, &suffix)) {
+ return NULL;
+ }
+
+ return serd_new_typed_literal_expanded(serd_node_string_view(node),
+ serd_node_flags(node),
+ SERD_URI,
+ prefix,
+ suffix);
+ }
+
+ if (serd_node_type(datatype) == SERD_URI) {
+ const SerdURIView datatype_uri = serd_parse_uri(serd_node_string(datatype));
+
+ const SerdURIView abs_datatype_uri =
+ serd_resolve_uri(datatype_uri, env->base_uri);
+
+ if (!abs_datatype_uri.scheme.len) {
+ return NULL;
}
- } else if (datatype && serd_node_type(datatype) == SERD_URI) {
return serd_new_typed_literal_uri(
serd_node_string_view(node),
serd_node_flags(node),
@@ -336,7 +355,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/src/uri.c b/src/uri.c
index 780f7e72..6b029284 100644
--- a/src/uri.c
+++ b/src/uri.c
@@ -283,9 +283,6 @@ serd_resolve_uri(const SerdURIView r, const SerdURIView base)
SerdURIView t = SERD_URI_NULL;
- t.path_prefix.buf = NULL;
- t.path_prefix.len = 0;
-
if (r.authority.len) {
t.authority = r.authority;
t.path = r.path;
diff --git a/test/test_env.c b/test/test_env.c
index 445e9f28..18fda1a6 100644
--- a/test/test_env.c
+++ b/test/test_env.c
@@ -115,59 +115,183 @@ test_set_prefix(void)
}
static void
-test_expand(void)
+test_expand_untyped_literal(void)
+{
+ SerdNode* const untyped = serd_new_string(SERD_STATIC_STRING("data"));
+ SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING());
+
+ SerdNode* const untyped_out = serd_env_expand(env, untyped);
+ assert(serd_node_equals(untyped_out, untyped));
+ serd_node_free(untyped_out);
+
+ serd_env_free(env);
+ serd_node_free(untyped);
+}
+
+static void
+test_expand_uri_datatype(void)
{
- static const SerdStringView eg = SERD_STATIC_STRING(NS_EG);
static const SerdStringView type = SERD_STATIC_STRING("Type");
+
static const SerdStringView base =
SERD_STATIC_STRING("http://example.org/b/");
- SerdNode* const name = serd_new_string(SERD_STATIC_STRING("eg.1"));
- SerdNode* const blank = serd_new_blank(SERD_STATIC_STRING("b1"));
- SerdNode* const rel = serd_new_uri(SERD_STATIC_STRING("rel"));
- SerdNode* const c1 = serd_new_curie(SERD_STATIC_STRING("eg.1:foo"));
- SerdNode* const c1_full =
- serd_new_uri(SERD_STATIC_STRING("http://example.org/foo"));
- SerdNode* const c2 = serd_new_curie(SERD_STATIC_STRING("hm:what"));
SerdNode* const typed =
serd_new_typed_literal(SERD_STATIC_STRING("data"), type);
+
SerdEnv* const env = serd_env_new(base);
- assert(!serd_env_set_prefix(env, serd_node_string_view(name), eg));
+ SerdNode* const typed_out = serd_env_expand(env, typed);
+ assert(typed_out);
+ assert(!strcmp(serd_node_string(typed_out), "data"));
- assert(!serd_env_expand(env, name));
- assert(!serd_env_expand(env, blank));
+ const SerdNode* const datatype = serd_node_datatype(typed_out);
+ assert(datatype);
+ assert(!strcmp(serd_node_string(datatype), "http://example.org/b/Type"));
+ serd_node_free(typed_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(typed);
+}
- // 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_bad_uri_datatype(void)
+{
+ static const SerdStringView type = SERD_STATIC_STRING("Type");
+
+ SerdNode* const typed =
+ serd_new_typed_literal(SERD_STATIC_STRING("data"), type);
+
+ SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING());
+
+ assert(!serd_env_expand(env, typed));
+
+ serd_env_free(env);
+ serd_node_free(typed);
+}
+
+static void
+test_expand_curie_datatype(void)
+{
+// FIXME
+#if 0
+ static const SerdStringView name = SERD_STATIC_STRING("eg");
+ static const SerdStringView eg = SERD_STATIC_STRING(NS_EG);
+ static const SerdStringView type = SERD_STATIC_STRING("eg:Type");
+
+ SerdNode* const typed =
+ serd_new_typed_literal(SERD_STATIC_STRING("data"), type);
+
+ SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING());
+
+ assert(!serd_env_set_prefix(env, name, eg));
- // 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"));
const SerdNode* const datatype = serd_node_datatype(typed_out);
assert(datatype);
- assert(!strcmp(serd_node_string(datatype), "http://example.org/b/Type"));
+ assert(!strcmp(serd_node_string(datatype), "http://example.org/Type"));
serd_node_free(typed_out);
- assert(!serd_env_expand(env, c2));
+ serd_env_free(env);
+ serd_node_free(typed);
+#endif
+}
+
+static void
+test_expand_bad_curie_datatype(void)
+{
+ // FIXME
+#if 0
+ static const SerdStringView type = SERD_STATIC_STRING("eg:Type");
+
+ SerdNode* const typed =
+ serd_new_typed_literal(SERD_STATIC_STRING("data"), type);
+
+ SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING());
+
+ assert(!serd_env_expand(env, typed));
serd_env_free(env);
serd_node_free(typed);
- serd_node_free(c2);
- serd_node_free(c1_full);
- serd_node_free(c1);
+#endif
+}
+
+static void
+test_expand_uri(void)
+{
+ static const SerdStringView base =
+ SERD_STATIC_STRING("http://example.org/b/");
+
+ SerdNode* const rel = serd_new_uri(SERD_STATIC_STRING("rel"));
+ 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(rel);
+}
+
+static void
+test_expand_bad_uri(void)
+{
+ SerdNode* const bad_uri = serd_new_uri(SERD_STATIC_STRING("rel"));
+ SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING());
+
+ assert(!serd_env_expand(env, bad_uri));
+
+ serd_env_free(env);
+ serd_node_free(bad_uri);
+}
+
+static void
+test_expand_curie(void)
+{
+ static const SerdStringView name = SERD_STATIC_STRING("eg.1");
+ static const SerdStringView eg = SERD_STATIC_STRING(NS_EG);
+
+ SerdNode* const curie = serd_new_curie(SERD_STATIC_STRING("eg.1:foo"));
+ SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING());
+
+ 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);
+}
+
+static void
+test_expand_bad_curie(void)
+{
+ SerdNode* const curie = serd_new_curie(SERD_STATIC_STRING("eg.1:foo"));
+ SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING());
+
+ 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(SERD_STATIC_STRING("b1"));
+ SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING());
+
+ 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);
- serd_node_free(name);
}
static void
@@ -188,8 +312,6 @@ test_qualify(void)
assert(!serd_env_set_prefix(env, serd_node_string_view(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);
@@ -246,7 +368,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;