Files
ArtPlayer/test/media-hosts.test.js
T

117 lines
4.1 KiB
JavaScript

import assert from 'node:assert/strict'
// eslint-disable-next-line test/no-import-node-test -- Use the repository Node runner.
import { test } from 'node:test'
import { loadModules } from './helpers/load.js'
const { playMix, pauseMix, playingMix, durationMix, rectMix } = await loadModules(Object.fromEntries(['playMix', 'pauseMix', 'playingMix', 'durationMix', 'rectMix'].map(name => [name, `packages/artplayer/src/player/${name}`])))
test('structural playback hosts retain synchronous proxy values, async play order and receivers', async () => {
const calls = []
const media = {
play() {
assert.equal(this, media)
calls.push('media:play')
return 'proxy-result'
},
pause() {
assert.equal(this, media)
calls.push('media:pause')
return 42
},
}
const art = {
template: { $video: media },
option: { mutex: true },
i18n: { get: key => key },
notice: {
get show() {
return false
},
set show(message) {
calls.push(`notice:${message}`)
},
},
emit: name => calls.push(`event:${name}`),
constructor: { instances: [] },
}
playMix(art)
pauseMix(art)
art.constructor.instances.push(art, {
pause: () => calls.push('mutex'),
})
const play = art.play
const pause = art.pause
const result = play()
assert(result instanceof Promise)
assert.deepEqual(calls, ['media:play'])
assert.equal(await result, 'proxy-result')
assert.deepEqual(calls, ['media:play', 'notice:Play', 'event:play', 'mutex'])
assert.equal(pause(), 42)
assert.deepEqual(calls.slice(-3), ['media:pause', 'notice:Pause', 'event:pause'])
for (const name of ['play', 'pause']) {
const descriptor = Object.getOwnPropertyDescriptor(art, name)
assert.equal(descriptor.enumerable, false)
assert.equal(descriptor.configurable, false)
assert.equal(descriptor.writable, false)
}
})
test('playing uses a shim boolean when present and otherwise keeps native fallback', () => {
const video = { currentTime: 1, paused: false, ended: false, readyState: 3 }
const art = { template: { $video: video } }
playingMix(art)
assert.equal(art.playing, true)
video.playing = false
assert.equal(art.playing, false)
video.currentTime = 0
video.playing = true
assert.equal(art.playing, true)
delete video.playing
assert.equal(art.playing, false)
video.currentTime = 1
video.readyState = 2
assert.equal(art.playing, false)
video.readyState = 3
video.ended = true
assert.equal(art.playing, false)
})
test('duration normalization reads the current media reference and keeps legacy infinity rules', () => {
const art = { template: { $video: { duration: Infinity } } }
durationMix(art)
assert.equal(art.duration, 0)
for (const [value, expected] of [[Number.NaN, 0], [0, 0], [-Infinity, -Infinity], [12.5, 12.5]]) {
art.template.$video = { duration: value }
assert.equal(art.duration, expected)
}
})
test('layout host getters stay live, preserve descriptor order and read scroll offsets', (context) => {
const previous = Object.getOwnPropertyDescriptor(globalThis, 'window')
Object.defineProperty(globalThis, 'window', { configurable: true, value: { pageXOffset: 4, pageYOffset: 8 } })
context.after(() => {
if (previous)
Object.defineProperty(globalThis, 'window', previous)
else
delete globalThis.window
})
let rectangle = { bottom: 40, height: 30, left: 10, right: 50, top: 10, width: 40 }
const player = { getBoundingClientRect() {
assert.equal(this, player)
return rectangle
} }
const art = { template: { $player: player } }
rectMix(art)
assert.equal(art.rect, rectangle)
assert.equal(art.x, 14)
assert.equal(art.y, 18)
rectangle = { ...rectangle, width: 80, left: 20 }
assert.equal(art.width, 80)
assert.equal(art.x, 24)
assert.deepEqual(Object.getOwnPropertyNames(art), ['template', 'rect', 'bottom', 'height', 'left', 'right', 'top', 'width', 'x', 'y'])
const descriptor = Object.getOwnPropertyDescriptor(art, 'width')
assert.equal(descriptor.enumerable, false)
assert.equal(descriptor.configurable, false)
assert.equal(descriptor.set, undefined)
})