import { readFileSync } from 'node:fs';
import { renderToStaticMarkup } from 'react-dom/server';
import { describe, expect, it } from 'vitest';
import { DonutMetricCard } from '../../src/components/DonutMetricCard/DonutMetricCard';
const styles = readFileSync(new URL('../../src/styles/components.css', import.meta.url), 'utf8');
const tileContract = readFileSync(new URL('../../src/styles/tile-contract.css', import.meta.url), 'utf8');
const tokens = readFileSync(new URL('../../src/styles/ui-tokens.css', import.meta.url), 'utf8');
describe('DonutMetricCard binding design contract', () => {
it('renders the shared full-circle reference with a bold count above a regular percentage', () => {
const html = renderToStaticMarkup(
);
expect(html).toContain('class="donut-metric-card donut-metric-card--deviation"');
expect(html).toContain('class="donut-metric-card__title">Deviation');
expect(html).toContain('class="donut-metric-card__track" cx="60" cy="60" r="48" pathLength="100"');
expect(html).toContain('stroke-dasharray="51 49"');
expect(html).toContain('
453
');
expect(html).toContain('51%');
expect(html).toContain('--donut-progress-dash:51 49');
expect(styles).toContain('transform: rotate(-90deg);');
expect(styles).toMatch(/\.donut-metric-card__values\s*\{[^}]*inset:\s*calc\(var\(--donut-ring-stroke\) \+ var\(--space-2\)\);/s);
expect(styles).toMatch(/\.donut-metric-card__primary strong\s*\{[^}]*font-weight:\s*var\(--fw-bold\);/s);
expect(styles).toMatch(/\.donut-metric-card__values > small\s*\{[^}]*font-weight:\s*var\(--fw-regular\);/s);
expect(styles).not.toContain('stroke-linecap: round;');
expect(styles).toContain('@keyframes donut-progress-build');
expect(styles).not.toContain('.donut-metric-card::before');
expect(styles).not.toContain('@keyframes donut-accent-build');
expect(styles).toContain('animation: donut-progress-build var(--dur-data-build) var(--ease-data-build) both;');
expect(styles).toMatch(/\.donut-metric-rack\s*\{[^}]*grid-template-columns:\s*repeat\(auto-fill, var\(--tile-compact-width\)\);[^}]*justify-content:\s*start;/s);
expect(tileContract).toMatch(/\.donut-metric-rack\s*\{[^}]*grid-template-columns:\s*repeat\(auto-fill, var\(--tile-compact-width\)\);[^}]*justify-content:\s*start;/s);
expect(tokens).toContain('--dur-data-build: 700ms;');
expect(tokens).toContain('--donut-value-size: 26px;');
expect(tokens).toContain('--donut-percent-size: 14px;');
expect(tokens).toContain('--donut-compact-value-size: 22px;');
expect(tokens).toContain('--donut-compact-percent-size: 12px;');
expect(styles).not.toContain('.sidebar-severity-card');
});
it('renders an empty progress arc at zero and clamps percentages', () => {
const zero = renderToStaticMarkup(
);
const clamped = renderToStaticMarkup(
);
expect(zero).toContain('stroke-dasharray="0 100"');
expect(zero).toContain('2');
expect(zero).toContain('0%');
expect(clamped).toContain('stroke-dasharray="100 0"');
expect(clamped).toContain('885');
expect(clamped).toContain('100%');
expect(zero).not.toContain(' {
const html = renderToStaticMarkup(
);
expect(html).toContain('36%');
expect(html).not.toContain('36%');
});
it('becomes an accessible active filter control when clickable', () => {
const html = renderToStaticMarkup(
undefined}
className="test-donut-card"
/>
);
expect(html).toContain('type="button"');
expect(html).toContain('aria-pressed="true"');
expect(html).toContain('donut-metric-card--high test-donut-card');
});
});