import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { createContext } from '../src/core/context.js'
let originalDPR
beforeEach(() => {
originalDPR = window.devicePixelRatio
Object.defineProperty(window, 'devicePixelRatio', {
configurable: true,
value: 2,
})
})
afterEach(() => {
Object.defineProperty(window, 'devicePixelRatio', {
configurable: true,
value: originalDPR ?? 1,
})
})
describe('createContext - defaults & normalization', () => {
it('returns sensible defaults when called without options', () => {
const ctx = createContext()
expect(ctx.debug).toBe(false)
expect(ctx.scale).toBe(1)
expect(Array.isArray(ctx.exclude)).toBe(true)
expect(ctx.exclude.length).toBe(0)
expect(ctx.excludeMode).toBe('hide')
expect(ctx.filter).toBe(null)
expect(ctx.filterMode).toBe('hide')
expect(ctx.embedFonts).toBe('auto')
expect(Array.isArray(ctx.iconFonts)).toBe(true)
expect(ctx.iconFonts.length).toBe(0)
expect(Array.isArray(ctx.localFonts)).toBe(true)
expect(ctx.localFonts.length).toBe(0)
expect(ctx.excludeFonts).toBeUndefined()
expect(ctx.cache).toBe('soft')
expect(ctx.useProxy).toBe('')
expect(ctx.width).toBeNull()
expect(ctx.height).toBeNull()
expect(ctx.format).toBe('png')
expect(ctx.type).toBe('png')
expect(ctx.quality).toBeCloseTo(0.92)
expect(ctx.dpr).toBe(2)
expect(ctx.backgroundColor).toBeNull()
expect(ctx.filename).toBe('snapDOM')
expect(ctx.resolvePicturePlaceholders).toBe(true)
})
it('normalizes iconFonts input (string → array, array stays, falsy → empty array)', () => {
expect(createContext({ iconFonts: 'FA' }).iconFonts).toEqual(['FA'])
expect(createContext({ iconFonts: ['A', 'B'] }).iconFonts).toEqual(['A', 'B'])
expect(createContext({ iconFonts: null }).iconFonts).toEqual([])
expect(createContext({}).iconFonts).toEqual([])
})
it('normalizes localFonts (array only; non-array → empty array)', () => {
const arr = [{ family: 'X', src: 'data:...' }]
expect(createContext({ localFonts: arr }).localFonts).toBe(arr)
expect(createContext({ localFonts: { family: 'X' } }).localFonts).toEqual([])
expect(createContext({}).localFonts).toEqual([])
})
it('passes through excludeFonts when provided, otherwise leaves undefined', () => {
const ex = { families: ['Foo'], domains: ['bar.com'], subsets: ['latin'] }
expect(createContext({ excludeFonts: ex }).excludeFonts).toBe(ex)
expect(createContext({}).excludeFonts).toBeUndefined()
})
it('normalizes cache: disabled opts out, every legacy string collapses to the structural default', () => {
expect(createContext({ cache: 'soft' }).cache).toBe('soft')
expect(createContext({ cache: 'full' }).cache).toBe('soft')
expect(createContext({ cache: 'auto' }).cache).toBe('soft')
expect(createContext({ cache: 'disabled' }).cache).toBe('disabled')
expect(createContext({ cache: false }).cache).toBe('disabled')
expect(createContext({ cache: 'weird' }).cache).toBe('soft')
expect(createContext({ cache: 123 }).cache).toBe('soft')
})
it('sets useProxy only when it is a string; otherwise empty string', () => {
expect(createContext({ useProxy: 'https://p/' }).useProxy).toBe('https://p/')
expect(createContext({ useProxy: 123 }).useProxy).toBe('')
expect(createContext({}).useProxy).toBe('')
})
it('uses provided dpr when present; otherwise window.devicePixelRatio || 1', () => {
expect(createContext({ dpr: 3 }).dpr).toBe(3)
Object.defineProperty(window, 'devicePixelRatio', {
configurable: true,
value: 1.5,
})
expect(createContext({}).dpr).toBe(1.5)
Object.defineProperty(window, 'devicePixelRatio', {
configurable: true,
value: undefined,
})
expect(createContext({}).dpr).toBe(1)
})
it('computes default backgroundColor by format, and allows override', () => {
let ctx = createContext({ format: 'webp' })
expect(ctx.backgroundColor).toBe('#ffffff')
ctx = createContext({ format: 'jpg' })
expect(ctx.backgroundColor).toBe('#ffffff')
ctx = createContext({ format: 'jpeg' })
expect(ctx.backgroundColor).toBe('#ffffff')
ctx = createContext({ format: 'png' })
expect(ctx.backgroundColor).toBeNull()
ctx = createContext({ format: 'jpg', backgroundColor: '#000' })
expect(ctx.backgroundColor).toBe('#000')
})
it('resolves format via resolvedFormat and keeps other output options', () => {
const ctx = createContext({
format: 'webp',
type: 'svg',
width: 800,
height: 600,
quality: 0.8,
filename: 'custom',
debug: true,
scale: 2,
})
expect(ctx.format).toBe('webp')
expect(ctx.type).toBe('webp')
expect(ctx.width).toBe(800)
expect(ctx.height).toBe(600)
expect(ctx.quality).toBeCloseTo(0.8)
expect(ctx.filename).toBe('custom')
expect(ctx.debug).toBe(true)
expect(ctx.scale).toBe(2)
})
})
describe('createContext - canvas target', () => {
it('keeps a canvas created by a same-origin iframe document', () => {
const iframe = document.createElement('iframe')
document.body.appendChild(iframe)
try {
const canvas = iframe.contentDocument.createElement('canvas')
expect(canvas instanceof HTMLCanvasElement).toBe(false)
expect(createContext({ canvas }).canvas).toBe(canvas)
expect(createContext({ canvas: iframe.contentDocument.createElement('div') }).canvas).toBe(null)
} finally {
iframe.remove()
}
})
})