aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--test/extra/bad/bad-bom-1.ttl3
-rw-r--r--test/extra/bad/bad-bom-2.ttl3
-rw-r--r--test/extra/bad/bad-bom-only-1.ttl1
-rw-r--r--test/extra/bad/bad-bom-only-2.ttl1
-rw-r--r--test/extra/bad/manifest.ttl26
-rw-r--r--test/extra/good/manifest.ttl7
-rw-r--r--test/extra/good/test-local-name-percent.nt2
-rw-r--r--test/extra/good/test-local-name-percent.ttl4
-rw-r--r--test/extra/pretty/datatypes.ttl2
-rw-r--r--test/meson.build7
-rw-r--r--test/test_env.c3
-rw-r--r--test/test_node.c90
-rw-r--r--test/test_reader_writer.c4
-rw-r--r--test/test_string.c30
-rw-r--r--test/test_uri.c35
16 files changed, 200 insertions, 21 deletions
diff --git a/NEWS b/NEWS
index e1bff8be..798eb672 100644
--- a/NEWS
+++ b/NEWS
@@ -6,11 +6,12 @@ serd (0.32.3) unstable; urgency=medium
* Fix parsing NQuads lines with no space before the final dot
* Fix rewriting special literals when datatype URIs are prefixed names
* Gracefully handle errors while writing the end of anonymous nodes
+ * Improve test suite coverage
* Support reading lone lists in lax mode
* Treat out of range unicode characters as errors
* Write blank lines between graphs and statements in TriG
- -- David Robillard <d@drobilla.net> Mon, 24 Jun 2024 19:06:33 +0000
+ -- David Robillard <d@drobilla.net> Mon, 24 Jun 2024 19:11:54 +0000
serd (0.32.2) stable; urgency=medium
diff --git a/test/extra/bad/bad-bom-1.ttl b/test/extra/bad/bad-bom-1.ttl
new file mode 100644
index 00000000..7d7681d4
--- /dev/null
+++ b/test/extra/bad/bad-bom-1.ttl
@@ -0,0 +1,3 @@
+ï# This file starts with the first byte of the UTF-8 Byte Order Mark
+
+<http://example.org/thing> a <http://example.org/Thing> .
diff --git a/test/extra/bad/bad-bom-2.ttl b/test/extra/bad/bad-bom-2.ttl
new file mode 100644
index 00000000..9ce3f093
--- /dev/null
+++ b/test/extra/bad/bad-bom-2.ttl
@@ -0,0 +1,3 @@
+ï»# This file starts with the first two bytes of the UTF-8 Byte Order Mark
+
+<http://example.org/thing> a <http://example.org/Thing> .
diff --git a/test/extra/bad/bad-bom-only-1.ttl b/test/extra/bad/bad-bom-only-1.ttl
new file mode 100644
index 00000000..a4a063a1
--- /dev/null
+++ b/test/extra/bad/bad-bom-only-1.ttl
@@ -0,0 +1 @@
+ï \ No newline at end of file
diff --git a/test/extra/bad/bad-bom-only-2.ttl b/test/extra/bad/bad-bom-only-2.ttl
new file mode 100644
index 00000000..022c50f1
--- /dev/null
+++ b/test/extra/bad/bad-bom-only-2.ttl
@@ -0,0 +1 @@
+ï» \ No newline at end of file
diff --git a/test/extra/bad/manifest.ttl b/test/extra/bad/manifest.ttl
index 7e35e5ff..64dbf05f 100644
--- a/test/extra/bad/manifest.ttl
+++ b/test/extra/bad/manifest.ttl
@@ -13,7 +13,10 @@
<#bad-blank-node-label>
<#bad-blank-predicate>
<#bad-blank-syntax>
- <#bad-bom>
+ <#bad-bom-1>
+ <#bad-bom-2>
+ <#bad-bom-only-1>
+ <#bad-bom-only-2>
<#bad-char-in-local>
<#bad-char-in-prefix>
<#bad-char-in-uri>
@@ -165,10 +168,25 @@
mf:action <bad-blank-syntax.ttl> ;
mf:name "bad-blank-syntax" .
-<#bad-bom>
+<#bad-bom-1>
a rdft:TestTurtleNegativeSyntax ;
- mf:action <bad-bom.ttl> ;
- mf:name "bad-bom" .
+ mf:action <bad-bom-1.ttl> ;
+ mf:name "bad-bom-1" .
+
+<#bad-bom-2>
+ a rdft:TestTurtleNegativeSyntax ;
+ mf:action <bad-bom-2.ttl> ;
+ mf:name "bad-bom-2" .
+
+<#bad-bom-only-1>
+ a rdft:TestTurtleNegativeSyntax ;
+ mf:action <bad-bom-only-1.ttl> ;
+ mf:name "bad-bom-only-1" .
+
+<#bad-bom-only-2>
+ a rdft:TestTurtleNegativeSyntax ;
+ mf:action <bad-bom-only-2.ttl> ;
+ mf:name "bad-bom-only-2" .
<#bad-char-in-local>
a rdft:TestTurtleNegativeSyntax ;
diff --git a/test/extra/good/manifest.ttl b/test/extra/good/manifest.ttl
index 5e7458ec..350d7d9c 100644
--- a/test/extra/good/manifest.ttl
+++ b/test/extra/good/manifest.ttl
@@ -30,6 +30,7 @@
<#test-list-subject>
<#test-local-name-ends-with-dot>
<#test-local-name-escapes>
+ <#test-local-name-percent>
<#test-long-utf8>
<#test-no-spaces>
<#test-non-curie-uri>
@@ -203,6 +204,12 @@
mf:name "test-local-name-escapes" ;
mf:result <test-local-name-escapes.nt> .
+<#test-local-name-percent>
+ a rdft:TestTurtleEval ;
+ mf:action <test-local-name-percent.ttl> ;
+ mf:name "test-local-name-percent" ;
+ mf:result <test-local-name-percent.nt> .
+
<#test-long-utf8>
a rdft:TestTurtleEval ;
mf:action <test-long-utf8.ttl> ;
diff --git a/test/extra/good/test-local-name-percent.nt b/test/extra/good/test-local-name-percent.nt
new file mode 100644
index 00000000..e6330547
--- /dev/null
+++ b/test/extra/good/test-local-name-percent.nt
@@ -0,0 +1,2 @@
+<http://example.org/s> <http://example.org/p> <http://example.org/o%3E> .
+<http://example.org/s> <http://example.org/p> <http://example.org/o%3f> .
diff --git a/test/extra/good/test-local-name-percent.ttl b/test/extra/good/test-local-name-percent.ttl
new file mode 100644
index 00000000..32fb63d5
--- /dev/null
+++ b/test/extra/good/test-local-name-percent.ttl
@@ -0,0 +1,4 @@
+@prefix eg: <http://example.org/> .
+
+eg:s eg:p eg:o%3E .
+eg:s eg:p eg:o%3f .
diff --git a/test/extra/pretty/datatypes.ttl b/test/extra/pretty/datatypes.ttl
index 721dfe4d..8f8b13f2 100644
--- a/test/extra/pretty/datatypes.ttl
+++ b/test/extra/pretty/datatypes.ttl
@@ -9,6 +9,8 @@ eg:s
1 ,
2.3 ,
"4."^^xsd:decimal ,
+ "5"^^xsd:decimal ,
+ "6.7E8"^^xsd:float ,
false ,
true ,
"x"^^eg:datatype ,
diff --git a/test/meson.build b/test/meson.build
index fe476491..ab012908 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -153,15 +153,20 @@ simple_command_tests = {
'serdi': {
'bad': [
['-c'],
+ ['-cx'],
['-fi'],
['-i', 'turtle'],
['-i', 'turt'],
['-i'],
+ ['-ix'],
['-o', '~unknown'],
['-o', 'ntripleses'],
['-o'],
+ ['-ox'],
['-p'],
+ ['-px'],
['-r'],
+ ['-rx'],
['-z'],
],
'good': [
@@ -178,6 +183,7 @@ if is_variable('serdi')
script_args = common_script_args + ['--serdi', serdi]
serd_ttl = files('../serd.ttl')[0]
bad_input_file = files('extra/bad/bad-base.ttl')
+ text_input_file = files('extra/bad/README.md')
test('serd_ttl', serdi, args: [serd_ttl], suite: 'data')
@@ -214,6 +220,7 @@ if is_variable('serdi')
'string': ['-s', '<foo> a <Bar> .'],
'no_such_file': ['no_such_file'],
'remote': ['ftp://example.org/unsupported.ttl'],
+ 'text': [text_input_file],
}
foreach name, args : bad_input_tests
diff --git a/test/test_env.c b/test/test_env.c
index 1de075f3..9547042f 100644
--- a/test/test_env.c
+++ b/test/test_env.c
@@ -39,7 +39,8 @@ test_env(void)
SerdChunk suffix;
assert(!serd_env_qualify(NULL, &u, &u, &suffix));
assert(serd_env_expand(NULL, &c, &prefix, &suffix));
- assert(serd_env_expand(env, &b, &prefix, &suffix));
+ assert(serd_env_expand(env, &b, &prefix, &suffix) == SERD_ERR_BAD_ARG);
+ assert(serd_env_expand(env, &u, &prefix, &suffix) == SERD_ERR_BAD_ARG);
SerdNode nxnode = serd_env_expand_node(NULL, &c);
assert(serd_node_equals(&nxnode, &SERD_NODE_NULL));
diff --git a/test/test_node.c b/test/test_node.c
index f08363cb..af14171b 100644
--- a/test/test_node.c
+++ b/test/test_node.c
@@ -42,8 +42,14 @@ test_string_to_double(void)
const double expt_test_nums[] = {
2.0E18, -5e19, +8e20, 2e+22, -5e-5, 8e0, 9e-0, 2e+0};
- const char* expt_test_strs[] = {
- "02e18", "-5e019", "+8e20", "2E+22", "-5E-5", "8E0", "9e-0", " 2e+0"};
+ const char* expt_test_strs[] = {"02e18",
+ "-5e019",
+ " +8e20",
+ "\f2E+22",
+ "\n-5E-5",
+ "\r8E0",
+ "\t9e-0",
+ "\v2e+0"};
for (size_t i = 0; i < sizeof(expt_test_nums) / sizeof(double); ++i) {
const double num = serd_strtod(expt_test_strs[i], NULL);
@@ -144,6 +150,58 @@ test_blob_to_node(void)
}
static void
+test_base64_decode(void)
+{
+ static const char* const decoded = "test";
+ static const size_t decoded_len = 4U;
+
+ // Test decoding clean base64
+ {
+ static const char* const encoded = "dGVzdA==";
+ static const size_t encoded_len = 8U;
+
+ size_t size = 0U;
+ void* const data =
+ serd_base64_decode((const uint8_t*)encoded, encoded_len, &size);
+
+ assert(data);
+ assert(size == decoded_len);
+ assert(!strncmp((const char*)data, decoded, decoded_len));
+ serd_free(data);
+ }
+
+ // Test decoding equivalent dirty base64 with ignored junk characters
+ {
+ static const char* const encoded = "d-G#V!z*d(A$%==";
+ static const size_t encoded_len = 13U;
+
+ size_t size = 0U;
+ void* const data =
+ serd_base64_decode((const uint8_t*)encoded, encoded_len, &size);
+
+ assert(data);
+ assert(size == decoded_len);
+ assert(!strncmp((const char*)data, decoded, decoded_len));
+ serd_free(data);
+ }
+
+ // Test decoding effectively nothing
+ {
+ static const char* const encoded = "@#$%";
+ static const size_t encoded_len = 4U;
+
+ size_t size = 0U;
+ void* const data =
+ serd_base64_decode((const uint8_t*)encoded, encoded_len, &size);
+
+ assert(data);
+ assert(!size);
+ // Contents of data are undefined
+ serd_free(data);
+ }
+}
+
+static void
test_node_equals(void)
{
const uint8_t replacement_char_str[] = {0xEF, 0xBF, 0xBD, 0};
@@ -176,6 +234,8 @@ test_node_from_string(void)
static void
test_node_from_substring(void)
{
+ static const uint8_t utf8_str[] = {'l', 0xC3, 0xB6, 'n', 'g', 0};
+
SerdNode empty = serd_node_from_substring(SERD_LITERAL, NULL, 32);
assert(!empty.buf && !empty.n_bytes && !empty.n_chars && !empty.flags &&
!empty.type);
@@ -187,6 +247,30 @@ test_node_from_substring(void)
a_b = serd_node_from_substring(SERD_LITERAL, USTR("a\"bc"), 10);
assert(a_b.n_bytes == 4 && a_b.n_chars == 4 && a_b.flags == SERD_HAS_QUOTE &&
!strncmp((const char*)a_b.buf, "a\"bc", 4));
+
+ SerdNode utf8 = serd_node_from_substring(SERD_LITERAL, utf8_str, 5);
+ assert(utf8.n_bytes == 5 && utf8.n_chars == 4 && !utf8.flags &&
+ !strncmp((const char*)utf8.buf, (const char*)utf8_str, 6));
+}
+
+static void
+test_uri_node_from_node(void)
+{
+ const SerdNode string = serd_node_from_string(SERD_LITERAL, USTR("s"));
+ SerdNode string_node = serd_node_new_uri_from_node(&string, NULL, NULL);
+ assert(!string_node.n_bytes);
+ serd_node_free(&string_node);
+
+ const SerdNode nouri = {NULL, 0U, 0U, 0U, SERD_URI};
+ SerdNode nouri_node = serd_node_new_uri_from_node(&nouri, NULL, NULL);
+ assert(!nouri_node.n_bytes);
+ serd_node_free(&nouri_node);
+
+ const SerdNode uri =
+ serd_node_from_string(SERD_URI, USTR("http://example.org/p"));
+ SerdNode uri_node = serd_node_new_uri_from_node(&uri, NULL, NULL);
+ assert(uri_node.n_bytes == 20U);
+ serd_node_free(&uri_node);
}
int
@@ -196,9 +280,11 @@ main(void)
test_double_to_node();
test_integer_to_node();
test_blob_to_node();
+ test_base64_decode();
test_node_equals();
test_node_from_string();
test_node_from_substring();
+ test_uri_node_from_node();
printf("Success\n");
return 0;
diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c
index cd7ca408..374ec4e1 100644
--- a/test/test_reader_writer.c
+++ b/test/test_reader_writer.c
@@ -41,6 +41,8 @@ static const char* const doc_string =
" \"lang\"@en ;\n"
" eg:p <http://example.com/o> .\n"
"}\n"
+ "@prefix other: <http://example.org/other> .\n"
+ "@base <http://drobilla.net/> .\n"
"eg:s\n"
" <http://example.org/p> [\n"
" eg:p 3.0 ,\n"
@@ -399,7 +401,7 @@ test_write_errors(void)
ErrorContext ctx = {0U, 0U};
const SerdStyle style = (SerdStyle)(SERD_STYLE_STRICT | SERD_STYLE_CURIED);
- const size_t max_offsets[] = {0, 386, 1911, 2003, 386};
+ const size_t max_offsets[] = {0, 462, 1911, 2003, 462};
// Test errors at different offsets to hit different code paths
for (unsigned s = 1; s <= (unsigned)SERD_TRIG; ++s) {
diff --git a/test/test_string.c b/test/test_string.c
index 6767e5ae..23835ca9 100644
--- a/test/test_string.c
+++ b/test/test_string.c
@@ -11,19 +11,31 @@
#include <string.h>
static void
+check_strlen(const char* const str,
+ const size_t expected_n_bytes,
+ const size_t expected_n_chars,
+ const SerdNodeFlags expected_flags)
+{
+ size_t n_bytes = 0U;
+ SerdNodeFlags flags = 0U;
+ const size_t n_chars = serd_strlen((const uint8_t*)str, &n_bytes, &flags);
+
+ assert(n_bytes == expected_n_bytes);
+ assert(n_chars == expected_n_chars);
+ assert(flags == expected_flags);
+}
+
+static void
test_strlen(void)
{
- const uint8_t str[] = {'"', '5', 0xE2, 0x82, 0xAC, '"', '\n', 0};
+ static const uint8_t utf8[] = {'"', '5', 0xE2, 0x82, 0xAC, '"', '\n', 0};
- size_t n_bytes = 0;
- SerdNodeFlags flags = 0;
- size_t len = serd_strlen(str, &n_bytes, &flags);
- assert(len == 5 && n_bytes == 7 &&
- flags == (SERD_HAS_QUOTE | SERD_HAS_NEWLINE));
- len = serd_strlen(str, NULL, &flags);
- assert(len == 5);
+ check_strlen("\"quotes\"", 8U, 8U, SERD_HAS_QUOTE);
+ check_strlen("newline\n", 8U, 8U, SERD_HAS_NEWLINE);
+ check_strlen("\rreturn", 7U, 7U, SERD_HAS_NEWLINE);
+ check_strlen((const char*)utf8, 7U, 5U, SERD_HAS_QUOTE | SERD_HAS_NEWLINE);
- assert(serd_strlen(str, &n_bytes, NULL) == 5);
+ assert(serd_strlen((const uint8_t*)"nulls", NULL, NULL) == 5U);
}
static void
diff --git a/test/test_uri.c b/test/test_uri.c
index cc81b40e..fc5eab71 100644
--- a/test/test_uri.c
+++ b/test/test_uri.c
@@ -16,6 +16,8 @@
static void
test_uri_string_has_scheme(void)
{
+ assert(!serd_uri_string_has_scheme(NULL));
+
assert(!serd_uri_string_has_scheme(USTR("relative")));
assert(!serd_uri_string_has_scheme(USTR("http")));
assert(!serd_uri_string_has_scheme(USTR("5nostartdigit")));
@@ -99,6 +101,8 @@ test_uri_to_path(void)
"C|/Windows/Sucks"));
assert(!serd_uri_to_path((const uint8_t*)"http://example.org/path"));
+
+ assert(!strcmp((const char*)serd_uri_to_path((const uint8_t*)"rel"), "rel"));
}
#if defined(__GNUC__)
@@ -166,11 +170,20 @@ test_uri_parsing(void)
"/C:\\Pointless Space");
#endif
+ // Test tolerance of NULL hostname parameter
+ uint8_t* const hosted = serd_file_uri_parse(USTR("file://host/path"), NULL);
+ assert(!strcmp((const char*)hosted, "/path"));
+ serd_free(hosted);
+
// Test tolerance of parsing junk URI escapes
- uint8_t* out_path = serd_file_uri_parse(USTR("file:///foo/%0Xbar"), NULL);
- assert(!strcmp((const char*)out_path, "/foo/bar"));
- serd_free(out_path);
+ uint8_t* const junk1 = serd_file_uri_parse(USTR("file:///foo/%0Xbar"), NULL);
+ assert(!strcmp((const char*)junk1, "/foo/bar"));
+ serd_free(junk1);
+
+ uint8_t* const junk2 = serd_file_uri_parse(USTR("file:///foo/%X0bar"), NULL);
+ assert(!strcmp((const char*)junk2, "/foo/bar"));
+ serd_free(junk2);
}
static void
@@ -343,6 +356,22 @@ test_relative_uri(void)
"http://example.org/a/b/c",
"http://example.org/a/b",
"http://example.org/a");
+
+ // Tolerance of NULL URI output parameter
+ {
+ SerdURI uri = SERD_URI_NULL;
+ assert(!serd_uri_parse(USTR("http://example.org/path"), &uri));
+
+ SerdURI base = SERD_URI_NULL;
+ assert(!serd_uri_parse(USTR("http://example.org/"), &base));
+
+ SerdNode result_node = serd_node_new_relative_uri(&uri, &base, NULL, NULL);
+
+ assert(result_node.n_bytes == 4U);
+ assert(!strcmp((const char*)result_node.buf, "path"));
+
+ serd_node_free(&result_node);
+ }
}
int