import { render } from '@testing-library/react'; import { describe, it, expect } from 'vitest'; import { Cuadrados } from './Cuadrados'; import { CUADRADOS_VARIANTS, CUADRADOS_VARIANT_IDS } from './cuadrados-variants'; import { ISOTYPE_COLORS } from './patterns'; import React from 'react'; describe('Cuadrados', () => { it('renders the two overlapping frame rects plus the intersection rect', () => { const { container } = render(); expect(container.querySelectorAll('rect')).toHaveLength(3); expect(container.querySelectorAll('rect[stroke]')).toHaveLength(2); }); it('defaults to the blue-magenta variant', () => { const { container } = render(); const rects = container.querySelectorAll('rect'); const [backKey, frontKey] = CUADRADOS_VARIANTS['blue-magenta']; expect(rects[0].getAttribute('stroke')).toBe(ISOTYPE_COLORS[backKey]); expect(rects[1].getAttribute('stroke')).toBe(ISOTYPE_COLORS[frontKey]); }); it('renders every registered variant with the right stroke colors', () => { for (const variant of CUADRADOS_VARIANT_IDS) { const { container } = render(); const rects = container.querySelectorAll('rect'); const [backKey, frontKey] = CUADRADOS_VARIANTS[variant]; expect(rects[0].getAttribute('stroke')).toBe(ISOTYPE_COLORS[backKey]); expect(rects[1].getAttribute('stroke')).toBe(ISOTYPE_COLORS[frontKey]); } }); it('renders each frame rect hollow (fill="none")', () => { const { container } = render(); container.querySelectorAll('rect[stroke]').forEach(rect => { expect(rect.getAttribute('fill')).toBe('none'); }); }); it('passes className through to the root', () => { const { container } = render(); expect((container.firstChild as HTMLElement).className).toContain('w-64'); }); it('offsets the front frame diagonally from the back frame by a sixth of the shared size', () => { const { container } = render(); const [back, front] = Array.from(container.querySelectorAll('rect')); const backX = Number(back.getAttribute('x')); const backY = Number(back.getAttribute('y')); const backSize = Number(back.getAttribute('width')); const frontX = Number(front.getAttribute('x')); const frontY = Number(front.getAttribute('y')); const frontSize = Number(front.getAttribute('width')); expect(backSize).toBe(frontSize); expect(frontX - backX).toBeCloseTo(backSize / 6); expect(frontY - backY).toBeCloseTo(backSize / 6); }); it('renders both frames fully opaque and paints the exact mandated intersection hex', () => { const { container } = render(); const [back, front, intersection] = Array.from(container.querySelectorAll('rect')); expect(back.getAttribute('opacity')).toBeNull(); expect(front.getAttribute('opacity')).toBeNull(); expect(back.style.mixBlendMode).toBeFalsy(); expect(front.style.mixBlendMode).toBeFalsy(); expect(intersection.getAttribute('fill')).toBe(CUADRADOS_VARIANTS['blue-magenta'][2]); }); it('paints the correct mandated intersection hex for every registered variant', () => { for (const variant of CUADRADOS_VARIANT_IDS) { const { container } = render(); const rects = container.querySelectorAll('rect'); const intersection = rects[rects.length - 1]; expect(intersection.getAttribute('fill')).toBe(CUADRADOS_VARIANTS[variant][2]); } }); it('clips the intersection rect via nested clip-paths rather than isolating a blend mode', () => { const { container } = render(); expect((container.firstChild as HTMLElement).className).not.toContain('isolate'); expect(container.querySelectorAll('clipPath')).toHaveLength(2); }); it('expands the viewBox so no edge of the stroked frames is clipped', () => { const { container } = render(); const svg = container.querySelector('svg')!; const [minX, minY, width, height] = svg.getAttribute('viewBox')!.split(' ').map(Number); container.querySelectorAll('rect').forEach(rect => { const x = Number(rect.getAttribute('x')); const y = Number(rect.getAttribute('y')); const size = Number(rect.getAttribute('width')); const half = Number(rect.getAttribute('stroke-width')) / 2; expect(x - half).toBeGreaterThanOrEqual(minX); expect(y - half).toBeGreaterThanOrEqual(minY); expect(x + size + half).toBeLessThanOrEqual(minX + width); expect(y + size + half).toBeLessThanOrEqual(minY + height); }); }); });