mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-09 03:17:46 -08:00
141 lines
6.2 KiB
JavaScript
141 lines
6.2 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
// eslint-disable-next-line test/no-import-node-test -- Frozen historical regressions use the repository Node runner.
|
|
import test from 'node:test'
|
|
import { autoThumbnailEnvironment, autoThumbnailHistorical } from './helpers/auto-thumbnail.js'
|
|
|
|
for (const implementation of await autoThumbnailHistorical()) {
|
|
test(`Auto-thumbnail ${implementation.name} historical: destroy leaves pending encode and final URL alive`, async () => {
|
|
const env = autoThumbnailEnvironment(implementation)
|
|
await env.factory({ number: 2 })(env.art)
|
|
env.art.emit('video:loadedmetadata')
|
|
env.metadata()
|
|
const video = env.videos[0]
|
|
env.art.emit('destroy')
|
|
env.finish()
|
|
assert.equal(env.updates.length, 1)
|
|
assert.equal(env.urls.size, 1)
|
|
assert.equal(env.listeners.get('video:loadedmetadata').size, 1)
|
|
assert.equal(typeof video.onloadedmetadata, 'function')
|
|
assert.equal(typeof video.onseeked, 'function')
|
|
assert.equal(video.src, 'original.mp4')
|
|
assert.equal(env.operations.filter(item => item.name === 'pause' || item.name === 'load').length, 0)
|
|
env.art.emit('destroy')
|
|
assert.equal(env.urls.size, 1)
|
|
})
|
|
|
|
test(`Auto-thumbnail ${implementation.name} historical: delayed old metadata overwrites a newer source sheet`, async () => {
|
|
const env = autoThumbnailEnvironment(implementation)
|
|
const options = { number: 2, width: 80 }
|
|
await env.factory(options)(env.art)
|
|
env.art.emit('video:loadedmetadata')
|
|
const oldVideo = env.videos[0]
|
|
env.art.option.url = 'replacement.mp4'
|
|
options.width = 160
|
|
env.art.emit('restart')
|
|
env.art.emit('video:loadedmetadata')
|
|
env.metadata(env.videos[1])
|
|
env.finish(0, { source: 'new' })
|
|
assert.equal(env.updates.at(-1).width, 160)
|
|
env.metadata(oldVideo)
|
|
env.finish(1, { source: 'old' })
|
|
assert.equal(env.updates.at(-1).width, 80)
|
|
assert.equal(env.urls.get(env.updates.at(-1).url).source, 'old')
|
|
assert.equal(env.urls.size, 2, 'Separate jobs never revoke each other or release the latest stale sheet')
|
|
})
|
|
|
|
test(`Auto-thumbnail ${implementation.name} historical: repeated metadata opens independent decoders without closing previous jobs`, async () => {
|
|
const env = autoThumbnailEnvironment(implementation)
|
|
await env.factory({ number: 1 })(env.art)
|
|
for (let index = 0; index < 3; index++) {
|
|
env.art.emit('video:loadedmetadata')
|
|
env.metadata()
|
|
env.finish(index)
|
|
}
|
|
assert.equal(env.videos.length, 3)
|
|
assert.equal(env.urls.size, 3)
|
|
assert.equal(env.operations.some(item => item.name === 'pause' || item.name === 'load'), false)
|
|
assert.equal(env.videos.every(video => typeof video.onseeked === 'function'), true)
|
|
})
|
|
|
|
test(`Auto-thumbnail ${implementation.name} historical: reverse Blob delivery replaces a complete sheet with its initial blank snapshot`, async () => {
|
|
const env = autoThumbnailEnvironment(implementation)
|
|
await env.factory({ number: 2 })(env.art)
|
|
env.art.emit('video:loadedmetadata')
|
|
env.metadata()
|
|
env.seeked()
|
|
env.seeked()
|
|
assert.equal(env.blobs.length, 3, 'All native encodes can be pending together')
|
|
env.finish(2, { frames: 2 })
|
|
const completed = env.updates.at(-1).url
|
|
env.finish(0, { frames: 0 })
|
|
assert.equal(env.urls.has(completed), false)
|
|
assert.equal(env.urls.get(env.updates.at(-1).url).frames, 0)
|
|
env.finish(1, { frames: 1 })
|
|
assert.equal(env.urls.get(env.updates.at(-1).url).frames, 1)
|
|
})
|
|
|
|
test(`Auto-thumbnail ${implementation.name} historical: null Blob revokes the previous usable URL before throwing`, async () => {
|
|
const env = autoThumbnailEnvironment(implementation)
|
|
await env.factory({ number: 2 })(env.art)
|
|
env.art.emit('video:loadedmetadata')
|
|
env.metadata()
|
|
env.finish()
|
|
const sheet = env.art.thumbnails
|
|
env.seeked()
|
|
assert.throws(() => env.finish(1, null), /Blob required/)
|
|
assert.equal(env.urls.has(sheet.url), false)
|
|
assert.equal(env.art.thumbnails, sheet, 'Public state still references the revoked URL')
|
|
assert.equal(typeof env.videos[0].onseeked, 'function')
|
|
})
|
|
|
|
test(`Auto-thumbnail ${implementation.name} historical: draw and encode exceptions escape and retain decoder callbacks`, async () => {
|
|
for (const phase of ['draw', 'encode']) {
|
|
const env = autoThumbnailEnvironment(implementation)
|
|
const failure = new Error(`${phase} failed`)
|
|
await env.factory({ number: 2 })(env.art)
|
|
env.art.emit('video:loadedmetadata')
|
|
if (phase === 'draw') {
|
|
env.metadata()
|
|
env.controls.drawError = failure
|
|
assert.throws(() => env.seeked(), error => error === failure)
|
|
}
|
|
else {
|
|
env.controls.encodeError = failure
|
|
assert.throws(() => env.metadata(), error => error === failure)
|
|
}
|
|
assert.equal(typeof env.videos[0].onloadedmetadata, 'function')
|
|
assert.equal(env.videos[0].src, 'original.mp4')
|
|
assert.equal(env.operations.some(item => item.name === 'pause' || item.name === 'load'), false)
|
|
}
|
|
})
|
|
|
|
test(`Auto-thumbnail ${implementation.name} historical: missing context and native media errors have no failure owner`, async () => {
|
|
const env = autoThumbnailEnvironment(implementation)
|
|
await env.factory({ number: 2 })(env.art)
|
|
env.art.emit('video:loadedmetadata')
|
|
env.controls.nullContext = true
|
|
env.metadata()
|
|
assert.throws(() => env.seeked(), /drawImage/)
|
|
assert.equal(env.videos[0].onerror, null)
|
|
assert.equal(env.operations.some(item => item.name === 'pause' || item.name === 'load'), false)
|
|
})
|
|
|
|
test(`Auto-thumbnail ${implementation.name} historical: thumbnail setter failure leaks the new URL and does not cancel later work`, async () => {
|
|
const env = autoThumbnailEnvironment(implementation)
|
|
const failure = new Error('thumbnail setter failed')
|
|
await env.factory({ number: 2 })(env.art)
|
|
env.art.emit('video:loadedmetadata')
|
|
env.metadata()
|
|
env.controls.updateError = failure
|
|
assert.throws(() => env.finish(), error => error === failure)
|
|
assert.equal(env.urls.size, 1)
|
|
assert.equal(env.updates.length, 0)
|
|
env.controls.updateError = null
|
|
env.seeked()
|
|
env.finish(1)
|
|
assert.equal(env.updates.length, 1)
|
|
env.art.emit('destroy')
|
|
assert.equal(env.urls.size, 1)
|
|
})
|
|
}
|