test(07-01): add failing tests for mode and metric controls
This commit is contained in:
parent
3472fccfe9
commit
cab07eedc3
1 changed files with 111 additions and 0 deletions
111
assets/test/controls.test.ts
Normal file
111
assets/test/controls.test.ts
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { createModeControl, createMetricControl } from '../src/ui/controls';
|
||||
|
||||
describe('createModeControl', () => {
|
||||
const modes = [
|
||||
{ key: 'year', label: 'Year' },
|
||||
{ key: 'week', label: 'Week' },
|
||||
];
|
||||
|
||||
it('returns a nav element with nav-segmented class and tablist role', () => {
|
||||
const nav = createModeControl('year', modes, () => {});
|
||||
expect(nav.tagName).toBe('NAV');
|
||||
expect(nav.className).toBe('nav nav-segmented');
|
||||
expect(nav.getAttribute('role')).toBe('tablist');
|
||||
});
|
||||
|
||||
it('renders buttons for each mode', () => {
|
||||
const nav = createModeControl('year', modes, () => {});
|
||||
const buttons = nav.querySelectorAll('button');
|
||||
expect(buttons.length).toBe(2);
|
||||
expect(buttons[0].textContent).toBe('Year');
|
||||
expect(buttons[1].textContent).toBe('Week');
|
||||
});
|
||||
|
||||
it('marks the active mode with active class and aria-selected', () => {
|
||||
const nav = createModeControl('year', modes, () => {});
|
||||
const buttons = nav.querySelectorAll('button');
|
||||
expect(buttons[0].classList.contains('active')).toBe(true);
|
||||
expect(buttons[0].getAttribute('aria-selected')).toBe('true');
|
||||
expect(buttons[1].classList.contains('active')).toBe(false);
|
||||
expect(buttons[1].getAttribute('aria-selected')).toBe('false');
|
||||
});
|
||||
|
||||
it('all buttons have nav-link class and role=tab', () => {
|
||||
const nav = createModeControl('year', modes, () => {});
|
||||
const buttons = nav.querySelectorAll('button');
|
||||
buttons.forEach((btn) => {
|
||||
expect(btn.classList.contains('nav-link')).toBe(true);
|
||||
expect(btn.getAttribute('role')).toBe('tab');
|
||||
});
|
||||
});
|
||||
|
||||
it('clicking inactive button updates active state and calls onChange', () => {
|
||||
const onChange = vi.fn();
|
||||
const nav = createModeControl('year', modes, onChange);
|
||||
const buttons = nav.querySelectorAll('button');
|
||||
|
||||
buttons[1].click();
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith('week');
|
||||
expect(buttons[1].classList.contains('active')).toBe(true);
|
||||
expect(buttons[1].getAttribute('aria-selected')).toBe('true');
|
||||
expect(buttons[0].classList.contains('active')).toBe(false);
|
||||
expect(buttons[0].getAttribute('aria-selected')).toBe('false');
|
||||
});
|
||||
|
||||
it('clicking already active button still calls onChange', () => {
|
||||
const onChange = vi.fn();
|
||||
const nav = createModeControl('year', modes, onChange);
|
||||
const buttons = nav.querySelectorAll('button');
|
||||
|
||||
buttons[0].click();
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith('year');
|
||||
});
|
||||
});
|
||||
|
||||
describe('createMetricControl', () => {
|
||||
it('returns a nav element with nav-segmented nav-sm classes', () => {
|
||||
const nav = createMetricControl('hours', () => {});
|
||||
expect(nav.tagName).toBe('NAV');
|
||||
expect(nav.className).toBe('nav nav-segmented nav-sm');
|
||||
expect(nav.getAttribute('role')).toBe('tablist');
|
||||
});
|
||||
|
||||
it('renders Hours and Count buttons', () => {
|
||||
const nav = createMetricControl('hours', () => {});
|
||||
const buttons = nav.querySelectorAll('button');
|
||||
expect(buttons.length).toBe(2);
|
||||
expect(buttons[0].textContent).toBe('Hours');
|
||||
expect(buttons[1].textContent).toBe('Count');
|
||||
});
|
||||
|
||||
it('marks hours as active by default', () => {
|
||||
const nav = createMetricControl('hours', () => {});
|
||||
const buttons = nav.querySelectorAll('button');
|
||||
expect(buttons[0].classList.contains('active')).toBe(true);
|
||||
expect(buttons[1].classList.contains('active')).toBe(false);
|
||||
});
|
||||
|
||||
it('clicking Count calls onChange with count', () => {
|
||||
const onChange = vi.fn();
|
||||
const nav = createMetricControl('hours', onChange);
|
||||
const buttons = nav.querySelectorAll('button');
|
||||
|
||||
buttons[1].click();
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith('count');
|
||||
expect(buttons[1].classList.contains('active')).toBe(true);
|
||||
expect(buttons[0].classList.contains('active')).toBe(false);
|
||||
});
|
||||
|
||||
it('buttons have proper ARIA attributes', () => {
|
||||
const nav = createMetricControl('count', () => {});
|
||||
const buttons = nav.querySelectorAll('button');
|
||||
expect(buttons[0].getAttribute('role')).toBe('tab');
|
||||
expect(buttons[0].getAttribute('aria-selected')).toBe('false');
|
||||
expect(buttons[1].getAttribute('role')).toBe('tab');
|
||||
expect(buttons[1].getAttribute('aria-selected')).toBe('true');
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue