Completed useResource tests

main
jaxoncreed 2 years ago
parent 1237625c7c
commit 787c50e330
  1. 2
      packages/solid-react/package.json
  2. 3
      packages/solid-react/src/useResource.ts
  3. 94
      packages/solid-react/test/Integration.test.tsx
  4. 1
      packages/solid/src/requester/BatchedRequester.ts
  5. 2
      packages/solid/src/resource/Resource.ts
  6. 24
      packages/solid/src/util/RequestBatcher.ts

@ -13,7 +13,7 @@
"lint": "eslint src/** --fix --no-error-on-unmatched-pattern",
"test:integration": "start-server-and-test start-test-server http://localhost:3001 start-integration-test",
"start-test-server": "ts-node ./test/test-server/runServer.ts",
"start-integration-test": "jest --coverage -t \"Reloads the data on mount\""
"start-integration-test": "jest --coverage"
},
"repository": {
"type": "git",

@ -42,15 +42,12 @@ export function useResource(
// Get the resource
const resource = useMemo(() => {
console.log(uri);
if (uri) {
const resource = getResource(uri);
// Run read operations if necissary
if (!options?.suppressInitialRead) {
if (options?.reloadOnMount) {
console.log("Reading again");
resource.read();
console.log(resource.isLoading());
} else {
resource.readIfUnfetched();
}

@ -1,7 +1,7 @@
import React, { useEffect, useState } from "react";
import type { FunctionComponent } from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { SAMPLE_DATA_URI, setUpServer } from "./setUpServer";
import { SAMPLE_BINARY_URI, SAMPLE_DATA_URI, setUpServer } from "./setUpServer";
import { UnauthenticatedSolidLdoProvider } from "../src/UnauthenticatedSolidLdoProvider";
import { useResource } from "../src/useResource";
@ -56,40 +56,66 @@ describe("Integration Tests", () => {
const resourceStatus = await screen.findByRole("status");
expect(resourceStatus.innerHTML).toBe("unfetched");
});
});
it("Reloads the data on mount", async () => {
const ReloadTest: FunctionComponent = () => {
const resource = useResource(SAMPLE_DATA_URI, { reloadOnMount: true });
if (resource?.isLoading()) return <p>Loading</p>;
return <p role="status">{resource.status.type}</p>;
};
const ReloadParent: FunctionComponent = () => {
const [showComponent, setShowComponent] = useState(true);
return (
<div>
<button onClick={() => setShowComponent(!showComponent)}>
Show Component
</button>
{showComponent ? <ReloadTest /> : <p>Hidden</p>}
</div>
it("Reloads the data on mount", async () => {
const ReloadTest: FunctionComponent = () => {
const resource = useResource(SAMPLE_DATA_URI, { reloadOnMount: true });
if (resource?.isLoading()) return <p>Loading</p>;
return <p role="status">{resource.status.type}</p>;
};
const ReloadParent: FunctionComponent = () => {
const [showComponent, setShowComponent] = useState(true);
return (
<div>
<button onClick={() => setShowComponent(!showComponent)}>
Show Component
</button>
{showComponent ? <ReloadTest /> : <p>Hidden</p>}
</div>
);
};
render(
<UnauthenticatedSolidLdoProvider>
<ReloadParent />
</UnauthenticatedSolidLdoProvider>,
);
};
render(
<UnauthenticatedSolidLdoProvider>
<ReloadParent />
</UnauthenticatedSolidLdoProvider>,
);
await screen.findByText("Loading");
const resourceStatus1 = await screen.findByRole("status");
expect(resourceStatus1.innerHTML).toBe("dataReadSuccess");
console.log("==============");
fireEvent.click(screen.getByText("Show Component"));
await screen.findByText("Hidden");
console.log("++++++++++++++");
fireEvent.click(screen.getByText("Show Component"));
await screen.findByText("Loading");
const resourceStatus2 = await screen.findByRole("status");
expect(resourceStatus2.innerHTML).toBe("dataReadSuccess");
await screen.findByText("Loading");
const resourceStatus1 = await screen.findByRole("status");
expect(resourceStatus1.innerHTML).toBe("dataReadSuccess");
fireEvent.click(screen.getByText("Show Component"));
await screen.findByText("Hidden");
fireEvent.click(screen.getByText("Show Component"));
await screen.findByText("Loading");
const resourceStatus2 = await screen.findByRole("status");
expect(resourceStatus2.innerHTML).toBe("dataReadSuccess");
});
it("handles swapping to a new resource", async () => {
const SwapResourceTest: FunctionComponent = () => {
const [uri, setUri] = useState(SAMPLE_DATA_URI);
const resource = useResource(uri);
if (resource?.isLoading()) return <p>Loading</p>;
return (
<div>
<p role="status">{resource.status.type}</p>
<button onClick={() => setUri(SAMPLE_BINARY_URI)}>
Update URI
</button>
</div>
);
};
render(
<UnauthenticatedSolidLdoProvider>
<SwapResourceTest />
</UnauthenticatedSolidLdoProvider>,
);
await screen.findByText("Loading");
const resourceStatus1 = await screen.findByRole("status");
expect(resourceStatus1.innerHTML).toBe("dataReadSuccess");
fireEvent.click(screen.getByText("Update URI"));
await screen.findByText("Loading");
const resourceStatus2 = await screen.findByRole("status");
expect(resourceStatus2.innerHTML).toBe("binaryReadSuccess");
});
});
});

@ -55,7 +55,6 @@ export abstract class BatchedRequester {
* @returns true if the resource is making any requests
*/
isLoading(): boolean {
console.log("In isLoading");
return this.requestBatcher.isLoading(ANY_KEY);
}

@ -325,9 +325,7 @@ export abstract class Resource extends (EventEmitter as new () => TypedEmitter<{
* @returns ReadResult
*/
protected async handleRead(): Promise<ReadContainerResult | ReadLeafResult> {
console.log("Handle read");
const result = await this.requester.read();
console.log("End Handle Read");
this.status = result;
if (result.isError) return result;
this.updateWithReadSuccess(result);

@ -89,9 +89,6 @@ export class RequestBatcher {
* @returns true if the batcher is currently working on the provided process
*/
public isLoading(key: string): boolean {
console.log("In Is loadin:", key);
console.log("CurrentlyProcessing:", this.currentlyProcessing);
if (key === ANY_KEY) return !!this.currentlyProcessing;
return this.currentlyProcessing?.name === key;
}
@ -102,10 +99,11 @@ export class RequestBatcher {
* the last process was triggered.
*/
private triggerOrWaitProcess() {
if (!this.processQueue[0]) {
if (!this.processQueue[0] || this.currentlyProcessing) {
return;
}
const processName = this.processQueue[0].name;
this.currentlyProcessing = this.processQueue.shift();
const processName = this.currentlyProcessing!.name;
// Set last request timestamp if not available
if (!this.lastRequestTimestampMap[processName]) {
@ -116,31 +114,20 @@ export class RequestBatcher {
const timeSinceLastTrigger = Date.now() - lastRequestTimestamp;
const triggerProcess = async () => {
console.log("Triggering process");
// Don't run the process if something is currently processing.
// "triggerProcess" will be called again because this item is still in the
// queue
if (this.currentlyProcessing) {
return;
}
this.lastRequestTimestampMap[processName] = Date.now();
this.lastRequestTimestampMap[ANY_KEY] = Date.now();
// Remove the process from the queue
const processToTrigger = this.processQueue.shift();
const processToTrigger = this.currentlyProcessing;
if (processToTrigger) {
this.currentlyProcessing = processToTrigger;
try {
console.log("Before process trigger");
console.log("The current:", this.currentlyProcessing);
const returnValue = await processToTrigger.perform(
...processToTrigger.args,
);
console.log("After process trigger");
if (processToTrigger.after) {
processToTrigger.after(returnValue);
}
processToTrigger.awaitingResolutions.forEach((callback) => {
console.log("Resolved");
callback(returnValue);
});
} catch (err) {
@ -155,10 +142,8 @@ export class RequestBatcher {
};
if (timeSinceLastTrigger < this.batchMillis) {
console.log("Waiting for the future");
setTimeout(triggerProcess, this.batchMillis - timeSinceLastTrigger);
} else {
console.log("Doing it now");
triggerProcess();
}
}
@ -172,7 +157,6 @@ export class RequestBatcher {
options: WaitingProcessOptions<Args, ReturnType>,
): Promise<ReturnType> {
return new Promise((resolve, reject) => {
console.log("Queuing process");
const shouldAwait = options.modifyQueue(
this.processQueue,
this.currentlyProcessing,

Loading…
Cancel
Save