mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-13 07:46:17 -08:00
refactor(core): CORE-19 type capture and preserve progress lifetimes
This commit is contained in:
1 parent
98a1800032
commit
ccf77c4ed2
49 files changed
+31570
-681
No files matched your search
@@ -0,0 +1,134 @@
|
||||
import assert from 'node:assert/strict'
|
||||
// eslint-disable-next-line test/no-import-node-test -- Use the repository Node test runner.
|
||||
import { test } from 'node:test'
|
||||
import { loadModules } from './helpers/load.js'
|
||||
|
||||
const { Emitter, installProgressInteractions, getPosFromEvent, beginLifecycle, getScope, beginSource, ownEntry, releaseEntry } = await loadModules({
|
||||
Emitter: 'packages/artplayer/src/utils/emitter',
|
||||
installProgressInteractions: { file: 'packages/artplayer/src/control/progress/interactions', name: 'installProgressInteractions' },
|
||||
getPosFromEvent: { file: 'packages/artplayer/src/control/progress/position', name: 'getPosFromEvent' },
|
||||
beginLifecycle: { file: 'packages/artplayer/src/lifecycle/instance', name: 'beginLifecycle' },
|
||||
getScope: { file: 'packages/artplayer/src/lifecycle/instance', name: 'getScope' },
|
||||
beginSource: { file: 'packages/artplayer/src/source/operation', name: 'beginSource' },
|
||||
ownEntry: { file: 'packages/artplayer/src/component/resources', name: 'ownEntry' },
|
||||
releaseEntry: { file: 'packages/artplayer/src/component/resources', name: 'releaseEntry' },
|
||||
})
|
||||
|
||||
function mouse(name, clientX = 60, button = 0) {
|
||||
return Object.assign(new Event(name), { clientX, button })
|
||||
}
|
||||
|
||||
function fixture() {
|
||||
const progress = Object.assign(new EventTarget(), { clientWidth: 100, getBoundingClientRect: () => ({ left: 10 }) })
|
||||
const indicator = new EventTarget()
|
||||
const control = Object.assign(new EventTarget(), { querySelector: () => indicator })
|
||||
const effects = []
|
||||
const art = Object.assign(new Emitter(), {
|
||||
template: { $progress: progress },
|
||||
duration: 200,
|
||||
isRotate: false,
|
||||
events: {
|
||||
proxy(target, name, callback) {
|
||||
target.addEventListener(name, callback)
|
||||
return () => target.removeEventListener(name, callback)
|
||||
},
|
||||
remove: cleanup => cleanup(),
|
||||
},
|
||||
})
|
||||
Object.defineProperty(art, 'seek', { get: () => 0, set: value => effects.push(['seek', value]) })
|
||||
art.on('setBar', (kind, percentage) => effects.push(['setBar', kind, percentage]))
|
||||
beginLifecycle(art)
|
||||
ownEntry(art, control)
|
||||
installProgressInteractions(art, control)
|
||||
return { art, progress, control, indicator, effects }
|
||||
}
|
||||
|
||||
test('progress position clamps outside edges and retains its time and percentage calculations', () => {
|
||||
const f = fixture()
|
||||
assert.deepEqual(getPosFromEvent(f.art, mouse('click', 60)), { second: 100, time: '01:40', width: 50, percentage: 0.5 })
|
||||
assert.equal(getPosFromEvent(f.art, mouse('click', -100)).percentage, 0)
|
||||
assert.equal(getPosFromEvent(f.art, mouse('click', 1000)).percentage, 1)
|
||||
f.progress.clientWidth = 0
|
||||
assert(Number.isNaN(getPosFromEvent(f.art, mouse('click', 10)).percentage))
|
||||
})
|
||||
|
||||
test('live progress clicks and drags preserve setBar before seek and mouseup stops dragging', () => {
|
||||
const f = fixture()
|
||||
f.progress.dispatchEvent(mouse('click'))
|
||||
assert.deepEqual(f.effects, [['setBar', 'played', 0.5], ['seek', 100]])
|
||||
f.effects.length = 0
|
||||
f.progress.dispatchEvent(mouse('mousedown'))
|
||||
f.art.emit('document:mousemove', mouse('mousemove', 85))
|
||||
f.art.emit('document:mouseup', mouse('mouseup'))
|
||||
f.art.emit('document:mousemove', mouse('mousemove', 100))
|
||||
assert.deepEqual(f.effects, [['setBar', 'played', 0.75], ['seek', 150]])
|
||||
})
|
||||
|
||||
for (const mode of ['control removal', 'destruction', 'source replacement']) {
|
||||
test(`progress click does not seek after ${mode} inside setBar`, () => {
|
||||
const f = fixture()
|
||||
f.art.on('setBar', () => {
|
||||
if (mode === 'control removal')
|
||||
releaseEntry(f.control)
|
||||
else if (mode === 'destruction')
|
||||
getScope(f.art).dispose()
|
||||
else
|
||||
beginSource(f.art)
|
||||
})
|
||||
f.progress.dispatchEvent(mouse('click'))
|
||||
assert.deepEqual(f.effects, [['setBar', 'played', 0.5]])
|
||||
})
|
||||
}
|
||||
|
||||
test('progress drag loses its source when media is replaced and a new mousedown can start again', () => {
|
||||
const f = fixture()
|
||||
f.progress.dispatchEvent(mouse('mousedown'))
|
||||
beginSource(f.art)
|
||||
f.art.emit('document:mousemove', mouse('mousemove', 85))
|
||||
assert.deepEqual(f.effects, [])
|
||||
f.progress.dispatchEvent(mouse('mousedown'))
|
||||
f.art.emit('document:mousemove', mouse('mousemove', 60))
|
||||
assert.deepEqual(f.effects, [['setBar', 'played', 0.5], ['seek', 100]])
|
||||
})
|
||||
|
||||
test('progress drag does not seek when its control is removed inside setBar', () => {
|
||||
const f = fixture()
|
||||
f.art.on('setBar', () => releaseEntry(f.control))
|
||||
f.progress.dispatchEvent(mouse('mousedown'))
|
||||
f.art.emit('document:mousemove', mouse('mousemove', 60))
|
||||
assert.deepEqual(f.effects, [['setBar', 'played', 0.5]])
|
||||
})
|
||||
|
||||
test('progress geometry reentry cannot emit or seek after disposal', () => {
|
||||
const f = fixture()
|
||||
f.progress.getBoundingClientRect = () => {
|
||||
getScope(f.art).dispose()
|
||||
return { left: 10 }
|
||||
}
|
||||
f.progress.dispatchEvent(mouse('click'))
|
||||
assert.deepEqual(f.effects, [])
|
||||
})
|
||||
|
||||
test('a newer nested progress click supersedes the earlier seek', () => {
|
||||
const f = fixture()
|
||||
let nested = false
|
||||
f.art.on('setBar', () => {
|
||||
if (!nested) {
|
||||
nested = true
|
||||
f.progress.dispatchEvent(mouse('click', 85))
|
||||
}
|
||||
})
|
||||
f.progress.dispatchEvent(mouse('click', 60))
|
||||
assert.deepEqual(f.effects, [['setBar', 'played', 0.5], ['setBar', 'played', 0.75], ['seek', 150]])
|
||||
})
|
||||
|
||||
test('right-button mousedown and mouseup inside setBar do not continue dragging', () => {
|
||||
const f = fixture()
|
||||
f.progress.dispatchEvent(mouse('mousedown', 60, 2))
|
||||
f.art.emit('document:mousemove', mouse('mousemove', 85))
|
||||
assert.deepEqual(f.effects, [])
|
||||
f.art.on('setBar', () => f.art.emit('document:mouseup', mouse('mouseup')))
|
||||
f.progress.dispatchEvent(mouse('mousedown'))
|
||||
f.art.emit('document:mousemove', mouse('mousemove', 60))
|
||||
assert.deepEqual(f.effects, [['setBar', 'played', 0.5]])
|
||||
})
|
||||
Reference in new issue
Block a user