Skip to content

Commit

Permalink
refactor: updated for readability
Browse files Browse the repository at this point in the history
  • Loading branch information
jenspots committed Mar 30, 2024
1 parent 1e807aa commit 1339f80
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 11 deletions.
19 changes: 16 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { Readable } from "stream";
import formatsPretty from "@rdfjs/formats/pretty.js";
import Serializer from "@rdfjs/serializer-turtle";
import { Validator } from "shacl-engine";
import { ShaclError } from "./error";

type ValidateArguments = {
path: string;
incoming: Stream<string>;
outgoing: Writer<string>;
report?: Writer<string>;
verbose?: boolean;
};

export async function validate(
Expand All @@ -29,7 +31,13 @@ export async function validate(

// Create shape stream.
const res = await rdf.fetch(path);
const shapes = await res.dataset();
if (!res.ok) {
throw ShaclError.fileSystemError();
}

const shapes = await res.dataset().catch(() => {
throw ShaclError.invalidRdfFormat();
});

// Parse input stream using shape stream.
// @ts-expect-error Factory is valid.
Expand All @@ -42,16 +50,21 @@ export async function validate(
// Parse data into a dataset.
const rawStream = Readable.from(data);
const quadStream = parser.import(rawStream);
const dataset = await rdf.dataset().import(quadStream);
const dataset = await rdf
.dataset()
.import(quadStream)
.catch(() => {
throw ShaclError.invalidRdfFormat();
});

// Run through validator.
const result = await validator.validate({ dataset });
const resultRaw = serializer.transform(result.dataset);

// Pass through data if valid.
if (result.conforms) {
await outgoing.push(data);
} else if (report) {
const resultRaw = serializer.transform(result.dataset);
await report.push(resultRaw);
}
});
Expand Down
16 changes: 8 additions & 8 deletions tests/data/invalid.report.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@
[ a sh:ValidationReport;
sh:conforms false;
sh:result [ a sh:ValidationResult;
sh:focusNode ex:ValidPoint;
sh:resultMessage "Requires an integer X coordinate";
sh:resultPath ex:x;
sh:resultSeverity sh:Violation;
sh:sourceConstraintComponent sh:DatatypeConstraintComponent;
sh:sourceShape [];
sh:value "1"
], [ a sh:ValidationResult;
sh:focusNode ex:ValidPoint;
sh:resultMessage "Requires an integer Y coordinate";
sh:resultPath ex:y;
Expand All @@ -27,5 +19,13 @@
sh:sourceConstraintComponent sh:ClosedConstraintComponent;
sh:sourceShape ex:PointShape;
sh:value "3"
], [ a sh:ValidationResult;
sh:focusNode ex:ValidPoint;
sh:resultMessage "Requires an integer X coordinate";
sh:resultPath ex:x;
sh:resultSeverity sh:Violation;
sh:sourceConstraintComponent sh:DatatypeConstraintComponent;
sh:sourceShape [];
sh:value "1"
]
].
30 changes: 30 additions & 0 deletions tests/error.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, test, expect } from "vitest";
import { validate } from "../src";
import { SimpleStream } from "@ajuvercr/js-runner";
import { ShaclError } from "../src/error";

describe("errors", () => {
test("invalid shacl file path", async () => {
expect.assertions(1);

const func = validate({
path: "/tmp/shacl-doesnt-exist.ttl",
incoming: new SimpleStream<string>(),
outgoing: new SimpleStream<string>(),
});

expect(func).rejects.toThrow(ShaclError.fileSystemError());
});

test("invalid shacl rdf format", async () => {
expect.assertions(1);

const func = validate({
path: "./tests/shacl/invalid.ttl",
incoming: new SimpleStream<string>(),
outgoing: new SimpleStream<string>(),
});

expect(func).rejects.toThrow(ShaclError.invalidRdfFormat());
});
});
25 changes: 25 additions & 0 deletions tests/shacl/invalid.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@prefix ex: <http://example.org#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:PointShape
a sh:NodeShape;
sh:targetClass ex:Point;
sh:closed true;
sh:ignoredProperties (rdf:type);
sh:property [
sh:path ex:x;
sh:message "Requires an integer X coordinate";
sh:name "X-coordinate";
sh:datatype xsd:integer;
sh:minCount 1;
sh:maxCount 1;
], [
sh:path ex:y;
sh:message "Requires an integer Y coordinate";
sh:name "Y-coordinate";
sh:datatype xsd:integer;
sh:minCount 1;
sh:maxCount 1;
] # NOTE: Intentionally misses a period here!

0 comments on commit 1339f80

Please sign in to comment.