Skip to content

Commit

Permalink
eclipse-rdf4jGH-5058: initial W3C test code
Browse files Browse the repository at this point in the history
  • Loading branch information
barthanssens committed Aug 21, 2024
1 parent ac24667 commit 8cd8cec
Showing 1 changed file with 88 additions and 126 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2019 Eclipse RDF4J contributors.
* Copyright (c) 2024 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
Expand All @@ -11,176 +11,138 @@

package org.eclipse.rdf4j.rio.csvw;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.net.MalformedURLException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayDeque;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.model.vocabulary.RDF4J;
import org.eclipse.rdf4j.repository.RepositoryConnection;
import org.eclipse.rdf4j.repository.sail.SailRepository;
import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection;
import org.eclipse.rdf4j.model.util.Models;
import org.eclipse.rdf4j.model.util.RDFCollections;
import org.eclipse.rdf4j.model.util.Values;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.rio.Rio;
import org.eclipse.rdf4j.rio.WriterConfig;
import org.eclipse.rdf4j.rio.helpers.BasicWriterSettings;
import org.eclipse.rdf4j.sail.memory.MemoryStore;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

/**
* Based upon the SHACL W3C Compliance Test
*
*
*/
public class W3cComplianceTest {

public static Stream<Arguments> data() {
return getTestFiles().stream()
.sorted(Comparator.comparing(URL::toString))
.map(Arguments::of);
return getTestFiles().stream().sorted().map(Arguments::of);
}

@ParameterizedTest
@MethodSource("data")
public void test(URL testCasePath) throws IOException {
boolean testPassed = false;

public void test(W3CTest testCase) throws IOException {
try {
runTest(testCasePath);
testPassed = true;
runTest(testCase);
} catch (AssertionError e) {
switch (e.toString()) {
case "org.opentest4j.AssertionFailedError: expected: <false> but was: <true>":
testPassed = false;
break;
case "org.opentest4j.AssertionFailedError: expected: <true> but was: <false>":
testPassed = false;
break;
default:
throw e;
}
throw e;
}
}

@ParameterizedTest
@MethodSource("data")
public void parsingTest(URL testCasePath) throws IOException, InterruptedException {
runParsingTest(testCasePath);
private static URL getLocation(String file) {
return W3cComplianceTest.class.getClassLoader().getResource("w3c/" + file);
}


private static Set<URL> getTestFiles() {
Set<URL> testFiles = new HashSet<>();

Deque<URL> manifests = new ArrayDeque<>();
manifests.add(W3cComplianceTest.class.getClassLoader().getResource("w3c/manifest.ttl"));

while (!manifests.isEmpty()) {
URL pop = manifests.pop();
Manifest manifest = new Manifest(pop);

if (manifest.include.isEmpty()) {
testFiles.add(pop);
} else {
manifests.addAll(manifest.include);
/*
* @ParameterizedTest
*
* @MethodSource("data") public void parsingTest(URL testCasePath) throws IOException, InterruptedException {
* runParsingTest(testCasePath); }
*
*/
/**
* Get test file URLs from manifest file(s)
*
* @return
*/
private static List<W3CTest> getTestFiles() {
List<W3CTest> tests = null;

String nsMF = "http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#";
String csvtMF = "http://www.w3.org/2013/csvw/tests/vocab#";
URL url = getLocation("manifest-rdf.ttl");

if (url != null) {
Model model;
try {
model = Rio.parse(url.openStream(), RDFFormat.TRIG, (Resource) null);
} catch (IOException e) {
throw new RuntimeException(e);
}
Value empty = Values.literal("");

List<Value> entries = RDFCollections.asValues(model, Values.iri(nsMF, "entries"), new ArrayList<>(),
(Resource) null);
tests = entries.stream()
.map(t -> (Resource) t)
.map(t -> new W3CTest(
t.stringValue(),
Models.getProperty(model, t, Values.iri(nsMF, "name"), (Resource) null)
.orElse(empty)
.stringValue(),
Models.getProperty(model, t, Values.iri(csvtMF, "action"), (Resource) null)
.orElse(empty)
.stringValue(),
Models.getProperty(model, t, Values.iri(nsMF, "implicit"), (Resource) null)
.orElse(empty)
.stringValue(),
Models.getProperty(model, t, Values.iri(nsMF, "result"), (Resource) null)
.orElse(empty)
.stringValue())
)
.collect(Collectors.toList());
}
return testFiles;
return tests;
}

// Test Manifest
static class Manifest {
List<URL> include;

public Manifest(URL filename) {
SailRepository sailRepository = new SailRepository(new MemoryStore());
try (SailRepositoryConnection connection = sailRepository.getConnection()) {
connection.add(filename, filename.toString(), RDFFormat.TRIG);
} catch (IOException e) {
throw new RuntimeException(e);
}

try (SailRepositoryConnection connection = sailRepository.getConnection()) {
try (Stream<Statement> stream = connection
.getStatements(null,
connection.getValueFactory()
.createIRI("http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#include"),
null)
.stream()) {
include = stream
.map(Statement::getObject)
.map(Value::stringValue)
.map(v -> {
try {
return new URL(v);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
}
static class W3CTest {
String id;
String name;
String csv;
String json;
String result;

public Model getExpected() throws IOException {
URL location = getLocation(result);
try (InputStream is = location.openStream()) {
return Rio.parse(is, RDFFormat.TURTLE, (Resource) null);
}
}
}

private void runTest(URL resourceName) throws IOException {
W3C_shaclTestValidate expected = new W3C_shaclTestValidate(resourceName);

SailRepository data = new SailRepository(new MemoryStore());

try (SailRepositoryConnection connection = data.getConnection()) {
connection.begin();
connection.add(resourceName, "http://example.org/", RDFFormat.TRIG);
connection.commit();
public URL getJson() throws IOException {
return getLocation(json);
}

SailRepository shapes = new SailRepository(new MemoryStore());

try (RepositoryConnection conn = shapes.getConnection()) {
conn.add(resourceName, resourceName.toString(), RDFFormat.TURTLE);
conn.commit();
public W3CTest(String id, String name, String csv, String json, String result) {
this.id = id;
this.name = name;
this.csv = csv;
this.json = json;
this.result = result;
}

assertEquals(expected.conforms, validate.conforms());
}

static class W3C_shaclTestValidate {

W3C_shaclTestValidate(URL filename) {
this.filename = filename.getPath();
SailRepository sailRepository = Utils.getSailRepository(filename, RDFFormat.TURTLE);
try (SailRepositoryConnection connection = sailRepository.getConnection()) {
try (Stream<Statement> stream = connection.getStatements(null, SHACL.CONFORMS, null).stream()) {
conforms = stream
.map(Statement::getObject)
.map(o -> (Literal) o)
.map(Literal::booleanValue)
.findFirst()
.orElseThrow();
}
}
}

String filename;
private void runTest(W3CTest test) throws IOException {
Model expected = test.getExpected();

boolean conforms;
try (InputStream is = test.getJson().openStream()) {
Model result = Rio.parse(is, RDFFormat.CSVW, (Resource) null);
assertTrue(Models.isomorphic(result, expected), test.name);
}
}

}

0 comments on commit 8cd8cec

Please sign in to comment.