aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_writer.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_writer.c')
-rw-r--r--test/test_writer.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/test/test_writer.c b/test/test_writer.c
index fd650ecd..9a59d92f 100644
--- a/test/test_writer.c
+++ b/test/test_writer.c
@@ -22,6 +22,7 @@
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
static void
@@ -329,6 +330,81 @@ test_write_bad_uri(void)
serd_world_free(world);
}
+static void
+check_pname_escape(const char* const lname, const char* const expected)
+{
+ SerdWorld* world = serd_world_new();
+ SerdNodes* nodes = serd_world_nodes(world);
+ SerdEnv* env = serd_env_new(SERD_EMPTY_STRING());
+ SerdBuffer buffer = {NULL, 0};
+ SerdByteSink* byte_sink = serd_byte_sink_new_buffer(&buffer);
+
+ SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, byte_sink);
+ assert(writer);
+
+ static const char* const prefix = "http://example.org/";
+ const size_t prefix_len = strlen(prefix);
+
+ serd_env_set_prefix(env, SERD_STRING("eg"), SERD_STRING(prefix));
+
+ const SerdNode* s =
+ serd_nodes_uri(nodes, SERD_STRING("http://example.org/s"));
+
+ const SerdNode* p =
+ serd_nodes_uri(nodes, SERD_STRING("http://example.org/p"));
+
+ char* const uri = (char*)calloc(1, prefix_len + strlen(lname) + 1);
+ memcpy(uri, prefix, prefix_len + 1);
+ memcpy(uri + prefix_len, lname, strlen(lname) + 1);
+
+ const SerdNode* node = serd_nodes_uri(nodes, SERD_STRING(uri));
+
+ assert(!serd_sink_write(serd_writer_sink(writer), 0, s, p, node, NULL));
+
+ serd_writer_free(writer);
+ serd_byte_sink_free(byte_sink);
+ serd_env_free(env);
+
+ char* out = serd_buffer_sink_finish(&buffer);
+
+ assert(!strcmp((char*)out, expected));
+ serd_free(out);
+
+ free(uri);
+ serd_world_free(world);
+}
+
+static void
+test_write_pname_escapes(void)
+{
+ // Check that '.' is escaped only at the start and end
+ check_pname_escape(".xyz", "eg:s\n\teg:p eg:\\.xyz .\n");
+ check_pname_escape("w.yz", "eg:s\n\teg:p eg:w.yz .\n");
+ check_pname_escape("wx.z", "eg:s\n\teg:p eg:wx.z .\n");
+ check_pname_escape("wxy.", "eg:s\n\teg:p eg:wxy\\. .\n");
+
+ // Check that ':' is not escaped anywhere
+ check_pname_escape(":xyz", "eg:s\n\teg:p eg::xyz .\n");
+ check_pname_escape("w:yz", "eg:s\n\teg:p eg:w:yz .\n");
+ check_pname_escape("wx:z", "eg:s\n\teg:p eg:wx:z .\n");
+ check_pname_escape("wxy:", "eg:s\n\teg:p eg:wxy: .\n");
+
+ // Check that special characters like '~' are escaped everywhere
+ check_pname_escape("~xyz", "eg:s\n\teg:p eg:\\~xyz .\n");
+ check_pname_escape("w~yz", "eg:s\n\teg:p eg:w\\~yz .\n");
+ check_pname_escape("wx~z", "eg:s\n\teg:p eg:wx\\~z .\n");
+ check_pname_escape("wxy~", "eg:s\n\teg:p eg:wxy\\~ .\n");
+
+ // Check that out of range multi-byte characters are escaped everywhere
+ static const char first_escape[] = {(char)0xC3u, (char)0xB7u, 'y', 'z', 0};
+ static const char mid_escape[] = {'w', (char)0xC3u, (char)0xB7u, 'z', 0};
+ static const char last_escape[] = {'w', 'x', (char)0xC3u, (char)0xB7u, 0};
+
+ check_pname_escape((const char*)first_escape, "eg:s\n\teg:p eg:%C3%B7yz .\n");
+ check_pname_escape((const char*)mid_escape, "eg:s\n\teg:p eg:w%C3%B7z .\n");
+ check_pname_escape((const char*)last_escape, "eg:s\n\teg:p eg:wx%C3%B7 .\n");
+}
+
int
main(void)
{
@@ -339,6 +415,7 @@ main(void)
test_write_error();
test_write_empty_syntax();
test_write_bad_uri();
+ test_write_pname_escapes();
return 0;
}