From acfc3b87d9559b1f92622af98717df756a406192 Mon Sep 17 00:00:00 2001 From: Jens Pots Date: Tue, 9 Apr 2024 11:13:41 +0200 Subject: [PATCH] refactor: do not return a function from `validate` --- src/index.ts | 62 ++++++++++++++++++++++----------------------- tests/error.test.ts | 57 ++++++++++++++++------------------------- tests/index.test.ts | 10 +++----- 3 files changed, 56 insertions(+), 73 deletions(-) diff --git a/src/index.ts b/src/index.ts index 3b7b620..2ece2e7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,7 +15,7 @@ type ValidateArguments = { validationIsFatal?: boolean; }; -export async function validate(args: ValidateArguments): Promise<() => void> { +export async function validate(args: ValidateArguments): Promise { const { shaclPath, incoming, outgoing, report } = args; // Default arguments. @@ -50,38 +50,36 @@ export async function validate(args: ValidateArguments): Promise<() => void> { // @ts-expect-error Factory is valid. const validator = new Validator(shapes, { factory: rdf }); - return () => { - // Anything that passes through this processor and identifies with a - // specific shape should match the SHACL definition. - incoming.on("data", async (data) => { - // Parse data into a dataset. - const rawStream = Readable.from(data); - const quadStream = parser.import(rawStream); - const dataset = await rdf - .dataset() - .import(quadStream) - .catch(() => { - throw ShaclError.invalidRdfFormat(); - }); + // Anything that passes through this processor and identifies with a + // specific shape should match the SHACL definition. + incoming.on("data", async (data) => { + // Parse data into a dataset. + const rawStream = Readable.from(data); + const quadStream = parser.import(rawStream); + const dataset = await rdf + .dataset() + .import(quadStream) + .catch(() => { + throw ShaclError.invalidRdfFormat(); + }); - // Run through validator. - const result = await validator.validate({ dataset }); + // Run through validator. + const result = await validator.validate({ dataset }); - // 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); - } - }); + // 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); + } + }); - // If the input stream closes itself, so should the output streams. - incoming.on("end", () => { - outgoing.end(); - report?.end(); - }); - }; + // If the input stream closes itself, so should the output streams. + incoming.on("end", () => { + outgoing.end(); + report?.end(); + }); } diff --git a/tests/error.test.ts b/tests/error.test.ts index ef9846b..3bd2dcd 100644 --- a/tests/error.test.ts +++ b/tests/error.test.ts @@ -4,22 +4,27 @@ import { SimpleStream } from "@ajuvercr/js-runner"; import { ShaclError } from "../src/error"; import fs from "fs"; +// Parse input files beforehand and share among tests. const shaclPath = "./tests/shacl/point.ttl"; - +const validJsonLd = fs.readFileSync("./tests/data/valid.jsonld").toString(); const invalidRdfData = fs.readFileSync("./tests/data/invalid.ttl").toString(); +// These streams can be used as a fallback, and shouldn't contain any tested +// data. +const incoming = new SimpleStream(); +const outgoing = new SimpleStream(); + describe("errors", () => { test("invalid shacl file path", async () => { expect.assertions(1); - const func = () => - validate({ - shaclPath: "/tmp/shacl-doesnt-exist.ttl", - incoming: new SimpleStream(), - outgoing: new SimpleStream(), - }); + const func = validate({ + shaclPath: "/tmp/shacl-doesnt-exist.ttl", + incoming, + outgoing, + }); - expect(func()).rejects.toThrow(ShaclError.fileSystemError()); + expect(func).rejects.toThrow(ShaclError.fileSystemError()); }); test("invalid data rdf format", async () => { @@ -27,8 +32,8 @@ describe("errors", () => { const func = validate({ shaclPath, - incoming: new SimpleStream(), - outgoing: new SimpleStream(), + incoming, + outgoing, mime: "text/invalid", }); @@ -40,8 +45,8 @@ describe("errors", () => { const func = validate({ shaclPath: "./tests/shacl/invalid.ttl", - incoming: new SimpleStream(), - outgoing: new SimpleStream(), + incoming, + outgoing, }); expect(func).rejects.toThrowError(ShaclError.invalidRdfFormat()); @@ -50,59 +55,41 @@ describe("errors", () => { test("invalid input data", async () => { expect.assertions(1); - const incoming = new SimpleStream(); - const outgoing = new SimpleStream(); - - const func = await validate({ + await validate({ shaclPath, incoming, outgoing, }); - 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(); - - const func = await validate({ + await validate({ shaclPath, incoming, - outgoing: new SimpleStream(), + outgoing, validationIsFatal: true, }); - func(); expect(incoming.push(invalidRdfData)).rejects.toThrow( ShaclError.validationFailed(), ); - - await incoming.end(); }); test("incorrect mime", async () => { expect.assertions(1); - const validJsonLd = fs - .readFileSync("./tests/data/valid.jsonld") - .toString(); - const incoming = new SimpleStream(); - - const func = await validate({ + await validate({ shaclPath, incoming, - outgoing: new SimpleStream(), + outgoing, mime: "text/turtle", }); - func(); expect(async () => { await incoming.push(validJsonLd); diff --git a/tests/index.test.ts b/tests/index.test.ts index c5243dc..333ae30 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -2,7 +2,6 @@ import { validate } from "../src"; import { SimpleStream } from "@ajuvercr/js-runner"; import { describe, test, expect, beforeEach } from "vitest"; import * as fs from "fs"; -import { ShaclError } from "../src/error"; // Channel which streams incoming RDF. let incoming: SimpleStream; @@ -59,14 +58,13 @@ beforeEach(async () => { describe("shacl", () => { beforeEach(async () => { - // Restart the processor, which is the same for each test. - const func = await validate({ + // Reset the validation function. + await validate({ shaclPath, incoming, outgoing, report, }); - func(); }); test("successful", async () => { @@ -104,14 +102,14 @@ describe("shacl - config", () => { test("mime", async () => { expect.assertions(2); - const func = await validate({ + const func = validate({ shaclPath, incoming, outgoing, report, mime: "application/n-triples", }); - func(); + await func; await incoming.push(validNTriples); await endAll();