diff --git a/packages/solid/src/requester/results/error/AccessControlError.ts b/packages/solid/src/requester/results/error/AccessControlError.ts index c9d128a..ba08ccf 100644 --- a/packages/solid/src/requester/results/error/AccessControlError.ts +++ b/packages/solid/src/requester/results/error/AccessControlError.ts @@ -1,3 +1,4 @@ +/* istanbul ignore file */ import { ResourceError } from "./ErrorResult"; export class AccessRuleFetchError extends ResourceError { diff --git a/packages/solid/src/requester/results/error/ErrorResult.ts b/packages/solid/src/requester/results/error/ErrorResult.ts index 0940884..2efaa56 100644 --- a/packages/solid/src/requester/results/error/ErrorResult.ts +++ b/packages/solid/src/requester/results/error/ErrorResult.ts @@ -5,7 +5,7 @@ export abstract class ErrorResult extends Error implements RequesterResult { readonly isError = true as const; constructor(message?: string) { - super(message || "An error unkown error was encountered."); + super(message || "An unkown error was encountered."); } } @@ -13,7 +13,7 @@ export abstract class ResourceError extends ErrorResult { readonly uri: string; constructor(uri: string, message?: string) { - super(message || `An error unkown error for ${uri}`); + super(message || `An unkown error for ${uri}`); this.uri = uri; } } diff --git a/packages/solid/test/Integration.test.ts b/packages/solid/test/Integration.test.ts index e21818b..f06b924 100644 --- a/packages/solid/test/Integration.test.ts +++ b/packages/solid/test/Integration.test.ts @@ -398,6 +398,35 @@ describe("SolidLdoDataset", () => { expect(resource.isUnfetched()).toBe(true); expect(resource.isPresent()).toBe(undefined); }); + + it("batches the read request when a read request is currently happening", async () => { + const resource = solidLdoDataset.getResource(SAMPLE_DATA_URI); + const [result, result1] = await Promise.all([ + resource.read(), + resource.read(), + ]); + + expect(result.type).toBe("dataReadSuccess"); + expect(result1.type).toBe("dataReadSuccess"); + expect(fetchMock).toHaveBeenCalledTimes(1); + }); + + it("batches the read request when a read request is in queue", async () => { + const resource = solidLdoDataset.getResource(SAMPLE_DATA_URI); + const [, result, result1] = await Promise.all([ + resource.update({ + added: createDataset([ + createQuad(namedNode("a"), namedNode("b"), namedNode("c")), + ]), + }), + resource.read(), + resource.read(), + ]); + + expect(result.type).toBe("dataReadSuccess"); + expect(result1.type).toBe("dataReadSuccess"); + expect(fetchMock).toHaveBeenCalledTimes(2); + }); }); /** @@ -708,6 +737,33 @@ describe("SolidLdoDataset", () => { expect(result.isError).toBe(true); expect(result.type).toBe("unexpectedResourceError"); }); + + it("batches the create request while waiting on another request", async () => { + const resource = solidLdoDataset.getResource(SAMPLE2_DATA_URI); + const [, result1, result2] = await Promise.all([ + resource.read(), + resource.createAndOverwrite(), + resource.createAndOverwrite(), + ]); + + expect(result1.type).toBe("createSuccess"); + expect(result2.type).toBe("createSuccess"); + // 1 for read, 1 for delete in createAndOverwrite, 1 for create + expect(fetchMock).toHaveBeenCalledTimes(3); + }); + + it("batches the create request while waiting on a similar request", async () => { + const resource = solidLdoDataset.getResource(SAMPLE2_DATA_URI); + const [result1, result2] = await Promise.all([ + resource.createAndOverwrite(), + resource.createAndOverwrite(), + ]); + + expect(result1.type).toBe("createSuccess"); + expect(result2.type).toBe("createSuccess"); + // 1 for delete in createAndOverwrite, 1 for create + expect(fetchMock).toHaveBeenCalledTimes(2); + }); }); describe("createIfAbsent", () => { @@ -1262,25 +1318,41 @@ describe("SolidLdoDataset", () => { const resource = solidLdoDataset.getResource(SAMPLE2_DATA_URI); const [, result1, result2] = await Promise.all([ resource.read(), - resource.createAndOverwrite(), - resource.createAndOverwrite(), + resource.uploadAndOverwrite( + Buffer.from("some text.") as unknown as Blob, + "text/plain", + ), + resource.uploadAndOverwrite( + Buffer.from("some text 2.") as unknown as Blob, + "text/plain", + ), ]); expect(result1.type).toBe("createSuccess"); expect(result2.type).toBe("createSuccess"); - expect(fetchMock).toHaveBeenCalledTimes(1); + // 1 for read, 1 for delete in createAndOverwrite, 1 for create + expect(fetchMock).toHaveBeenCalledTimes(3); + expect(resource.getBlob()?.toString()).toBe("some text 2."); }); it("batches the upload request while waiting on a similar request", async () => { const resource = solidLdoDataset.getResource(SAMPLE2_DATA_URI); const [result1, result2] = await Promise.all([ - resource.createAndOverwrite(), - resource.createAndOverwrite(), + resource.uploadAndOverwrite( + Buffer.from("some text.") as unknown as Blob, + "text/plain", + ), + resource.uploadAndOverwrite( + Buffer.from("some text 2.") as unknown as Blob, + "text/plain", + ), ]); expect(result1.type).toBe("createSuccess"); expect(result2.type).toBe("createSuccess"); - expect(fetchMock).toHaveBeenCalledTimes(1); + // 1 for delete in createAndOverwrite, 1 for create + expect(fetchMock).toHaveBeenCalledTimes(2); + expect(resource.getBlob()?.toString()).toBe("some text 2."); }); }); diff --git a/packages/solid/test/guaranteeFetch.test.ts b/packages/solid/test/guaranteeFetch.test.ts new file mode 100644 index 0000000..92cf6c4 --- /dev/null +++ b/packages/solid/test/guaranteeFetch.test.ts @@ -0,0 +1,8 @@ +import { guaranteeFetch } from "../src/util/guaranteeFetch"; +import crossFetch from "cross-fetch"; + +describe("guaranteeFetch", () => { + it("returns crossfetch when no fetch is provided", () => { + expect(guaranteeFetch()).toBe(crossFetch); + }); +}); diff --git a/packages/solid/test/uriTypes.test.ts b/packages/solid/test/uriTypes.test.ts new file mode 100644 index 0000000..589e874 --- /dev/null +++ b/packages/solid/test/uriTypes.test.ts @@ -0,0 +1,7 @@ +import { isLeafUri } from "../src"; + +describe("isLeafUri", () => { + it("returns true if the given value is a leaf URI", () => { + expect(isLeafUri("https://example.com/index.ttl")).toBe(true); + }); +});