test: add test spec for timing functions

This commit is contained in:
bubkoo
2021-04-11 19:52:43 +08:00
parent eb6adb4d7f
commit 5992b4e041
2 changed files with 39 additions and 35 deletions

View File

@ -3,7 +3,7 @@ import { Timing } from './timing'
import { MockRAF } from '../../global/mock-raf'
import { Global } from '../../global'
describe('Animator.js', () => {
describe('Timing', () => {
let raf: MockRAF
beforeEach(() => {
@ -21,71 +21,63 @@ describe('Animator.js', () => {
const spy = sinon.spy()
Timing.timeout(spy, 100)
raf.tick(99)
expect(spy).not.toHaveBeenCalled()
expect(spy.callCount).toBe(0)
raf.tick()
expect(spy).toHaveBeenCalled()
expect(spy.callCount).toBe(1)
})
})
describe('cancelTimeout()', () => {
it('should cancel a timeout which was created with timeout()', () => {
const spy = sinon.spy()
const id = Timing.timeout(spy, 100)
Timing.clearTimeout(id)
expect(spy).not.toHaveBeenCalled()
expect(spy.called).toBeFalse()
raf.tick(100)
expect(spy).not.toHaveBeenCalled()
expect(spy.called).toBeFalse()
})
})
describe('frame()', () => {
it('should call a function at the next animationFrame', () => {
const spy = sinon.spy()
Timing.frame(spy)
expect(spy).not.toHaveBeenCalled()
expect(spy.called).toBeFalse()
raf.tick()
expect(spy).toHaveBeenCalled()
expect(spy.called).toBeTrue()
})
})
describe('cancelFrame()', () => {
it('should cancel a single frame which was created with frame()', () => {
const spy = sinon.spy()
const id = Timing.frame(spy)
Timing.cancelFrame(id)
expect(spy).not.toHaveBeenCalled()
expect(spy.called).toBeFalse()
raf.tick()
expect(spy).not.toHaveBeenCalled()
expect(spy.called).toBeFalse()
})
})
describe('immediate()', () => {
it('should call a function at the next animationFrame but after all frames are processed', () => {
const spy = sinon.spy()
Timing.immediate(spy)
expect(spy).not.toHaveBeenCalled()
expect(spy.called).toBeFalse()
raf.tick()
expect(spy).toHaveBeenCalled()
expect(spy.called).toBeTrue()
})
})
describe('cancelImmediate()', () => {
it('should cancel an immediate cakk which was created with immediate()', () => {
const spy = sinon.spy()
const id = Timing.immediate(spy)
Timing.cancelImmediate(id)
expect(spy).not.toHaveBeenCalled()
expect(spy.called).toBeFalse()
raf.tick()
expect(spy).not.toHaveBeenCalled()
expect(spy.called).toBeFalse()
})
})
})

View File

@ -5,39 +5,51 @@ export class MockRAF {
protected mockRAF: typeof requestAnimationFrame
protected realCAF: typeof cancelAnimationFrame
protected mockCAF: typeof cancelAnimationFrame
protected realPerf: { now: () => number }
protected mockPerf: { now: () => number }
protected callbacks: FrameRequestCallback[] = []
protected nextTime = 0
constructor() {
this.mockRAF = (fn: FrameRequestCallback) => {
this.callbacks.push(fn)
return this.callbacks.length
return this.callbacks.length - 1
}
this.mockCAF = (requestID: number) => {
this.callbacks.splice(requestID, 1)
}
this.mockPerf = {
now: () => this.nextTime,
}
}
install(global: Global.WindowType) {
this.realRAF = global.requestAnimationFrame
this.realCAF = global.cancelAnimationFrame
global.requestAnimationFrame = this.mockRAF
global.cancelAnimationFrame = this.mockCAF
install(win: Global.WindowType) {
this.realRAF = win.requestAnimationFrame
this.realCAF = win.cancelAnimationFrame
this.realPerf = win.performance
win.requestAnimationFrame = this.mockRAF
win.cancelAnimationFrame = this.mockCAF
const w = win as any
w.performance = this.mockPerf
}
uninstall(global: Global.WindowType) {
global.requestAnimationFrame = this.realRAF
global.cancelAnimationFrame = this.realCAF
uninstall(win: Global.WindowType) {
const w = win as any
win.requestAnimationFrame = this.realRAF
win.cancelAnimationFrame = this.realCAF
w.performance = this.realPerf
this.nextTime = 0
this.callbacks = []
}
tick(dt?: number) {
this.nextTime += dt || 1
this.callbacks.forEach((fn) => {
fn(this.nextTime)
})
tick(dt = 1) {
this.nextTime += dt
const callbacks = this.callbacks
this.callbacks = []
callbacks.forEach((fn) => fn(this.nextTime))
}
}