Skip to content

Commit

Permalink
Add support for JSON-LD fromRdf tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rubensworks committed Mar 29, 2019
1 parent 79f4d79 commit 116f653
Show file tree
Hide file tree
Showing 10 changed files with 427 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ $ rdf-test-suite myengine.js http://w3c.github.io/rdf-tests/sparql11/data-sparql
| [Turtle Tests](https://w3c.github.io/rdf-tests/turtle/) | [RDF 1.1 Turtle](https://www.w3.org/TR/turtle/) | [`IParser`](https://github.com/rubensworks/rdf-test-suite.js/blob/master/lib/testcase/rdfsyntax/IParser.ts) | http://w3c.github.io/rdf-tests/turtle/manifest.ttl |
| [TriG Tests](https://w3c.github.io/rdf-tests/trig/) | [RDF 1.1 TriG](https://www.w3.org/TR/trig/) | [`IParser`](https://github.com/rubensworks/rdf-test-suite.js/blob/master/lib/testcase/rdfsyntax/IParser.ts) | http://w3c.github.io/rdf-tests/trig/manifest.ttl |
| [JSON-LD Test Suite](https://w3c.github.io/json-ld-api/tests/) | [JSON-LD 1.0](https://www.w3.org/TR/json-ld/) | [`IParser`](https://github.com/rubensworks/rdf-test-suite.js/blob/master/lib/testcase/rdfsyntax/IParser.ts) | https://w3c.github.io/json-ld-api/tests/toRdf-manifest.jsonld |
| [JSON-LD Test Suite](https://w3c.github.io/json-ld-api/tests/) | [JSON-LD 1.0](https://www.w3.org/TR/json-ld/) | [`ISerializer`](https://github.com/rubensworks/rdf-test-suite.js/blob/master/lib/testcase/rdfsyntax/ISerializer.ts) | https://w3c.github.io/json-ld-api/tests/fromRdf-manifest.jsonld |

## License
This software is written by [Ruben Taelman](http://rubensworks.net/).
Expand Down
5 changes: 5 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
export * from "./lib/testcase/rdfsyntax/jsonld/TestCaseJsonLdFromRdf";
export * from "./lib/testcase/rdfsyntax/jsonld/TestCaseJsonLdSyntax";
export * from "./lib/testcase/rdfsyntax/jsonld/TestCaseJsonLdToRdf";
export * from "./lib/testcase/rdfsyntax/TestCaseEval";
export * from "./lib/testcase/rdfsyntax/TestCaseSyntax";
export * from "./lib/testcase/rdfsyntax/IParser";
export * from "./lib/testcase/rdfsyntax/ISerializer";
export * from "./lib/testcase/rdfsyntax/ITestCaseFromRdfSyntax";
export * from "./lib/testcase/rdfsyntax/ITestCaseRdfSyntax";
export * from "./lib/testcase/sparql/IQueryEngine";
export * from "./lib/testcase/sparql/ITestCaseSparql";
Expand Down
4 changes: 3 additions & 1 deletion lib/context-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,7 @@
"jsonLdProduceGeneralizedRdf": "jld:produceGeneralizedRdf",
"processingMode": "jld:processingMode",
"specVersion": "jld:specVersion",
"context": "jld:context"
"context": "jld:context",
"useNativeTypes": "jld:useNativeTypes",
"useRdfType": "jld:useRdfType"
}
3 changes: 3 additions & 0 deletions lib/testcase/TestCaseHandlers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {TestCaseJsonLdFromRdfHandler} from "./rdfsyntax/jsonld/TestCaseJsonLdFromRdf";
import {TestCaseJsonLdSyntaxHandler} from "./rdfsyntax/jsonld/TestCaseJsonLdSyntax";
import {TestCaseJsonLdToRdfHandler} from "./rdfsyntax/jsonld/TestCaseJsonLdToRdf";
import {TestCaseEvalHandler} from "./rdfsyntax/TestCaseEval";
Expand Down Expand Up @@ -81,6 +82,8 @@ module.exports = {
new TestCaseJsonLdToRdfHandler(),
'https://w3c.github.io/json-ld-api/tests/vocab#ToRDFTest https://w3c.github.io/json-ld-api/tests/vocab#PositiveSyntaxTest':
new TestCaseJsonLdSyntaxHandler(true),
'https://w3c.github.io/json-ld-api/tests/vocab#FromRDFTest https://w3c.github.io/json-ld-api/tests/vocab#PositiveEvaluationTest':
new TestCaseJsonLdFromRdfHandler(),
};
// tslint:enable:object-literal-sort-keys
// tslint:enable:max-line-length
8 changes: 8 additions & 0 deletions lib/testcase/rdfsyntax/ISerializer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as RDF from "rdf-js";

/**
* A serializer handler.
*/
export interface ISerializer {
serialize(data: RDF.Quad[], baseIRI: string, options: {[key: string]: any}): Promise<string>;
}
10 changes: 10 additions & 0 deletions lib/testcase/rdfsyntax/ITestCaseFromRdfSyntax.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {ITestCase} from "../ITestCase";
import {IParser} from "./IParser";
import {ISerializer} from "./ISerializer";

/**
* An test case data holder for serializations from RDF syntax.
*/
export interface ITestCaseFromRdfSyntax extends ITestCase<ISerializer> {
type: 'fromrdfsyntax';
}
137 changes: 137 additions & 0 deletions lib/testcase/rdfsyntax/jsonld/TestCaseJsonLdFromRdf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import * as RDF from "rdf-js";
import {Resource} from "rdf-object";
import {Util} from "../../../Util";
import {ITestCaseData} from "../../ITestCase";
import {ITestCaseHandler} from "../../ITestCaseHandler";
import {ISerializer} from "../ISerializer";
import {ITestCaseFromRdfSyntax} from "../ITestCaseFromRdfSyntax";
// tslint:disable:no-var-requires
const arrayifyStream = require('arrayify-stream');
const stringifyStream = require('stream-to-string');

/**
* Test case handler for:
* * https://w3c.github.io/json-ld-api/tests/vocab#FromRDFTest
* * https://w3c.github.io/json-ld-api/tests/vocab#PositiveEvaluationTest
*
* It will check if the serialization from RDF to JSON-LD matches with the expected JSON-LD document.
*/
export class TestCaseJsonLdFromRdfHandler implements ITestCaseHandler<TestCaseJsonLdFromRdf> {

public async resourceToTestCase(resource: Resource, testCaseData: ITestCaseData,
cachePath?: string): Promise<TestCaseJsonLdFromRdf> {
if (!resource.property.action) {
throw new Error(`Missing mf:action in ${resource}`);
}
if (!resource.property.result) {
throw new Error(`Missing mf:result in ${resource}`);
}

// Loop over the options
let useNativeTypes: boolean = false;
let useRdfType: boolean = false;
let processingMode: string = null;
let specVersion: string = '1.0';
for (const option of resource.properties.jsonLdOptions) {
// Should native types be used?
if (option.property.useNativeTypes) {
useNativeTypes = option.property.useNativeTypes.term.value === 'true';
}

// Should RDF type be used?
if (option.property.useRdfType) {
useRdfType = option.property.useRdfType.term.value === 'true';
}

// The processing mode
// If undefined, all processors should be able to handle the test,
// otherwise, only processors explicitly supporting that mode should run the test.
if (option.property.processingMode) {
// Remove the 'json-ld-' prefix from the string
processingMode = option.property.processingMode.term.value.substr(8);
}

// The spec for which this test was defined.
if (option.property.specVersion) {
// Remove the 'json-ld-' prefix from the string
specVersion = option.property.specVersion.term.value.substr(8);
}
}
const options = { useNativeTypes, useRdfType, processingMode, specVersion };

return new TestCaseJsonLdFromRdf(testCaseData,
await arrayifyStream(<any> (await Util.fetchRdf(resource.property.action.value, cachePath, true))[1]),
await stringifyStream((await Util.fetchCached(resource.property.result.value, cachePath)).body),
resource.property.action.value, options);
}

}

export class TestCaseJsonLdFromRdf implements ITestCaseFromRdfSyntax {
public readonly type = "fromrdfsyntax";
public readonly approval: string;
public readonly approvedBy: string;
public readonly comment: string;
public readonly types: string[];
public readonly name: string;
public readonly uri: string;

public readonly data: RDF.Quad[];
public readonly expected: string;
public readonly baseIRI: string;
public readonly options: any;

constructor(testCaseData: ITestCaseData, data: RDF.Quad[], expected: string, baseIRI: string, options: any) {
Object.assign(this, testCaseData);
this.data = data;
this.expected = expected;
this.baseIRI = baseIRI;
this.options = options;
}

public async test(serializer: ISerializer, injectArguments: any): Promise<void> {
const serialized: string = await serializer.serialize(this.data, this.baseIRI,
{ ...this.options, ...injectArguments });
if (!objectsIsomorphic(JSON.parse(serialized), JSON.parse(this.expected))) {
throw new Error(`Invalid data serialization
Input: ${this.data}
Expected: ${this.expected}
Got: ${serialized}
`);
}
}

}

export function objectsIsomorphic(obj1: any, obj2: any) {
// Loop through properties in object 1
for (const p in obj1) {
// Check property exists on obj2
if (!(p in obj2)) {
return false;
}

switch (typeof (obj1[p])) {
case 'object':
if (!objectsIsomorphic(obj1[p], obj2[p])) {
return false;
}
break;
// Compare values
default:
if (obj1[p] !== obj2[p]) {
return false;
}
}
}

// Check object 2 for any extra properties
for (const p in obj2) {
if (!(p in obj1)) {
return false;
}
}
return true;
}
2 changes: 1 addition & 1 deletion lib/testcase/rdfsyntax/jsonld/TestCaseJsonLdToRdf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {TestCaseEval, TestCaseEvalHandler} from "../TestCaseEval";

/**
* Test case handler for:
* * https://json-ld.org/test-suite/vocab#ToRDFTest
* * https://w3c.github.io/json-ld-api/tests/vocab#ToRDFTest
* * https://w3c.github.io/json-ld-api/tests/vocab#PositiveEvaluationTest
*/
export class TestCaseJsonLdToRdfHandler extends TestCaseEvalHandler {
Expand Down
Loading

0 comments on commit 116f653

Please sign in to comment.