Skip to content

Commit

Permalink
feat: validationIsFatal option
Browse files Browse the repository at this point in the history
  • Loading branch information
jenspots committed Mar 30, 2024
1 parent 1ff49f4 commit a0267a6
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Validate an incoming data stream using SHACL. If the incoming data is valid, it
- `incoming`: channel which is used as the data source.
- `outgoing`: channel into which valid data is written.
- `report`: an optional channel into which the SHACL reports of invalid input data is written. (default: `null`)
- `validationIsFatal`: throw a fatal error if validation fails. (default: `false`)

## Limitations

Expand Down
8 changes: 8 additions & 0 deletions src/error.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
enum ShaclErrorType {
FileSystemError,
InvalidRdfFormat,
ValidationFailed,
}

export class ShaclError extends Error {
Expand All @@ -25,4 +26,11 @@ export class ShaclError extends Error {
ShaclErrorType.InvalidRdfFormat,
);
}

static validationFailed() {
return new ShaclError(
"Validation failed and is fatal.",
ShaclErrorType.ValidationFailed,
);
}
}
6 changes: 4 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ type ValidateArguments = {
incoming: Stream<string>;
outgoing: Writer<string>;
report?: Writer<string>;
verbose?: boolean;
validationIsFatal?: boolean;
};

export async function validate(
args: ValidateArguments,
): Promise<() => Promise<void>> {
const { path, incoming, outgoing, report } = args;
const { path, incoming, outgoing, report, validationIsFatal } = args;

// Initialize the shared serializer.
const prefixes = new PrefixMapFactory().prefixMap();
Expand Down Expand Up @@ -63,6 +63,8 @@ export async function validate(
// Pass through data if valid.
if (result.conforms) {
await outgoing.push(data);
} else if (validationIsFatal) {
throw ShaclError.validationFailed();
} else if (report) {
const resultRaw = serializer.transform(result.dataset);
await report.push(resultRaw);
Expand Down
46 changes: 46 additions & 0 deletions tests/error.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { describe, test, expect } from "vitest";
import { validate } from "../src";
import { SimpleStream } from "@ajuvercr/js-runner";
import { ShaclError } from "../src/error";
import fs from "fs";

const shaclPath = "./tests/shacl/point.ttl";

const invalidRdfData = fs.readFileSync("./tests/data/invalid.ttl").toString();

describe("errors", () => {
test("invalid shacl file path", async () => {
Expand All @@ -27,4 +32,45 @@ describe("errors", () => {

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

test("invalid input data", async () => {
expect.assertions(1);

const incoming = new SimpleStream<string>();
const outgoing = new SimpleStream<string>();

const func = await validate({
path: shaclPath,
incoming,
outgoing,
});
await func();

expect(
incoming.push("This is not a valid Turtle file!"),
).rejects.toThrow(ShaclError.invalidRdfFormat());

await incoming.end();
await outgoing.end();
});

test("invalid and fatal", async () => {
expect.assertions(1);

const incoming = new SimpleStream<string>();

const func = await validate({
path: shaclPath,
incoming,
outgoing: new SimpleStream<string>(),
validationIsFatal: true,
});
await func();

expect(incoming.push(invalidRdfData)).rejects.toThrow(
ShaclError.validationFailed(),
);

await incoming.end();
});
});

0 comments on commit a0267a6

Please sign in to comment.