mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-19 03:11:20 -08:00
fix(dash): [PKG-DASH-CLEANUP-01] preserve first cleanup exception
This commit is contained in:
1 parent
1c522f181b
commit
25faf88e80
23 files changed
+49546
-147
No files matched your search
@@ -0,0 +1,87 @@
|
||||
import assert from 'node:assert/strict'
|
||||
// eslint-disable-next-line test/no-import-node-test -- Cleanup exception identity uses the Node lifecycle runner.
|
||||
import test from 'node:test'
|
||||
import { bothMenus, dashHost, dashImplementations } from './helpers/dash-control.js'
|
||||
|
||||
const implementations = (await dashImplementations()).filter(item => item.name.startsWith('source') || item.name.startsWith('artifact'))
|
||||
const failures = [undefined, null, false, 0, -0, '', Number.NaN]
|
||||
function attempt(callback) {
|
||||
try {
|
||||
callback()
|
||||
return { threw: false }
|
||||
}
|
||||
catch (error) {
|
||||
return { threw: true, error }
|
||||
}
|
||||
}
|
||||
|
||||
for (const { sdk, name, factory } of implementations) {
|
||||
for (const trigger of ['update', 'destroy']) {
|
||||
test(`DASH ${sdk} (${name}): ${trigger} preserves the first falsy menu cleanup failure`, (t) => {
|
||||
const warnings = []
|
||||
t.mock.method(console, 'warn', (...args) => warnings.push(args))
|
||||
for (const failure of failures) {
|
||||
const host = dashHost(sdk)
|
||||
const plugin = factory(bothMenus())(host.art)
|
||||
plugin.update()
|
||||
const calls = []
|
||||
for (const surface of ['controls', 'setting']) {
|
||||
const remove = host.art[surface].remove
|
||||
host.art[surface].remove = (key) => {
|
||||
remove(key)
|
||||
calls.push([surface, key])
|
||||
if (surface === 'controls' && key === 'dash-quality')
|
||||
throw failure
|
||||
throw new Error(`later ${surface}/${key} failure`)
|
||||
}
|
||||
}
|
||||
if (trigger === 'update') {
|
||||
host.state.levels = []
|
||||
host.state.tracks = []
|
||||
}
|
||||
const result = attempt(() => trigger === 'update' ? plugin.update() : host.art.destroy())
|
||||
assert.equal(result.threw, true)
|
||||
assert(Object.is(result.error, failure), 'Later menu cleanup errors cannot replace the first value')
|
||||
assert.deepEqual(calls, [['controls', 'dash-quality'], ['setting', 'dash-quality'], ['controls', 'dash-audio'], ['setting', 'dash-audio']])
|
||||
assert.equal(host.controls.size + host.settings.size, 0)
|
||||
if (trigger === 'destroy') {
|
||||
assert.equal([...host.listeners.values()].reduce((sum, list) => sum + list.size, 0), 0)
|
||||
assert.doesNotThrow(() => host.art.destroy())
|
||||
}
|
||||
}
|
||||
if (trigger === 'update') {
|
||||
assert.equal(warnings.length, failures.length)
|
||||
assert(warnings.every(([message, error]) => message === 'ArtPlayer DASH cleanup failed:' && error instanceof Error))
|
||||
}
|
||||
else {
|
||||
assert.equal(warnings.length, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
test(`DASH ${sdk} (${name}): SDK unsubscribe preserves a falsy first failure while releasing all resources`, () => {
|
||||
for (const failure of failures) {
|
||||
const host = dashHost(sdk)
|
||||
const events = new Map()
|
||||
host.dash.on = (name, callback) => events.set(name, callback)
|
||||
let offCalls = 0
|
||||
host.dash.off = (name) => {
|
||||
events.delete(name)
|
||||
if (++offCalls === 1)
|
||||
throw failure
|
||||
throw new Error('later SDK removal failure')
|
||||
}
|
||||
factory(bothMenus())(host.art).update()
|
||||
const count = events.size
|
||||
assert(count > 0)
|
||||
const result = attempt(() => host.art.destroy())
|
||||
assert.equal(result.threw, true)
|
||||
assert(Object.is(result.error, failure))
|
||||
assert.equal(offCalls, count)
|
||||
assert.equal(events.size, 0)
|
||||
assert.equal(host.controls.size + host.settings.size, 0)
|
||||
assert.equal([...host.listeners.values()].reduce((sum, list) => sum + list.size, 0), 0)
|
||||
assert(!host.calls.some(call => call[0] === 'dash.destroy'), 'SDK remains caller-owned')
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user