import { describe, expect, mock, test } from 'bun:test' import type { Canvas } from 'canvaskit-wasm' import type { SceneGraph } from '@open-pencil/scene-graph' import { createDefaultNode } from '@open-pencil/scene-graph/node-defaults' import { renderShapeUncached } from '#core/canvas/scene' import { createMockCanvas, createMockRenderer } from './helpers' describe('Renderer effect ordering (Behavioral)', () => { test('drop shadow renders before fills', () => { const r = createMockRenderer() const canvas = createMockCanvas() const node = createDefaultNode(() => 'node1', 'RECTANGLE', { width: 100, height: 100, effects: [ { type: 'DROP_SHADOW', visible: true, color: { r: 0, g: 0, b: 0, a: 0.5 }, offset: { x: 0, y: 0 }, radius: 10, spread: 0 } ], fills: [{ visible: true, type: 'SOLID', color: { r: 1, g: 0, b: 0, a: 1 }, opacity: 1 }], strokes: [] }) const graph: Partial = { getNode: mock(() => node) } const callOrder: string[] = [] r.renderEffects = mock((_c, _n, _r, _h, pass) => { callOrder.push(`renderEffects:${pass}`) }) r.drawNodeFill = mock(() => { callOrder.push('drawNodeFill') }) renderShapeUncached(r, canvas as Canvas, node, graph as SceneGraph) expect(callOrder).toEqual(['renderEffects:behind', 'drawNodeFill', 'renderEffects:front']) }) test('inner shadow and blur render after strokes', () => { const r = createMockRenderer() const canvas = createMockCanvas() const node = createDefaultNode(() => 'node1', 'RECTANGLE', { width: 100, height: 100, fills: [], childIds: [], effects: [ { type: 'INNER_SHADOW', visible: true, color: { r: 0, g: 0, b: 0, a: 0.5 }, offset: { x: 0, y: 0 }, radius: 10, spread: 0 } ], strokes: [{ visible: true, weight: 1, opacity: 1, color: { r: 0, g: 0, b: 0, a: 1 } }] }) const graph: Partial = { getNode: mock(() => node) } const callOrder: string[] = [] r.renderEffects = mock((_c, _n, _r, _h, pass) => { callOrder.push(`renderEffects:${pass}`) }) r.drawStrokeWithAlign = mock(() => { callOrder.push('drawStrokeWithAlign') }) renderShapeUncached(r, canvas as Canvas, node, graph as SceneGraph) const strokeIdx = callOrder.indexOf('drawStrokeWithAlign') const frontIdx = callOrder.indexOf('renderEffects:front') expect(strokeIdx).toBeGreaterThan(-1) expect(frontIdx).toBeGreaterThan(-1) expect(strokeIdx).toBeLessThan(frontIdx) }) })