import { mount } from "@vue/test-utils";
import { baseClassCase, tagCase } from "@/utils/test-case-factories";
import { FONT } from "@darwin-studio/ui-codegen/dist/constants/font";
import { SIZE } from "@darwin-studio/ui-codegen/dist/constants/size";
import { PADDING } from "@darwin-studio/ui-codegen/dist/constants/padding";
import { TRANSITION } from "@darwin-studio/ui-codegen/dist/constants/transition";
import { DTabs, DTab, DTabpanel } from "./index";
import config from "./config";
jest.mock("chalk", () => ({
greenBright: jest.fn(),
red: jest.fn(),
yellowBright: jest.fn(),
}));
describe("DTabs", () => {
const wrapper = mount(DTabs);
baseClassCase(wrapper, config.tabsClass);
it("Should render config.tablistOptions.className to the tablist class name", () => {
const tablist = wrapper.find(`.${config.tablistOptions.class}`);
expect(tablist).toBeTruthy();
});
it("Should render props.tablistLabel to the tablist aria-label attr", async () => {
const tablistLabel = "Some aria label";
await wrapper.setProps({
tablistOptions: { ["aria-label"]: tablistLabel },
});
const tablist = wrapper.find(`.${config.tablistOptions.class}`);
expect(tablist.attributes("aria-label")).toBe(tablistLabel);
});
it("Should props.tablistOptions.class to the tablist class name", async () => {
const tablistClass = "some-tablist-class";
await wrapper.setProps({ tablistOptions: { class: tablistClass } });
const tablist = wrapper.find(`.${config.tablistOptions.class}`);
expect(tablist.classes()).toContain(tablistClass);
});
it("Should render props.tabs as content of the tablist", async () => {
// TODO: reactivity is broken ???
const wrapper = mount(DTabs, {
props: {
tabs: [
,
,
],
tabpanels: [
,
,
],
},
});
const tablist = wrapper.find(`.${config.tablistOptions.class}`);
const tabs = tablist.findAllComponents(DTab);
expect(tabs?.[0]?.element).toMatchSnapshot(); // TODO: find out other way to compare
expect(tabs?.[1]?.element).toMatchSnapshot(); // TODO: find out other way to compare
});
it("Should render slots.tabs as content of the tablist", async () => {
// TODO: reactivity is broken ???
const wrapper = mount(DTabs, {
slots: {
tabs: [
,
,
],
tabpanels: [
,
,
],
},
});
const tablist = wrapper.find(`.${config.tablistOptions.class}`);
const tabs = tablist.findAllComponents(DTab);
expect(tabs?.[0]?.element).toMatchSnapshot(); // TODO: find out other way to compare
expect(tabs?.[1]?.element).toMatchSnapshot(); // TODO: find out other way to compare
});
it("Should inject props.size to commonProps.size of containing DTab components", async () => {
const size = SIZE.LARGE;
await wrapper.setProps({
size,
tabs: [],
});
const tabWrapper = wrapper.findComponent(DTab);
expect(tabWrapper.vm.commonProps?.size).toBe(size);
});
it("Should render props.tabpanels as content of the list of tabpanels", async () => {
// TODO: reactivity is broken ???
const wrapper = mount(DTabs, {
props: {
tabs: [
,
,
],
tabpanels: [
,
,
],
},
});
const tabpanels = wrapper.findAllComponents(DTabpanel);
expect(tabpanels?.[0]?.element).toMatchSnapshot(); // TODO: find out other way to compare
expect(tabpanels?.[1]?.element).toMatchSnapshot(); // TODO: find out other way to compare
});
it("Should render slots.tabpanels as content of the list of tabpanels", async () => {
// TODO: reactivity is broken ???
const wrapper = mount(DTabs, {
slots: {
tabs: [
,
,
],
tabpanels: [
,
,
],
},
});
const tabpanels = wrapper.findAllComponents(DTabpanel);
expect(tabpanels?.[0]?.element).toMatchSnapshot(); // TODO: find out other way to compare
expect(tabpanels?.[1]?.element).toMatchSnapshot(); // TODO: find out other way to compare
});
it("Should inject props.size to commonProps.size of the DTabpanel components", async () => {
const size = FONT.SMALL;
await wrapper.setProps({
size,
tabpanels: [],
});
const tabpanelWrapper = wrapper.findComponent(DTabpanel);
expect(tabpanelWrapper.vm.commonProps?.size).toBe(size);
});
it("Should pass props.disabled to the containing DTabs", async () => {
const disabled = true;
await wrapper.setProps({
disabled,
tabs: [
,
,
],
});
const tabs = wrapper.findAllComponents(DTab);
expect(tabs[0]?.vm.commonProps.disabled).toBe(disabled);
expect(tabs[1]?.vm.commonProps.disabled).toBe(true);
});
// TODO paddingClassesCase(wrapper, wrapper.findComponent(DTab));
it(`Should render props.padding to DTab padding classes`, async () => {
const padding = PADDING.EQUAL;
const wrapper = mount(DTabs, {
props: {
padding,
tabs: [],
},
});
const tab = wrapper.findComponent(DTab);
expect(tab.vm.commonProps.padding).toBe(padding);
});
// TODO: transitionClassCase(wrapper, wrapper.findComponent(DTab))
it(`Should render props.transition to DTab transition class`, async () => {
const transition = TRANSITION.AVERAGE;
// TODO: reactivity is broken ???
const wrapper = mount(DTabs, {
props: {
transition,
tabs: [],
},
});
const tab = wrapper.findComponent(DTab);
expect(tab.vm.commonProps.transition).toBe(transition);
});
tagCase(wrapper);
it("Should render tablist as element passed in props.tablistTag", async () => {
const tablistTag = "section";
await wrapper.setProps({ tablistTag });
const tablist = wrapper.find(`.${config.tablistOptions.class}`);
expect(tablist.element.tagName).toEqual(tablistTag.toLocaleUpperCase());
});
it("Should focus on prev tab on ArrowLeft keydown", async () => {
// TODO: reactivity is broken ???
const wrapper = mount(DTabs, {
props: {
tabs: [
,
,
],
},
});
const tabs = wrapper.findAllComponents(DTab);
const tab0 = tabs?.[0];
tab0.vm.$el.focus = jest.fn();
const tab1 = tabs?.[1];
tab1.vm.$el.focus = jest.fn();
await tab0?.trigger("focus");
await tab0?.trigger("keydown", { key: "ArrowLeft" });
expect(tab1.vm.$el.focus).toBeCalled();
await tab1?.trigger("focus");
await tab1?.trigger("keydown", { key: "ArrowLeft" });
expect(tab0.vm.$el.focus).toBeCalled();
});
it("Should focus on next tab on ArrowRight keydown", async () => {
// TODO: reactivity is broken ???
const wrapper = mount(DTabs, {
props: {
tabs: [
,
,
],
},
});
const tabs = wrapper.findAllComponents(DTab);
const tab0 = tabs?.[0];
tab0.vm.$el.focus = jest.fn();
const tab1 = tabs?.[1];
tab1.vm.$el.focus = jest.fn();
await tab0?.trigger("focus");
await tab0?.trigger("keydown", { key: "ArrowRight" });
expect(tab1.vm.$el.focus).toBeCalled();
await tab1?.trigger("focus");
await tab1?.trigger("keydown", { key: "ArrowRight" });
expect(tab0.vm.$el.focus).toBeCalled();
});
it("Should call props.whenChange with focused tab id on Enter", async () => {
// TODO: reactivity is broken ???
const whenChange = jest.fn();
const tabId0 = "a";
const tabId1 = "b";
const wrapper = mount(DTabs, {
props: {
tabs: [
,
,
],
whenChange,
},
});
const tabs = wrapper.findAllComponents(DTab);
const tab0 = tabs?.[0];
const tab1 = tabs?.[1];
await tab0?.trigger("focus");
await tab0?.trigger("keydown", { key: "Enter" });
expect(whenChange).toBeCalledWith(tabId0);
await tab1?.trigger("focus");
await tab1?.trigger("keydown", { key: "Enter" });
expect(whenChange).toBeCalledWith(tabId1);
});
it("Shouldn't do anything on keydown if there are less than 2 DTabs", async () => {
const whenChange = jest.fn();
const wrapper = mount(DTabs, {
props: {
tabs: [],
whenChange,
},
});
const tab = wrapper.findComponent(DTab);
await tab?.trigger("focus");
await tab?.trigger("keydown", { key: "Enter" });
expect(whenChange).not.toHaveBeenCalled();
});
it("Shouldn't do anything on keydown if DTabs haven't id", async () => {
const whenChange = jest.fn();
const wrapper = mount(DTabs, {
props: {
tabs: [, ],
whenChange,
},
});
const tab = wrapper.findComponent(DTab);
await tab?.trigger("focus");
await tab?.trigger("keydown", { key: "Enter" });
await tab?.trigger("keydown", { key: "ArrowLeft" });
await tab?.trigger("keydown", { key: "ArrowRight" });
expect(whenChange).not.toHaveBeenCalled();
});
// TODO: Should following to be a part of the DTabs component:
// DTabpanel.active ???
// DTab.active ???
// DTab.onClick ???
// DTab.whenClick ???
});