import { beforeEach, describe, expect, it, vi } from 'vitest';
import { Tooltip } from './tooltip';
import { TOOLTIP_OPEN_EVENT } from './tooltip.types';
const MARKUP = `
Tip
`;
function setup(): HTMLElement {
document.body.innerHTML = MARKUP;
return document.body.firstElementChild as HTMLElement;
}
describe('Tooltip', () => {
beforeEach(() => {
document.body.innerHTML = '';
});
it('wires aria-describedby and hides content on init', () => {
const root = setup();
new Tooltip(root);
const trigger = root.querySelector('[data-c42-tooltip-trigger]')!;
const content = root.querySelector('[data-c42-tooltip-content]')!;
expect(content.getAttribute('role')).toBe('tooltip');
expect(trigger.getAttribute('aria-describedby')).toBe(content.id);
expect(content.hasAttribute('hidden')).toBe(true);
});
it('throws without trigger or content', () => {
document.body.innerHTML = '';
const root = document.body.firstElementChild as HTMLElement;
expect(() => new Tooltip(root)).toThrow(/trigger and a content/);
});
it('shows on mouseenter and hides on mouseleave', () => {
const root = setup();
new Tooltip(root);
const trigger = root.querySelector('[data-c42-tooltip-trigger]')!;
const content = root.querySelector('[data-c42-tooltip-content]')!;
trigger.dispatchEvent(new MouseEvent('mouseenter'));
expect(content.hasAttribute('hidden')).toBe(false);
expect(content.dataset.state).toBe('open');
trigger.dispatchEvent(new MouseEvent('mouseleave'));
expect(content.hasAttribute('hidden')).toBe(true);
});
it('hides on Escape', () => {
const root = setup();
const tooltip = new Tooltip(root);
tooltip.show();
const trigger = root.querySelector('[data-c42-tooltip-trigger]')!;
trigger.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }));
expect(tooltip.isOpen).toBe(false);
});
it('emits open event', () => {
const root = setup();
const tooltip = new Tooltip(root);
const spy = vi.fn();
tooltip.on(TOOLTIP_OPEN_EVENT, spy);
tooltip.show();
expect(spy).toHaveBeenCalledOnce();
});
it('stops reacting after destroy', () => {
const root = setup();
const tooltip = new Tooltip(root);
tooltip.destroy();
const trigger = root.querySelector('[data-c42-tooltip-trigger]')!;
trigger.dispatchEvent(new MouseEvent('mouseenter'));
expect(tooltip.isOpen).toBe(false);
});
});