diff options
Diffstat (limited to 'test')
101 files changed, 1098 insertions, 555 deletions
diff --git a/test/.clang-tidy b/test/.clang-tidy index 99a3264a..80737308 100644 --- a/test/.clang-tidy +++ b/test/.clang-tidy @@ -7,7 +7,6 @@ Checks: > -bugprone-assert-side-effect, -bugprone-easily-swappable-parameters, -cert-err33-c, - -clang-analyzer-nullability.NullableDereferenced, -clang-analyzer-optin.core.EnumCastOutOfRange, -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling, -concurrency-mt-unsafe, diff --git a/test/expect_string.h b/test/expect_string.h new file mode 100644 index 00000000..ecd1762e --- /dev/null +++ b/test/expect_string.h @@ -0,0 +1,19 @@ +// Copyright 2025 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <string.h> + +static inline bool +expect_string(const char* const actual, const char* const expected) +{ + assert(expected); + const bool equal = actual && !strcmp(actual, expected); + if (!equal) { + fprintf(stderr, "Expected:\n%s\n\n", expected); + fprintf(stderr, "Actual:\n%s\n\n", actual ? actual : "(null)"); + } + return equal; +} diff --git a/test/extra/abbreviate/manifest.ttl b/test/extra/abbreviate/manifest.ttl index ddcfdf03..69e6eb76 100644 --- a/test/extra/abbreviate/manifest.ttl +++ b/test/extra/abbreviate/manifest.ttl @@ -1,7 +1,6 @@ @prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix rdft: <http://www.w3.org/ns/rdftest#> . -@prefix serd: <http://drobilla.net/ns/serd#> . <> a mf:Manifest ; diff --git a/test/extra/bad/bad-lang-start-delete.nt b/test/extra/bad/bad-lang-start-delete.nt new file mode 100644 index 00000000..122625e0 --- /dev/null +++ b/test/extra/bad/bad-lang-start-delete.nt @@ -0,0 +1 @@ +<http://example.org/s> <http://example.org/p> "hello"@bad . diff --git a/test/extra/bad/bad-lang-start-space.nt b/test/extra/bad/bad-lang-start-space.nt new file mode 100644 index 00000000..ff5c12ab --- /dev/null +++ b/test/extra/bad/bad-lang-start-space.nt @@ -0,0 +1 @@ +<http://example.org/s> <http://example.org/p> "hello"@ bad . diff --git a/test/extra/bad/bad-lang-start-tab.nt b/test/extra/bad/bad-lang-start-tab.nt new file mode 100644 index 00000000..ad005c6d --- /dev/null +++ b/test/extra/bad/bad-lang-start-tab.nt @@ -0,0 +1 @@ +<http://example.org/s> <http://example.org/p> "hello"@ bad . diff --git a/test/extra/bad/bad-lang-start-wide.nt b/test/extra/bad/bad-lang-start-wide.nt new file mode 100644 index 00000000..04ca4899 --- /dev/null +++ b/test/extra/bad/bad-lang-start-wide.nt @@ -0,0 +1 @@ +<http://example.org/s> <http://example.org/p> "hello"@βad . diff --git a/test/extra/bad/bad-lang.ttl b/test/extra/bad/bad-lang.ttl index 01e04328..b51df89c 100644 --- a/test/extra/bad/bad-lang.ttl +++ b/test/extra/bad/bad-lang.ttl @@ -1 +1 @@ -<> <http://example.org/pred> "hello"@\bad .
\ No newline at end of file +<> <http://example.org/pred> "hello"@b\ad . diff --git a/test/extra/bad/bad-predicate-in-blank.ttl b/test/extra/bad/bad-predicate-in-blank.ttl new file mode 100644 index 00000000..e4200f15 --- /dev/null +++ b/test/extra/bad/bad-predicate-in-blank.ttl @@ -0,0 +1 @@ +<a> <b> [ ERRORHERE <c> ] diff --git a/test/extra/bad/bad-uri-scheme-start-apostrophe.nt b/test/extra/bad/bad-uri-scheme-start-apostrophe.nt new file mode 100644 index 00000000..265b46d1 --- /dev/null +++ b/test/extra/bad/bad-uri-scheme-start-apostrophe.nt @@ -0,0 +1 @@ +<http://example.org/s> <http://example.org/p> <'http://example.org/o> . diff --git a/test/extra/bad/bad-uri-scheme-start-delete.nt b/test/extra/bad/bad-uri-scheme-start-delete.nt new file mode 100644 index 00000000..70b4962a --- /dev/null +++ b/test/extra/bad/bad-uri-scheme-start-delete.nt @@ -0,0 +1 @@ +<http://example.org/s> <http://example.org/p> <http://example.org/o> . diff --git a/test/extra/bad/bad-uri-scheme-start-space.nt b/test/extra/bad/bad-uri-scheme-start-space.nt new file mode 100644 index 00000000..d396d6dd --- /dev/null +++ b/test/extra/bad/bad-uri-scheme-start-space.nt @@ -0,0 +1 @@ +<http://example.org/s> <http://example.org/p> < http://example.org/o> . diff --git a/test/extra/bad/bad-uri-scheme-start-tab.nt b/test/extra/bad/bad-uri-scheme-start-tab.nt new file mode 100644 index 00000000..458a5743 --- /dev/null +++ b/test/extra/bad/bad-uri-scheme-start-tab.nt @@ -0,0 +1 @@ +<http://example.org/s> <http://example.org/p> < http://example.org/o> . diff --git a/test/extra/bad/bad-uri-scheme-start-wide.nt b/test/extra/bad/bad-uri-scheme-start-wide.nt new file mode 100644 index 00000000..7ddfff60 --- /dev/null +++ b/test/extra/bad/bad-uri-scheme-start-wide.nt @@ -0,0 +1 @@ +<http://example.org/s> <http://example.org/p> <σhttp://example.org/o> . diff --git a/test/extra/bad/bad-uri-scheme-start.nt b/test/extra/bad/bad-uri-scheme-start.nt deleted file mode 100644 index cd3fd70f..00000000 --- a/test/extra/bad/bad-uri-scheme-start.nt +++ /dev/null @@ -1 +0,0 @@ -<2http://example.org/s> <http://example.org/p> <http://example.org/o> . diff --git a/test/extra/bad/manifest.ttl b/test/extra/bad/manifest.ttl index 64dbf05f..acadde28 100644 --- a/test/extra/bad/manifest.ttl +++ b/test/extra/bad/manifest.ttl @@ -28,24 +28,6 @@ <#bad-dot-after-subject> <#bad-dot-in-collection> <#bad-empty-blank-predicate> - <#bad-nt-eof-after-blank> - <#bad-nt-eof-after-lang> - <#bad-nt-eof-after-lang-hyphen> - <#bad-nt-eof-after-lang-subtag> - <#bad-nt-eof-after-object> - <#bad-nt-eof-after-predicate> - <#bad-nt-eof-after-string> - <#bad-nt-eof-after-string-escape> - <#bad-nt-eof-after-subject> - <#bad-nt-eof-after-underscore> - <#bad-nt-eof-before-blank> - <#bad-nt-eof-before-iri> - <#bad-nt-eof-before-lang> - <#bad-nt-eof-before-string> - <#bad-nt-eof-before-string-escape> - <#bad-nt-eof-in-iri-path> - <#bad-nt-eof-in-iri-scheme> - <#bad-nt-eof-in-string> <#bad-nt-syntax-blank-u00F7.nt> <#bad-nt-syntax-blank-u037E.nt> <#bad-nt-syntax-blank-u200B.nt> @@ -65,24 +47,6 @@ <#bad-nt-syntax-uri-grave> <#bad-nt-syntax-uri-less-than> <#bad-nt-syntax-uri-opening-brace> - <#bad-eof-after-quotes> - <#bad-eof-at-string-start> - <#bad-eof-in-blank> - <#bad-eof-in-escape> - <#bad-eof-in-lang-suffix> - <#bad-eof-in-lang> - <#bad-eof-in-list> - <#bad-eof-in-long-string> - <#bad-eof-in-object-list> - <#bad-eof-in-object-list2> - <#bad-eof-in-predicate-list> - <#bad-eof-in-string> - <#bad-eof-in-text-character> - <#bad-eof-in-triple-quote> - <#bad-eof-in-uri> - <#bad-eof-in-uri-character> - <#bad-eof-in-uri-scheme> - <#bad-eof-in-utf8-character> <#bad-equivalence> <#bad-escape> <#bad-ext-namedblank-op> @@ -99,6 +63,10 @@ <#bad-is-of-keywords> <#bad-keywords> <#bad-lang> + <#bad-lang-start-delete> + <#bad-lang-start-space> + <#bad-lang-start-tab> + <#bad-lang-start-wide> <#bad-list> <#bad-list-close-object> <#bad-list2> @@ -116,6 +84,7 @@ <#bad-object2> <#bad-paths> <#bad-pn-escape> + <#bad-predicate-in-blank> <#bad-prefix> <#bad-prefix-dot> <#bad-prefix-missing-colon> @@ -128,7 +97,10 @@ <#bad-true-subject> <#bad-uri-escape> <#bad-uri-scheme> - <#bad-uri-scheme-start> + <#bad-uri-scheme-start-delete> + <#bad-uri-scheme-start-space> + <#bad-uri-scheme-start-tab> + <#bad-uri-scheme-start-wide> <#bad-uri-truncated> <#bad-verb> ) . @@ -243,96 +215,6 @@ mf:action <bad-empty-blank-predicate.ttl> ; mf:name "bad-empty-blank-predicate" . -<#bad-nt-eof-after-blank> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-after-blank.nt> ; - mf:name "bad-nt-eof-after-blank" . - -<#bad-nt-eof-after-lang> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-after-lang.nt> ; - mf:name "bad-nt-eof-after-lang" . - -<#bad-nt-eof-after-lang-hyphen> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-after-lang-hyphen.nt> ; - mf:name "bad-nt-eof-after-lang-hyphen" . - -<#bad-nt-eof-after-lang-subtag> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-after-lang-subtag.nt> ; - mf:name "bad-nt-eof-after-lang-subtag" . - -<#bad-nt-eof-after-object> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-after-object.nt> ; - mf:name "bad-nt-eof-after-object" . - -<#bad-nt-eof-after-predicate> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-after-predicate.nt> ; - mf:name "bad-nt-eof-after-predicate" . - -<#bad-nt-eof-after-string> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-after-string.nt> ; - mf:name "bad-nt-eof-after-string" . - -<#bad-nt-eof-after-string-escape> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-after-string-escape.nt> ; - mf:name "bad-nt-eof-after-string-escape" . - -<#bad-nt-eof-after-subject> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-after-subject.nt> ; - mf:name "bad-nt-eof-after-subject" . - -<#bad-nt-eof-after-underscore> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-after-underscore.nt> ; - mf:name "bad-nt-eof-after-underscore" . - -<#bad-nt-eof-before-blank> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-before-blank.nt> ; - mf:name "bad-nt-eof-before-blank" . - -<#bad-nt-eof-before-iri> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-before-iri.nt> ; - mf:name "bad-nt-eof-before-iri" . - -<#bad-nt-eof-before-lang> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-before-lang.nt> ; - mf:name "bad-nt-eof-before-lang" . - -<#bad-nt-eof-before-string> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-before-string.nt> ; - mf:name "bad-nt-eof-before-string" . - -<#bad-nt-eof-before-string-escape> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-before-string-escape.nt> ; - mf:name "bad-nt-eof-before-string-escape" . - -<#bad-nt-eof-in-iri-path> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-in-iri-path.nt> ; - mf:name "bad-nt-eof-in-iri-path" . - -<#bad-nt-eof-in-iri-scheme> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-in-iri-scheme.nt> ; - mf:name "bad-nt-eof-in-iri-scheme" . - -<#bad-nt-eof-in-string> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-nt-eof-in-string.nt> ; - mf:name "bad-nt-eof-in-string" . - <#bad-nt-syntax-blank-u00F7> a rdft:TestNTriplesNegativeSyntax ; mf:action <bad-nt-syntax-blank-u00F7.nt> ; @@ -428,96 +310,6 @@ mf:action <bad-nt-syntax-uri-opening-brace.nt> ; mf:name "bad-nt-syntax-uri-opening-brace" . -<#bad-eof-after-quotes> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-after-quotes.ttl> ; - mf:name "bad-eof-after-quotes" . - -<#bad-eof-at-string-start> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-at-string-start.ttl> ; - mf:name "bad-eof-at-string-start" . - -<#bad-eof-in-blank> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-blank.ttl> ; - mf:name "bad-eof-in-blank" . - -<#bad-eof-in-escape> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-escape.ttl> ; - mf:name "bad-eof-in-escape" . - -<#bad-eof-in-lang> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-lang.ttl> ; - mf:name "bad-eof-in-lang" . - -<#bad-eof-in-lang-suffix> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-lang-suffix.ttl> ; - mf:name "bad-eof-in-lang-suffix" . - -<#bad-eof-in-list> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-list.ttl> ; - mf:name "bad-eof-in-list" . - -<#bad-eof-in-long-string> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-long-string.ttl> ; - mf:name "bad-eof-in-long-string" . - -<#bad-eof-in-object-list> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-object-list.ttl> ; - mf:name "bad-eof-in-object-list" . - -<#bad-eof-in-object-list2> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-object-list2.ttl> ; - mf:name "bad-eof-in-object-list2" . - -<#bad-eof-in-predicate-list> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-predicate-list.ttl> ; - mf:name "bad-eof-in-predicate-list" . - -<#bad-eof-in-string> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-string.ttl> ; - mf:name "bad-eof-in-string" . - -<#bad-eof-in-text-character> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-text-character.ttl> ; - mf:name "bad-eof-in-text-character" . - -<#bad-eof-in-triple-quote> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-triple-quote.ttl> ; - mf:name "bad-eof-in-triple-quote" . - -<#bad-eof-in-uri> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-uri.ttl> ; - mf:name "bad-eof-in-uri" . - -<#bad-eof-in-uri-character> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-uri-character.ttl> ; - mf:name "bad-eof-in-uri-character" . - -<#bad-eof-in-uri-scheme> - a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-eof-in-uri-scheme.nt> ; - mf:name "bad-eof-in-uri-scheme" . - -<#bad-eof-in-utf8-character> - a rdft:TestTurtleNegativeSyntax ; - mf:action <bad-eof-in-utf8-character.ttl> ; - mf:name "bad-eof-in-utf8-character" . - <#bad-equivalence> a rdft:TestTurtleNegativeSyntax ; mf:action <bad-equivalence.ttl> ; @@ -598,6 +390,26 @@ mf:action <bad-lang.ttl> ; mf:name "bad-lang" . +<#bad-lang-start-delete> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-lang-start-delete.nt> ; + mf:name "bad-lang-start-delete" . + +<#bad-lang-start-space> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-lang-start-space.nt> ; + mf:name "bad-lang-start-space" . + +<#bad-lang-start-tab> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-lang-start-tab.nt> ; + mf:name "bad-lang-start-tab" . + +<#bad-lang-start-wide> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-lang-start-wide.nt> ; + mf:name "bad-lang-start-wide" . + <#bad-list> a rdft:TestTurtleNegativeSyntax ; mf:action <bad-list.ttl> ; @@ -683,6 +495,11 @@ mf:action <bad-pn-escape.ttl> ; mf:name "bad-pn-escape" . +<#bad-predicate-in-blank> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-predicate-in-blank.ttl> ; + mf:name "bad-predicate-in-blank" . + <#bad-prefix> a rdft:TestTurtleNegativeSyntax ; mf:action <bad-prefix.ttl> ; @@ -743,10 +560,30 @@ mf:action <bad-uri-scheme.nt> ; mf:name "bad-uri-scheme" . -<#bad-uri-scheme-start> +<#bad-uri-scheme-start-apostrophe> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-uri-scheme-start-apostrophe.nt> ; + mf:name "bad-uri-scheme-start-apostrophe" . + +<#bad-uri-scheme-start-delete> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-uri-scheme-start-delete.nt> ; + mf:name "bad-uri-scheme-start-delete" . + +<#bad-uri-scheme-start-space> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-uri-scheme-start-space.nt> ; + mf:name "bad-uri-scheme-start-space" . + +<#bad-uri-scheme-start-tab> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-uri-scheme-start-tab.nt> ; + mf:name "bad-uri-scheme-start-tab" . + +<#bad-uri-scheme-start-wide> a rdft:TestNTriplesNegativeSyntax ; - mf:action <bad-uri-scheme-start.nt> ; - mf:name "bad-uri-scheme-start" . + mf:action <bad-uri-scheme-start-wide.nt> ; + mf:name "bad-uri-scheme-start-wide" . <#bad-uri-truncated> a rdft:TestNTriplesNegativeSyntax ; diff --git a/test/extra/eof/README.md b/test/extra/eof/README.md new file mode 100644 index 00000000..1e461f79 --- /dev/null +++ b/test/extra/eof/README.md @@ -0,0 +1,5 @@ +EOF Test Suite +============== + +This simple suite tests that inputs truncated in various places are handled +correctly. diff --git a/test/extra/bad/bad-nt-eof-after-blank.nt b/test/extra/eof/bad-nt-eof-after-blank.nt index bc66ca37..bc66ca37 100644 --- a/test/extra/bad/bad-nt-eof-after-blank.nt +++ b/test/extra/eof/bad-nt-eof-after-blank.nt diff --git a/test/extra/bad/bad-nt-eof-after-lang-hyphen.nt b/test/extra/eof/bad-nt-eof-after-lang-hyphen.nt index 9e885d80..9e885d80 100644 --- a/test/extra/bad/bad-nt-eof-after-lang-hyphen.nt +++ b/test/extra/eof/bad-nt-eof-after-lang-hyphen.nt diff --git a/test/extra/bad/bad-nt-eof-after-lang-subtag.nt b/test/extra/eof/bad-nt-eof-after-lang-subtag.nt index f8158aec..f8158aec 100644 --- a/test/extra/bad/bad-nt-eof-after-lang-subtag.nt +++ b/test/extra/eof/bad-nt-eof-after-lang-subtag.nt diff --git a/test/extra/bad/bad-nt-eof-after-lang.nt b/test/extra/eof/bad-nt-eof-after-lang.nt index 7ab04b06..7ab04b06 100644 --- a/test/extra/bad/bad-nt-eof-after-lang.nt +++ b/test/extra/eof/bad-nt-eof-after-lang.nt diff --git a/test/extra/bad/bad-nt-eof-after-object.nt b/test/extra/eof/bad-nt-eof-after-object.nt index e796f2b0..e796f2b0 100644 --- a/test/extra/bad/bad-nt-eof-after-object.nt +++ b/test/extra/eof/bad-nt-eof-after-object.nt diff --git a/test/extra/bad/bad-nt-eof-after-predicate.nt b/test/extra/eof/bad-nt-eof-after-predicate.nt index ea47bfbe..ea47bfbe 100644 --- a/test/extra/bad/bad-nt-eof-after-predicate.nt +++ b/test/extra/eof/bad-nt-eof-after-predicate.nt diff --git a/test/extra/bad/bad-nt-eof-after-string-escape.nt b/test/extra/eof/bad-nt-eof-after-string-escape.nt index 869907e8..869907e8 100644 --- a/test/extra/bad/bad-nt-eof-after-string-escape.nt +++ b/test/extra/eof/bad-nt-eof-after-string-escape.nt diff --git a/test/extra/bad/bad-nt-eof-after-string.nt b/test/extra/eof/bad-nt-eof-after-string.nt index 32dda36d..32dda36d 100644 --- a/test/extra/bad/bad-nt-eof-after-string.nt +++ b/test/extra/eof/bad-nt-eof-after-string.nt diff --git a/test/extra/bad/bad-nt-eof-after-subject.nt b/test/extra/eof/bad-nt-eof-after-subject.nt index 21fa07f4..21fa07f4 100644 --- a/test/extra/bad/bad-nt-eof-after-subject.nt +++ b/test/extra/eof/bad-nt-eof-after-subject.nt diff --git a/test/extra/bad/bad-nt-eof-after-underscore.nt b/test/extra/eof/bad-nt-eof-after-underscore.nt index 4b05f2ac..4b05f2ac 100644 --- a/test/extra/bad/bad-nt-eof-after-underscore.nt +++ b/test/extra/eof/bad-nt-eof-after-underscore.nt diff --git a/test/extra/bad/bad-nt-eof-before-blank.nt b/test/extra/eof/bad-nt-eof-before-blank.nt index 99f70844..99f70844 100644 --- a/test/extra/bad/bad-nt-eof-before-blank.nt +++ b/test/extra/eof/bad-nt-eof-before-blank.nt diff --git a/test/extra/bad/bad-nt-eof-before-iri.nt b/test/extra/eof/bad-nt-eof-before-iri.nt index c5fa7845..c5fa7845 100644 --- a/test/extra/bad/bad-nt-eof-before-iri.nt +++ b/test/extra/eof/bad-nt-eof-before-iri.nt diff --git a/test/extra/bad/bad-nt-eof-before-lang.nt b/test/extra/eof/bad-nt-eof-before-lang.nt index f1a9d0df..f1a9d0df 100644 --- a/test/extra/bad/bad-nt-eof-before-lang.nt +++ b/test/extra/eof/bad-nt-eof-before-lang.nt diff --git a/test/extra/bad/bad-nt-eof-before-string-escape.nt b/test/extra/eof/bad-nt-eof-before-string-escape.nt index 30443488..30443488 100644 --- a/test/extra/bad/bad-nt-eof-before-string-escape.nt +++ b/test/extra/eof/bad-nt-eof-before-string-escape.nt diff --git a/test/extra/bad/bad-nt-eof-before-string.nt b/test/extra/eof/bad-nt-eof-before-string.nt index 6a2a7543..6a2a7543 100644 --- a/test/extra/bad/bad-nt-eof-before-string.nt +++ b/test/extra/eof/bad-nt-eof-before-string.nt diff --git a/test/extra/bad/bad-nt-eof-in-iri-path.nt b/test/extra/eof/bad-nt-eof-in-iri-path.nt index e8555e2b..e8555e2b 100644 --- a/test/extra/bad/bad-nt-eof-in-iri-path.nt +++ b/test/extra/eof/bad-nt-eof-in-iri-path.nt diff --git a/test/extra/bad/bad-nt-eof-in-iri-scheme.nt b/test/extra/eof/bad-nt-eof-in-iri-scheme.nt index 2c071547..2c071547 100644 --- a/test/extra/bad/bad-nt-eof-in-iri-scheme.nt +++ b/test/extra/eof/bad-nt-eof-in-iri-scheme.nt diff --git a/test/extra/bad/bad-nt-eof-in-string.nt b/test/extra/eof/bad-nt-eof-in-string.nt index 98944654..98944654 100644 --- a/test/extra/bad/bad-nt-eof-in-string.nt +++ b/test/extra/eof/bad-nt-eof-in-string.nt diff --git a/test/extra/bad/bad-eof-after-quotes.ttl b/test/extra/eof/bad-ttl-eof-after-quotes.ttl index 40e429cb..40e429cb 100644 --- a/test/extra/bad/bad-eof-after-quotes.ttl +++ b/test/extra/eof/bad-ttl-eof-after-quotes.ttl diff --git a/test/extra/bad/bad-eof-at-string-start.ttl b/test/extra/eof/bad-ttl-eof-at-string-start.ttl index 93d20bcc..93d20bcc 100644 --- a/test/extra/bad/bad-eof-at-string-start.ttl +++ b/test/extra/eof/bad-ttl-eof-at-string-start.ttl diff --git a/test/extra/bad/bad-eof-in-blank.ttl b/test/extra/eof/bad-ttl-eof-in-blank.ttl index 8cf4ee84..8cf4ee84 100644 --- a/test/extra/bad/bad-eof-in-blank.ttl +++ b/test/extra/eof/bad-ttl-eof-in-blank.ttl diff --git a/test/extra/bad/bad-eof-in-escape.ttl b/test/extra/eof/bad-ttl-eof-in-escape.ttl index 24b4eec6..24b4eec6 100644 --- a/test/extra/bad/bad-eof-in-escape.ttl +++ b/test/extra/eof/bad-ttl-eof-in-escape.ttl diff --git a/test/extra/bad/bad-eof-in-lang-suffix.ttl b/test/extra/eof/bad-ttl-eof-in-lang-suffix.ttl index f46a7763..f46a7763 100644 --- a/test/extra/bad/bad-eof-in-lang-suffix.ttl +++ b/test/extra/eof/bad-ttl-eof-in-lang-suffix.ttl diff --git a/test/extra/bad/bad-eof-in-lang.ttl b/test/extra/eof/bad-ttl-eof-in-lang.ttl index bfdffd02..bfdffd02 100644 --- a/test/extra/bad/bad-eof-in-lang.ttl +++ b/test/extra/eof/bad-ttl-eof-in-lang.ttl diff --git a/test/extra/bad/bad-eof-in-list.ttl b/test/extra/eof/bad-ttl-eof-in-list.ttl index 13eeb88d..13eeb88d 100644 --- a/test/extra/bad/bad-eof-in-list.ttl +++ b/test/extra/eof/bad-ttl-eof-in-list.ttl diff --git a/test/extra/bad/bad-eof-in-long-string.ttl b/test/extra/eof/bad-ttl-eof-in-long-string.ttl index 2ef179a8..2ef179a8 100644 --- a/test/extra/bad/bad-eof-in-long-string.ttl +++ b/test/extra/eof/bad-ttl-eof-in-long-string.ttl diff --git a/test/extra/bad/bad-eof-in-object-list.ttl b/test/extra/eof/bad-ttl-eof-in-object-list.ttl index 9bbcd17a..9bbcd17a 100644 --- a/test/extra/bad/bad-eof-in-object-list.ttl +++ b/test/extra/eof/bad-ttl-eof-in-object-list.ttl diff --git a/test/extra/bad/bad-eof-in-object-list2.ttl b/test/extra/eof/bad-ttl-eof-in-object-list2.ttl index 9186fb9f..9186fb9f 100644 --- a/test/extra/bad/bad-eof-in-object-list2.ttl +++ b/test/extra/eof/bad-ttl-eof-in-object-list2.ttl diff --git a/test/extra/bad/bad-eof-in-predicate-list.ttl b/test/extra/eof/bad-ttl-eof-in-predicate-list.ttl index eab5b05b..eab5b05b 100644 --- a/test/extra/bad/bad-eof-in-predicate-list.ttl +++ b/test/extra/eof/bad-ttl-eof-in-predicate-list.ttl diff --git a/test/extra/bad/bad-eof-in-string.ttl b/test/extra/eof/bad-ttl-eof-in-string.ttl index bb6e817f..bb6e817f 100644 --- a/test/extra/bad/bad-eof-in-string.ttl +++ b/test/extra/eof/bad-ttl-eof-in-string.ttl diff --git a/test/extra/bad/bad-eof-in-text-character.ttl b/test/extra/eof/bad-ttl-eof-in-text-character.ttl index a614803a..a614803a 100644 --- a/test/extra/bad/bad-eof-in-text-character.ttl +++ b/test/extra/eof/bad-ttl-eof-in-text-character.ttl diff --git a/test/extra/bad/bad-eof-in-triple-quote.ttl b/test/extra/eof/bad-ttl-eof-in-triple-quote.ttl index fb935441..fb935441 100644 --- a/test/extra/bad/bad-eof-in-triple-quote.ttl +++ b/test/extra/eof/bad-ttl-eof-in-triple-quote.ttl diff --git a/test/extra/bad/bad-eof-in-uri-character.ttl b/test/extra/eof/bad-ttl-eof-in-uri-character.ttl index eda70770..eda70770 100644 --- a/test/extra/bad/bad-eof-in-uri-character.ttl +++ b/test/extra/eof/bad-ttl-eof-in-uri-character.ttl diff --git a/test/extra/bad/bad-eof-in-uri-scheme.nt b/test/extra/eof/bad-ttl-eof-in-uri-scheme.ttl index de892dcf..de892dcf 100644 --- a/test/extra/bad/bad-eof-in-uri-scheme.nt +++ b/test/extra/eof/bad-ttl-eof-in-uri-scheme.ttl diff --git a/test/extra/bad/bad-eof-in-uri.ttl b/test/extra/eof/bad-ttl-eof-in-uri.ttl index 07b6e6ab..07b6e6ab 100644 --- a/test/extra/bad/bad-eof-in-uri.ttl +++ b/test/extra/eof/bad-ttl-eof-in-uri.ttl diff --git a/test/extra/bad/bad-eof-in-utf8-character.ttl b/test/extra/eof/bad-ttl-eof-in-utf8-character.ttl index 16784e88..16784e88 100644 --- a/test/extra/bad/bad-eof-in-utf8-character.ttl +++ b/test/extra/eof/bad-ttl-eof-in-utf8-character.ttl diff --git a/test/extra/eof/manifest.ttl b/test/extra/eof/manifest.ttl new file mode 100644 index 00000000..465333f7 --- /dev/null +++ b/test/extra/eof/manifest.ttl @@ -0,0 +1,225 @@ +@prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> . +@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . +@prefix rdft: <http://www.w3.org/ns/rdftest#> . + +<> + a mf:Manifest ; + rdfs:comment "Serd EOF (truncated input) test suite" ; + mf:entries ( + <#bad-nt-eof-after-blank> + <#bad-nt-eof-after-lang> + <#bad-nt-eof-after-lang-hyphen> + <#bad-nt-eof-after-lang-subtag> + <#bad-nt-eof-after-object> + <#bad-nt-eof-after-predicate> + <#bad-nt-eof-after-string> + <#bad-nt-eof-after-string-escape> + <#bad-nt-eof-after-subject> + <#bad-nt-eof-after-underscore> + <#bad-nt-eof-before-blank> + <#bad-nt-eof-before-iri> + <#bad-nt-eof-before-lang> + <#bad-nt-eof-before-string> + <#bad-nt-eof-before-string-escape> + <#bad-nt-eof-in-iri-path> + <#bad-nt-eof-in-iri-scheme> + <#bad-nt-eof-in-string> + <#bad-ttl-eof-after-quotes> + <#bad-ttl-eof-at-string-start> + <#bad-ttl-eof-in-blank> + <#bad-ttl-eof-in-escape> + <#bad-ttl-eof-in-lang> + <#bad-ttl-eof-in-lang-suffix> + <#bad-ttl-eof-in-list> + <#bad-ttl-eof-in-long-string> + <#bad-ttl-eof-in-object-list> + <#bad-ttl-eof-in-object-list2> + <#bad-ttl-eof-in-predicate-list> + <#bad-ttl-eof-in-string> + <#bad-ttl-eof-in-text-character> + <#bad-ttl-eof-in-triple-quote> + <#bad-ttl-eof-in-uri> + <#bad-ttl-eof-in-uri-character> + <#bad-ttl-eof-in-uri-scheme> + <#bad-ttl-eof-in-utf8-character> + ) . + +<#bad-nt-eof-after-blank> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-after-blank.nt> ; + mf:name "bad-nt-eof-after-blank" . + +<#bad-nt-eof-after-lang> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-after-lang.nt> ; + mf:name "bad-nt-eof-after-lang" . + +<#bad-nt-eof-after-lang-hyphen> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-after-lang-hyphen.nt> ; + mf:name "bad-nt-eof-after-lang-hyphen" . + +<#bad-nt-eof-after-lang-subtag> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-after-lang-subtag.nt> ; + mf:name "bad-nt-eof-after-lang-subtag" . + +<#bad-nt-eof-after-object> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-after-object.nt> ; + mf:name "bad-nt-eof-after-object" . + +<#bad-nt-eof-after-predicate> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-after-predicate.nt> ; + mf:name "bad-nt-eof-after-predicate" . + +<#bad-nt-eof-after-string> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-after-string.nt> ; + mf:name "bad-nt-eof-after-string" . + +<#bad-nt-eof-after-string-escape> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-after-string-escape.nt> ; + mf:name "bad-nt-eof-after-string-escape" . + +<#bad-nt-eof-after-subject> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-after-subject.nt> ; + mf:name "bad-nt-eof-after-subject" . + +<#bad-nt-eof-after-underscore> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-after-underscore.nt> ; + mf:name "bad-nt-eof-after-underscore" . + +<#bad-nt-eof-before-blank> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-before-blank.nt> ; + mf:name "bad-nt-eof-before-blank" . + +<#bad-nt-eof-before-iri> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-before-iri.nt> ; + mf:name "bad-nt-eof-before-iri" . + +<#bad-nt-eof-before-lang> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-before-lang.nt> ; + mf:name "bad-nt-eof-before-lang" . + +<#bad-nt-eof-before-string> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-before-string.nt> ; + mf:name "bad-nt-eof-before-string" . + +<#bad-nt-eof-before-string-escape> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-before-string-escape.nt> ; + mf:name "bad-nt-eof-before-string-escape" . + +<#bad-nt-eof-in-iri-path> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-in-iri-path.nt> ; + mf:name "bad-nt-eof-in-iri-path" . + +<#bad-nt-eof-in-iri-scheme> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-in-iri-scheme.nt> ; + mf:name "bad-nt-eof-in-iri-scheme" . + +<#bad-nt-eof-in-string> + a rdft:TestNTriplesNegativeSyntax ; + mf:action <bad-nt-eof-in-string.nt> ; + mf:name "bad-nt-eof-in-string" . + +<#bad-ttl-eof-after-quotes> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-after-quotes.ttl> ; + mf:name "bad-ttl-eof-after-quotes" . + +<#bad-ttl-eof-at-string-start> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-at-string-start.ttl> ; + mf:name "bad-ttl-eof-at-string-start" . + +<#bad-ttl-eof-in-blank> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-blank.ttl> ; + mf:name "bad-ttl-eof-in-blank" . + +<#bad-ttl-eof-in-escape> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-escape.ttl> ; + mf:name "bad-ttl-eof-in-escape" . + +<#bad-ttl-eof-in-lang> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-lang.ttl> ; + mf:name "bad-ttl-eof-in-lang" . + +<#bad-ttl-eof-in-lang-suffix> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-lang-suffix.ttl> ; + mf:name "bad-ttl-eof-in-lang-suffix" . + +<#bad-ttl-eof-in-list> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-list.ttl> ; + mf:name "bad-ttl-eof-in-list" . + +<#bad-ttl-eof-in-long-string> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-long-string.ttl> ; + mf:name "bad-ttl-eof-in-long-string" . + +<#bad-ttl-eof-in-object-list> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-object-list.ttl> ; + mf:name "bad-ttl-eof-in-object-list" . + +<#bad-ttl-eof-in-object-list2> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-object-list2.ttl> ; + mf:name "bad-ttl-eof-in-object-list2" . + +<#bad-ttl-eof-in-predicate-list> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-predicate-list.ttl> ; + mf:name "bad-ttl-eof-in-predicate-list" . + +<#bad-ttl-eof-in-string> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-string.ttl> ; + mf:name "bad-ttl-eof-in-string" . + +<#bad-ttl-eof-in-text-character> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-text-character.ttl> ; + mf:name "bad-ttl-eof-in-text-character" . + +<#bad-ttl-eof-in-triple-quote> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-triple-quote.ttl> ; + mf:name "bad-ttl-eof-in-triple-quote" . + +<#bad-ttl-eof-in-uri> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-uri.ttl> ; + mf:name "bad-ttl-eof-in-uri" . + +<#bad-ttl-eof-in-uri-character> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-uri-character.ttl> ; + mf:name "bad-ttl-eof-in-uri-character" . + +<#bad-ttl-eof-in-uri-scheme> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-uri-scheme.ttl> ; + mf:name "bad-ttl-eof-in-uri-scheme" . + +<#bad-ttl-eof-in-utf8-character> + a rdft:TestTurtleNegativeSyntax ; + mf:action <bad-ttl-eof-in-utf8-character.ttl> ; + mf:name "bad-ttl-eof-in-utf8-character" . diff --git a/test/extra/full/manifest.ttl b/test/extra/full/manifest.ttl index a7cfac4a..e73971e7 100644 --- a/test/extra/full/manifest.ttl +++ b/test/extra/full/manifest.ttl @@ -1,7 +1,6 @@ @prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix rdft: <http://www.w3.org/ns/rdftest#> . -@prefix serd: <http://drobilla.net/ns/serd#> . <> a mf:Manifest ; diff --git a/test/extra/good/manifest.ttl b/test/extra/good/manifest.ttl index 350d7d9c..659f8fd1 100644 --- a/test/extra/good/manifest.ttl +++ b/test/extra/good/manifest.ttl @@ -16,16 +16,21 @@ <#test-blank-node-statement> <#test-blankdot> <#test-bom> + <#test-boolish-prefix> <#test-changing-base> <#test-comment-whitespace> <#test-cr> <#test-digit-start-pname> + <#test-decimal-ends-with-dot> <#test-double> + <#test-double-ends-with-dot> <#test-empty-path-base> <#test-eof-at-page-end> <#test-ext-namedblank-iri> <#test-ext-namedblank-prefix> + <#test-false-ends-with-dot> <#test-id> + <#test-integer-ends-with-dot> <#test-list-in-blank> <#test-list-subject> <#test-local-name-ends-with-dot> @@ -56,6 +61,7 @@ <#test-several-eaten-dots> <#test-string-escapes> <#test-trig-syntax-all-rules> + <#test-true-ends-with-dot> <#test-ttl-syntax-all-rules> <#test-uri> ) . @@ -120,6 +126,18 @@ mf:name "test-bom" ; mf:result <test-bom.nt> . +<#test-bom-only> + a rdft:TestTurtleEval ; + mf:action <test-bom-only.ttl> ; + mf:name "test-bom-only" ; + mf:result <test-bom-only.nt> . + +<#test-boolish-prefix> + a rdft:TestTurtleEval ; + mf:action <test-boolish-prefix.ttl> ; + mf:name "test-boolish-prefix" ; + mf:result <test-boolish-prefix.nt> . + <#test-changing-base> a rdft:TestTurtleEval ; mf:action <test-changing-base.ttl> ; @@ -144,12 +162,24 @@ mf:name "test-digit-start-pname" ; mf:result <test-digit-start-pname.nt> . +<#test-decimal-ends-with-dot> + a rdft:TestTurtleEval ; + mf:action <test-decimal-ends-with-dot.ttl> ; + mf:name "test-decimal-ends-with-dot" ; + mf:result <test-decimal-ends-with-dot.nt> . + <#test-double> a rdft:TestTurtleEval ; mf:action <test-double.ttl> ; mf:name "test-double" ; mf:result <test-double.nt> . +<#test-double-ends-with-dot> + a rdft:TestTurtleEval ; + mf:action <test-double-ends-with-dot.ttl> ; + mf:name "test-double-ends-with-dot" ; + mf:result <test-double-ends-with-dot.nt> . + <#test-empty-path-base> a rdft:TestTurtleEval ; mf:action <test-empty-path-base.ttl> ; @@ -174,12 +204,24 @@ mf:name "test-ext-namedblank-prefix" ; mf:result <test-ext-namedblank-prefix.nt> . +<#test-false-ends-with-dot> + a rdft:TestTurtleEval ; + mf:action <test-false-ends-with-dot.ttl> ; + mf:name "test-false-ends-with-dot" ; + mf:result <test-false-ends-with-dot.nt> . + <#test-id> a rdft:TestTurtleEval ; mf:action <test-id.ttl> ; mf:name "test-id" ; mf:result <test-id.nt> . +<#test-integer-ends-with-dot> + a rdft:TestTurtleEval ; + mf:action <test-integer-ends-with-dot.ttl> ; + mf:name "test-integer-ends-with-dot" ; + mf:result <test-integer-ends-with-dot.nt> . + <#test-list-in-blank> a rdft:TestTurtleEval ; mf:action <test-list-in-blank.ttl> ; @@ -344,6 +386,12 @@ mf:action <test-trig-syntax-all-rules.trig> ; mf:name "test-trig-syntax-all-rules" . +<#test-true-ends-with-dot> + a rdft:TestTurtleEval ; + mf:action <test-true-ends-with-dot.ttl> ; + mf:name "test-true-ends-with-dot" ; + mf:result <test-true-ends-with-dot.nt> . + <#test-ttl-syntax-all-rules> a rdft:TestTurtlePositiveSyntax ; mf:action <test-ttl-syntax-all-rules.ttl> ; diff --git a/test/extra/good/test-bom-only.nt b/test/extra/good/test-bom-only.nt new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/test/extra/good/test-bom-only.nt diff --git a/test/extra/good/test-bom-only.ttl b/test/extra/good/test-bom-only.ttl new file mode 100644 index 00000000..5f282702 --- /dev/null +++ b/test/extra/good/test-bom-only.ttl @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/test/extra/good/test-boolish-prefix.nt b/test/extra/good/test-boolish-prefix.nt new file mode 100644 index 00000000..d49eeab2 --- /dev/null +++ b/test/extra/good/test-boolish-prefix.nt @@ -0,0 +1,2 @@ +<http://example.org/s> <http://example.org/p> <http://example.org/falseish#o> . +<http://example.org/s> <http://example.org/p> <http://example.org/trueish#o> . diff --git a/test/extra/good/test-boolish-prefix.ttl b/test/extra/good/test-boolish-prefix.ttl new file mode 100644 index 00000000..81ffdf11 --- /dev/null +++ b/test/extra/good/test-boolish-prefix.ttl @@ -0,0 +1,5 @@ +@prefix false.ish: <http://example.org/falseish#> . +@prefix true.ish: <http://example.org/trueish#> . + +<http://example.org/s> <http://example.org/p> false.ish:o . +<http://example.org/s> <http://example.org/p> true.ish:o . diff --git a/test/extra/good/test-decimal-ends-with-dot.nt b/test/extra/good/test-decimal-ends-with-dot.nt new file mode 100644 index 00000000..be0802bc --- /dev/null +++ b/test/extra/good/test-decimal-ends-with-dot.nt @@ -0,0 +1 @@ +<http://example.org/eg#s> <http://example.org/eg#p> "12.3"^^<http://www.w3.org/2001/XMLSchema#decimal> . diff --git a/test/extra/good/test-decimal-ends-with-dot.ttl b/test/extra/good/test-decimal-ends-with-dot.ttl new file mode 100644 index 00000000..a63970d3 --- /dev/null +++ b/test/extra/good/test-decimal-ends-with-dot.ttl @@ -0,0 +1,4 @@ +@prefix eg: <http://example.org/eg#> . + +eg:s + eg:p 12.3. diff --git a/test/extra/good/test-double-ends-with-dot.nt b/test/extra/good/test-double-ends-with-dot.nt new file mode 100644 index 00000000..20e4395e --- /dev/null +++ b/test/extra/good/test-double-ends-with-dot.nt @@ -0,0 +1 @@ +<http://example.org/eg#s> <http://example.org/eg#p> "12.3e4"^^<http://www.w3.org/2001/XMLSchema#double> . diff --git a/test/extra/good/test-double-ends-with-dot.ttl b/test/extra/good/test-double-ends-with-dot.ttl new file mode 100644 index 00000000..4bd17a0b --- /dev/null +++ b/test/extra/good/test-double-ends-with-dot.ttl @@ -0,0 +1,4 @@ +@prefix eg: <http://example.org/eg#> . + +eg:s + eg:p 12.3e4. diff --git a/test/extra/good/test-false-ends-with-dot.nt b/test/extra/good/test-false-ends-with-dot.nt new file mode 100644 index 00000000..3b811813 --- /dev/null +++ b/test/extra/good/test-false-ends-with-dot.nt @@ -0,0 +1 @@ +<http://example.org/eg#s> <http://example.org/eg#p> "false"^^<http://www.w3.org/2001/XMLSchema#boolean> . diff --git a/test/extra/good/test-false-ends-with-dot.ttl b/test/extra/good/test-false-ends-with-dot.ttl new file mode 100644 index 00000000..14e2aa90 --- /dev/null +++ b/test/extra/good/test-false-ends-with-dot.ttl @@ -0,0 +1,4 @@ +@prefix eg: <http://example.org/eg#> . + +eg:s + eg:p false. diff --git a/test/extra/good/test-integer-ends-with-dot.nt b/test/extra/good/test-integer-ends-with-dot.nt new file mode 100644 index 00000000..7d6ff362 --- /dev/null +++ b/test/extra/good/test-integer-ends-with-dot.nt @@ -0,0 +1 @@ +<http://example.org/eg#s> <http://example.org/eg#p> "12"^^<http://www.w3.org/2001/XMLSchema#integer> . diff --git a/test/extra/good/test-integer-ends-with-dot.ttl b/test/extra/good/test-integer-ends-with-dot.ttl new file mode 100644 index 00000000..350ea41d --- /dev/null +++ b/test/extra/good/test-integer-ends-with-dot.ttl @@ -0,0 +1,4 @@ +@prefix eg: <http://example.org/eg#> . + +eg:s + eg:p 12. diff --git a/test/extra/good/test-nq-syntax-all-rules.nq b/test/extra/good/test-nq-syntax-all-rules.nq index a8b80b9a..f9bffe20 100644 --- a/test/extra/good/test-nq-syntax-all-rules.nq +++ b/test/extra/good/test-nq-syntax-all-rules.nq @@ -2,6 +2,6 @@ _:e.u.s <http://example.org/p> _:o. _:e.u.s <http://example.org/p> "o"@en-gb _:g. _:s <http://example.org/p> "ob\t\b\n\r\f\\\"\'\u0025\U00015678ject" <http://example.org/g> . -_:s <http://example.org/p> "߿ࠀက쿿퀀�𐀀" <http://example.org/g> . +_:Σ <http://example.org/p> "߿ࠀက쿿퀀�𐀀" <http://example.org/g> . _:s <http://example.org/p> "o"^^<http://example.org/T> <http://example.org/g> . _:s <http://example.org/p> "o"@en _:g . diff --git a/test/extra/good/test-nt-syntax-all-rules.nt b/test/extra/good/test-nt-syntax-all-rules.nt index ed84f410..c626a702 100644 --- a/test/extra/good/test-nt-syntax-all-rules.nt +++ b/test/extra/good/test-nt-syntax-all-rules.nt @@ -4,4 +4,4 @@ _:s <http://example.org/p> "߿ࠀက쿿퀀�𐀀 _:s <http://example.org/p> "o"^^<http://example.org/T> . _:s <http://example.org/p> "o"@en . _:e.u.s <http://example.org/p> "o"@en-gb . -_:e.u.s <http://example.org/p> _:o. +_:e.u.s <http://example.org/p> _:Ω. diff --git a/test/extra/good/test-rel.nt b/test/extra/good/test-rel.nt index 343ce19c..80f1944c 100644 --- a/test/extra/good/test-rel.nt +++ b/test/extra/good/test-rel.nt @@ -1,6 +1,6 @@ -<http://drobilla.net/sw/serd/test/good/a/b/c> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Thing> . -<http://drobilla.net/sw/serd/test> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Thing> . -<http://drobilla.net/sw/serd/test/good/test-rel.ttl> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Thing> . -<http://drobilla.net/sw/serd/test/good/test-not.ttl> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Thing> . -<http://drobilla.net/sw/serd/test/good/a/b/c> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Thing> . -<http://www.w3.org/> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Thing> . +<http://drobilla.net/sw/serd/test> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Parent> . +<http://drobilla.net/sw/serd/test/good/a/> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Child> . +<http://drobilla.net/sw/serd/test/good/a/b> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/GrandChild> . +<http://drobilla.net/sw/serd/test/good/test-rel.ttl> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/TestFile> . +<http://drobilla.net/sw/serd/test/good/test-not.ttl> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/TestFile> . +<http://www.w3.org/> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/External> . diff --git a/test/extra/good/test-rel.ttl b/test/extra/good/test-rel.ttl index 4752be70..37375283 100644 --- a/test/extra/good/test-rel.ttl +++ b/test/extra/good/test-rel.ttl @@ -1,6 +1,6 @@ -<http://drobilla.net/sw/serd/test/good/a/b/c> a <http://example.org/Thing> . -<http://drobilla.net/sw/serd/test> a <http://example.org/Thing> . -<http://drobilla.net/sw/serd/test/good/test-rel.ttl> a <http://example.org/Thing> . -<http://drobilla.net/sw/serd/test/good/test-not.ttl> a <http://example.org/Thing> . -<a/b/c> a <http://example.org/Thing> . -<http://www.w3.org/> a <http://example.org/Thing> . +<http://drobilla.net/sw/serd/test> a <http://example.org/Parent> . +<http://drobilla.net/sw/serd/test/good/a/> a <http://example.org/Child> . +<a/b> a <http://example.org/GrandChild> . +<http://drobilla.net/sw/serd/test/good/test-rel.ttl> a <http://example.org/TestFile> . +<test-not.ttl> a <http://example.org/TestFile> . +<http://www.w3.org/> a <http://example.org/External> . diff --git a/test/extra/good/test-trig-syntax-all-rules.trig b/test/extra/good/test-trig-syntax-all-rules.trig index 97557b86..c824ffae 100644 --- a/test/extra/good/test-trig-syntax-all-rules.trig +++ b/test/extra/good/test-trig-syntax-all-rules.trig @@ -7,13 +7,13 @@ ""string""\t\b\n\r\f\'\u0025\U00015678""" . eg:s eg:p "߿ࠀက쿿퀀�𐀀" . eg:sub%25ject eg:pr\~d "o"^^eg:T . -eg:sub%25ject eg:pr\~d "o"@en . +eg:s\@bject eg:pr\~d "o"@en . _:e.u.s eg:p "o"@en-gb . _:e.u.s eg:p _:o. _:e.u.s eg:p‿r⁀d 2. _:e.u.s eg:prèd 3 . _:e.u.s eg:pͯ 4.5. -eg:s eg:p 0 , .1 , 2.3 , 4E5, 6e07 . +eg:Σ eg:p 0 , .1 , 2.3 , 4E5, 6e07 . eg:s eg:p .7e8 , .9E0 , 1.e2 , 3.E4 . eg:s eg:p .2E3 , .4e5 , 6.7E8 , 9. [ ] eg:p 0.e1, 2.E3. diff --git a/test/extra/good/test-true-ends-with-dot.nt b/test/extra/good/test-true-ends-with-dot.nt new file mode 100644 index 00000000..9938065b --- /dev/null +++ b/test/extra/good/test-true-ends-with-dot.nt @@ -0,0 +1 @@ +<http://example.org/eg#s> <http://example.org/eg#p> "true"^^<http://www.w3.org/2001/XMLSchema#boolean> . diff --git a/test/extra/good/test-true-ends-with-dot.ttl b/test/extra/good/test-true-ends-with-dot.ttl new file mode 100644 index 00000000..ebd3b6e1 --- /dev/null +++ b/test/extra/good/test-true-ends-with-dot.ttl @@ -0,0 +1,4 @@ +@prefix eg: <http://example.org/eg#> . + +eg:s + eg:p true. diff --git a/test/extra/good/test-ttl-syntax-all-rules.ttl b/test/extra/good/test-ttl-syntax-all-rules.ttl index ead2e8a8..dd4fa315 100644 --- a/test/extra/good/test-ttl-syntax-all-rules.ttl +++ b/test/extra/good/test-ttl-syntax-all-rules.ttl @@ -6,13 +6,13 @@ ""string""\t\b\n\r\f\'\u0025\U00015678""" . eg:s eg:p "߿ࠀက쿿퀀�𐀀" . eg:sub%25ject eg:pr\~d "o"^^eg:T . -eg:sub%25ject eg:pr\~d "o"@en . +eg:s\@bject eg:pr\~d "o"@en . _:e.u.s eg:p "o"@en-gb . _:e.u.s eg:p _:o. _:e.u.s eg:p‿r⁀d 2. _:e.u.s eg:prèd 3 . _:e.u.s eg:pͯ 4.5. -eg:s eg:p 0 , .1 , 2.3 , 4E5, 6e07 . +eg:Σ eg:p 0 , .1 , 2.3 , 4E5, 6e07 . eg:s eg:p .7e8 , .9E0 , 1.e2 , 3.E4 . eg:s eg:p .2E3 , .4e5 , 6.7E8 , 9. [ ] eg:p 0.e1, 2.E3. @@ -20,7 +20,7 @@ eg:s eg:p .2E3 , .4e5 , 6.7E8 , 9. eg:s eg:p [] . [ eg:p1 eg:o1 ; - eg:p2 _:o2 ; + eg:p2 _:β2 ; eg:p3 "o3" ; ] a eg:S . diff --git a/test/extra/prefix/manifest.ttl b/test/extra/prefix/manifest.ttl index 12a0f9ca..cfdd488d 100644 --- a/test/extra/prefix/manifest.ttl +++ b/test/extra/prefix/manifest.ttl @@ -1,7 +1,6 @@ @prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix rdft: <http://www.w3.org/ns/rdftest#> . -@prefix serd: <http://drobilla.net/ns/serd#> . <> a mf:Manifest ; diff --git a/test/extra/pretty/anonymous-comma.ttl b/test/extra/pretty/anonymous-comma.ttl new file mode 100644 index 00000000..b8f2d86e --- /dev/null +++ b/test/extra/pretty/anonymous-comma.ttl @@ -0,0 +1,126 @@ +@prefix eg: <http://example.org/> . + +eg:sa01 + eg:p1 [] , + eg:o1 , + eg:o2 . + +eg:sa02 + eg:p1 [] , + [] . + +eg:sa03 + eg:p1 [] , + [ + eg:p2 eg:o2 + ] . + +eg:sa04 + eg:p1 [] , + () . + +eg:sa05 + eg:p1 [] , + ( + eg:o1 + eg:o2 + ) . + +eg:sa06 + eg:p1 [ + eg:p2 eg:o2 + ] , + eg:o3 , + eg:o4 . + +eg:sa07 + eg:p1 [ + eg:p2 eg:o2 + ] , + [] . + +eg:sa08 + eg:p1 [ + eg:p2 eg:o2 + ] , [ + eg:p3 eg:o3 + ] . + +eg:sa09 + eg:p1 [ + eg:p2 eg:o2 + ] , + () . + +eg:sa10 + eg:p1 [ + eg:p2 eg:o2 + ] , ( + eg:o3 + eg:o4 + ) . + +eg:sl01 + eg:p1 () , + eg:o1 , + eg:o2 . + +eg:sl02 + eg:p1 () , + [] . + +eg:sl03 + eg:p1 () , + [ + eg:p2 eg:o2 + ] . + +eg:sl04 + eg:p1 () , + () . + +eg:sl05 + eg:p1 () , + ( + eg:o1 + eg:o2 + ) . + +eg:sl06 + eg:p1 ( + eg:o1 + eg:o2 + ) , + eg:o3 , + eg:o4 . + +eg:sl07 + eg:p1 ( + eg:o1 + eg:o2 + ) , + [] . + +eg:sl08 + eg:p1 ( + eg:o1 + eg:o2 + ) , [ + eg:p3 eg:o3 + ] . + +eg:sl09 + eg:p1 ( + eg:o1 + eg:o2 + ) , + () . + +eg:sl10 + eg:p1 ( + eg:o1 + eg:o2 + ) , ( + eg:o3 + eg:o4 + ) . diff --git a/test/extra/pretty/base-after-statement.ttl b/test/extra/pretty/base-after-statement.ttl new file mode 100644 index 00000000..7881f693 --- /dev/null +++ b/test/extra/pretty/base-after-statement.ttl @@ -0,0 +1,9 @@ +@base <http://example.org/a/> . + +<s> + <p> <o> . + +@base <http://example.org/b/> . + +<s> + <p> <o> . diff --git a/test/extra/pretty/manifest.ttl b/test/extra/pretty/manifest.ttl index 6422c9e0..9f0c0493 100644 --- a/test/extra/pretty/manifest.ttl +++ b/test/extra/pretty/manifest.ttl @@ -1,17 +1,18 @@ @prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix rdft: <http://www.w3.org/ns/rdftest#> . -@prefix serd: <http://drobilla.net/ns/serd#> . <> a mf:Manifest ; rdfs:comment "Serd pretty-printing test suite" ; mf:entries ( <#abbreviation> + <#anonymous-comma> <#anonymous-in-list-object> <#anonymous-object> <#anonymous-subject> <#anonymous-subject-and-object> + <#base-after-statement> <#datatypes> <#empty-anonymous-object> <#empty-list-object> @@ -31,10 +32,13 @@ <#long-string-escapes> <#long-string-quotes> <#many-objects> + <#many-objects-ending-anon> <#named-graph> <#nested-list-object> <#nested-list-object-with-empty-lists> + <#prefix-after-statement> <#relative-uris> + <#repeated-directives> <#short-string-escapes> <#uri-escapes> <#nested-list-subject> @@ -46,6 +50,12 @@ mf:name "abbreviation" ; mf:result <abbreviation.ttl> . +<#anonymous-comma> + a rdft:TestTurtleEval ; + mf:action <anonymous-comma.ttl> ; + mf:name "anonymous-comma" ; + mf:result <anonymous-comma.ttl> . + <#anonymous-in-list-object> a rdft:TestTurtleEval ; mf:action <anonymous-in-list-object.ttl> ; @@ -70,6 +80,12 @@ mf:name "anonymous-subject-and-object" ; mf:result <anonymous-subject-and-object.ttl> . +<#base-after-statement> + a rdft:TestTurtleEval ; + mf:action <base-after-statement.ttl> ; + mf:name "base-after-statement" ; + mf:result <base-after-statement.ttl> . + <#datatypes> a rdft:TestTurtleEval ; mf:action <datatypes.ttl> ; @@ -184,6 +200,12 @@ mf:name "many-objects" ; mf:result <many-objects.ttl> . +<#many-objects-ending-anon> + a rdft:TestTurtleEval ; + mf:action <many-objects-ending-anon.ttl> ; + mf:name "many-objects-ending-anon" ; + mf:result <many-objects-ending-anon.ttl> . + <#named-graph> a rdft:TestTrigEval ; mf:action <named-graph.trig> ; @@ -208,12 +230,24 @@ mf:name "nested-list-subject" ; mf:result <nested-list-subject.ttl> . +<#prefix-after-statement> + a rdft:TestTurtleEval ; + mf:action <prefix-after-statement.ttl> ; + mf:name "prefix-after-statement" ; + mf:result <prefix-after-statement.ttl> . + <#relative-uris> a rdft:TestTurtleEval ; mf:action <relative-uris.ttl> ; mf:name "relative-uris" ; mf:result <relative-uris.ttl> . +<#repeated-directives> + a rdft:TestTurtleEval ; + mf:action <repeated-directives.ttl> ; + mf:name "repeated-directives" ; + mf:result <repeated-directives.ttl> . + <#short-string-escapes> a rdft:TestTurtleEval ; mf:action <short-string-escapes.ttl> ; diff --git a/test/extra/pretty/many-objects-ending-anon.ttl b/test/extra/pretty/many-objects-ending-anon.ttl new file mode 100644 index 00000000..25b67ed0 --- /dev/null +++ b/test/extra/pretty/many-objects-ending-anon.ttl @@ -0,0 +1,22 @@ +@prefix eg: <http://example.org/> . + +eg:s1 + eg:p1 [ + eg:p11 eg:o11 , + eg:o12 + ] , [ + eg:p11 eg:o11 , + eg:o12 + ] . + +eg:s2 + eg:p2 ( + [ + eg:p21 eg:o21 , + eg:o22 + ] + [ + eg:p21 eg:o21 , + eg:o22 + ] + ) . diff --git a/test/extra/pretty/many-objects.ttl b/test/extra/pretty/many-objects.ttl index 534741dd..e15df0ba 100644 --- a/test/extra/pretty/many-objects.ttl +++ b/test/extra/pretty/many-objects.ttl @@ -1,9 +1,12 @@ @prefix eg: <http://example.org/> . -eg:s +eg:s1 eg:p1 "apple" , "banana" , "cherry" ; eg:p2 "asparagus" , "beet" , "carrot" . + +eg:s2 + eg:p3 "apricot" . diff --git a/test/extra/pretty/prefix-after-statement.ttl b/test/extra/pretty/prefix-after-statement.ttl new file mode 100644 index 00000000..c9481ee7 --- /dev/null +++ b/test/extra/pretty/prefix-after-statement.ttl @@ -0,0 +1,9 @@ +@prefix a: <http://example.org/a/> . + +a:s + a:p a:o . + +@prefix b: <http://example.org/b/> . + +b:s + b:p b:o . diff --git a/test/extra/pretty/repeated-directives.ttl b/test/extra/pretty/repeated-directives.ttl new file mode 100644 index 00000000..c7875c31 --- /dev/null +++ b/test/extra/pretty/repeated-directives.ttl @@ -0,0 +1,17 @@ +@base <http://example.org/base> . +@base <http://example.org/base> . +@base <base> . +@prefix eg: <http://example.org/eg#> . +@prefix eg: <http://example.org/eg#> . +@prefix eg: <eg#> . + +eg:s + eg:p eg:o , + eg:o . + +@prefix eg: <eg#> . +@prefix eg: <http://example.org/eg#> . +@prefix eg: <http://example.org/eg#> . +@base <base> . +@base <http://example.org/base> . +@base <http://example.org/base> . diff --git a/test/extra/qualify/manifest.ttl b/test/extra/qualify/manifest.ttl index 0a2fb698..7387c180 100644 --- a/test/extra/qualify/manifest.ttl +++ b/test/extra/qualify/manifest.ttl @@ -1,7 +1,6 @@ @prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix rdft: <http://www.w3.org/ns/rdftest#> . -@prefix serd: <http://drobilla.net/ns/serd#> . <> a mf:Manifest ; diff --git a/test/extra/root/manifest.ttl b/test/extra/root/manifest.ttl index 90c6a527..1eeb886e 100644 --- a/test/extra/root/manifest.ttl +++ b/test/extra/root/manifest.ttl @@ -1,7 +1,6 @@ @prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix rdft: <http://www.w3.org/ns/rdftest#> . -@prefix serd: <http://drobilla.net/ns/serd#> . <> a mf:Manifest ; diff --git a/test/headers/.clang-tidy b/test/headers/.clang-tidy index 06ede334..45eaf357 100644 --- a/test/headers/.clang-tidy +++ b/test/headers/.clang-tidy @@ -5,10 +5,11 @@ Checks: > *, -altera-*, -llvmlibc-*, - -readability-identifier-length, CheckOptions: - key: readability-function-cognitive-complexity.Threshold value: '0' + - key: readability-identifier-length.IgnoredParameterNames + value: '^[abdirt]$' WarningsAsErrors: '*' HeaderFilterRegex: '.*' FormatStyle: file diff --git a/test/headers/meson.build b/test/headers/meson.build index 6cb14f6e..b9125d2b 100644 --- a/test/headers/meson.build +++ b/test/headers/meson.build @@ -38,6 +38,7 @@ test( files('test_headers.c'), c_args: header_c_suppressions, dependencies: serd_dep, + implicit_include_directories: false, ), suite: 'unit', ) diff --git a/test/lint/meson.build b/test/lint/meson.build new file mode 100644 index 00000000..cca43342 --- /dev/null +++ b/test/lint/meson.build @@ -0,0 +1,133 @@ +# Copyright 2020-2023 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: 0BSD OR ISC + +plot_script_paths = [ + '../../scripts/serd_bench.py', +] + +simple_script_paths = [ + '../../scripts/check_formatting.py', + '../serd_test_util/__init__.py', + '../run_suite.py', + '../test_quiet.py', + '../test_stdin.py', + '../test_write_error.py', +] + +ttl_metadata_file_paths = [ + '../../serd.ttl', + '../extra/abbreviate/manifest.ttl', + '../extra/bad/manifest.ttl', + '../extra/big/manifest.ttl', + '../extra/full/manifest.ttl', + '../extra/good/manifest.ttl', + '../extra/lax/manifest.ttl', + '../extra/perfect/manifest.ttl', + '../extra/prefix/manifest.ttl', + '../extra/pretty/manifest.ttl', + '../extra/qualify/manifest.ttl', + '../extra/root/manifest.ttl', +] + +plot_scripts = files(plot_script_paths) +simple_scripts = files(simple_script_paths) +python_script_paths = simple_script_paths + plot_script_paths +python_scripts = plot_scripts + simple_scripts + +all_sources = sources + unit_test_sources + files('../../src/serdi.c') + +# Check licensing metadata +reuse = find_program('reuse', required: false) +if reuse.found() + test( + 'REUSE', + reuse, + args: ['--root', serd_src_root, 'lint'], + suite: 'data', + ) +endif + +# Check code formatting +clang_format = find_program('clang-format', required: false) +if clang_format.found() + test( + 'format', + clang_format, + args: ['--Werror', '--dry-run'] + c_headers + all_sources, + suite: 'code', + ) +endif + +# Check script formatting +black = find_program('black', required: false) +if black.found() + black_opts = ['--check', '-q', '-l', '79'] + foreach script_path : python_script_paths + script = files(script_path) + name = 'black_' + script_path.substring(3).underscorify() + test(name, black, args: black_opts + [script], suite: 'scripts') + endforeach +endif + +# Check scripts for errors with flake8 +flake8 = find_program('flake8', required: false) +if flake8.found() + test('flake8', flake8, args: python_scripts, suite: 'scripts') +endif + +# Check scripts for errors with pylint +pylint = find_program('pylint', required: false) +if pylint.found() + pymod = import('python') + plot_py = pymod.find_installation( + 'python3', + modules: ['matplotlib'], + required: false, + ) + + pylint_args = ['--disable', 'bad-option-value'] + simple_scripts + if plot_py.found() + pylint_args += plot_scripts + endif + + test('pylint', pylint, args: pylint_args, suite: 'scripts') +endif + +# Check Turtle formatting with serdi +if is_variable('serdi') + foreach ttl_file_path : ttl_metadata_file_paths + test( + ttl_file_path.substring(3).underscorify(), + check_formatting_py, + args: [files(ttl_file_path), serdi, '-o', 'turtle'], + suite: 'data', + ) + endforeach +endif + +if not meson.is_subproject() + # Check release metadata + autoship = find_program('autoship', required: false) + if autoship.found() + test('autoship', autoship, args: ['test', serd_src_root], suite: 'data') + endif + + # Check code with cppcheck + cppcheck = find_program('cppcheck', required: false) + if cppcheck.found() + compdb_path = join_paths(serd_build_root, 'compile_commands.json') + suppress_path = join_paths(serd_src_root, '.suppress.cppcheck') + test( + 'cppcheck', + cppcheck, + args: [ + '--enable=warning,style,performance,portability', + '--error-exitcode=1', + '--project=' + compdb_path, + '--suppressions-list=' + suppress_path, + '-q', + ], + suite: 'code', + ) + endif +endif diff --git a/test/meson.build b/test/meson.build index 4d770304..d39808d9 100644 --- a/test/meson.build +++ b/test/meson.build @@ -37,6 +37,7 @@ foreach name : unit_test_names source, c_args: c_suppressions, dependencies: serd_dep, + implicit_include_directories: false, ), suite: 'unit', ) @@ -212,6 +213,17 @@ test_suites = { '--', '-b', ], + 'eof': [ + files('extra/eof/manifest.ttl'), + ns_serdtest + 'eof/', + ], + 'eof_lax': [ + '--lax', + files('extra/eof/manifest.ttl'), + ns_serdtest + 'eof/', + '--', + '-l' + ], 'fast': [ files('extra/good/manifest.ttl'), ns_serdtest + 'good/', @@ -298,133 +310,6 @@ endif # Lint # ######## -plot_script_paths = [ - '../scripts/serd_bench.py', -] - -simple_script_paths = [ - '../scripts/check_formatting.py', - 'serd_test_util/__init__.py', - 'run_suite.py', - 'test_quiet.py', - 'test_stdin.py', - 'test_write_error.py', -] - -ttl_metadata_file_paths = [ - '../serd.ttl', - 'extra/abbreviate/manifest.ttl', - 'extra/bad/manifest.ttl', - 'extra/big/manifest.ttl', - 'extra/full/manifest.ttl', - 'extra/good/manifest.ttl', - 'extra/lax/manifest.ttl', - 'extra/perfect/manifest.ttl', - 'extra/prefix/manifest.ttl', - 'extra/pretty/manifest.ttl', - 'extra/qualify/manifest.ttl', - 'extra/root/manifest.ttl', -] - -plot_scripts = files(plot_script_paths) -simple_scripts = files(simple_script_paths) -python_script_paths = simple_script_paths + plot_script_paths -python_scripts = plot_scripts + simple_scripts - if get_option('lint') - all_sources = sources + unit_test_sources + files('../src/serdi.c') - - if not meson.is_subproject() - # Check release metadata - autoship = find_program('autoship', required: false) - if autoship.found() - test('autoship', autoship, args: ['test', serd_src_root], suite: 'data') - endif - - # Check code with cppcheck - cppcheck = find_program('cppcheck', required: false) - if cppcheck.found() - compdb_path = join_paths(serd_build_root, 'compile_commands.json') - suppress_path = join_paths(serd_src_root, '.suppress.cppcheck') - test( - 'cppcheck', - cppcheck, - args: [ - '--enable=warning,style,performance,portability', - '--error-exitcode=1', - '--project=' + compdb_path, - '--suppressions-list=' + suppress_path, - '-q', - ], - suite: 'code', - ) - endif - endif - - # Check licensing metadata - reuse = find_program('reuse', required: false) - if reuse.found() - test( - 'REUSE', - reuse, - args: ['--root', serd_src_root, 'lint'], - suite: 'data', - ) - endif - - # Check code formatting - clang_format = find_program('clang-format', required: false) - if clang_format.found() - test( - 'format', - clang_format, - args: ['--Werror', '--dry-run'] + c_headers + all_sources, - suite: 'code', - ) - endif - - # Check script formatting - black = find_program('black', required: false) - if black.found() - black_opts = ['--check', '-q', '-l', '79'] - foreach script_path : python_script_paths - script = files(script_path) - name = script_path.underscorify() - test(name, black, args: black_opts + [script], suite: 'scripts') - endforeach - endif - - # Check scripts for errors with flake8 - flake8 = find_program('flake8', required: false) - if flake8.found() - test('flake8', flake8, args: python_scripts, suite: 'scripts') - endif - - # Check scripts for errors with pylint - pylint = find_program('pylint', required: false) - if pylint.found() - pymod = import('python') - plot_py = pymod.find_installation( - 'python3', - modules: ['matplotlib'], - required: false, - ) - - pylint_args = ['--disable', 'bad-option-value'] + simple_scripts - if plot_py.found() - pylint_args += plot_scripts - endif - - test('pylint', pylint, args: pylint_args, suite: 'scripts') - endif - - # Check Turtle formatting with serdi - foreach ttl_file_path : ttl_metadata_file_paths - test( - ttl_file_path.underscorify(), - check_formatting_py, - args: [files(ttl_file_path), serdi, '-o', 'turtle'], - suite: 'data', - ) - endforeach + subdir('lint') endif diff --git a/test/run_suite.py b/test/run_suite.py index 2e93502f..e7f1c600 100755 --- a/test/run_suite.py +++ b/test/run_suite.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright 2022-2023 David Robillard <d@drobilla.net> +# Copyright 2022-2025 David Robillard <d@drobilla.net> # SPDX-License-Identifier: ISC """Run a "simple" one-pass RDF-based test suite for serd.""" @@ -43,7 +43,7 @@ def run_eval_test(base_uri, command, in_path, good_path, out_path): syntax = util.syntax_from_path(out_path) command = command + ["-o", syntax, in_path, base_uri] - with subprocess.Popen(command, stdout=PIPE, encoding="utf-8") as proc: + with subprocess.Popen(command, encoding="utf-8", stdout=PIPE) as proc: out = list(proc.stdout) with open(good_path, "r", encoding="utf-8") as good: @@ -65,12 +65,18 @@ def run_negative_test(base_uri, command, in_path): raise RuntimeError("Input file missing: " + in_path) command = command + [in_path, base_uri] - proc = subprocess.run(command, check=False, stderr=PIPE, stdout=DEVNULL) + proc = subprocess.run( + command, check=False, encoding="utf-8", stderr=PIPE, stdout=DEVNULL + ) if proc.returncode == 0: util.error("Unexpected successful return: " + in_path) return False + if proc.returncode < 0: + util.error("Command seems to have crashed: " + in_path) + return False + if len(proc.stderr) == 0: util.error("Command failed with no error output: " + in_path) return False diff --git a/test/serd_test_util/__init__.py b/test/serd_test_util/__init__.py index ad417762..c38100b5 100644 --- a/test/serd_test_util/__init__.py +++ b/test/serd_test_util/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright 2022-2023 David Robillard <d@drobilla.net> +# Copyright 2022-2025 David Robillard <d@drobilla.net> # SPDX-License-Identifier: ISC """Utilities for data-driven tests.""" @@ -157,12 +157,14 @@ def load_rdf(filename, base_uri, command_prefix): cmd = command_prefix + [filename, base_uri] proc = subprocess.run( - cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True + cmd, + encoding="utf-8", + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + check=True, ) for line in proc.stdout.splitlines(): - matches = re.match( - r"<([^ ]*)> <([^ ]*)> <([^ ]*)> \.", line.decode("utf-8") - ) + matches = re.match(r"<([^ ]*)> <([^ ]*)> <([^ ]*)> \.", line) if matches: s, p, o = (matches.group(1), matches.group(2), matches.group(3)) if s not in model: diff --git a/test/test_env.c b/test/test_env.c index bd55e47e..73c84a5e 100644 --- a/test/test_env.c +++ b/test/test_env.c @@ -3,6 +3,8 @@ #undef NDEBUG +#include "expect_string.h" + #include <serd/serd.h> #include <assert.h> @@ -51,7 +53,7 @@ test_env(void) assert(serd_node_equals(&xnode, &SERD_NODE_NULL)); SerdNode xu = serd_env_expand_node(env, &u); - assert(!strcmp((const char*)xu.buf, NS_EG "foo")); + assert(expect_string((const char*)xu.buf, NS_EG "foo")); serd_node_free(&xu); SerdNode badpre = serd_node_from_string(SERD_CURIE, USTR("hm:what")); @@ -59,7 +61,7 @@ test_env(void) assert(serd_node_equals(&xbadpre, &SERD_NODE_NULL)); SerdNode xc = serd_env_expand_node(env, &c); - assert(!strcmp((const char*)xc.buf, NS_EG "b")); + assert(expect_string((const char*)xc.buf, NS_EG "b")); serd_node_free(&xc); assert(serd_env_set_prefix(env, &SERD_NODE_NULL, &SERD_NODE_NULL)); diff --git a/test/test_node.c b/test/test_node.c index eb432c40..4d5cf1c2 100644 --- a/test/test_node.c +++ b/test/test_node.c @@ -3,6 +3,8 @@ #undef NDEBUG +#include "expect_string.h" + #include <serd/serd.h> #include <assert.h> @@ -71,8 +73,8 @@ test_double_to_node(void) -16.00001, 5.000000005, 0.0000000001, - NAN, - INFINITY}; + (double)NAN, + (double)INFINITY}; const char* dbl_test_strs[] = {"0.0", "9.0", @@ -88,7 +90,7 @@ test_double_to_node(void) for (size_t i = 0; i < sizeof(dbl_test_nums) / sizeof(double); ++i) { SerdNode node = serd_node_new_decimal(dbl_test_nums[i], 8); const bool pass = (node.buf && dbl_test_strs[i]) - ? !strcmp((const char*)node.buf, dbl_test_strs[i]) + ? expect_string((const char*)node.buf, dbl_test_strs[i]) : ((const char*)node.buf == dbl_test_strs[i]); assert(pass); const size_t len = node.buf ? strlen((const char*)node.buf) : 0; @@ -109,7 +111,7 @@ test_integer_to_node(void) for (size_t i = 0; i < N_TEST_NUMS; ++i) { SerdNode node = serd_node_new_integer(int_test_nums[i]); - assert(!strcmp((const char*)node.buf, (const char*)int_test_strs[i])); + assert(expect_string((const char*)node.buf, (const char*)int_test_strs[i])); const size_t len = strlen((const char*)node.buf); assert(node.n_bytes == len && node.n_chars == len); serd_node_free(&node); @@ -123,6 +125,7 @@ test_blob_to_node(void) { for (size_t size = 1; size < 256; ++size) { uint8_t* const data = (uint8_t*)malloc(size); + assert(data); for (size_t i = 0; i < size; ++i) { data[i] = (uint8_t)((size + i) % 256); } @@ -225,7 +228,7 @@ test_node_from_string(void) assert(node.n_bytes == 6 && node.n_chars == 6 && node.flags == SERD_HAS_QUOTE && - !strcmp((const char*)node.buf, "hello\"")); + expect_string((const char*)node.buf, "hello\"")); node = serd_node_from_string(SERD_URI, NULL); assert(serd_node_equals(&node, &SERD_NODE_NULL)); diff --git a/test/test_quiet.py b/test/test_quiet.py index 676284bb..ff53e26e 100755 --- a/test/test_quiet.py +++ b/test/test_quiet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright 2022 David Robillard <d@drobilla.net> +# Copyright 2022-2025 David Robillard <d@drobilla.net> # SPDX-License-Identifier: ISC """Test quiet command-line option.""" @@ -13,7 +13,11 @@ import serd_test_util as util args = util.wrapper_args(__doc__, True) command = shlex.split(args.wrapper) + [args.serdi, "-q", args.input] proc = subprocess.run( - command, check=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE + command, + encoding="utf-8", + check=False, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, ) assert proc.returncode != 0 diff --git a/test/test_reader.c b/test/test_reader.c index e1ca0934..610a1fdb 100644 --- a/test/test_reader.c +++ b/test/test_reader.c @@ -82,6 +82,22 @@ end_sink(void* const handle, const SerdNode* const node) } static void +test_null_callbacks(void) +{ + SerdReader* const reader = + serd_reader_new(SERD_TURTLE, NULL, NULL, NULL, NULL, NULL, NULL); + + assert(reader); + assert(!serd_reader_get_handle(reader)); + + const SerdStatus st = + serd_reader_read_string(reader, USTR("_:s <http://example.org/p> _:o .")); + + assert(!st); + serd_reader_free(reader); +} + +static void test_read_string(void) { ReaderTest rt = {0, 0, 0, 0}; @@ -217,6 +233,7 @@ test_read_nquads_chunks(const char* const path) static const char null = 0; FILE* const f = fopen(path, "w+b"); + assert(f); // Write two statements, a null separator, then another statement @@ -303,6 +320,7 @@ test_read_turtle_chunks(const char* const path) static const char null = 0; FILE* const f = fopen(path, "w+b"); + assert(f); // Write two statements separated by null characters fprintf(f, "@base <http://example.org/base/> .\n"); @@ -406,6 +424,7 @@ main(void) const size_t nq_name_len = strlen(nq_name); const size_t path_len = tmp_len + 1 + ttl_name_len; char* const path = (char*)calloc(path_len + 1, 1); + assert(path); memcpy(path, tmp, tmp_len + 1); path[tmp_len] = '/'; @@ -416,6 +435,7 @@ main(void) memcpy(path + tmp_len + 1, ttl_name, ttl_name_len + 1); test_read_turtle_chunks(path); + test_null_callbacks(); test_read_string(); test_read_eof_file(path); test_read_eof_by_byte(); diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c index bebda449..3e371d1c 100644 --- a/test/test_reader_writer.c +++ b/test/test_reader_writer.c @@ -1,8 +1,10 @@ -// Copyright 2011-2024 David Robillard <d@drobilla.net> +// Copyright 2011-2025 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC #undef NDEBUG +#include "expect_string.h" + #include <serd/serd.h> #ifdef _WIN32 @@ -103,42 +105,58 @@ quiet_error_sink(void* const handle, const SerdError* const e) } static void -test_write_errors(void) +check_write_error_offset(const SerdSyntax syntax, + const size_t offset, + const SerdStatus expected_status) { - ErrorContext ctx = {0U, 0U}; + ErrorContext ctx = {0U, offset}; const SerdStyle style = (SerdStyle)(SERD_STYLE_STRICT | SERD_STYLE_CURIED); + SerdEnv* const env = serd_env_new(NULL); + assert(env); + + SerdWriter* const writer = + serd_writer_new(syntax, style, env, NULL, faulty_sink, &ctx); + assert(writer); + + SerdReader* const reader = + serd_reader_new(SERD_TRIG, + writer, + NULL, + (SerdBaseSink)serd_writer_set_base_uri, + (SerdPrefixSink)serd_writer_set_prefix, + (SerdStatementSink)serd_writer_write_statement, + (SerdEndSink)serd_writer_end_anon); + assert(reader); + + serd_writer_set_error_sink(writer, quiet_error_sink, NULL); + serd_reader_set_error_sink(reader, quiet_error_sink, NULL); + + const SerdStatus rst = serd_reader_read_string(reader, USTR(doc_string)); + const SerdStatus wst = serd_writer_finish(writer); + + serd_reader_free(reader); + serd_writer_free(writer); + serd_env_free(env); - const size_t max_offsets[] = {0, 462, 1911, 2003, 462}; + const SerdStatus st = rst ? rst : wst; + assert(st == expected_status); +} + +static void +test_write_errors(void) +{ + // Syntax-keyed array of output document sizes + static const size_t max_offsets[] = {0, 443, 1911, 2003, 457}; - // Test errors at different offsets to hit different code paths for (unsigned s = 1; s <= (unsigned)SERD_TRIG; ++s) { const SerdSyntax syntax = (SerdSyntax)s; + + // Check successfully writing with enough space + check_write_error_offset(syntax, max_offsets[s], SERD_SUCCESS); + + // Check write error at every offset in the output for (size_t o = 0; o < max_offsets[s]; ++o) { - ctx.n_written = 0; - ctx.error_offset = o; - - SerdEnv* const env = serd_env_new(NULL); - SerdWriter* const writer = - serd_writer_new(syntax, style, env, NULL, faulty_sink, &ctx); - - SerdReader* const reader = - serd_reader_new(SERD_TRIG, - writer, - NULL, - (SerdBaseSink)serd_writer_set_base_uri, - (SerdPrefixSink)serd_writer_set_prefix, - (SerdStatementSink)serd_writer_write_statement, - (SerdEndSink)serd_writer_end_anon); - - serd_reader_set_error_sink(reader, quiet_error_sink, NULL); - serd_writer_set_error_sink(writer, quiet_error_sink, NULL); - - const SerdStatus st = serd_reader_read_string(reader, USTR(doc_string)); - assert(st == SERD_ERR_BAD_WRITE); - - serd_reader_free(reader); - serd_writer_free(writer); - serd_env_free(env); + check_write_error_offset(syntax, o, SERD_ERR_BAD_WRITE); } } } @@ -146,10 +164,12 @@ test_write_errors(void) static void test_writer(const char* const path) { - FILE* fd = fopen(path, "wb"); - SerdEnv* env = serd_env_new(NULL); + FILE* const fd = fopen(path, "wb"); assert(fd); + SerdEnv* const env = serd_env_new(NULL); + assert(env); + SerdWriter* writer = serd_writer_new(SERD_TURTLE, (SerdStyle)0, env, NULL, serd_file_sink, fd); assert(writer); @@ -166,15 +186,19 @@ test_writer(const char* const path) const uint8_t buf[] = {0x80, 0, 0, 0, 0}; - SerdNode s = serd_node_from_string(SERD_URI, USTR("")); - SerdNode p = serd_node_from_string(SERD_URI, USTR("http://example.org/pred")); - SerdNode o = serd_node_from_string(SERD_LITERAL, buf); + const SerdNode s = serd_node_from_string(SERD_URI, USTR("")); + const SerdNode p = + serd_node_from_string(SERD_URI, USTR("http://example.org/pred")); + const SerdNode o = serd_node_from_string(SERD_LITERAL, buf); + const SerdNode t = serd_node_from_string(SERD_URI, USTR("urn:Type")); + const SerdNode l = serd_node_from_string(SERD_LITERAL, USTR("en")); - // Write 3 invalid statements (should write nothing) + // Attempt to write invalid statements (should write nothing) const SerdNode* junk[][5] = {{&s, &p, &SERD_NODE_NULL, NULL, NULL}, {&s, &SERD_NODE_NULL, &o, NULL, NULL}, {&SERD_NODE_NULL, &p, &o, NULL, NULL}, {&s, &o, &o, NULL, NULL}, + {&s, &o, &o, &t, &l}, {&o, &p, &o, NULL, NULL}, {&s, &p, &SERD_NODE_NULL, NULL, NULL}}; for (size_t i = 0; i < sizeof(junk) / (sizeof(SerdNode*) * 5); ++i) { @@ -188,13 +212,12 @@ test_writer(const char* const path) junk[i][4])); } - const SerdNode t = serd_node_from_string(SERD_URI, USTR("urn:Type")); - const SerdNode l = serd_node_from_string(SERD_LITERAL, USTR("en")); + // Write some valid statements const SerdNode* good[][5] = {{&s, &p, &o, NULL, NULL}, + {&s, &p, &lit, NULL, NULL}, {&s, &p, &o, &SERD_NODE_NULL, &SERD_NODE_NULL}, {&s, &p, &o, &t, NULL}, {&s, &p, &o, NULL, &l}, - {&s, &p, &o, &t, &l}, {&s, &p, &o, &t, &SERD_NODE_NULL}, {&s, &p, &o, &SERD_NODE_NULL, &l}, {&s, &p, &o, NULL, &SERD_NODE_NULL}, @@ -220,46 +243,7 @@ test_writer(const char* const path) assert(!serd_writer_write_statement( writer, 0, NULL, &s, &p, &bad_uri, NULL, NULL)); - // Write 1 valid statement - o = serd_node_from_string(SERD_LITERAL, USTR("hello")); - assert(!serd_writer_write_statement(writer, 0, NULL, &s, &p, &o, NULL, NULL)); - - serd_writer_free(writer); - - // Test chunk sink - SerdChunk chunk = {NULL, 0}; - writer = serd_writer_new( - SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk); - - o = serd_node_from_string(SERD_URI, USTR("http://example.org/base")); - assert(!serd_writer_set_base_uri(writer, &o)); - - serd_writer_free(writer); - uint8_t* out = serd_chunk_sink_finish(&chunk); - - assert(!strcmp((const char*)out, "@base <http://example.org/base> .\n")); - serd_free(out); - - // Test writing empty node - SerdNode nothing = serd_node_from_string(SERD_NOTHING, USTR("")); - - chunk.buf = NULL; - chunk.len = 0; - writer = serd_writer_new( - SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk); - - assert(!serd_writer_write_statement( - writer, 0, NULL, &s, &p, ¬hing, NULL, NULL)); - - assert( - !strncmp((const char*)chunk.buf, "<>\n\t<http://example.org/pred> ", 30)); - serd_writer_free(writer); - out = serd_chunk_sink_finish(&chunk); - - assert(!strcmp((const char*)out, "<>\n\t<http://example.org/pred> .\n")); - serd_free(out); - serd_env_free(env); assert(!fclose(fd)); } @@ -267,7 +251,9 @@ test_writer(const char* const path) static void test_reader(const char* const path) { - ReaderTest* rt = (ReaderTest*)calloc(1, sizeof(ReaderTest)); + ReaderTest* const rt = (ReaderTest*)calloc(1, sizeof(ReaderTest)); + assert(rt); + SerdReader* reader = serd_reader_new( SERD_TURTLE, rt, free, NULL, NULL, test_statement_sink, NULL); @@ -295,9 +281,9 @@ test_reader(const char* const path) const SerdStatus st = serd_reader_read_file(reader, USTR(path)); assert(!st); - assert(rt->n_statement == 13); + assert(rt->n_statement == 12); assert(rt->graph && rt->graph->buf && - !strcmp((const char*)rt->graph->buf, "http://example.org/")); + expect_string((const char*)rt->graph->buf, "http://example.org/")); assert(serd_reader_read_string(reader, USTR("This isn't Turtle at all."))); @@ -320,6 +306,7 @@ main(void) const size_t ttl_name_len = strlen(ttl_name); const size_t path_len = tmp_len + 1 + ttl_name_len; char* const path = (char*)calloc(path_len + 1, 1); + assert(path); memcpy(path, tmp, tmp_len + 1); path[tmp_len] = '/'; diff --git a/test/test_string.c b/test/test_string.c index 86b5d19e..83d42215 100644 --- a/test/test_string.c +++ b/test/test_string.c @@ -1,8 +1,10 @@ -// Copyright 2011-2020 David Robillard <d@drobilla.net> +// Copyright 2011-2025 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC #undef NDEBUG +#include "expect_string.h" + #include <serd/serd.h> #include <assert.h> @@ -10,6 +12,13 @@ #include <string.h> static void +test_expect_string(void) +{ + assert(expect_string("match", "match")); + assert(!expect_string("intentional", "failure")); +} + +static void check_strlen(const char* const str, const size_t expected_n_bytes, const size_t expected_n_chars, @@ -41,19 +50,20 @@ static void test_strerror(void) { const uint8_t* msg = serd_strerror(SERD_SUCCESS); - assert(!strcmp((const char*)msg, "Success")); + assert(expect_string((const char*)msg, "Success")); for (int i = SERD_FAILURE; i <= SERD_ERR_BAD_TEXT; ++i) { msg = serd_strerror((SerdStatus)i); assert(strcmp((const char*)msg, "Success")); } msg = serd_strerror((SerdStatus)-1); - assert(!strcmp((const char*)msg, "Unknown error")); + assert(expect_string((const char*)msg, "Unknown error")); } int main(void) { + test_expect_string(); test_strlen(); test_strerror(); return 0; diff --git a/test/test_uri.c b/test/test_uri.c index 5177359c..feb2a8f6 100644 --- a/test/test_uri.c +++ b/test/test_uri.c @@ -1,8 +1,10 @@ -// Copyright 2011-2023 David Robillard <d@drobilla.net> +// Copyright 2011-2025 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC #undef NDEBUG +#include "expect_string.h" + #include <serd/serd.h> #include <assert.h> @@ -52,10 +54,10 @@ check_file_uri(const char* const hostname, uint8_t* out_path = serd_file_uri_parse((const uint8_t*)node.buf, &out_hostname); - assert(!strcmp((const char*)node.buf, expected_uri)); + assert(expect_string((const char*)node.buf, expected_uri)); assert((hostname && out_hostname) || (!hostname && !out_hostname)); - assert(!hostname || !strcmp(hostname, (const char*)out_hostname)); - assert(!strcmp((const char*)out_path, (const char*)expected_path)); + assert(!hostname || expect_string(hostname, (const char*)out_hostname)); + assert(expect_string((const char*)out_path, (const char*)expected_path)); serd_free(out_path); serd_free(out_hostname); @@ -68,40 +70,26 @@ check_file_uri(const char* const hostname, #endif static void -test_uri_to_path(void) +check_uri_to_path(const char* const uri, const char* const expected_path) { - assert(!strcmp( - (const char*)serd_uri_to_path((const uint8_t*)"file:///home/user/foo.ttl"), - "/home/user/foo.ttl")); - - assert(!strcmp((const char*)serd_uri_to_path( - (const uint8_t*)"file://localhost/home/user/foo.ttl"), - "/home/user/foo.ttl")); - - assert(!serd_uri_to_path((const uint8_t*)"file:illegal/file/uri")); - - assert(!strcmp( - (const char*)serd_uri_to_path((const uint8_t*)"file:///c:/awful/system"), - "c:/awful/system")); - - assert(!strcmp( - (const char*)serd_uri_to_path((const uint8_t*)"file:///c:awful/system"), - "/c:awful/system")); - - assert(!strcmp((const char*)serd_uri_to_path((const uint8_t*)"file:///0/1"), - "/0/1")); - - assert( - !strcmp((const char*)serd_uri_to_path((const uint8_t*)"C:\\Windows\\Sucks"), - "C:\\Windows\\Sucks")); - - assert( - !strcmp((const char*)serd_uri_to_path((const uint8_t*)"C|/Windows/Sucks"), - "C|/Windows/Sucks")); + const uint8_t* const path = serd_uri_to_path((const uint8_t*)uri); + assert(expect_string((const char*)path, expected_path)); +} +static void +test_uri_to_path(void) +{ + assert(!serd_uri_to_path((const uint8_t*)"file:invalid/file/uri")); 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")); + check_uri_to_path("file:///home/user/foo.ttl", "/home/user/foo.ttl"); + check_uri_to_path("file://localhost/home/user/foo.ttl", "/home/user/foo.ttl"); + check_uri_to_path("file:///c:/awful/system", "c:/awful/system"); + check_uri_to_path("file:///c:awful/system", "/c:awful/system"); + check_uri_to_path("file:///0/1", "/0/1"); + check_uri_to_path("C:\\Windows\\Sucks", "C:\\Windows\\Sucks"); + check_uri_to_path("C|/Windows/Sucks", "C|/Windows/Sucks"); + check_uri_to_path("rel", "rel"); } #if defined(__GNUC__) @@ -171,17 +159,17 @@ test_uri_parsing(void) // 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")); + assert(expect_string((const char*)hosted, "/path")); serd_free(hosted); // Test tolerance of parsing junk URI escapes uint8_t* const junk1 = serd_file_uri_parse(USTR("file:///foo/%0Xbar"), NULL); - assert(!strcmp((const char*)junk1, "/foo/bar")); + assert(expect_string((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")); + assert(expect_string((const char*)junk2, "/foo/bar")); serd_free(junk2); } @@ -197,16 +185,16 @@ test_uri_from_string(void) SerdNode nil = serd_node_new_uri_from_string(NULL, &base_uri, NULL); SerdNode nil2 = serd_node_new_uri_from_string(USTR(""), &base_uri, NULL); assert(nil.type == SERD_URI); - assert(!strcmp((const char*)nil.buf, (const char*)base.buf)); + assert(expect_string((const char*)nil.buf, (const char*)base.buf)); assert(nil2.type == SERD_URI); - assert(!strcmp((const char*)nil2.buf, (const char*)base.buf)); + assert(expect_string((const char*)nil2.buf, (const char*)base.buf)); serd_node_free(&nil); serd_node_free(&nil2); serd_node_free(&base); } -static inline bool +static bool chunk_equals(const SerdChunk* const a, const SerdChunk* const b) { return (!a->len && !b->len && !a->buf && !b->buf) || @@ -246,7 +234,7 @@ check_relative_uri(const char* const uri_string, result_node = serd_node_new_relative_uri(&uri, &base, NULL, &result); } - assert(!strcmp((const char*)result_node.buf, expected_string)); + assert(expect_string((const char*)result_node.buf, expected_string)); SerdURI expected = SERD_URI_NULL; assert(!serd_uri_parse(USTR(expected_string), &expected)); @@ -367,7 +355,7 @@ test_relative_uri(void) 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")); + assert(expect_string((const char*)result_node.buf, "path")); serd_node_free(&result_node); } diff --git a/test/test_write_error.py b/test/test_write_error.py index b62f981a..93b0249a 100755 --- a/test/test_write_error.py +++ b/test/test_write_error.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright 2022-2023 David Robillard <d@drobilla.net> +# Copyright 2022-2025 David Robillard <d@drobilla.net> # SPDX-License-Identifier: ISC """Test errors writing to a file.""" @@ -18,11 +18,15 @@ command = shlex.split(args.wrapper) + [args.serdi, args.input] if os.path.exists("/dev/full"): with open("/dev/full", "w", encoding="utf-8") as out: proc = subprocess.run( - command, check=False, stdout=out, stderr=subprocess.PIPE + command, + encoding="utf-8", + check=False, + stdout=out, + stderr=subprocess.PIPE, ) assert proc.returncode != 0 - assert "error" in proc.stderr.decode("utf-8") + assert "error" in proc.stderr else: sys.stderr.write("warning: /dev/full not present, skipping test") diff --git a/test/test_writer.c b/test/test_writer.c index 28c8e117..cbf89f09 100644 --- a/test/test_writer.c +++ b/test/test_writer.c @@ -1,8 +1,10 @@ -// Copyright 2011-2023 David Robillard <d@drobilla.net> +// Copyright 2011-2025 David Robillard <d@drobilla.net> // SPDX-License-Identifier: ISC #undef NDEBUG +#include "expect_string.h" + #include <serd/serd.h> #include <assert.h> @@ -21,7 +23,6 @@ test_write_long_literal(void) SerdChunk chunk = {NULL, 0}; SerdWriter* writer = serd_writer_new( SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk); - assert(writer); SerdNode s = serd_node_from_string(SERD_URI, USTR(NS_EG "s")); @@ -30,18 +31,18 @@ test_write_long_literal(void) serd_node_from_string(SERD_LITERAL, USTR("hello \"\"\"world\"\"\"!")); assert(!serd_writer_write_statement(writer, 0, NULL, &s, &p, &o, NULL, NULL)); - - serd_writer_free(writer); - serd_env_free(env); - - uint8_t* out = serd_chunk_sink_finish(&chunk); + assert(!serd_writer_finish(writer)); static const char* const expected = "<http://example.org/s>\n" "\t<http://example.org/p> \"\"\"hello \"\"\\\"world\"\"\\\"!\"\"\" .\n"; - assert(!strcmp((char*)out, expected)); + uint8_t* const out = serd_chunk_sink_finish(&chunk); + assert(expect_string((char*)out, expected)); serd_free(out); + + serd_writer_free(writer); + serd_env_free(env); } static void @@ -51,7 +52,6 @@ test_write_nested_anon(void) SerdChunk chunk = {NULL, 0}; SerdWriter* writer = serd_writer_new( SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk); - assert(writer); SerdNode s0 = serd_node_from_string(SERD_URI, USTR(NS_EG "s0")); @@ -96,11 +96,7 @@ test_write_nested_anon(void) writer, SERD_ANON_CONT, NULL, &b0, &p4, &o4, NULL, NULL)); assert(!serd_writer_end_anon(writer, &b0)); - - serd_writer_free(writer); - serd_env_free(env); - - uint8_t* const out = serd_chunk_sink_finish(&chunk); + assert(!serd_writer_finish(writer)); static const char* const expected = "<http://example.org/s0>\n" @@ -112,8 +108,12 @@ test_write_nested_anon(void) "\t\t<http://example.org/p4> <http://example.org/o4>\n" "\t] .\n"; - assert(!strcmp((char*)out, expected)); + uint8_t* const out = serd_chunk_sink_finish(&chunk); + assert(expect_string((char*)out, expected)); serd_free(out); + + serd_writer_free(writer); + serd_env_free(env); } static size_t @@ -132,6 +132,7 @@ test_writer_cleanup(void) SerdEnv* env = serd_env_new(NULL); SerdWriter* writer = serd_writer_new(SERD_TURTLE, (SerdStyle)0U, env, NULL, null_sink, NULL); + assert(writer); SerdNode s = serd_node_from_string(SERD_URI, USTR(NS_EG "s")); SerdNode p = serd_node_from_string(SERD_URI, USTR(NS_EG "p")); @@ -185,6 +186,7 @@ test_write_bad_anon_stack(void) SerdEnv* env = serd_env_new(NULL); SerdWriter* writer = serd_writer_new(SERD_TURTLE, (SerdStyle)0U, env, NULL, null_sink, NULL); + assert(writer); SerdNode s = serd_node_from_string(SERD_URI, USTR(NS_EG "s")); SerdNode p = serd_node_from_string(SERD_URI, USTR(NS_EG "p")); @@ -212,14 +214,9 @@ test_write_bad_anon_stack(void) static void test_strict_write(void) { - const char* const path = "serd_strict_write_test.ttl"; - FILE* const fd = fopen(path, "wb"); - assert(fd); - SerdEnv* const env = serd_env_new(NULL); SerdWriter* const writer = serd_writer_new( - SERD_TURTLE, (SerdStyle)SERD_STYLE_STRICT, env, NULL, null_sink, fd); - + SERD_TURTLE, (SerdStyle)SERD_STYLE_STRICT, env, NULL, null_sink, NULL); assert(writer); const uint8_t bad_str[] = {0xFF, 0x90, 'h', 'i', 0}; @@ -238,9 +235,6 @@ test_strict_write(void) serd_writer_free(writer); serd_env_free(env); - - assert(!fclose(fd)); - assert(!remove(path)); } // Produce a write error without setting errno @@ -256,19 +250,129 @@ error_sink(const void* const buf, const size_t len, void* const stream) static void test_write_error(void) { - SerdEnv* const env = serd_env_new(NULL); - SerdWriter* writer = NULL; - SerdStatus st = SERD_SUCCESS; + SerdEnv* const env = serd_env_new(NULL); - SerdNode u = serd_node_from_string(SERD_URI, USTR("http://example.com/u")); - - writer = + SerdWriter* const writer = serd_writer_new(SERD_TURTLE, (SerdStyle)0, env, NULL, error_sink, NULL); assert(writer); - st = serd_writer_write_statement(writer, 0U, NULL, &u, &u, &u, NULL, NULL); + + SerdNode u = serd_node_from_string(SERD_URI, USTR("http://example.com/u")); + + const SerdStatus st = + serd_writer_write_statement(writer, 0U, NULL, &u, &u, &u, NULL, NULL); assert(st == SERD_ERR_BAD_WRITE); + serd_writer_free(writer); + serd_env_free(env); +} +static void +test_chunk_sink(void) +{ + SerdEnv* const env = serd_env_new(NULL); + assert(env); + + SerdChunk chunk = {NULL, 0}; + SerdWriter* const writer = serd_writer_new( + SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk); + assert(writer); + + const SerdNode base = + serd_node_from_string(SERD_URI, USTR("http://example.org/base")); + assert(!serd_writer_set_base_uri(writer, &base)); + assert(!serd_writer_finish(writer)); + + uint8_t* const out = serd_chunk_sink_finish(&chunk); + assert( + expect_string((const char*)out, "@base <http://example.org/base> .\n")); + serd_free(out); + + serd_writer_free(writer); + serd_env_free(env); +} + +static void +test_write_nothing_node(void) +{ + SerdEnv* const env = serd_env_new(NULL); + assert(env); + + SerdChunk chunk = {NULL, 0}; + SerdWriter* const writer = serd_writer_new( + SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk); + assert(writer); + + SerdNode s = serd_node_from_string(SERD_URI, USTR("")); + SerdNode p = serd_node_from_string(SERD_URI, USTR("http://example.org/pred")); + SerdNode o = serd_node_from_string(SERD_NOTHING, USTR("")); + assert(serd_writer_write_statement(writer, 0, NULL, &s, &p, &o, NULL, NULL) == + SERD_ERR_BAD_ARG); + + assert(!chunk.buf); + serd_writer_free(writer); + serd_env_free(env); +} + +static void +test_write_bad_statement(void) +{ + SerdEnv* const env = serd_env_new(NULL); + assert(env); + + SerdChunk chunk = {NULL, 0}; + SerdWriter* const writer = serd_writer_new( + SERD_TURTLE, (SerdStyle)0, env, NULL, serd_chunk_sink, &chunk); + assert(writer); + + SerdNode s = serd_node_from_string(SERD_URI, USTR("http://example.org/s")); + SerdNode p = serd_node_from_string(SERD_URI, USTR("http://example.org/p")); + SerdNode o = serd_node_from_string(SERD_URI, USTR("http://example.org/o")); + SerdNode l = serd_node_from_string(SERD_LITERAL, USTR("lang")); + + assert(serd_writer_write_statement( + writer, + (SerdStatementFlags)(SERD_ANON_S_BEGIN | SERD_LIST_S_BEGIN), + NULL, + &s, + &p, + &o, + NULL, + NULL) == SERD_ERR_BAD_ARG); + + assert(serd_writer_write_statement( + writer, + (SerdStatementFlags)(SERD_EMPTY_S | SERD_LIST_S_BEGIN), + NULL, + &s, + &p, + &o, + NULL, + NULL) == SERD_ERR_BAD_ARG); + + assert(serd_writer_write_statement( + writer, + (SerdStatementFlags)(SERD_ANON_O_BEGIN | SERD_LIST_O_BEGIN), + NULL, + &s, + &p, + &o, + NULL, + NULL) == SERD_ERR_BAD_ARG); + + assert(serd_writer_write_statement( + writer, + (SerdStatementFlags)(SERD_EMPTY_O | SERD_LIST_O_BEGIN), + NULL, + &s, + &p, + &o, + NULL, + NULL) == SERD_ERR_BAD_ARG); + + assert(serd_writer_write_statement(writer, 0U, NULL, &s, &p, &o, &o, &l) == + SERD_ERR_BAD_ARG); + + serd_writer_free(writer); serd_env_free(env); } @@ -281,6 +385,9 @@ main(void) test_write_bad_anon_stack(); test_strict_write(); test_write_error(); + test_chunk_sink(); + test_write_nothing_node(); + test_write_bad_statement(); return 0; } |