import assert from 'node:assert/strict'; import { createRequire } from 'node:module'; import test from 'node:test'; const require = createRequire(import.meta.url); const HDREnhancer = require('../src/hdr-enhance.js'); function createMatchMedia(matches) { return (query) => ({ media: query, matches: Boolean(matches[query]), addEventListener() {}, removeEventListener() {} }); } function createFakeDocument() { const nodesById = new Map(); const attach = (node, parentList) => { parentList.push(node); if (node.id) nodesById.set(node.id, node); return node; }; const documentElement = { dataset: {}, style: { values: {}, setProperty(name, value) { this.values[name] = value; }, removeProperty(name) { delete this.values[name]; } } }; const body = { dataset: {}, children: [], appendChild(node) { return attach(node, this.children); }, removeAttribute(name) { if (name === 'data-hdr-enhanced') delete this.dataset.hdrEnhanced; if (name === 'data-hdr-mode') delete this.dataset.hdrMode; if (name === 'data-hdr-media') delete this.dataset.hdrMedia; if (name === 'data-hdr-text') delete this.dataset.hdrText; } }; const head = { children: [], appendChild(node) { return attach(node, this.children); } }; return { body, documentElement, head, createElement(tagName) { return { tagName: tagName.toUpperCase(), id: '', className: '', textContent: '', innerHTML: '', dataset: {}, style: {}, children: [], attributes: {}, setAttribute(name, value) { this.attributes[name] = String(value); }, appendChild(child) { return attach(child, this.children); }, remove() { nodesById.delete(this.id); head.children = head.children.filter((node) => node !== this); body.children = body.children.filter((node) => node !== this); } }; }, getElementById(id) { return nodesById.get(id) || null; }, querySelectorAll() { return []; } }; } test('detectCapabilities prefers the widest available gamut and HDR dynamic range', () => { const capabilities = HDREnhancer.detectCapabilities({ matchMedia: createMatchMedia({ '(dynamic-range: high)': true, '(color-gamut: rec2020)': true, '(color-gamut: p3)': true, '(prefers-reduced-motion: reduce)': false }), CSS: { supports(property, value) { return ( property === 'color' && value === 'color(display-p3 1 0 0)' ) || ( property === 'dynamic-range-limit' && value === 'no-limit' ); } } }); assert.equal(capabilities.dynamicRange, 'high'); assert.equal(capabilities.colorGamut, 'rec2020'); assert.equal(capabilities.supportsDisplayP3, true); assert.equal(capabilities.supportsDynamicRangeLimit, true); assert.equal(capabilities.prefersReducedMotion, false); }); test('createStyleText includes HDR, P3, pure-black, no-limit, and reduced-motion rules', () => { const css = HDREnhancer.createStyleText({ intensity: 1.2, animated: true, text: true, textBoost: 2.4 }, { dynamicRange: 'high', colorGamut: 'p3', supportsDisplayP3: true, supportsHdrColor: true, prefersReducedMotion: false }); assert.match(css, /@media \(dynamic-range: high\)/); assert.match(css, /@media \(color-gamut: p3\)/); assert.match(css, /dynamic-range-limit: no-limit/); assert.match(css, /background: #000000 !important/); assert.match(css, /body\[data-hdr-enhanced="true"\]::before/); assert.match(css, /color\(display-p3/); assert.match(css, /--hdr-fallback-cyan/); assert.match(css, /--hdr-text-boost: 2\.40/); assert.match(css, /data-hdr-text/); assert.match(css, /--hdr-texture-url/); assert.match(css, /background-clip: text/); assert.match(css, /-webkit-text-fill-color: transparent/); assert.match(css, /hdr-color/); assert.match(css, /:where\(body\[data-hdr-enhanced="true"\] > :not/); assert.match(css, /prefers-reduced-motion: reduce/); }); test('createMediaConfig defaults to HDR video on HDR-capable outputs only', () => { const hdr = HDREnhancer.createMediaConfig({ assetBase: 'https://example.com/', media: true }, { dynamicRange: 'high' }); const sdr = HDREnhancer.createMediaConfig({ assetBase: 'https://example.com/', media: true }, { dynamicRange: 'standard' }); const disabled = HDREnhancer.createMediaConfig({ assetBase: 'https://example.com/', media: false }, { dynamicRange: 'high' }); assert.equal(hdr.enabled, true); assert.equal(hdr.type, 'video'); assert.equal(hdr.src, 'https://example.com/media/hdr-galaxy-fireworks.mp4'); assert.deepEqual(hdr.sources, [ { src: 'https://example.com/media/hdr-galaxy-fireworks.mp4', type: 'video/mp4; codecs="hvc1"' }, { src: 'https://example.com/media/hdr-galaxy-fireworks.webm', type: 'video/webm; codecs="vp09.02.10.10.01.09.16.09.01"' } ]); assert.equal(sdr.enabled, false); assert.equal(disabled.enabled, false); }); test('createMediaConfig can inject a swappable HDR image stage', () => { const hdr = HDREnhancer.createMediaConfig({ assetBase: 'https://example.com/', media: true, mediaType: 'image', imageSrc: '/assets/custom-hdr.png' }, { dynamicRange: 'high' }); assert.equal(hdr.enabled, true); assert.equal(hdr.type, 'image'); assert.equal(hdr.src, 'https://example.com/assets/custom-hdr.png'); assert.equal(hdr.sources.length, 1); assert.equal(hdr.sources[0].type, 'image/png'); }); test('enhance injects pure-black HDR media once, then disable removes it', () => { const document = createFakeDocument(); const window = { document, matchMedia: createMatchMedia({ '(dynamic-range: high)': true, '(color-gamut: p3)': true }), CSS: { supports() { return true; } } }; const first = HDREnhancer.enhance({ window, intensity: 1.1 }); const second = HDREnhancer.enhance({ window, intensity: 1.1 }); assert.equal(first.active, true); assert.equal(second.active, true); assert.equal(second.reused, true); assert.equal(document.head.children.filter((node) => node.id === 'hdr-enhancer-style').length, 1); assert.equal(document.body.children.filter((node) => node.id === 'hdr-enhancer-overlay').length, 0); assert.equal(document.body.children.filter((node) => node.id === 'hdr-enhancer-video').length, 1); assert.equal(document.body.dataset.hdrEnhanced, 'true'); assert.equal(document.body.dataset.hdrMode, 'p3'); assert.equal(document.body.dataset.hdrMedia, 'true'); const disabled = HDREnhancer.disable({ window }); assert.equal(disabled.active, false); assert.equal(document.getElementById('hdr-enhancer-style'), null); assert.equal(document.getElementById('hdr-enhancer-overlay'), null); assert.equal(document.getElementById('hdr-enhancer-video'), null); assert.equal(document.body.dataset.hdrEnhanced, undefined); assert.equal(document.body.dataset.hdrMedia, undefined); }); test('readScriptOptions maps script data attributes into plugin options', () => { const options = HDREnhancer.readScriptOptions({ dataset: { hdrIntensity: '1.35', hdrAnimated: 'false', hdrOverlay: 'true', hdrScanlines: 'false', hdrBadge: 'false', hdrEffects: 'true', hdrEffect: 'cosmic-fireworks', hdrQuality: 'high', hdrFps: '48', hdrMaxDpr: '1.5', hdrMotion: 'ambient', hdrMedia: 'true', hdrBlackout: 'true', hdrVideoSrc: '/media/custom-hdr.mp4', hdrWebmSrc: '/media/custom-hdr.webm', hdrImageSrc: '/media/custom-hdr.png', hdrMediaType: 'image', hdrText: 'true', hdrTextBoost: '2.65', hdrTextSrc: '/media/custom-text-hdr.png' }, src: 'https://cdn.example.com/dist/hdr-web-plugin.js' }); assert.deepEqual(options, { intensity: 1.35, animated: false, overlay: true, scanlines: false, badge: false, effects: true, effect: 'cosmic-fireworks', quality: 'high', fps: 48, maxDpr: 1.5, motion: 'ambient', media: true, blackout: true, videoSrc: '/media/custom-hdr.mp4', webmSrc: '/media/custom-hdr.webm', imageSrc: '/media/custom-hdr.png', mediaType: 'image', text: true, textBoost: 2.65, textSrc: '/media/custom-text-hdr.png', assetBase: 'https://cdn.example.com/' }); }); test('plugin exposes stable metadata for script tag consumers', () => { assert.equal(HDREnhancer.pluginName, 'HDR Web Plugin'); assert.match(HDREnhancer.version, /^\d+\.\d+\.\d+$/); assert.equal(typeof HDREnhancer.install, 'function'); }); test('dist plugin entry exports the same public API', () => { const DistHDREnhancer = require('../dist/hdr-web-plugin.js'); assert.equal(DistHDREnhancer.pluginName, HDREnhancer.pluginName); assert.equal(DistHDREnhancer.version, HDREnhancer.version); assert.equal(typeof DistHDREnhancer.enhance, 'function'); assert.equal(typeof DistHDREnhancer.disable, 'function'); }); test('createEffectConfig enables cosmic fireworks with reduced-motion fallback', () => { const active = HDREnhancer.createEffectConfig({ intensity: 1.5, effect: 'cosmic-fireworks', effects: true, motion: 'ambient' }, { prefersReducedMotion: false, colorGamut: 'p3' }); const reduced = HDREnhancer.createEffectConfig({ intensity: 1.5, effect: 'cosmic-fireworks', effects: true }, { prefersReducedMotion: true, colorGamut: 'p3' }); assert.equal(active.enabled, true); assert.equal(active.effect, 'cosmic-fireworks'); assert.equal(active.fireworkBursts, true); assert.equal(active.galaxy, true); assert.equal(active.motionScale, 1); assert.equal(reduced.motionScale, 0.18); }); test('createEffectConfig defaults to a static low-power budget', () => { const config = HDREnhancer.createEffectConfig({ intensity: 1.55, effect: 'cosmic-fireworks', effects: true }, { prefersReducedMotion: false, colorGamut: 'p3' }); assert.equal(config.quality, 'low'); assert.equal(config.motion, 'static'); assert.equal(config.shouldAnimate, false); assert.equal(config.targetFps <= 1, true); assert.equal(config.dprCap, 1); assert.equal(config.starCount <= 50, true); assert.equal(config.galaxyCount <= 58, true); assert.equal(config.burstParticleCount, 0); assert.equal(config.maxSparks, 0); }); test('createEffectConfig requires explicit ambient motion for continuous animation', () => { const config = HDREnhancer.createEffectConfig({ intensity: 1.55, effect: 'cosmic-fireworks', effects: true, quality: 'balanced', motion: 'ambient' }, { prefersReducedMotion: false, colorGamut: 'p3' }); assert.equal(config.quality, 'balanced'); assert.equal(config.motion, 'ambient'); assert.equal(config.shouldAnimate, true); assert.equal(config.targetFps <= 24, true); assert.equal(config.dprCap <= 1.15, true); assert.equal(config.maxSparks <= 90, true); });