From 8e30b617725a50a5b27d400247095d0577e5874e Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 31 Jul 2021 19:32:21 -0400 Subject: Support writing all escapes in Turtle and TriG prefixed names --- test/test_writer.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'test') 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 #include #include +#include #include 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; } -- cgit v1.2.1