mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-28 18:41:20 -08:00
refactor(jassub): [PKG-JASSUB-03] isolate registration and fix adapter cleanup
This commit is contained in:
1 parent
944e2cc9d0
commit
38e7b37878
21 files changed
+6553
-70
No files matched your search
@@ -0,0 +1,121 @@
|
||||
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)
|
||||
})
|
||||
Reference in new issue
Block a user