Skip to content

Commit

Permalink
Extract test function as general-use utility (#2947)
Browse files Browse the repository at this point in the history
  • Loading branch information
imnasnainaec authored Feb 14, 2024
1 parent 854c085 commit 71b75cc
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/components/GoalTimeline/tests/GoalRedux.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { GoalStatus, GoalType } from "types/goals";
import { Path } from "types/path";
import { newUser } from "types/user";
import * as goalUtilities from "utilities/goalUtilities";
import { renderWithProviders } from "utilities/testUtilities";
import { renderWithProviders } from "utilities/testingLibraryUtilities";

jest.mock("backend", () => ({
addGoalToUserEdit: (...args: any[]) => mockAddGoalToUserEdit(...args),
Expand Down
22 changes: 8 additions & 14 deletions src/components/ProjectScreen/tests/ChooseProject.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import renderer from "react-test-renderer";

import "tests/reactI18nextMock";

import { Project } from "api/models";
import { type Project } from "api/models";
import ChooseProject from "components/ProjectScreen/ChooseProject";
import { newProject } from "types/project";
import { testInstanceHasText } from "utilities/testRendererUtilities";
import { randomIntString } from "utilities/utilities";

jest.mock("backend", () => ({
Expand All @@ -27,13 +28,6 @@ const mockProj = (name: string): Project => ({

let testRenderer: renderer.ReactTestRenderer;

const hasText = (item: renderer.ReactTestInstance, text: string): boolean => {
const found = item.findAll(
(node) => node.children.length === 1 && node.children[0] === text
);
return found.length !== 0;
};

it("renders with projects in alphabetical order", async () => {
const unordered = ["In the middle", "should be last", "alphabetically first"];
mockGetProjects.mockResolvedValue(unordered.map((name) => mockProj(name)));
Expand All @@ -42,10 +36,10 @@ it("renders with projects in alphabetical order", async () => {
});
const items = testRenderer.root.findAllByType(ListItemButton);
expect(items).toHaveLength(unordered.length);
expect(hasText(items[0], unordered[0])).toBeFalsy;
expect(hasText(items[1], unordered[1])).toBeFalsy;
expect(hasText(items[2], unordered[2])).toBeFalsy;
expect(hasText(items[0], unordered[2])).toBeTruthy;
expect(hasText(items[1], unordered[0])).toBeTruthy;
expect(hasText(items[2], unordered[1])).toBeTruthy;
expect(testInstanceHasText(items[0], unordered[0])).toBeFalsy();
expect(testInstanceHasText(items[1], unordered[1])).toBeFalsy();
expect(testInstanceHasText(items[2], unordered[2])).toBeFalsy();
expect(testInstanceHasText(items[0], unordered[2])).toBeTruthy();
expect(testInstanceHasText(items[1], unordered[0])).toBeTruthy();
expect(testInstanceHasText(items[2], unordered[1])).toBeTruthy();
});
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { Provider } from "react-redux";
import {
ReactTestInstance,
ReactTestRenderer,
act,
create,
} from "react-test-renderer";
import { type ReactTestRenderer, act, create } from "react-test-renderer";
import configureMockStore from "redux-mock-store";

import "tests/reactI18nextMock";
Expand All @@ -17,7 +12,8 @@ import {
} from "goals/CharacterInventory/CharInv/CharacterDetail/FindAndReplace";
import CharacterReplaceDialog from "goals/CharacterInventory/CharInv/CharacterDetail/FindAndReplace/CharacterReplaceDialog";
import { defaultState } from "goals/CharacterInventory/Redux/CharacterInventoryReduxTypes";
import { StoreState } from "types";
import { type StoreState } from "types";
import { testInstanceHasText } from "utilities/testRendererUtilities";

// Dialog uses portals, which are not supported in react-test-renderer.
jest.mock("@mui/material", () => {
Expand Down Expand Up @@ -66,21 +62,14 @@ async function renderCharacterDetail(): Promise<void> {
});
}

const hasText = (item: ReactTestInstance, text: string): boolean => {
const found = item.findAll(
(node) => node.children.length === 1 && node.children[0] === text
);
return found.length !== 0;
};

beforeEach(async () => {
jest.resetAllMocks();
await renderCharacterDetail();
});

describe("CharacterDetail", () => {
it("renders with example word", () => {
expect(hasText(charMaster.root, mockPrefix)).toBeTruthy();
expect(testInstanceHasText(charMaster.root, mockPrefix)).toBeTruthy();
});

describe("FindAndReplace", () => {
Expand Down
13 changes: 13 additions & 0 deletions src/utilities/testRendererUtilities.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { type ReactTestInstance } from "react-test-renderer";

/** Checks if any node in the given `react-test-renderer` instance has the given text. */
export function testInstanceHasText(
instance: ReactTestInstance,
text: string
): boolean {
return (
instance.findAll(
(node) => node.children.length === 1 && node.children[0] === text
).length > 0
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,16 @@ import { PersistGate } from "redux-persist/integration/react";
import { defaultState } from "components/App/DefaultState";
import { type AppStore, type RootState, persistor, setupStore } from "store";

// These test utilities are leveraged from the Redux documentation for Writing Tests:
// https://redux.js.org/usage/writing-tests
// Specifically, see the section on "Integration Testing Connected Components
// and Redux Logic"

// This type interface extends the default options for render from RTL, as well
// as allows the user to specify other things such as initialState, store.
/** This extends the default options for `render` from `@testing-library/react`,
* allowing the user to specify other things such as `initialState`, `store`. */
interface ExtendedRenderOptions extends Omit<RenderOptions, "queries"> {
preloadedState?: PreloadedState<RootState>;
store?: AppStore;
}

/** This test utility is leveraged from the Redux documentation for Writing Tests:
* https://redux.js.org/usage/writing-tests. Specifically, see the section on
* "Integration Testing Connected Components and Redux Logic" */
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export function renderWithProviders(
ui: ReactElement,
Expand Down

0 comments on commit 71b75cc

Please sign in to comment.