gradio/js/checkboxgroup/checkboxgroup.test.ts
2024-04-03 07:19:58 -07:00

404 lines
10 KiB
TypeScript

import { test, describe, assert, afterEach, vi } from "vitest";
import { cleanup, render } from "@gradio/tootils";
import event from "@testing-library/user-event";
import { setupi18n } from "../app/src/i18n";
import CheckboxGroup from "./Index.svelte";
import type { LoadingStatus } from "@gradio/statustracker";
const loading_status: LoadingStatus = {
eta: 0,
queue_position: 1,
queue_size: 1,
status: "complete" as LoadingStatus["status"],
scroll_to_output: false,
visible: true,
fn_index: 0,
show_progress: "full"
};
beforeEach(() => {
setupi18n();
});
afterEach(cleanup);
describe("Values", () => {
test("renders correct value when passed as string: single value", async () => {
const { getByLabelText } = await render(CheckboxGroup, {
value: ["choice_one"],
label: "Dropdown",
choices: [
["Choice One", "choice_one"],
["Choice Two", "choice_two"]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const item_two = getByLabelText("Choice Two") as HTMLInputElement;
expect(item_one).toBeChecked();
expect(item_two).not.toBeChecked();
});
test("renders correct value when passed as string: multiple values", async () => {
const { getByLabelText } = await render(CheckboxGroup, {
value: ["choice_one", "choice_three"],
label: "Dropdown",
choices: [
["Choice One", "choice_one"],
["Choice Two", "choice_two"],
["Choice Three", "choice_three"]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const item_two = getByLabelText("Choice Two") as HTMLInputElement;
const item_three = getByLabelText("Choice Three") as HTMLInputElement;
assert.equal(item_one.checked, true);
assert.equal(item_two.checked, false);
assert.equal(item_three.checked, true);
expect(item_one).toBeChecked();
expect(item_two).not.toBeChecked();
expect(item_three).toBeChecked();
});
test("renders correct value when passed as number: single value", async () => {
const { getByLabelText } = await render(CheckboxGroup, {
value: [1],
label: "Dropdown",
choices: [
["Choice One", 1],
["Choice Two", 2]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const item_two = getByLabelText("Choice Two") as HTMLInputElement;
expect(item_one).toBeChecked();
expect(item_two).not.toBeChecked();
});
test("renders correct value when passed as number: multiple values", async () => {
const { getByLabelText } = await render(CheckboxGroup, {
value: [1, 3],
label: "Dropdown",
choices: [
["Choice One", 1],
["Choice Two", 2],
["Choice Three", 3]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const item_two = getByLabelText("Choice Two") as HTMLInputElement;
const item_three = getByLabelText("Choice Three") as HTMLInputElement;
expect(item_one).toBeChecked();
expect(item_two).not.toBeChecked();
expect(item_three).toBeChecked();
});
test("component value and rendered value are in sync", async () => {
const { getByLabelText, debug, component } = await render(CheckboxGroup, {
value: [1, 3],
label: "Dropdown",
choices: [
["Choice One", 1],
["Choice Two", 2],
["Choice Three", 3]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const item_two = getByLabelText("Choice Two") as HTMLInputElement;
const item_three = getByLabelText("Choice Three") as HTMLInputElement;
expect(item_one).toBeChecked();
expect(item_two).not.toBeChecked();
expect(item_three).toBeChecked();
expect(component.value).toEqual([1, 3]);
});
test("changing the component value updates the checkboxes", async () => {
const { getByLabelText, component } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
choices: [
["Choice One", 1],
["Choice Two", 2],
["Choice Three", 3]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const item_two = getByLabelText("Choice Two") as HTMLInputElement;
const item_three = getByLabelText("Choice Three") as HTMLInputElement;
expect(item_one).not.toBeChecked();
expect(item_two).not.toBeChecked();
expect(item_three).not.toBeChecked();
component.value = [1, 3];
expect(item_one).toBeChecked();
expect(item_two).not.toBeChecked();
expect(item_three).toBeChecked();
});
test("setting a value that does not exist does nothing", async () => {
const { getByLabelText, component } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
choices: [
["Choice One", 1],
["Choice Two", 2],
["Choice Three", 3]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const item_two = getByLabelText("Choice Two") as HTMLInputElement;
const item_three = getByLabelText("Choice Three") as HTMLInputElement;
expect(item_one).not.toBeChecked();
expect(item_two).not.toBeChecked();
expect(item_three).not.toBeChecked();
component.value = ["choice_one"];
expect(item_one).not.toBeChecked();
expect(item_two).not.toBeChecked();
expect(item_three).not.toBeChecked();
});
});
describe("Events", () => {
test("changing the value via the UI emits a change event", async () => {
const { getByLabelText, listen } = await render(CheckboxGroup, {
loading_status,
value: [],
label: "Dropdown",
choices: [
["Choice One", 1],
["Choice Two", 2],
["Choice Three", 3]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const item_two = getByLabelText("Choice Two") as HTMLInputElement;
const item_three = getByLabelText("Choice Three") as HTMLInputElement;
expect(item_one).not.toBeChecked();
expect(item_two).not.toBeChecked();
expect(item_three).not.toBeChecked();
const mock = listen("change");
await event.click(item_one);
expect(mock.callCount).toBe(1);
await event.click(item_three);
expect(mock.callCount).toBe(2);
});
test("changing the value from outside emits a change event", async () => {
const { getByLabelText, component, listen } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
choices: [
["Choice One", 1],
["Choice Two", 2],
["Choice Three", 3]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const item_two = getByLabelText("Choice Two") as HTMLInputElement;
const item_three = getByLabelText("Choice Three") as HTMLInputElement;
expect(item_one).not.toBeChecked();
expect(item_two).not.toBeChecked();
expect(item_three).not.toBeChecked();
const mock = listen("change");
await (component.value = [1]);
expect(mock.callCount).toBe(1);
});
test("changing the value from the UI emits an input event", async () => {
const { getByLabelText, listen } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
choices: [
["Choice One", 1],
["Choice Two", 2],
["Choice Three", 3]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const mock = listen("input");
await event.click(item_one);
expect(mock.callCount).toBe(1);
});
test("changing the value from outside DOES NOT emit an input event", async () => {
const { getByLabelText, component, listen } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
choices: [
["Choice One", 1],
["Choice Two", 2],
["Choice Three", 3]
]
});
const mock = listen("input");
await (component.value = [1]);
expect(mock.callCount).toBe(0);
});
test("changing the value via the UI emits a select event", async () => {
const { getByLabelText, listen } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
choices: [
["Choice One", 1],
["Choice Two", 2],
["Choice Three", 3]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
const mock = listen("select");
await event.click(item_one);
expect(mock.callCount).toBe(1);
});
test("select event payload contains the selected value and index", async () => {
const { getByLabelText, listen } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
choices: [
["Choice One", "val"],
["Choice Two", "val_two"],
["Choice Three", 3]
]
});
const item = getByLabelText("Choice Two") as HTMLInputElement;
const mock = listen("select");
await event.click(item);
expect(mock.calls[0][0].detail.data.value).toBe("val_two");
expect(mock.calls[0][0].detail.data.index).toBe(1);
});
test("select event payload contains the correct selected state", async () => {
const { getByLabelText, listen } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
choices: [
["Choice One", "val"],
["Choice Two", "val_two"],
["Choice Three", 3]
]
});
const item = getByLabelText("Choice Two") as HTMLInputElement;
const mock = listen("select");
await event.click(item);
expect(mock.calls[0][0].detail.data.selected).toBe(true);
await event.click(item);
expect(mock.calls[1][0].detail.data.selected).toBe(false);
});
});
describe("interactive vs static", () => {
test("interactive component can be checked", async () => {
const { getByLabelText } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
interactive: true,
choices: [
["Choice One", 1],
["Choice Two", 2]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
await event.click(item_one);
expect(item_one).toBeChecked();
});
test("static component cannot be checked", async () => {
const { getByLabelText } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
interactive: false,
choices: [
["Choice One", 1],
["Choice Two", 2]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
await event.click(item_one);
expect(item_one).not.toBeChecked();
});
test("interactive component updates the value", async () => {
const { getByLabelText, component } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
interactive: true,
choices: [
["Choice One", 1],
["Choice Two", 2]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
await event.click(item_one);
expect(component.value).toEqual([1]);
});
test("static component doe not update the value", async () => {
const { getByLabelText, component } = await render(CheckboxGroup, {
value: [],
label: "Dropdown",
interactive: false,
choices: [
["Choice One", 1],
["Choice Two", 2]
]
});
const item_one = getByLabelText("Choice One") as HTMLInputElement;
await event.click(item_one);
expect(component.value).toEqual([]);
});
});