mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 10:56:15 -08:00
122 lines
4.5 KiB
JavaScript
122 lines
4.5 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
// eslint-disable-next-line test/no-import-node-test -- Candidate adapter regressions use the repository runner.
|
|
import test from 'node:test'
|
|
import { jassubCandidate, jassubEnvironment } from './helpers/jassub.js'
|
|
|
|
const implementation = await jassubCandidate()
|
|
|
|
test('JASSUB custom canvas registration keeps caller DOM while releasing its actual vendor instance', async () => {
|
|
const env = jassubEnvironment(implementation)
|
|
const canvas = env.parent.appendChild(env.createCanvas())
|
|
const result = env.factory({ canvas })(env.art)
|
|
assert.equal(result.instance._canvas, canvas)
|
|
assert.equal(result.instance._canvasParent, undefined)
|
|
assert.equal(env.listeners.get('destroy').length, 1)
|
|
await env.ready()
|
|
assert.equal(env.workers[0].messages[0].target, 'init')
|
|
env.emit('destroy')
|
|
assert.equal(env.workers[0].terminated, 1)
|
|
assert.equal(canvas.parentNode, env.parent)
|
|
assert.equal(env.parent.children.length, 2)
|
|
})
|
|
|
|
test('JASSUB host cleanup tolerates an already destroyed exposed instance', async () => {
|
|
const env = jassubEnvironment(implementation)
|
|
const { instance } = env.factory()(env.art)
|
|
await env.ready()
|
|
instance.destroy()
|
|
assert.doesNotThrow(() => env.emit('destroy'))
|
|
assert.doesNotThrow(() => env.emit('destroy'))
|
|
assert.equal(env.workers[0].terminated, 1)
|
|
assert.equal(env.parent.children.length, 1)
|
|
})
|
|
|
|
test('JASSUB host cleanup before ready terminates once and retains the vendor destroyed-frame guard', async () => {
|
|
const env = jassubEnvironment(implementation)
|
|
const { instance } = env.factory()(env.art)
|
|
env.emit('destroy')
|
|
env.emit('destroy')
|
|
await env.flush()
|
|
assert.equal(instance._destroyed, true)
|
|
assert.equal(env.workers[0].terminated, 1)
|
|
assert.equal(env.parent.children.length, 1)
|
|
})
|
|
|
|
test('JASSUB host cleanup guards synchronous reentry without replacing the exposed destroy method', async () => {
|
|
const env = jassubEnvironment(implementation)
|
|
const { instance } = env.factory()(env.art)
|
|
await env.ready()
|
|
const original = instance.destroy
|
|
let calls = 0
|
|
const custom = function () {
|
|
calls++
|
|
env.emit('destroy')
|
|
return original.call(this)
|
|
}
|
|
instance.destroy = custom
|
|
env.emit('destroy')
|
|
assert.equal(calls, 1)
|
|
assert.equal(instance.destroy, custom)
|
|
assert.equal(env.workers[0].terminated, 1)
|
|
})
|
|
|
|
test('JASSUB failing host disposal preserves its error and allows another cleanup attempt', async () => {
|
|
const env = jassubEnvironment(implementation)
|
|
const { instance } = env.factory()(env.art)
|
|
await env.ready()
|
|
const original = instance.destroy
|
|
const failure = new Error('consumer cleanup failure')
|
|
instance.destroy = () => {
|
|
throw failure
|
|
}
|
|
assert.throws(() => env.emit('destroy'), error => error === failure)
|
|
assert.equal(env.workers[0].terminated, 0)
|
|
instance.destroy = original
|
|
env.emit('destroy')
|
|
assert.equal(env.workers[0].terminated, 1)
|
|
})
|
|
|
|
for (const offThrows of [false, true]) {
|
|
test(`JASSUB registration failure rolls back its instance and retains the original error when offThrows=${offThrows}`, async () => {
|
|
const env = jassubEnvironment(implementation)
|
|
const unrelated = () => {}
|
|
env.art.on('destroy', unrelated)
|
|
const on = env.art.on
|
|
const failure = new Error('host listener registration failed')
|
|
env.art.on = (name, listener) => {
|
|
on(name, listener)
|
|
throw failure
|
|
}
|
|
if (offThrows)
|
|
env.art.off = () => { throw new Error('secondary rollback failure') }
|
|
assert.throws(() => env.factory()(env.art), error => error === failure)
|
|
await env.flush()
|
|
assert.equal(env.workers[0].terminated, 1)
|
|
assert.equal(env.parent.children.length, 1)
|
|
if (!offThrows)
|
|
assert.deepEqual(env.listeners.get('destroy'), [unrelated])
|
|
assert.doesNotThrow(() => env.emit('destroy'))
|
|
assert.equal(env.workers[0].terminated, 1)
|
|
})
|
|
}
|
|
|
|
test('JASSUB style setup failure releases the created instance before returning the original exception', async () => {
|
|
const env = jassubEnvironment(implementation)
|
|
const insert = env.art.video.insertAdjacentElement
|
|
const failure = new Error('style setter failed')
|
|
env.art.video.insertAdjacentElement = function (position, child) {
|
|
insert.call(this, position, child)
|
|
Object.defineProperty(child.style, 'zIndex', {
|
|
get() { return undefined },
|
|
set() {
|
|
throw failure
|
|
},
|
|
})
|
|
}
|
|
assert.throws(() => env.factory()(env.art), error => error === failure)
|
|
await env.flush()
|
|
assert.equal(env.workers[0].terminated, 1)
|
|
assert.equal(env.parent.children.length, 1)
|
|
assert.equal(env.listeners.get('destroy'), undefined)
|
|
})
|