import { describe, it, expect, afterEach, beforeEach, vi } from 'vitest'; import '@testing-library/jest-dom/vitest'; import { render, cleanup, fireEvent, screen } from '@solidjs/testing-library'; import { Context, ContextTrigger, ContextContent, ContextContentHeader, ContextContentBody, ContextContentFooter, computeSeverity, DEFAULT_WARN_THRESHOLD, DEFAULT_DANGER_THRESHOLD, } from './context'; // jsdom does not implement PointerEvent — shim it so fireEvent.pointerEnter works. if (typeof (globalThis as unknown as Record).PointerEvent === 'undefined') { (globalThis as unknown as Record).PointerEvent = class PointerEvent extends MouseEvent { constructor(type: string, params?: PointerEventInit) { super(type, params); } }; } beforeEach(() => vi.useFakeTimers()); afterEach(() => { vi.useRealTimers(); cleanup(); }); // --------------------------------------------------------------------------- // computeSeverity — pure function unit tests // --------------------------------------------------------------------------- describe('computeSeverity', () => { it('returns ok below the warn threshold (defaults)', () => { expect(computeSeverity(0)).toBe('ok'); expect(computeSeverity(0.5)).toBe('ok'); expect(computeSeverity(DEFAULT_WARN_THRESHOLD)).toBe('ok'); // exactly at threshold → still ok }); it('returns warn when usage exceeds the warn threshold but not the danger threshold', () => { expect(computeSeverity(0.71)).toBe('warn'); expect(computeSeverity(DEFAULT_WARN_THRESHOLD + 0.001)).toBe('warn'); expect(computeSeverity(DEFAULT_DANGER_THRESHOLD)).toBe('warn'); // exactly at danger threshold → still warn }); it('returns danger when usage exceeds the danger threshold', () => { expect(computeSeverity(0.91)).toBe('danger'); expect(computeSeverity(1.0)).toBe('danger'); }); it('respects custom warnThreshold', () => { expect(computeSeverity(0.49, 0.5, 0.9)).toBe('ok'); expect(computeSeverity(0.51, 0.5, 0.9)).toBe('warn'); expect(computeSeverity(0.91, 0.5, 0.9)).toBe('danger'); }); it('respects custom dangerThreshold', () => { expect(computeSeverity(0.49, 0.5, 0.75)).toBe('ok'); expect(computeSeverity(0.6, 0.5, 0.75)).toBe('warn'); expect(computeSeverity(0.76, 0.5, 0.75)).toBe('danger'); }); }); // --------------------------------------------------------------------------- // Context component — color class flips at configured thresholds // // HoverCardRoot uses openDelay={0} inside Context, so after a pointerEnter // the card opens immediately; we advance fake timers by 0 to flush it. // --------------------------------------------------------------------------- function FullMeter(props: { usedTokens: number; maxTokens: number; warnThreshold?: number; dangerThreshold?: number; }) { return ( ); } /** Open the hover card so ContextContentHeader is in the DOM. */ function openCard() { // ContextTrigger renders HoverCardTrigger; the host wrapper is the parent of the button. const btn = screen.getByRole('button'); fireEvent.pointerEnter(btn.parentElement!); vi.advanceTimersByTime(0); // openDelay=0 → card opens immediately } describe('Context color thresholds', () => { it('renders bg-primary bar below default warn threshold (< 70%)', () => { render(() => ); openCard(); expect(document.querySelector('.bg-primary')).toBeInTheDocument(); }); it('renders bg-yellow-400 bar between default warn (70%) and danger (90%) thresholds', () => { render(() => ); openCard(); expect(document.querySelector('.bg-yellow-400')).toBeInTheDocument(); }); it('renders bg-red-400 bar above default danger threshold (> 90%)', () => { render(() => ); openCard(); expect(document.querySelector('.bg-red-400')).toBeInTheDocument(); }); it('flips to warn colour at a custom warnThreshold of 0.5', () => { render(() => ); openCard(); expect(document.querySelector('.bg-yellow-400')).toBeInTheDocument(); }); it('flips to danger colour at custom thresholds (warn 0.5, danger 0.75)', () => { render(() => ); openCard(); expect(document.querySelector('.bg-red-400')).toBeInTheDocument(); }); it('stays green at 50% when custom warnThreshold is 0.6', () => { render(() => ); openCard(); expect(document.querySelector('.bg-primary')).toBeInTheDocument(); }); });