Skip to content

Commit

Permalink
Add test suite reports.
Browse files Browse the repository at this point in the history
  • Loading branch information
q-uint committed Sep 9, 2023
1 parent 6af02b6 commit 3a945f3
Show file tree
Hide file tree
Showing 31 changed files with 2,716 additions and 1,319 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ fmt:
gofmt -s -w .
goarrange run -r .
golangci-lint run ./...

report:
TEST_SUITE_REPORT=true go test ./...
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# RDF 1.1

## Test Cases

| Name | Report | Compliance |
|-----------|----------------------------------------------------|------------------|
| N-Triples | [report.ttl](./ntriples/testdata/suite/report.ttl) | 68/68 (100.0%) |
| N-Quads | [report.ttl](./nquads/testdata/suite/report.ttl) | 85/85 (100.0%) |
| Turtle | [report.ttl](./turtle/testdata/suite/report.ttl) | 291/291 (100.0%) |

## References

- [RDF 1.1 Concepts and Abstract Syntax](https://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ module github.com/0x51-dev/rdf

go 1.21.0

require github.com/0x51-dev/upeg v0.0.0-20230829161504-bdf1e5e3b220
require github.com/0x51-dev/upeg v0.0.0-20230905211053-ee881c4f4508

require github.com/0x51-dev/ri v0.0.0-20230708135038-029eea38546f
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
github.com/0x51-dev/ri v0.0.0-20230708135038-029eea38546f h1:6bWTNS1c7TqLdQEruMwLvDQ7Jn+vJniE/dqeTmOenVA=
github.com/0x51-dev/ri v0.0.0-20230708135038-029eea38546f/go.mod h1:jw6tYgXeAqwcKnvjTOI6rfGEhLj3R5PSMUbRlKL2DvM=
github.com/0x51-dev/upeg v0.0.0-20230829161504-bdf1e5e3b220 h1:Agg2TMCsToB6SOGEHNa9EAJEG32Ej9pV+g6lRTlaQxg=
github.com/0x51-dev/upeg v0.0.0-20230829161504-bdf1e5e3b220/go.mod h1:ts9/Zafxb9W9drZFTmQNMR7kLOyHyBw37NuowyiDork=
github.com/0x51-dev/upeg v0.0.0-20230905211053-ee881c4f4508 h1:QuF39EbNtzj2iQ6d/eetRDbz8YGCctZQN1AJxa6wc2I=
github.com/0x51-dev/upeg v0.0.0-20230905211053-ee881c4f4508/go.mod h1:ts9/Zafxb9W9drZFTmQNMR7kLOyHyBw37NuowyiDork=
67 changes: 67 additions & 0 deletions internal/project/report.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package project

import (
"fmt"
"github.com/0x51-dev/rdf/internal/testsuite"
"github.com/0x51-dev/rdf/turtle"
"time"
)

var (
assertedBy = turtle.IRI{Value: "https://github.com/q-uint"}
subject = turtle.IRI{Value: "https://github.com/0x51-dev/rdf"}
)

type Report struct {
test turtle.IRI
r *testsuite.Report
}

func NewReport(test turtle.IRI) *Report {
r := testsuite.NewReport()
r.Project = testsuite.Project{
IRI: turtle.IRI{Value: "https://github.com/0x51-dev/rdf"},
Name: "RDF",
Homepage: "https://github.com/0x51-dev/rdf",
License: "https://www.apache.org/licenses/LICENSE-2.0",
Description: "RDF is a Go library for working with RDF data.",
Created: time.Date(2023, 7, 15, 0, 0, 0, 0, time.UTC),
ProgrammingLanguage: "Go",
Implements: []string{
"https://www.w3.org/TR/n-triples/",
"https://www.w3.org/TR/n-quads/",
"https://www.w3.org/TR/turtle/",
},
Developer: []testsuite.Developer{
{
IRI: turtle.IRI{Value: "https://github.com/q-uint"},
Name: "Quint Daenen",
Title: "Implementor",
MBox: "mailto:[email protected]",
Homepage: "https://0x51.dev",
},
},
}
return &Report{test: test, r: r}
}

func (r *Report) AddTest(name string, outcome testsuite.OutcomeValue) {
test := turtle.IRI{Prefixed: r.test.Prefixed, Value: fmt.Sprintf("%s%s", r.test.Value, name)}
r.r.AddTestCase(testsuite.TestCase{
AssertedBy: assertedBy,
Mode: testsuite.Automatic,
Result: testsuite.TestResult{
Date: turtle.StringLiteral{
Value: time.Now().In(time.UTC).Format("2006-01-02-0700"),
DatatypeIRI: "xsd:date",
},
Outcome: outcome,
},
Subject: subject,
Test: test,
})
}

func (r *Report) String() string {
return r.r.String()
}
19 changes: 13 additions & 6 deletions internal/testsuite/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package testsuite
import (
"fmt"
ttl "github.com/0x51-dev/rdf/turtle"
"github.com/0x51-dev/rdf/turtle/grammar/ir"
)

type ApprovalType string
Expand Down Expand Up @@ -43,11 +42,11 @@ func LoadManifest(raw string) (*Manifest, error) {
var keys []string
entries := make(map[string]*Test)
switch t := mfEntries[0].(type) {
case ir.Collection:
case ttl.Collection:
for _, entry := range t {
var name string
switch t := entry.(type) {
case *ir.IRI:
case *ttl.IRI:
name = t.Value
default:
return nil, fmt.Errorf("manifest: entry name not an IRI")
Expand All @@ -70,9 +69,10 @@ type Test struct {
Comment string
Approval ApprovalType
Action string
Result string
}

func NewTest(triple ir.Triple) (*Test, error) {
func NewTest(triple *ttl.Triple) (*Test, error) {
pom, err := triple.PredicateObjectMap()
if err != nil {
return nil, err
Expand All @@ -96,11 +96,18 @@ func NewTest(triple ir.Triple) (*Test, error) {
if !ok {
return nil, fmt.Errorf("test: no action")
}
result, ok := pom["mf:result"]
var r string
if ok {
r = (result[0].(*ttl.IRI)).Value
}

return &Test{
Type: typ.String(),
Name: (name[0].(*ir.StringLiteral)).Value,
Name: (name[0].(*ttl.StringLiteral)).Value,
Comment: comment.String(),
Approval: ApprovalType(approval.String()),
Action: (action[0].(*ir.IRI)).Value,
Action: (action[0].(*ttl.IRI)).Value,
Result: r, // optional, only with eval tests
}, nil
}
240 changes: 240 additions & 0 deletions internal/testsuite/report.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
package testsuite

import (
"github.com/0x51-dev/rdf/turtle"
"time"
)

type Developer struct {
IRI turtle.IRI
Name string
Title string
MBox string
Homepage string
}

func (d Developer) line() turtle.Line {
var b turtle.Triple
b.Subject = d.IRI
b.PredicateObjectList = turtle.PredicateObjectList{
{
Verb: new(turtle.A),
ObjectList: []turtle.Object{
&turtle.IRI{Prefixed: true, Value: "foaf:Person"},
&turtle.IRI{Prefixed: true, Value: "earl:Assertor"},
},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "foaf:name"},
ObjectList: []turtle.Object{&turtle.StringLiteral{Value: d.Name}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "foaf:title"},
ObjectList: []turtle.Object{&turtle.StringLiteral{Value: d.Title}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "foaf:mbox"},
ObjectList: []turtle.Object{&turtle.IRI{Value: d.MBox}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "foaf:homepage"},
ObjectList: []turtle.Object{&turtle.IRI{Value: d.Homepage}},
},
}
return &b
}

// OutcomeValue describes a resulting condition from carrying out the test.
type OutcomeValue string

const (
// Passed - the subject passed the test.
Passed OutcomeValue = "earl:passed"
// Failed - the subject failed the test.
Failed OutcomeValue = "earl:failed"
// CantTell - it is unclear if the subject passed or failed the test.
CantTell OutcomeValue = "earl:cantTell"
// Inapplicable - the test is not applicable to the subject.
Inapplicable OutcomeValue = "earl:inapplicable"
// Untested - the test has not been carried out.
Untested OutcomeValue = "earl:untested"
)

type Project struct {
IRI turtle.IRI
Name string
Homepage string
License string
Description string
Created time.Time
ProgrammingLanguage string
Implements []string
Developer []Developer
}

func (p Project) line() turtle.Line {
var t turtle.Triple
t.Subject = p.IRI
var implements []turtle.Object
for _, i := range p.Implements {
implements = append(implements, &turtle.IRI{Value: i})
}
var developers []turtle.Object
for _, d := range p.Developer {
developers = append(developers, &d.IRI)
}
t.PredicateObjectList = []turtle.PredicateObject{
{
Verb: new(turtle.A),
ObjectList: []turtle.Object{&turtle.IRI{Prefixed: true, Value: "doap:Project"}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "doap:name"},
ObjectList: []turtle.Object{&turtle.StringLiteral{Value: p.Name}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "doap:homepage"},
ObjectList: []turtle.Object{&turtle.IRI{Value: p.Homepage}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "doap:license"},
ObjectList: []turtle.Object{&turtle.IRI{Value: p.License}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "doap:description"},
ObjectList: []turtle.Object{&turtle.StringLiteral{Value: p.Description, LanguageTag: "en"}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "doap:created"},
ObjectList: []turtle.Object{&turtle.StringLiteral{Value: p.Created.Format("2006-01-02-0700"), DatatypeIRI: "xsd:date"}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "doap:programming-language"},
ObjectList: []turtle.Object{&turtle.IRI{Value: p.ProgrammingLanguage}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "doap:implements"},
ObjectList: implements,
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "doap:developer"},
ObjectList: developers,
},
}
return t
}

type Report struct {
prefixes []turtle.Line
Project Project
testcases []TestCase
}

func NewReport() *Report {
return &Report{
prefixes: []turtle.Line{
&turtle.Prefix{Name: "dc:", IRI: "http:https://purl.org/dc/elements/1.1/"},
&turtle.Prefix{Name: "rdft:", IRI: "http:https://www.w3.org/ns/rdftest#"},
&turtle.Prefix{Name: "earl:", IRI: "http:https://www.w3.org/ns/earl#"},
&turtle.Prefix{Name: "foaf:", IRI: "http:https://xmlns.com/foaf/0.1/"},
&turtle.Prefix{Name: "turtletest:", IRI: "http:https://www.w3.org/2013/TurtleTests/manifest.ttl#"},
&turtle.Prefix{Name: "dct:", IRI: "http:https://purl.org/dc/terms/"},
&turtle.Prefix{Name: "xsd:", IRI: "http:https://www.w3.org/2001/XMLSchema#"},
&turtle.Prefix{Name: "rdf:", IRI: "http:https://www.w3.org/1999/02/22-rdf-syntax-ns#"},
&turtle.Prefix{Name: "doap:", IRI: "http:https://usefulinc.com/ns/doap#"},
},
}
}

func (r *Report) AddTestCase(tc TestCase) {
r.testcases = append(r.testcases, tc)
}

func (r *Report) String() string {
var d turtle.Document
d = append(d, r.prefixes...)
for _, dev := range r.Project.Developer {
d = append(d, dev.line())
}
d = append(d, r.Project.line())
for _, tc := range r.testcases {
d = append(d, tc.line())
}
return d.String()
}

type TestCase struct {
AssertedBy turtle.IRI
Mode TestMode
Result TestResult
Subject turtle.IRI
Test turtle.IRI
}

func (tc TestCase) line() turtle.Line {
var b turtle.Triple
b.BlankNodePropertyList = turtle.BlankNodePropertyList{
{
Verb: new(turtle.A),
ObjectList: []turtle.Object{&turtle.IRI{Prefixed: true, Value: "earl:Assertion"}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "earl:assertedBy"},
ObjectList: []turtle.Object{&tc.AssertedBy},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "earl:mode"},
ObjectList: []turtle.Object{&turtle.IRI{Prefixed: true, Value: string(tc.Mode)}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "earl:result"},
ObjectList: []turtle.Object{turtle.BlankNodePropertyList{
{
Verb: new(turtle.A),
ObjectList: []turtle.Object{&turtle.IRI{Prefixed: true, Value: "earl:TestResult"}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "dct:date"},
ObjectList: []turtle.Object{&tc.Result.Date},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "earl:outcome"},
ObjectList: []turtle.Object{&turtle.IRI{Prefixed: true, Value: string(tc.Result.Outcome)}},
},
}},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "earl:subject"},
ObjectList: []turtle.Object{&tc.Subject},
},
{
Verb: &turtle.IRI{Prefixed: true, Value: "earl:test"},
ObjectList: []turtle.Object{&tc.Test},
},
}
return &b
}

// TestMode describes how a test was carried out.
type TestMode string

const (
// Automatic - where the test was carried out automatically by the software tool and without any human intervention.
Automatic TestMode = "earl:automatic"
// Manual - where the test was carried out by human evaluators. This includes the case where the evaluators are
// aided by instructions or guidance provided by software tools, but where the evaluators carried out the actual
// test procedure.
Manual TestMode = "earl:manual"
// SemiAuto - where the test was partially carried out by software tools, but where human input or judgment was
// still required to decide or help decide the outcome of the test.
SemiAuto TestMode = "earl:semiAuto"
// Undisclosed - where the exact testing process is undisclosed.
Undisclosed TestMode = "earl:undisclosed"
// UnknownMode - where the testing process is unknown or undetermined.
UnknownMode TestMode = "earl:unknownMode"
)

type TestResult struct {
Date turtle.StringLiteral
Outcome OutcomeValue
}
Loading

0 comments on commit 3a945f3

Please sign in to comment.