import {
describe,
each,
expect,
getFormValues,
it,
render,
select,
trapEvents,
user,
} from "../../utils/Test";
describe("uwc-input[type=number]", () => {
const getVisibleText = (input: UwcInputElement) =>
select(input, "div[contenteditable]").textContent ||
select(input, "div[part=placeholder]").textContent;
it("should render a placeholder when empty", () => {
const page = render(
,
);
const placeholder = select(page, "[part=placeholder]");
expect(window.getComputedStyle(placeholder).visibility).to.eq("visible");
});
it("should not render a placeholder when filled out", () => {
const page = render();
const placeholder = select(page, "[part=placeholder]");
expect(window.getComputedStyle(placeholder).visibility).to.eq("hidden");
});
it("should start with undefined if no value is specified", () => {
const page = render();
const input = select(page, "uwc-input");
expect(getVisibleText(input)).to.eq("");
expect(input.value).to.be.undefined;
});
it("should remove non-numeric values from the form", () => {
const page = render(
,
);
const form = select(page, "form");
const input = select(page, "uwc-input");
expect(getFormValues(form)).to.deep.eq({ foo: "3" });
input.value = undefined;
expect(input.value).to.eq(undefined);
expect(getFormValues(form)).to.deep.eq({});
});
it("should not accept invalid values", () => {
const page = render();
const input = select(page, "uwc-input");
expect(getVisibleText(input)).to.eq("");
expect(input.value).to.be.undefined;
});
it("should be possible to clear it", () => {
const page = render(
,
);
const form = select(page, "form");
const input = select(page, "uwc-input");
expect(getFormValues(form)).to.deep.eq({ foo: "3.1415" });
input.clear();
expect(getFormValues(form)).to.deep.eq({});
expect(getVisibleText(input)).to.eq("");
expect(input.value).to.be.undefined;
});
it("should have a numeric value", () => {
const page = render();
const input = select(page, "uwc-input");
expect(input.value).to.eq(3);
});
it("should not be possible to enter non-numeric values", async () => {
const page = render();
const input = select(page, "uwc-input");
await user.type(input, "abc");
expect(input.value).to.eq(undefined);
});
it("should format numbers according to locale", () => {
const page = render(
,
);
const input = select(page, "uwc-input");
expect(input.value).to.eq(3.1415);
expect(getVisibleText(input)).to.eq("3,1415");
});
it("should only allow input according to locale", async () => {
const page = render();
const input = select(page, "uwc-input");
await user.type(input, "3.1415");
expect(input.value).to.eq(31415);
await user.type(
input,
"{Backspace}{Backspace}{Backspace}{Backspace}{Backspace}",
);
await user.type(input, "3,1415");
expect(input.value).to.eq(3.1415);
});
it("should not emit input events for invalid changes", async () => {
const page = render();
const input = select(page, "uwc-input");
const inputEvents = trapEvents(input, ["input"]);
await user.type(input, "a");
expect(inputEvents.get()).to.have.length(0);
});
it("should emit a change event on focusout when changed", async () => {
const page = render();
const input = select(page, "uwc-input");
const changeEvents = trapEvents(input, ["change"]);
await user.type(input, "123");
await user.tab();
expect(changeEvents.get()).to.have.length(1);
});
it("should reset itself when the associated form resets", async () => {
const page = render(
,
);
const input = select(page, "uwc-input");
await user.type(input, "123");
await user.click(select(page, "button"));
expect(input).to.include({
className: "pristine",
value: undefined,
});
});
describe("validation", () => {
each<
Partial> & {
type: "number";
message: string;
expectedInvalidState?: boolean;
expectedErrormessages?: string[];
}
>(
[
{
message: "should be invalid if type number and the value is too high",
type: "number",
max: "2",
value: "3",
expectedInvalidState: true,
},
{
message: "should be valid if type number the value is low enough",
type: "number",
max: "2",
value: "1",
expectedInvalidState: false,
},
{
message:
"should be possible to customize the range-overflow error message",
type: "number",
max: "2",
value: "3",
"range-overflow": "Must be 2 or higher",
expectedInvalidState: true,
expectedErrormessages: ["Must be 2 or higher"],
},
{
message: "should be invalid if number, required and empty",
type: "number",
required: true,
expectedInvalidState: true,
},
{
message:
"should be invalid if number is lexically higher than min but numerically lower",
type: "number",
min: "20",
value: "3",
expectedInvalidState: true,
},
{
message:
"should be invalid if number is lexically lower than max but numerically higher",
type: "number",
max: "20",
value: "100",
expectedInvalidState: true,
},
],
"$message",
async ({
message: _,
expectedInvalidState,
expectedErrormessages,
...props
}) => {
const page = render();
const input = select(page, "uwc-input");
if (expectedInvalidState != null) {
expect(input.matches(":invalid")).to.eq(expectedInvalidState);
}
expectedErrormessages?.forEach((message) =>
expect(
Array.from(input.querySelectorAll("small.validation-message")).some(
(element) => element.textContent === message,
),
).to.eq(
true,
`expected to find a small.validation-message with '${message}'`,
),
);
},
);
});
});