Skip to content

Commit

Permalink
[ui] Improved CommaNumberInput (#13187)
Browse files Browse the repository at this point in the history
GitOrigin-RevId: 7aaedd8deda222983fb7a8c42ab69e6e39e6ea51
  • Loading branch information
coreymartin authored and Lightspark Eng committed Nov 4, 2024
1 parent da44b3d commit d72f2ba
Show file tree
Hide file tree
Showing 28 changed files with 1,416 additions and 295 deletions.
16 changes: 2 additions & 14 deletions apps/examples/ui-test-app/src/tests/Banner.test.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import { ThemeProvider } from "@emotion/react";
import { Banner } from "@lightsparkdev/ui/components";
import { themes } from "@lightsparkdev/ui/styles/themes";
import { link } from "@lightsparkdev/ui/utils/toReactNodes/nodes";
import { screen, render as tlRender, waitFor } from "@testing-library/react";
import type { ReactElement, ReactNode } from "react";
import { screen, waitFor } from "@testing-library/react";
import { BrowserRouter } from "react-router-dom";
import { TestAppRoutes } from "../types";

function Providers({ children }: { children: ReactNode }) {
return <ThemeProvider theme={themes.dark}>{children}</ThemeProvider>;
}

function render(renderElement: ReactElement) {
return tlRender(renderElement, {
wrapper: Providers,
});
}
import { render } from "./render";

describe("Banner", () => {
test("should properly infer argument types and raise errors for invalid values", async () => {
Expand Down
21 changes: 2 additions & 19 deletions apps/examples/ui-test-app/src/tests/CodeInput.test.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
import { ThemeProvider } from "@emotion/react";
import { jest } from "@jest/globals";
import { CodeInput } from "@lightsparkdev/ui/components/CodeInput/CodeInput";
import { themes } from "@lightsparkdev/ui/styles/themes";
import {
fireEvent,
screen,
render as tlRender,
waitFor,
} from "@testing-library/react";
import { type ReactElement, type ReactNode } from "react";

function Providers({ children }: { children: ReactNode }) {
return <ThemeProvider theme={themes.dark}>{children}</ThemeProvider>;
}

function render(renderElement: ReactElement) {
return tlRender(renderElement, {
wrapper: Providers,
});
}
import { fireEvent, screen, waitFor } from "@testing-library/react";
import { render } from "./render";

describe("CodeInput", () => {
beforeEach(() => {
Expand Down
163 changes: 163 additions & 0 deletions apps/examples/ui-test-app/src/tests/NumberInput.core.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import { jest } from "@jest/globals";
import { NumberInput } from "@lightsparkdev/ui/components/NumberInput";
import "@testing-library/jest-dom";
import { fireEvent, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { render } from "./render";

describe("NumberInput core", () => {
const onChangeSpy = jest.fn();

beforeEach(() => {
jest.clearAllMocks();
});

it("Renders without error", () => {
render(
<NumberInput
id="validationCustom01"
name="inputName"
placeholder="£1,000"
value=""
onChange={() => {}}
/>,
);
const input = screen.getByRole("textbox");

expect(input).toHaveValue("");
});

it("Renders with value", () => {
render(<NumberInput value="1234.56" prefix="£" onChange={() => {}} />);
const input = screen.getByRole("textbox");

expect(input).toHaveValue("£1,234.56");
});

it("Renders with value 0", () => {
render(<NumberInput value="0" prefix="£" onChange={() => {}} />);

expect(screen.getByRole("textbox")).toHaveValue("£0");
});

it("Renders with value 0 with decimalScale 2", () => {
render(
<NumberInput value="0" decimalScale={2} prefix="£" onChange={() => {}} />,
);

expect(screen.getByRole("textbox")).toHaveValue("£0.00");
});

it("Renders with value prop", () => {
render(<NumberInput value="49.99" prefix="£" onChange={() => {}} />);

expect(screen.getByRole("textbox")).toHaveValue("£49.99");
});

it("Renders with value 0.1 with decimalScale 2", async () => {
render(
<NumberInput
value="0.1"
prefix="£"
decimalScale={2}
onChange={() => {}}
/>,
);

expect(screen.getByRole("textbox")).toHaveValue("£0.10");

await userEvent.type(screen.getByRole("textbox"), "{backspace}");

expect(screen.getByRole("textbox")).toHaveValue("£0.1");
});

it("should prefix 0 value", () => {
render(<NumberInput prefix="£" value="0" onChange={onChangeSpy} />);

expect(screen.getByRole("textbox")).toHaveValue("£0");
});

it("should allow empty value", async () => {
const { rerender } = render(
<NumberInput prefix="£" onChange={onChangeSpy} value="1" />,
);
await userEvent.clear(screen.getByRole("textbox"));

expect(onChangeSpy).toHaveBeenLastCalledWith("", {
float: null,
formatted: "",
value: "",
});
rerender(<NumberInput prefix="£" onChange={onChangeSpy} value="" />);
expect(screen.getByRole("textbox")).toHaveValue("");
});

it("should not allow invalid characters", async () => {
render(<NumberInput prefix="£" value="" onChange={onChangeSpy} />);
await userEvent.type(screen.getByRole("textbox"), "hello");

expect(onChangeSpy).toHaveBeenLastCalledWith("", {
float: null,
formatted: "",
value: "",
});

expect(screen.getByRole("textbox")).toHaveValue("");
});

it("should clear decimal point only input", async () => {
render(<NumberInput prefix="£" value="" onChange={onChangeSpy} />);
await userEvent.type(screen.getByRole("textbox"), ".");

expect(onChangeSpy).toHaveBeenLastCalledWith("", {
float: null,
formatted: "",
value: "",
});

fireEvent.focusOut(screen.getByRole("textbox"));
expect(screen.getByRole("textbox")).toHaveValue("");
});

it("should allow .3 decimal inputs", async () => {
const { rerender } = render(
<NumberInput prefix="£" value="" onChange={onChangeSpy} />,
);
await userEvent.type(screen.getByRole("textbox"), ".3");

expect(onChangeSpy).toHaveBeenLastCalledWith(".3", {
float: 0.3,
formatted: "£0.3",
value: ".3",
});

rerender(<NumberInput prefix="£" value=".3" onChange={onChangeSpy} />);
fireEvent.focusOut(screen.getByRole("textbox"));
expect(screen.getByRole("textbox")).toHaveValue("£0.3");
});

it("should update the input when prop value changes to another number", () => {
const { rerender } = render(
<NumberInput
value="1"
placeholder="Please enter a number"
prefix="£"
onChange={() => {}}
/>,
);

const field = screen.getByRole("textbox");
expect(field).toHaveValue("£1");

rerender(
<NumberInput
value="2"
placeholder="Please enter a number"
prefix="£"
onChange={() => {}}
/>,
);

expect(field).toHaveValue("£2");
});
});
Loading

0 comments on commit d72f2ba

Please sign in to comment.