Files
tickte-system/tests/unit/helpers/fakeCtx.mjs
T

52 lines
2.4 KiB
JavaScript

// Aufzeichnender Canvas-Kontext für die Engine-Tests (Muster: Proxy aus entwuerfe/smoke.js).
// fillRect/fillText werden mit dem aktuellen fillStyle/font notiert, alles Übrige ist ein No-op.
/**
* makeCtx({ width, height }) → { ctx, rects, texts, strokes, counts, alphas }
* rects: [{ x, y, w, h, fill }] jedes fillRect
* texts: [{ text, x, y, font }] jedes fillText (Nicht-String wirft wie im Smoke-Test)
* strokes: [{ text, x, y, style, width, rects, texts }] jedes strokeText (style/width = strokeStyle/lineWidth, rects/texts =
* Anzahl der bis dahin gezeichneten fillRect/fillText: so ist die Reihenfolge prüfbar)
* counts: { save, restore } Aufrufe von ctx.save()/ctx.restore()
* alphas: [] jede Zuweisung an ctx.globalAlpha
*/
export function makeCtx({ width = 960, height = 768 } = {}) {
const rects = []
const texts = []
const strokes = []
const counts = { save: 0, restore: 0 }
const alphas = []
const target = { canvas: { width, height }, fillStyle: '#000000', font: '10px sans-serif', globalAlpha: 1 }
const ctx = new Proxy(target, {
get(t, prop) {
if (typeof prop === 'symbol') return undefined
if (prop === 'save') return () => { counts.save++ }
if (prop === 'restore') return () => { counts.restore++ }
if (prop === 'measureText') return (text) => ({ width: String(text).length * 7 })
if (prop === 'fillRect') return (x, y, w, h) => { rects.push({ x, y, w, h, fill: t.fillStyle }) }
if (prop === 'fillText') {
return (text, x, y) => {
if (typeof text !== 'string') throw new Error('fillText mit Nicht-String: ' + text)
texts.push({ text, x, y, font: t.font })
}
}
if (prop === 'strokeText') {
return (text, x, y) => {
if (typeof text !== 'string') throw new Error('strokeText mit Nicht-String: ' + text)
strokes.push({ text, x, y, style: t.strokeStyle, width: t.lineWidth, rects: rects.length, texts: texts.length })
}
}
if (prop === 'createLinearGradient' || prop === 'createRadialGradient') return () => ({ addColorStop() {} })
if (prop === 'getImageData') return () => ({ data: new Uint8ClampedArray(4) })
if (prop in t) return t[prop]
return () => {}
},
set(t, prop, value) {
if (prop === 'globalAlpha') alphas.push(value)
t[prop] = value
return true
},
})
return { ctx, rects, texts, strokes, counts, alphas }
}