import { describe, expect, it } from 'bun:test' import { renderJSX } from '@open-pencil/core' import { makeSceneGraph } from '#tests/helpers/scene' describe('jsx gaps', () => { it('mask prop sets isMask + maskType', async () => { const g = makeSceneGraph() await renderJSX( g, `` ) const ellipse = [...g.nodes.values()].find((n) => n.type === 'ELLIPSE') expect(ellipse?.isMask).toBe(true) expect(ellipse?.maskType).toBe('ALPHA') }) it('svg element renders vector paths', async () => { const g = makeSceneGraph() await renderJSX( g, `` ) const vector = [...g.nodes.values()].find((n) => n.type === 'VECTOR') expect(vector).toBeTruthy() expect(vector?.vectorNetwork).toBeTruthy() }) it('renders SVG element children for every supported primitive', async () => { const g = makeSceneGraph() await renderJSX( g, ` ` ) const vectors = [...g.nodes.values()].filter((node) => node.type === 'VECTOR') expect(vectors).toHaveLength(7) expect(vectors.filter((node) => node.fills.length > 0)).toHaveLength(6) expect(vectors.filter((node) => node.strokes.length > 0)).toHaveLength(2) expect(vectors.every((node) => (node.vectorNetwork?.vertices.length ?? 0) > 0)).toBe(true) }) it('preserves root presentation and applies nested transforms', async () => { const g = makeSceneGraph() await renderJSX( g, ` ` ) const vector = [...g.nodes.values()].find((node) => node.type === 'VECTOR') expect(vector?.fills[0]?.color).toMatchObject({ r: 1, g: 0, b: 0 }) expect(vector?.vectorNetwork?.vertices.map(({ x, y }) => ({ x, y }))).toEqual([ { x: 32, y: 24 }, { x: 40, y: 24 }, { x: 40, y: 34 }, { x: 32, y: 34 } ]) }) it('renders an SVG containing only a circle', async () => { const g = makeSceneGraph() await renderJSX( g, `` ) const vectors = [...g.nodes.values()].filter((node) => node.type === 'VECTOR') expect(vectors).toHaveLength(1) expect(vectors[0].fills).toHaveLength(1) }) it('renders open and closed SVG paths as separate stroked vectors', async () => { const g = makeSceneGraph() await renderJSX( g, `` ) const vectors = [...g.nodes.values()].filter((node) => node.type === 'VECTOR') expect(vectors).toHaveLength(2) for (const vector of vectors) { expect(vector.vectorNetwork?.vertices.length).toBeGreaterThan(0) expect(vector.strokes.length).toBeGreaterThan(0) } }) it('respects none paints on inline SVG paths', async () => { const g = makeSceneGraph() await renderJSX( g, ` ` ) const vectors = [...g.nodes.values()].filter((node) => node.type === 'VECTOR') expect(vectors).toHaveLength(2) expect(vectors[0].fills).toEqual([]) expect(vectors[0].strokes).toHaveLength(1) expect(vectors[1].fills).toHaveLength(1) expect(vectors[1].strokes).toEqual([]) }) it('instance overrides apply child text by name', async () => { const g = makeSceneGraph() await renderJSX( g, `+0% ` ) const inst = [...g.nodes.values()].find((n) => n.type === 'INSTANCE') const label = [...g.nodes.values()].find( (n) => n.type === 'TEXT' && inst && n.parentId === inst.id ) expect(label?.text).toBe('+14%') }) })