From 5953a8dfa07f251734ea5918dfc812083c74a104 Mon Sep 17 00:00:00 2001 From: kortschak Date: Sat, 26 Jul 2014 11:58:56 +0930 Subject: [PATCH] Add RDF test suite testing and fix grammar errors --- nquads/nquad_tests.tar.gz | Bin 0 -> 7167 bytes nquads/nquads.rl | 9 +++--- nquads/nquads_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++++ nquads/ntriple_tests.tar.gz | Bin 0 -> 6324 bytes 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 nquads/nquad_tests.tar.gz create mode 100644 nquads/ntriple_tests.tar.gz diff --git a/nquads/nquad_tests.tar.gz b/nquads/nquad_tests.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..f0414931b9766032ba745ef4b35ac192f1bc0f2c GIT binary patch literal 7167 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

SiXmU$)hyT_U}xv zBmFc!3FRF~qXJh)=6%T%oO3k3&)^m+tY~A~L(~}lZaF7=Ad1`XUb$=7OXjO*C$c6s a0b7k}65Rjq*}Fami0rm4#$j_ru>S!i$g_|D literal 0 HcmV?d00001 diff --git a/nquads/nquads.rl b/nquads/nquads.rl index 990213a..b5b3529 100644 --- a/nquads/nquads.rl +++ b/nquads/nquads.rl @@ -57,8 +57,7 @@ | 0x0b .. 0x0c | 0x0e .. '!' | '#' .. '[' - | ']' .. '~' - | 0x80 .. 0x10ffff + | ']' .. 0x10ffff | ECHAR | UCHAR)* '"' @@ -90,9 +89,9 @@ statement := ( whitespace* subject >StartSubject %SetSubject - whitespace+ predicate >StartPredicate %SetPredicate - whitespace+ object >StartObject %SetObject - (whitespace+ graphLabel >StartLabel %SetLabel)? + whitespace* predicate >StartPredicate %SetPredicate + whitespace* object >StartObject %SetObject + (whitespace* graphLabel >StartLabel %SetLabel)? whitespace* '.' whitespace* ('#' any*)? >Comment ) %Return @!Error ; }%% diff --git a/nquads/nquads_test.go b/nquads/nquads_test.go index 337d918..827691d 100644 --- a/nquads/nquads_test.go +++ b/nquads/nquads_test.go @@ -15,8 +15,12 @@ package nquads import ( + "archive/tar" + "compress/gzip" "fmt" "io" + "os" + "path/filepath" "reflect" "strings" "testing" @@ -480,6 +484,72 @@ func TestDecoder(t *testing.T) { } } +func TestRDFWorkingGroupSuit(t *testing.T) { + // These tests erroneously pass because the parser does not + // perform semantic testing on the URI in the IRIRef as required + // by the specification. So, we skip them. + skip := map[string]bool{ + // N-Triples. + "nt-syntax-bad-uri-06.nt": true, + "nt-syntax-bad-uri-07.nt": true, + "nt-syntax-bad-uri-08.nt": true, + "nt-syntax-bad-uri-09.nt": true, + + // N-Quads. + "nq-syntax-bad-uri-01.nq": true, + "nt-syntax-bad-uri-06.nq": true, + "nt-syntax-bad-uri-07.nq": true, + "nt-syntax-bad-uri-08.nq": true, + "nt-syntax-bad-uri-09.nq": true, + } + + for _, file := range []string{ + "ntriple_tests.tar.gz", + "ntriple_tests.tar.gz", + } { + suite, err := os.Open(file) + if err != nil { + t.Fatalf("Failed to open N-Quads test suite in %q: %v", file, err) + } + defer suite.Close() + + r, err := gzip.NewReader(suite) + if err != nil { + t.Fatalf("Failed to uncompress N-Quads test suite in %q: %v", file, err) + } + + tr := tar.NewReader(r) + for { + h, err := tr.Next() + if err != nil { + if err == io.EOF { + break + } + t.Fatalf("Unexpected error while reading suite archive: %v", err) + } + + h.Name = filepath.Base(h.Name) + if (filepath.Ext(h.Name) != ".nt" && filepath.Ext(h.Name) != ".nq") || skip[h.Name] { + continue + } + + isBad := strings.Contains(h.Name, "bad") + + dec := NewDecoder(tr) + for { + _, err := dec.Unmarshal() + if err == io.EOF { + break + } + got := err == nil + if got == isBad { + t.Errorf("Unexpected error return for test suite item %q, got: %v", h.Name, err) + } + } + } + } +} + var escapeSequenceTests = []struct { input string expect string diff --git a/nquads/ntriple_tests.tar.gz b/nquads/ntriple_tests.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..5e2ba80100620f388478d335afeb94bdd37689bb GIT binary patch literal 6324 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