mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
chore: add @idraw/core jest testing
This commit is contained in:
parent
4c4913c5ae
commit
5dd5bc0797
9 changed files with 391 additions and 7 deletions
|
|
@ -70,7 +70,7 @@ class Context implements TypeContext {
|
|||
}
|
||||
|
||||
fill(fillRule?: CanvasFillRule | undefined) {
|
||||
return this._ctx.fill(fillRule);
|
||||
return this._ctx.fill(fillRule || 'nonzero');
|
||||
}
|
||||
|
||||
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean | undefined): void {
|
||||
|
|
|
|||
95
packages/core/__tests__/__snapshots__/index.test.ts.snap
Normal file
95
packages/core/__tests__/__snapshots__/index.test.ts.snap
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`@idraw/core @idraw/core: context 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"props": Object {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": Array [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
Object {
|
||||
"props": Object {
|
||||
"dHeight": 1600,
|
||||
"dWidth": 2400,
|
||||
"dx": 0,
|
||||
"dy": 0,
|
||||
"img": <canvas
|
||||
height="1600"
|
||||
width="2400"
|
||||
/>,
|
||||
"sHeight": 1600,
|
||||
"sWidth": 2400,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": Array [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@idraw/core @idraw/core: context 2`] = `
|
||||
Array [
|
||||
Object {
|
||||
"props": Object {
|
||||
"height": 1600,
|
||||
"width": 2400,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
},
|
||||
"transform": Array [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "clearRect",
|
||||
},
|
||||
Object {
|
||||
"props": Object {
|
||||
"dHeight": 1600,
|
||||
"dWidth": 2400,
|
||||
"dx": 0,
|
||||
"dy": 0,
|
||||
"img": <canvas
|
||||
height="1600"
|
||||
width="2400"
|
||||
/>,
|
||||
"sHeight": 1600,
|
||||
"sWidth": 2400,
|
||||
"sx": 0,
|
||||
"sy": 0,
|
||||
},
|
||||
"transform": Array [
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
],
|
||||
"type": "drawImage",
|
||||
},
|
||||
]
|
||||
`;
|
||||
62
packages/core/__tests__/data.ts
Normal file
62
packages/core/__tests__/data.ts
Normal file
File diff suppressed because one or more lines are too long
46
packages/core/__tests__/index.test.ts
Normal file
46
packages/core/__tests__/index.test.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { requestAnimationFrameMock } from './polyfill/requestanimateframe';
|
||||
import './polyfill/image';
|
||||
|
||||
import Core from './../src';
|
||||
import { getData } from './data';
|
||||
|
||||
describe("@idraw/core", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
requestAnimationFrameMock.reset();
|
||||
})
|
||||
|
||||
test('@idraw/core: context', async () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="mount"></div>
|
||||
`;
|
||||
const opts = {
|
||||
width: 600,
|
||||
height: 400,
|
||||
contextWidth: 600,
|
||||
contextHeight: 400,
|
||||
devicePixelRatio: 4
|
||||
}
|
||||
const mount = document.querySelector('#mount') as HTMLDivElement;
|
||||
const core = new Core(mount, opts);
|
||||
const data = getData();
|
||||
core.initData(data);
|
||||
core.draw();
|
||||
|
||||
requestAnimationFrameMock.triggerNextAnimationFrame();
|
||||
|
||||
const originCtx = core.__getOriginContext();
|
||||
// @ts-ignore;
|
||||
const originCalls = originCtx.__getDrawCalls();
|
||||
expect(originCalls).toMatchSnapshot();
|
||||
|
||||
const displayCtx = core.__getDisplayContext();
|
||||
// @ts-ignore;
|
||||
const displayCalls = displayCtx.__getDrawCalls();
|
||||
expect(displayCalls).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
9
packages/core/__tests__/polyfill/image.ts
Normal file
9
packages/core/__tests__/polyfill/image.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// @ts-ignore
|
||||
window.Image = class {
|
||||
constructor() {
|
||||
setTimeout(() => {
|
||||
// @ts-ignore
|
||||
this.onload();
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
124
packages/core/__tests__/polyfill/mock-test.ts
Normal file
124
packages/core/__tests__/polyfill/mock-test.ts
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
// https://stackoverflow.com/questions/61593774/how-do-i-test-code-that-uses-requestanimationframe-in-jest
|
||||
|
||||
import { requestAnimationFrameMock } from "./requestanimateframe";
|
||||
|
||||
describe("mock_requestAnimationFrame", () => {
|
||||
beforeEach(() => {
|
||||
requestAnimationFrameMock.reset();
|
||||
})
|
||||
test("reqest -> trigger", () => {
|
||||
const order: any = [];
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
requestAnimationFrame(t => order.push(1));
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(1);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
requestAnimationFrameMock.triggerNextAnimationFrame();
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([1]);
|
||||
});
|
||||
|
||||
test("reqest -> request -> trigger -> trigger", () => {
|
||||
const order: any = [];
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
requestAnimationFrame(t => order.push(1));
|
||||
requestAnimationFrame(t => order.push(2));
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(2);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
requestAnimationFrameMock.triggerNextAnimationFrame();
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(1);
|
||||
expect(order).toEqual([1]);
|
||||
|
||||
requestAnimationFrameMock.triggerNextAnimationFrame();
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
test("reqest -> cancel", () => {
|
||||
const order: any = [];
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
const handle = requestAnimationFrame(t => order.push(1));
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(1);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
cancelAnimationFrame(handle);
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([]);
|
||||
});
|
||||
|
||||
test("reqest -> request -> cancel(1) -> trigger", () => {
|
||||
const order: any = [];
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
const handle = requestAnimationFrame(t => order.push(1));
|
||||
requestAnimationFrame(t => order.push(2));
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(2);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
cancelAnimationFrame(handle);
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(1);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
requestAnimationFrameMock.triggerNextAnimationFrame();
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([2]);
|
||||
});
|
||||
|
||||
test("reqest -> request -> cancel(2) -> trigger", () => {
|
||||
const order: any = [];
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
requestAnimationFrame(t => order.push(1));
|
||||
const handle = requestAnimationFrame(t => order.push(2));
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(2);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
cancelAnimationFrame(handle);
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(1);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
requestAnimationFrameMock.triggerNextAnimationFrame();
|
||||
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([1]);
|
||||
});
|
||||
|
||||
test("triggerAllAnimationFrames", () => {
|
||||
const order: any = [];
|
||||
expect(requestAnimationFrameMock.queue.size).toBe(0);
|
||||
expect(order).toEqual([]);
|
||||
|
||||
requestAnimationFrame(t => order.push(1));
|
||||
requestAnimationFrame(t => order.push(2));
|
||||
|
||||
requestAnimationFrameMock.triggerAllAnimationFrames();
|
||||
|
||||
expect(order).toEqual([1,2]);
|
||||
|
||||
});
|
||||
|
||||
test("does not fail if triggerNextAnimationFrame() is called with an empty queue.", () => {
|
||||
requestAnimationFrameMock.triggerNextAnimationFrame();
|
||||
})
|
||||
});
|
||||
37
packages/core/__tests__/polyfill/requestanimateframe.ts
Normal file
37
packages/core/__tests__/polyfill/requestanimateframe.ts
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// https://stackoverflow.com/questions/61593774/how-do-i-test-code-that-uses-requestanimationframe-in-jest
|
||||
// mock_requestAnimationFrame.js
|
||||
|
||||
class RequestAnimationFrameMockSession {
|
||||
handleCounter = 0;
|
||||
queue = new Map();
|
||||
requestAnimationFrame(callback: Function) {
|
||||
const handle = this.handleCounter++;
|
||||
this.queue.set(handle, callback);
|
||||
return handle;
|
||||
}
|
||||
cancelAnimationFrame(handle: Function) {
|
||||
this.queue.delete(handle);
|
||||
}
|
||||
triggerNextAnimationFrame(time=performance.now()) {
|
||||
const nextEntry = this.queue.entries().next().value;
|
||||
if(nextEntry === undefined) return;
|
||||
|
||||
const [nextHandle, nextCallback] = nextEntry;
|
||||
|
||||
nextCallback(time);
|
||||
this.queue.delete(nextHandle);
|
||||
}
|
||||
triggerAllAnimationFrames(time=performance.now()) {
|
||||
while(this.queue.size > 0) this.triggerNextAnimationFrame(time);
|
||||
}
|
||||
reset() {
|
||||
this.queue.clear();
|
||||
this.handleCounter = 0;
|
||||
}
|
||||
};
|
||||
|
||||
export const requestAnimationFrameMock = new RequestAnimationFrameMockSession();
|
||||
|
||||
window.requestAnimationFrame = requestAnimationFrameMock.requestAnimationFrame.bind(requestAnimationFrameMock);
|
||||
// @ts-ignore
|
||||
window.cancelAnimationFrame = requestAnimationFrameMock.cancelAnimationFrame.bind(requestAnimationFrameMock);
|
||||
|
|
@ -193,6 +193,14 @@ class Core {
|
|||
this[_coreEvent].off(key, callback);
|
||||
}
|
||||
|
||||
__getDisplayContext(): CanvasRenderingContext2D {
|
||||
return this[_board].getDisplayContext()
|
||||
}
|
||||
|
||||
__getOriginContext(): CanvasRenderingContext2D {
|
||||
return this[_board].getOriginContext()
|
||||
}
|
||||
|
||||
private _initEvent(): void {
|
||||
if (this[_hasInited] === true) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ export class Renderer {
|
|||
});
|
||||
// TODO
|
||||
this._loader.on('load', (res) => {
|
||||
// console.log('load: ', res);
|
||||
console.log('load: ', res);
|
||||
});
|
||||
this._loader.on('error', (res) => {
|
||||
// console.log('error: ', res);
|
||||
console.log('error: ', res);
|
||||
});
|
||||
this._loader.on('complete', (res) => {
|
||||
// console.log('complete: ', res);
|
||||
console.log('complete: ', res);
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +50,9 @@ export class Renderer {
|
|||
|
||||
private _drawFrame() {
|
||||
requestAnimationFrame(() => {
|
||||
const ctx = this._board.getContext();
|
||||
// console.log('------ render frame ------', this._loader.isComplete())
|
||||
|
||||
let item: QueueItem | undefined = this._queue[0];
|
||||
let isLastFrame = false;
|
||||
if (this._queue.length > 1) {
|
||||
|
|
@ -60,11 +62,12 @@ export class Renderer {
|
|||
}
|
||||
if (this._loader.isComplete() !== true) {
|
||||
this._drawFrame();
|
||||
if (item) {
|
||||
drawContext(ctx, item.data, item.helper, this._loader);
|
||||
this._board.draw();
|
||||
}
|
||||
} else if (item) {
|
||||
const ctx = this._board.getContext();
|
||||
|
||||
drawContext(ctx, item.data, item.helper, this._loader);
|
||||
|
||||
this._board.draw();
|
||||
this._retainQueueOneItem();
|
||||
if (!isLastFrame) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue