From 9cca11b7854ef3814940bdef77c0fbdc410481c2 Mon Sep 17 00:00:00 2001 From: "Ziyuan (Jerry) Zhang" <ziyuanzhang2019@gmail.com> Date: Fri, 23 Feb 2024 16:49:33 -0500 Subject: [PATCH] Add prop types, error boundary tests --- demo/src/App.tsx | 10 ++++- demo/src/MemoryModels.tsx | 10 ++++- demo/src/SvgDisplay.tsx | 6 ++- demo/src/__tests__/App.spec.tsx | 44 +++++++++++++++++++ .../__tests__/MemoryModelsUserInput.spec.tsx | 1 + demo/src/__tests__/SvgDisplay.spec.tsx | 2 +- 6 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 demo/src/__tests__/App.spec.tsx diff --git a/demo/src/App.tsx b/demo/src/App.tsx index 7d80a2e7..aedec23b 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -12,7 +12,7 @@ export default function App() { try { setJsonResult(JSON.parse(formData)); } catch (error) { - console.error("Error parsing inputted JSON: ", error); + console.error(`Error parsing inputted JSON: ${error.message}`); setJsonResult(null); } }; @@ -26,7 +26,13 @@ export default function App() { /> <section> <h2>Output</h2> - <ErrorBoundary fallback={<div>Something went wrong</div>}> + <ErrorBoundary + fallback={ + <div data-testid="svg-display-error-boundary"> + Something went wrong + </div> + } + > <SvgDisplay jsonResult={jsonResult} /> </ErrorBoundary> </section> diff --git a/demo/src/MemoryModels.tsx b/demo/src/MemoryModels.tsx index 404369c2..70b647ac 100644 --- a/demo/src/MemoryModels.tsx +++ b/demo/src/MemoryModels.tsx @@ -1,7 +1,15 @@ import React from "react"; import { Button, Card, CardContent, TextField, Grid } from "@mui/material"; -export default function MemoryModelsUserInput(props) { +type MemoryModelsUserInputPropTypes = { + onSubmit: (event: React.MouseEvent<HTMLFormElement>) => void; + setFormData: React.Dispatch<React.SetStateAction<string>>; + formData: string; +}; + +export default function MemoryModelsUserInput( + props: MemoryModelsUserInputPropTypes +) { const handleTextFieldChange = (event) => { props.setFormData(event.target.value); }; diff --git a/demo/src/SvgDisplay.tsx b/demo/src/SvgDisplay.tsx index dd4d10d0..c993e54d 100644 --- a/demo/src/SvgDisplay.tsx +++ b/demo/src/SvgDisplay.tsx @@ -1,7 +1,11 @@ import React, { useRef, useEffect } from "react"; import mem from "../../src/index"; // TODO: replace with import of the package after it's been published -export default function SvgDisplay(props) { +type SvgDisplayPropTypes = { + jsonResult: object; +}; + +export default function SvgDisplay(props: SvgDisplayPropTypes) { const canvasRef = useRef(null); useEffect(() => { diff --git a/demo/src/__tests__/App.spec.tsx b/demo/src/__tests__/App.spec.tsx new file mode 100644 index 00000000..769beb4f --- /dev/null +++ b/demo/src/__tests__/App.spec.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import { fireEvent, render, screen } from "@testing-library/react"; +import App from "../App"; + +describe("App", () => { + beforeEach(() => { + render(<App />); + }); + + it("renders Output heading", () => { + expect(screen.getByText("Output").nodeName).toEqual("H2"); + }); + + it("renders ErrorBoundary fallback element when draw function throws error", () => { + jest.mock("../../../src/index", () => ({ + draw: jest.fn(() => { + throw new Error(); + }), + })); + const input = screen.getByLabelText("Enter memory model JSON here"); + // In order to get to draw function, input has to be valid json otherwise JSON.parse fails + fireEvent.change(input, { target: { value: "[{}]" } }); + const button = screen.getByTestId("input-submit-button"); + fireEvent.click(button); + + const errorBoundary = screen.getByTestId("svg-display-error-boundary"); + expect(errorBoundary.textContent).toEqual("Something went wrong"); + }); + + it("calls console error when the input is not valid JSON", () => { + const consoleErrorSpy = jest + .spyOn(console, "error") + .mockImplementation(); + + const input = screen.getByLabelText("Enter memory model JSON here"); + fireEvent.change(input, { target: { value: "*&#*#(@(!(" } }); + const button = screen.getByTestId("input-submit-button"); + fireEvent.click(button); + + expect(consoleErrorSpy).toHaveBeenCalledWith( + expect.stringMatching(/^Error parsing inputted JSON: /) + ); + }); +}); diff --git a/demo/src/__tests__/MemoryModelsUserInput.spec.tsx b/demo/src/__tests__/MemoryModelsUserInput.spec.tsx index e4f59d1b..d4f799e9 100644 --- a/demo/src/__tests__/MemoryModelsUserInput.spec.tsx +++ b/demo/src/__tests__/MemoryModelsUserInput.spec.tsx @@ -30,6 +30,7 @@ describe("MemoryModelsUserInput", () => { render( <MemoryModelsUserInput + onSubmit={onSubmitMock} setFormData={setFormDataMock} formData={formDataMock} /> diff --git a/demo/src/__tests__/SvgDisplay.spec.tsx b/demo/src/__tests__/SvgDisplay.spec.tsx index cfd649b9..7fb48f7d 100644 --- a/demo/src/__tests__/SvgDisplay.spec.tsx +++ b/demo/src/__tests__/SvgDisplay.spec.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { cleanup, render, screen } from "@testing-library/react"; +import { render, screen } from "@testing-library/react"; import SvgDisplay from "../SvgDisplay"; import mem from "../../../src/index"; const { draw } = mem;