diff --git a/test/ut/.eslintrc.yaml b/test/ut/.eslintrc.yaml new file mode 100644 index 000000000..b2e406721 --- /dev/null +++ b/test/ut/.eslintrc.yaml @@ -0,0 +1,196 @@ +parser: "@typescript-eslint/parser" +parserOptions: + ecmaVersion: 6 + sourceType: module + ecmaFeatures: + modules: true + project: "./test/ut/tsconfig.json" +plugins: ["@typescript-eslint"] +env: + browser: true + node: true + es6: false + jest: true +globals: + jQuery: true + Promise: true +rules: + no-console: + - 2 + - + allow: + - "warn" + - "error" + no-constant-condition: 0 + comma-dangle: 2 + no-debugger: 2 + no-dupe-keys: 2 + no-empty-character-class: 2 + no-ex-assign: 2 + no-extra-boolean-cast: 0 + no-func-assign: 2 + no-inner-declarations: 2 + no-invalid-regexp: 2 + no-negated-in-lhs: 2 + no-obj-calls: 2 + no-sparse-arrays: 2 + no-unreachable: 2 + use-isnan: 2 + valid-typeof: 2 + block-scoped-var: 0 + curly: + - 2 + - "all" + eqeqeq: + - 2 + - "allow-null" + guard-for-in: 2 + no-else-return: 0 + no-labels: + - 2 + - + allowLoop: true + no-eval: 2 + no-extend-native: 2 + no-extra-bind: 0 + no-implied-eval: 2 + no-iterator: 2 + no-irregular-whitespace: 2 + no-lone-blocks: 2 + no-loop-func: 2 + no-multi-str: 2 + no-native-reassign: 2 + no-new-wrappers: 2 + no-octal: 2 + no-octal-escape: 2 + no-proto: 2 + no-redeclare: 0 + no-self-compare: 2 + no-unneeded-ternary: 2 + no-with: 2 + radix: 2 + wrap-iife: + - 2 + - "any" + no-delete-var: 2 + no-dupe-args: 2 + no-duplicate-case: 2 + no-label-var: 2 + no-shadow-restricted-names: 2 + no-undef: 2 + no-undef-init: 2 + no-use-before-define: 0 + brace-style: + - 2 + - "stroustrup" + - {} + comma-spacing: + - 2 + - + before: false + after: true + comma-style: + - 2 + - "last" + new-parens: 2 + no-array-constructor: 2 + no-multi-spaces: + - 1 + - + ignoreEOLComments: true + exceptions: + Property: true + no-new-object: 2 + no-spaced-func: 2 + no-trailing-spaces: 2 + no-extra-parens: + - 2 + - "functions" + no-mixed-spaces-and-tabs: 2 + one-var: + - 2 + - "never" + operator-linebreak: + - 2 + - "before" + - + overrides: + "=": "after" + quotes: + - 2 + - "single" + semi: + - 2 + - "always" + semi-spacing: 2 + keyword-spacing: 2 + key-spacing: + - 2 + - + beforeColon: false + afterColon: true + space-before-function-paren: + - 2 + - + anonymous: "always" + named: "never" + space-before-blocks: + - 2 + - "always" + computed-property-spacing: + - 2 + - "never" + space-in-parens: + - 2 + - "never" + space-unary-ops: 2 + spaced-comment: 0 + + max-nested-callbacks: + - 1 + - 5 + max-depth: + - 1 + - 6 + max-len: + - 2 + - 120 + - 4 + - + ignoreUrls: true + ignoreComments: true + max-params: + - 1 + - 15 + + space-infix-ops: 2 + dot-notation: + - 2 + - + allowKeywords: true + allowPattern: "^catch$" + + arrow-spacing: 2 + constructor-super: 2 + no-confusing-arrow: + - 2 + - + allowParens: true + no-class-assign: 2 + no-const-assign: 2 + # no-dupe-class-members: 2 + no-this-before-super: 0 + no-var: 0 + no-duplicate-imports: 2 + prefer-rest-params: 0 + unicode-bom: 2 + max-statements-per-line: 2 + + no-useless-constructor: 0 + + + "@typescript-eslint/no-unused-vars": + - 1 + - + vars: "local" + args: "none" \ No newline at end of file diff --git a/test/ut/spec/animation/Animator.test.ts b/test/ut/spec/animation/Animator.test.ts new file mode 100644 index 000000000..7af2cca49 --- /dev/null +++ b/test/ut/spec/animation/Animator.test.ts @@ -0,0 +1,44 @@ +import Animator from '../../../../src/animation/Animator'; +import Clip from '../../../../src/animation/Clip'; + +describe('Animator', function () { + it('valueType number Animator', async () => { + const obj = { + x: 100, + y: 100 + }; + const duringFn = jest.fn(); + const clips: Clip[] = []; + const addClip = jest.fn((t) => clips.push(t)); + const attClip = new Animator(obj, + false).during(duringFn); + attClip.animation = { + addClip + } as any; + attClip.when(1000, { + x: 200, + y: 300 + }).when(2000, { + x: 300, + y: 500 + }).start(); + expect(addClip).toBeCalledTimes(1); + clips[0].onframe(0.25); + expect(obj).toStrictEqual({ + x: 150, + y: 200 + }); + clips[0].onframe(0.5); + expect(obj).toStrictEqual({ + x: 200, + y: 300 + }); + clips[0].onframe(0.75); + expect(obj).toStrictEqual({ + x: 250, + y: 400 + }); + expect(duringFn).toBeCalledTimes(3); + }); + +}); diff --git a/test/ut/spec/animation/ElementAnimation.test.ts b/test/ut/spec/animation/ElementAnimation.test.ts index 26b528124..1bef83fdc 100644 --- a/test/ut/spec/animation/ElementAnimation.test.ts +++ b/test/ut/spec/animation/ElementAnimation.test.ts @@ -1,4 +1,4 @@ -import {Polyline, Rect, init} from '../zrender'; +import {Polyline, Rect} from '../zrender'; import Animation from '../../../../src/animation/Animation'; describe('ElementAnimation', function () { diff --git a/test/ut/spec/animation/Track.test.ts b/test/ut/spec/animation/Track.test.ts new file mode 100644 index 000000000..fa26cd296 --- /dev/null +++ b/test/ut/spec/animation/Track.test.ts @@ -0,0 +1,130 @@ +import { Track } from '../../../../src/animation/Animator'; + +describe('Track', function () { + it('valueType number', async () => { + const obj = { + x: 100 + }; + const track = new Track('x'); + track.addKeyframe(0, 100); + track.addKeyframe(1000, 150); + track.addKeyframe(2000, 300); + track.prepare(2000); + track.step(obj, 0.25); + expect(obj.x).toBe(125); + }); + + it('valueType 1d array', async () => { + const obj = { + x: [100, 100] + }; + const track = new Track('x'); + track.addKeyframe(0, [100, 100]); + track.addKeyframe(1000, [150, 200]); + track.addKeyframe(2000, [300, 400]); + track.prepare(2000); + track.step(obj, 0.25); + expect(obj.x).toStrictEqual([125, 150]); + track.step(obj, 0.75); + expect(obj.x).toStrictEqual([225, 300]); + }); + + it('valueType 2d array', async () => { + const obj = { + x: [[100, 50], [100, 30]] + }; + const track = new Track('x'); + track.addKeyframe(0, [[100, 50], [100, 30]]); + track.addKeyframe(1000, [[150, 100], [200, 60]]); + track.addKeyframe(2000, [[300, 150], [400, 120]]); + track.prepare(2000); + track.step(obj, 0.25); + expect(obj.x).toStrictEqual([[125, 75], [150, 45]]); + track.step(obj, 0.75); + expect(obj.x).toStrictEqual([[225, 125], [300, 90]]); + }); + + it('valueType color', async () => { + const obj = { + x: 'rgba(0,0,0,0)' + }; + const track = new Track('x'); + track.addKeyframe(0, 'rgba(0,0,0,0)'); + track.addKeyframe(1000, 'rgba(200,200,200,1)'); + track.addKeyframe(2000, 'rgba(100,100,100,0)'); + track.prepare(2000); + track.step(obj, 0.25); + expect(obj.x).toStrictEqual('rgba(100,100,100,0.5)'); + track.step(obj, 0.75); + expect(obj.x).toStrictEqual('rgba(150,150,150,0.5)'); + }); + + it('valueType linear', async () => { + const obj = { + x: { + type: 'linear', + x: 0, + y: 0, + x2: 1, + y2: 0, + colorStops: [{ + offset: 0, + color: '#00f' + }, { + offset: 1, + color: '#f0f' + }] + } + }; + const track = new Track('x'); + track.addKeyframe(0, { + type: 'linear', + x: 0, + y: 0, + x2: 1, + y2: 1, + colorStops: [{ + offset: 0, + color: '#00f' + }, { + offset: 1, + color: '#f0f' + }] + }); + track.addKeyframe(1000, { + type: 'linear', + x: 1, + y: 1, + x2: 0, + y2: 0, + colorStops: [{ + offset: 0, + color: '#00f' + }, { + offset: 1, + color: '#f0f' + }] + }); + track.prepare(1000); + track.step(obj, 0.25); + expect(obj.x).toStrictEqual({ + 'colorStops': [{'color': 'rgba(0,0,255,1)', 'offset': 0}, {'color': 'rgba(255,0,255,1)', 'offset': 1}], + 'global': undefined, + 'type': 'linear', + 'x': 0.25, + 'x2': 0.75, + 'y': 0.25, + 'y2': 0.75 + }); + track.step(obj, 0.75); + expect(obj.x).toStrictEqual({ + 'colorStops': [{'color': 'rgba(0,0,255,1)', 'offset': 0}, {'color': 'rgba(255,0,255,1)', 'offset': 1}], + 'global': undefined, + 'type': 'linear', + 'x': 0.75, + 'x2': 0.25, + 'y': 0.75, + 'y2': 0.25 + }); + }); +}); diff --git a/test/ut/spec/animation/clip.test.ts b/test/ut/spec/animation/clip.test.ts new file mode 100644 index 000000000..957466087 --- /dev/null +++ b/test/ut/spec/animation/clip.test.ts @@ -0,0 +1,102 @@ +import Clip from '../../../../src/animation/Clip'; +import easingFuncs from '../../../../src/animation/easing'; + +describe('clip', function () { + const life = 2000; + const interval = 200; + const delay = 300; + /** '2022/12/22 00:42:45' */ + const now = 1671640965219; + it('normal clip call onframe correct', () => { + const onframe = jest.fn(); + const attClip = new Clip({ + life, + onframe + }); + attClip.step(now, 100); + attClip.step(now + interval, 100); + attClip.step(now + interval + life, 100); + expect(onframe).toHaveBeenNthCalledWith(1, 0); + expect(onframe).toHaveBeenNthCalledWith(2, interval / life); + expect(onframe).toHaveBeenNthCalledWith(3, 1); + }); + + it('delay clip call onframe correct', () => { + const onframe = jest.fn(); + + const attClip = new Clip({ + life, + onframe, + delay + }); + attClip.step(now, 100); + attClip.step(now + interval, 100); + attClip.step(now + interval + delay, 100); + expect(onframe).toHaveBeenNthCalledWith(1, 0); + expect(onframe).toHaveBeenNthCalledWith(2, 0); + expect(onframe).toHaveBeenNthCalledWith(3, interval / life); + }); + + it('loop clip call onframe correct', () => { + const onframe = jest.fn(); + const onrestart = jest.fn(); + + const attClip = new Clip({ + life, + onframe, + loop: true, + onrestart + }); + attClip.step(now, 100); + attClip.step(now + interval, 100); + attClip.step(now + interval + life, 100); + attClip.step(now + interval + life + 100, 100); + expect(onframe).toHaveBeenNthCalledWith(1, 0); + expect(onframe).toHaveBeenNthCalledWith(2, interval / life); + expect(onframe).toHaveBeenNthCalledWith(3, 1); + expect(onframe).toHaveBeenNthCalledWith(4, (interval + 100) / life); + expect(onrestart).toBeCalledTimes(1); + }); + + it('clip pause correct', () => { + const onframe = jest.fn(); + const onrestart = jest.fn(); + + const attClip = new Clip({ + life, + onframe, + loop: true, + onrestart + }); + attClip.pause(); + attClip.step(now, interval); + attClip.step(now + interval, interval); + attClip.resume(); + // pause two interval + attClip.step(now + interval + interval + interval, interval); + expect(onframe).toBeCalledTimes(1); + expect(onframe).toHaveBeenNthCalledWith(1, interval / life); + }); + + const buildInEasing = Object.keys(easingFuncs) as Array; + + test.each(buildInEasing)('setEasing buildIn %s correct', (easingName) => { + const onframe = jest.fn(); + const onrestart = jest.fn(); + + const attClip = new Clip({ + life, + onframe, + onrestart + }); + attClip.setEasing(easingName); + /** init */ + attClip.step(now, interval); + attClip.step(now + interval, interval); + attClip.step(now + 2 * interval, interval); + expect(onframe).toBeCalledTimes(3); + expect(onframe).toHaveBeenNthCalledWith(1, easingFuncs[easingName](0)); + expect(onframe).toHaveBeenNthCalledWith(2, easingFuncs[easingName](interval / life)); + expect(onframe).toHaveBeenNthCalledWith(3, easingFuncs[easingName](2 * interval / life)); + }); +}); diff --git a/test/ut/spec/core/arrayDiff.test.ts b/test/ut/spec/core/arrayDiff.test.ts index a984a38ad..80a52d4e6 100644 --- a/test/ut/spec/core/arrayDiff.test.ts +++ b/test/ut/spec/core/arrayDiff.test.ts @@ -3,8 +3,22 @@ import arrayDiff from '../../../../src/core/arrayDiff'; describe('arrayDiff', function () { it('Basic', function () { - const newArr = [{"name":"类目12"},{"name":"类目13"},{"name":"类目14"},{"name":"类目15"},{"name":"类目16"},{"name":"类目17"}]; - const oldArr = [{"name":"类目11"},{"name":"类目12"},{"name":"类目13"},{"name":"类目14"},{"name":"类目15"},{"name":"类目16"}]; + const newArr = [ + {'name': '类目12'}, + {'name': '类目13'}, + {'name': '类目14'}, + {'name': '类目15'}, + {'name': '类目16'}, + {'name': '类目17'} + ]; + const oldArr = [ + {'name': '类目11'}, + {'name': '类目12'}, + {'name': '类目13'}, + {'name': '类目14'}, + {'name': '类目15'}, + {'name': '类目16'} + ]; const result = arrayDiff(newArr, oldArr, function (a, b) { return a.name === b.name; @@ -25,7 +39,7 @@ describe('arrayDiff', function () { const result = arrayDiff([1, 2, 3, 4], [1, 2, 3, 4]); expect(result[0].added).toBe(false); expect(result[0].removed).toBe(false); - expect(result[0].indices).toEqual([0, 1, 2, 3]) + expect(result[0].indices).toEqual([0, 1, 2, 3]); }); it('All different array', function () { diff --git a/test/ut/spec/core/matrix.test.ts b/test/ut/spec/core/matrix.test.ts new file mode 100644 index 000000000..78104bfa5 --- /dev/null +++ b/test/ut/spec/core/matrix.test.ts @@ -0,0 +1,19 @@ +import * as matrix from '../../../../src/core/matrix'; + +describe('zrUtil', function () { + const identity = [1, 0, 0, 1, 0, 0]; + it('create', function () { + expect(matrix.create()).toStrictEqual(identity); + }); + it('identity', function () { + const origin = [1, 2, 3, 1, 2, 3]; + matrix.identity(origin); + expect(origin).toStrictEqual(identity); + }); + it('copy', function () { + const origin = [1, 2, 3, 4, 5, 6]; + const target = [0]; + matrix.copy(target, origin); + expect(target).toStrictEqual(origin); + }); +}); diff --git a/test/ut/spec/core/platform.test.ts b/test/ut/spec/core/platform.test.ts index f96ca5b44..7b4a5ee7e 100644 --- a/test/ut/spec/core/platform.test.ts +++ b/test/ut/spec/core/platform.test.ts @@ -1,6 +1,6 @@ import * as platform from '../../../../src/core/platform'; -describe('platform', function() { +describe('platform', function () { it('Default font should be correct', function () { expect(platform.DEFAULT_FONT_SIZE).toBe(12); diff --git a/test/ut/spec/core/util.test.ts b/test/ut/spec/core/util.test.ts index 618471853..02925d2ec 100755 --- a/test/ut/spec/core/util.test.ts +++ b/test/ut/spec/core/util.test.ts @@ -1,6 +1,6 @@ import * as zrUtil from '../../../../src/core/util'; -describe('zrUtil', function() { +describe('zrUtil', function () { describe('merge', function () { @@ -147,4 +147,54 @@ describe('zrUtil', function() { }); }); -}); \ No newline at end of file + + describe('each', function () { + + it('array base', function () { + const basicArray = ['z', 'r', 'e', 'n', 'd', 'e', 'r']; + const target: string[] = []; + const thisObject = { + count: 0 + }; + const cb = jest.fn(function (char, index) { + this.count++; + target[index] = char + 'E'; + }); + zrUtil.each(basicArray, cb, thisObject); + expect(cb).toBeCalledTimes(basicArray.length); + new Array(basicArray.length).fill('Z').forEach((_, index) => { + expect(cb).toHaveBeenNthCalledWith(index + 1, basicArray[index], index, basicArray); + }); + expect(target).toEqual(['zE', 'rE', 'eE', 'nE', 'dE', 'eE', 'rE']); + expect(thisObject.count).toBe(7); + }); + + it('object base', function () { + const basicObject = { + name: 'zRender', + version: '5.4.1' + }; + const ObjectKeys = Object.keys(basicObject); + const ObjectKeysLength = ObjectKeys.length; + const ObjectValues = Object.values(basicObject); + const target: Partial = {}; + const thisObject = { + count: 0 + }; + const cb = jest.fn(function (value: string, key: keyof typeof basicObject) { + this.count++; + target[key] = value + 'E'; + }); + zrUtil.each(basicObject, cb, thisObject); + expect(cb).toBeCalledTimes(ObjectKeysLength); + new Array(ObjectKeysLength).fill('Z').forEach((_, index) => { + expect(cb).toHaveBeenNthCalledWith(index + 1, ObjectValues[index], ObjectKeys[index], basicObject); + }); + expect(target).toEqual({ + name: 'zRenderE', + version: '5.4.1E' + }); + expect(thisObject.count).toBe(2); + }); + }); +}); diff --git a/test/ut/spec/graphic/Group.test.ts b/test/ut/spec/graphic/Group.test.ts index c72d2e977..0f79306c7 100644 --- a/test/ut/spec/graphic/Group.test.ts +++ b/test/ut/spec/graphic/Group.test.ts @@ -1,4 +1,4 @@ -import {Group, Path, Image as ZImage, Element} from '../zrender'; +import {Group, Element} from '../zrender'; describe('Group', function () { diff --git a/test/ut/spec/graphic/Path.test.ts b/test/ut/spec/graphic/Path.test.ts index 5dfda2e77..18e622786 100644 --- a/test/ut/spec/graphic/Path.test.ts +++ b/test/ut/spec/graphic/Path.test.ts @@ -194,7 +194,7 @@ describe('Path', function () { // TODO textContent }); - it('Path#useStates. Mutiple states should be merged properly', function () { + it('Path#useStates. Multiple states should be merged properly', function () { const rect = createRectForStateTest(); rect.states = { diff --git a/test/ut/spec/graphic/Text.test.ts b/test/ut/spec/graphic/Text.test.ts index a2fb78f97..7cd18730a 100644 --- a/test/ut/spec/graphic/Text.test.ts +++ b/test/ut/spec/graphic/Text.test.ts @@ -19,7 +19,7 @@ describe('Text', function () { stroke: 'blue' } } - } + }; text.useState('emphasis'); diff --git a/test/ut/tsconfig.json b/test/ut/tsconfig.json index 88d25b431..7f96991d5 100644 --- a/test/ut/tsconfig.json +++ b/test/ut/tsconfig.json @@ -4,7 +4,7 @@ "noImplicitAny": true, "strictBindCallApply": true, - "noImplicitThis": true, + "noImplicitThis": false, // https://github.com/ezolenko/rollup-plugin-typescript2/issues/12#issuecomment-536173372 "moduleResolution": "Node", @@ -12,7 +12,7 @@ "pretty": true }, "include": [ - "**/*.ts" + "spec/**/*.ts", ], "exclude": [ ]