Skip to content

Commit

Permalink
test: update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mlmoravek committed Dec 16, 2024
1 parent 94ed439 commit 7f6723f
Show file tree
Hide file tree
Showing 2 changed files with 284 additions and 4 deletions.
6 changes: 4 additions & 2 deletions packages/oruga/src/components/table/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,10 @@ const isScrollable = computed(() => {
const tableCurrentPage = defineModel<number>("currentPage", { default: 1 });
// recompute table rows visibility on page change
watch([tableCurrentPage, () => props.perPage], () => filterTableRows());
// recompute table rows visibility on page change or data change
watch([tableCurrentPage, () => props.perPage, () => props.data], () =>
filterTableRows(),
);
// create a unique id sequence
const { nextSequence } = useSequentialId();
Expand Down
282 changes: 280 additions & 2 deletions packages/oruga/src/components/table/tests/table.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, test, expect, afterEach } from "vitest";
import { enableAutoUnmount, mount } from "@vue/test-utils";
import { describe, test, expect, afterEach, vi, beforeEach } from "vitest";
import { enableAutoUnmount, flushPromises, mount } from "@vue/test-utils";
import { nextTick } from "vue";

import type { TableColumn } from "../types";
Expand Down Expand Up @@ -90,6 +90,48 @@ describe("OTable tests", () => {
expect(wrapper.html()).toMatchSnapshot();
});

test("holds columns", async () => {
const wrapper = mount(OTable, {
props: {
columns: [
{ label: "default", width: "100px" },
{ label: "pecent", width: "50%" },
{ label: "fixed_num", width: 100 },
{ label: "fixed_str", width: "100" },
],
},
});
await nextTick();

const headers = wrapper.findAll("th");

expect(headers).toHaveLength(4);

const cols = headers.filter((th) => th.find("span"));
expect(cols).toHaveLength(4);

expect(cols[0].attributes("style")).toBe("width: 100px;");
expect(cols[1].attributes("style")).toBe("width: 50%;");
expect(cols[2].attributes("style")).toBe("width: 100px;");
expect(cols[3].attributes("style")).toBe("width: 100px;");
});

test("displays all data", async () => {
const wrapper = mount(OTable, {
props: {
columns: [
{ label: "ID", field: "id", numeric: true },
{ label: "Name", field: "name", searchable: true },
],
data,
},
});
await nextTick();

const bodyRows = wrapper.findAll("tbody tr");
expect(bodyRows).toHaveLength(5);
});

describe("test column props", () => {
test("test column label", async () => {
const wrapper = mount<typeof OTable<(typeof data)[number]>>(
Expand Down Expand Up @@ -220,4 +262,240 @@ describe("OTable tests", () => {
}
});
});

describe("test searchable", () => {
const data = [
{ id: 1, name: "Jesse" },
{ id: 2, name: "João" },
{ id: 3, name: "Tina" },
{ id: 4, name: "Anne" },
{ id: 5, name: "Clarence" },
];

beforeEach(() => {
vi.useFakeTimers();
});

afterEach(() => {
vi.clearAllTimers();
vi.restoreAllMocks();
});

test("displays filter row when at least one column is searchable", async () => {
const wrapper = mount(OTable, {
props: {
columns: [
{ label: "ID", field: "id", numeric: true },
{ label: "Name", field: "name", searchable: true },
],
data,
},
});
await nextTick();

const header = wrapper.find("thead");
expect(header.exists()).toBeTruthy();

const headRows = header.findAll("tr");
expect(headRows).toHaveLength(2);

const inputs = headRows[1].findAll("input");
expect(inputs).toHaveLength(1);
});

test("displays filter input only on searchable columns", async () => {
const wrapper = mount(OTable, {
props: {
columns: [
{ label: "ID", field: "id", numeric: true },
{ label: "Name", field: "name", searchable: true },
],
data,
},
});
await nextTick();

const headRows = wrapper.findAll("thead tr");
expect(headRows).toHaveLength(2);
const filterCells = headRows[1].findAll("th");

expect(filterCells[0].find("input").exists()).toBeFalsy(); // ID column is not searchable
expect(filterCells[1].find("input").exists()).toBeTruthy(); // Name column is searchable
});

test("displays filtered data when searching", async () => {
const wrapper = mount(OTable, {
props: {
columns: [
{ label: "ID", field: "id", numeric: true },
{ label: "Name", field: "name", searchable: true },
],
data,
},
});
await nextTick();

const header = wrapper.find("thead");

const inputs = header.findAll("input");
expect(inputs).toHaveLength(1);

const input = inputs[0];

await input.setValue("J");
await input.trigger("input");
vi.runAllTimers(); // run debounce timer
await flushPromises();

const bodyRows = wrapper.findAll("tbody tr");
expect(bodyRows).toHaveLength(2); // Jesse and João

expect(wrapper.emitted("filters-change")).toHaveLength(1);
});

test("displays filtered data when searching and updating data", async () => {
const wrapper = mount(OTable, {
props: {
columns: [
{ label: "ID", field: "id", numeric: true },
{ label: "Name", field: "name", searchable: true },
],
data,
},
});
await nextTick();

const input = wrapper.find("thead input");
expect(input.exists()).toBeTruthy();

await input.setValue("J");
await input.trigger("input");
vi.runAllTimers(); // run debounce timer
await flushPromises();

let bodyRows = wrapper.findAll("tbody tr");
expect(bodyRows).toHaveLength(2); // Jesse and João

wrapper.setProps({
data: [...data, { id: 6, name: "Justin" }],
});
await nextTick();

console.log(wrapper.find("tbody").html());

bodyRows = wrapper.findAll("tbody tr");
expect(bodyRows).toHaveLength(3); // Jesse, João and Justin
});

test("displays filtered data when searching by name without accent", async () => {
const wrapper = mount(OTable, {
props: {
columns: [
{ label: "ID", field: "id", numeric: true },
{ label: "Name", field: "name", searchable: true },
],
data,
},
});
await nextTick();

const input = wrapper.find("thead input");
expect(input.exists()).toBeTruthy();

await input.setValue("Joao");
await input.trigger("input");
vi.runAllTimers(); // run debounce timer
await flushPromises();

const bodyRows = wrapper.findAll("tbody tr");
expect(bodyRows).toHaveLength(1); // João
});

test("displays filtered data when searching by name with accent", async () => {
const wrapper = mount(OTable, {
props: {
columns: [
{ label: "ID", field: "id", numeric: true },
{ label: "Name", field: "name", searchable: true },
],
data,
},
});
await nextTick();

const input = wrapper.find("thead input");
expect(input.exists()).toBeTruthy();

await input.setValue("João");
await input.trigger("input");
vi.runAllTimers(); // run debounce timer
await flushPromises();

const bodyRows = wrapper.findAll("tbody tr");
expect(bodyRows).toHaveLength(1); // João
});

test("debounce search filtering when debounce-search is defined", async () => {
const wrapper = mount(OTable, {
props: {
columns: [
{ label: "ID", field: "id", numeric: true },
{ label: "Name", field: "name", searchable: true },
],
data,
debounceSearch: 1000,
},
});
await nextTick();

const input = wrapper.find("thead input");
expect(input.exists()).toBeTruthy();

for (let i = 0; i < 10; i++) {
await input.setValue("J".repeat(10 - i));
await input.trigger("input");
await setTimeout(() => {}, 500);
const bodyRows = wrapper.findAll("tbody tr");
expect(bodyRows).toHaveLength(5); // No filtering yet
}

vi.runAllTimers(); // run debounce timer

const bodyRows = wrapper.findAll("tbody tr");
expect(bodyRows).toHaveLength(5); // Filtering after debounce
});
});

describe("test checkable", () => {
test("tests isAllUncheckable method", async () => {
const isRowCheckable = vi.fn(() => false);

const wrapper = mount(OTable, {
props: {
columns: [
{ label: "ID", field: "id", numeric: true },
{ label: "Name", field: "name", searchable: true },
],
checkable: true,
isRowCheckable: isRowCheckable,
paginated: false,
data: [
{
id: 1,
first_name: "Jesse",
last_name: "Simmons",
date: "2016-10-15 13:43:27",
gender: "Male",
},
],
},
});
await nextTick();

const body = wrapper.find("tbody");
const checkboxes = body.findAll("input");
expect(checkboxes).toHaveLength(1);
expect(checkboxes[0].attributes("disabled")).toBe("");
});
});
});

0 comments on commit 7f6723f

Please sign in to comment.