import {describe, expect, it, vi} from 'vitest';
import {parseMergedSvg} from './MergedSvg';
// Three disjoint squares: three shapes, one fill color.
const MONOCHROME_ICON = `
`;
// Two shapes with different fill colors.
const MULTICOLOR_ICON = `
`;
describe('parseMergedSvg', () => {
it('merges all same-fill shapes into a single mesh without deprecation warnings', () => {
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
const {meshes} = parseMergedSvg(MONOCHROME_ICON);
expect(warnSpy).not.toHaveBeenCalled();
warnSpy.mockRestore();
expect(meshes).toHaveLength(1);
const singleSquare = parseMergedSvg(
''
);
const squareCount =
singleSquare.meshes[0].geometry.getAttribute('position').count;
const mergedCount = meshes[0].geometry.getAttribute('position').count;
expect(mergedCount).toBe(squareCount * 3);
});
it('keeps one mesh per distinct fill color', () => {
const {meshes} = parseMergedSvg(MULTICOLOR_ICON);
expect(meshes).toHaveLength(2);
const colors = meshes.map((mesh) =>
(
mesh.material as unknown as {color: {getHexString(): string}}
).color.getHexString()
);
expect(colors.sort()).toEqual(['00ff00', 'ff0000']);
});
it('exposes the viewBox bounding box', () => {
const {boundingBox} = parseMergedSvg(MONOCHROME_ICON);
expect(boundingBox).toBeDefined();
expect(boundingBox!.size.x).toBe(24);
expect(boundingBox!.size.y).toBe(24);
expect(boundingBox!.center.x).toBe(12);
expect(boundingBox!.center.y).toBe(-12);
});
it('flips Y via mesh scale exactly like uikit', () => {
const {meshes} = parseMergedSvg(
''
);
const mesh = meshes[0];
// The flip lives on the mesh (negative-determinant matrixWorld keeps
// three's frontFace culling parity with uikit), not in the geometry.
expect(mesh.scale.y).toBe(-1);
expect(mesh.matrix.elements[5]).toBe(-1);
const positions = mesh.geometry.getAttribute('position');
for (let index = 0; index < positions.count; index++) {
expect(positions.getY(index)).toBeGreaterThanOrEqual(1.9);
expect(positions.getY(index)).toBeLessThanOrEqual(8.1);
}
});
});