mirror of
https://gitee.com/antv/g6.git
synced 2024-12-01 11:18:30 +08:00
feat: 增加plugins,util,graph的单测
This commit is contained in:
parent
631684b7db
commit
523d353ed8
@ -77,9 +77,9 @@
|
||||
"@antv/path-util": "^2.0.3",
|
||||
"@antv/scale": "^0.2.0",
|
||||
"@antv/util": "~2.0.5",
|
||||
"lodash": "^4.17.15",
|
||||
"d3-force": "^2.0.1",
|
||||
"dagre": "^0.8.5",
|
||||
"lodash": "^4.17.15",
|
||||
"numericjs": "^1.2.6",
|
||||
"tslib": "^1.10.0",
|
||||
"webpack": "^4.41.4"
|
||||
|
@ -271,7 +271,7 @@ export default class ItemController {
|
||||
* @param {string[]} states 状态名称集合
|
||||
* @memberof ItemController
|
||||
*/
|
||||
public clearItemStates(item: Item | string, states: string[]): void {
|
||||
public clearItemStates(item: Item | string, states: string | string[]): void {
|
||||
const graph = this.graph;
|
||||
|
||||
if (isString(item)) {
|
||||
|
@ -133,7 +133,6 @@ export default class StateController {
|
||||
*/
|
||||
public updateGraphStates() {
|
||||
const states = this.graph.get('states')
|
||||
|
||||
const cachedStates = this.cachedStates;
|
||||
|
||||
each(cachedStates.disabled, (val, key) => {
|
||||
@ -148,6 +147,8 @@ export default class StateController {
|
||||
if (!states[key]) {
|
||||
states[key] = val;
|
||||
} else {
|
||||
// TODO 需要测试是否能够走到这个分支
|
||||
console.log('走到这里没有', states)
|
||||
const map = {};
|
||||
states[key].forEach(item => {
|
||||
if (!item.destroyed) {
|
||||
|
@ -378,7 +378,7 @@ export default class Graph extends EventEmitter implements IGraph {
|
||||
* @param {string|Item} item 元素id或元素实例
|
||||
* @param {string[]} states 状态
|
||||
*/
|
||||
public clearItemStates(item: Item | string, states?: string[]): void {
|
||||
public clearItemStates(item: Item | string, states?: string[] | string): void {
|
||||
if(isString(item)) {
|
||||
item = this.findById(item)
|
||||
}
|
||||
@ -725,9 +725,11 @@ export default class Graph extends EventEmitter implements IGraph {
|
||||
}
|
||||
|
||||
if (!nodeItem && isString(item)) {
|
||||
this.get('customGroupControll').remove(item);
|
||||
const customGroupControll: CustomGroup = this.get('customGroupControll')
|
||||
customGroupControll.remove(item);
|
||||
} else {
|
||||
this.get('itemController').removeItem(item);
|
||||
const itemController: ItemController = this.get('itemController')
|
||||
itemController.removeItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
@ -783,7 +785,7 @@ export default class Graph extends EventEmitter implements IGraph {
|
||||
* @param {string} state 状态
|
||||
* @param {boolean} enabled 是否启用状态
|
||||
*/
|
||||
public setItemState(item: Item | string | string, state: string, enabled: boolean): void {
|
||||
public setItemState(item: Item | string, state: string, enabled: boolean): void {
|
||||
if (isString(item)) {
|
||||
item = this.findById(item);
|
||||
}
|
||||
@ -1380,7 +1382,6 @@ export default class Graph extends EventEmitter implements IGraph {
|
||||
customGroupControll.expandGroup(groupId);
|
||||
}
|
||||
|
||||
// TODO plugin 机制完善后再补充类型
|
||||
/**
|
||||
* 添加插件
|
||||
* @param {object} plugin 插件实例
|
||||
|
@ -386,9 +386,9 @@ export interface IGraph extends EventEmitter {
|
||||
/**
|
||||
* 清理元素多个状态
|
||||
* @param {string|Item} item 元素id或元素实例
|
||||
* @param {String[]} states 状态
|
||||
* @param {string | string[]} states 状态
|
||||
*/
|
||||
clearItemStates(item: Item | string, states?: string[]): void;
|
||||
clearItemStates(item: Item | string, states?: string | string[]): void;
|
||||
|
||||
/**
|
||||
* 设置各个节点样式,以及在各种状态下节点 keyShape 的样式。
|
||||
|
@ -4,7 +4,7 @@ import Graph from '@g6/graph/graph';
|
||||
import { GraphData, NodeConfig, NodeMapConfig, EdgeConfig } from '@g6/types';
|
||||
import { Point } from '@antv/g-base/lib/types';
|
||||
|
||||
interface IBundlingConfig extends IPluginBaseConfig {
|
||||
interface BundlingConfig extends IPluginBaseConfig {
|
||||
edgeBundles?: Edge[];
|
||||
edgePoints?: NodeConfig[];
|
||||
K?: number;
|
||||
@ -47,10 +47,10 @@ function projectPointToEdge(p: Point, e): Point {
|
||||
}
|
||||
|
||||
export default class Bundling extends Base {
|
||||
constructor(cfg?: IBundlingConfig) {
|
||||
constructor(cfg?: BundlingConfig) {
|
||||
super(cfg)
|
||||
}
|
||||
public getDefaultCfgs(): IBundlingConfig {
|
||||
public getDefaultCfgs(): BundlingConfig {
|
||||
return {
|
||||
edgeBundles: [], // |edges| arrays, each one stores the related edges' id
|
||||
edgePoints: [], // |edges| * divisions edge points
|
||||
|
@ -5,12 +5,17 @@ import Base, { IPluginBaseConfig } from '../base'
|
||||
|
||||
interface MenuConfig extends IPluginBaseConfig {
|
||||
createDOM?: boolean;
|
||||
getContent: (evt?: IG6GraphEvent) => string;
|
||||
menu?: HTMLDivElement;
|
||||
getContent?: (evt?: IG6GraphEvent) => string;
|
||||
onShow: (evt?: IG6GraphEvent) => boolean;
|
||||
onHide: (evt?: IG6GraphEvent) => boolean;
|
||||
}
|
||||
|
||||
export default class Menu extends Base {
|
||||
constructor(cfg: MenuConfig) {
|
||||
super(cfg)
|
||||
}
|
||||
|
||||
public getDefaultCfgs(): MenuConfig {
|
||||
return {
|
||||
createDOM: true, // 是否渲染 dom
|
||||
|
@ -17,7 +17,7 @@ const DEFAULT_MODE = 'default';
|
||||
const KEYSHAPE_MODE = 'keyShape';
|
||||
const DELEGATE_MODE = 'delegate';
|
||||
|
||||
interface IMiniMapConfig extends IPluginBaseConfig {
|
||||
interface MiniMapConfig extends IPluginBaseConfig {
|
||||
viewportClassName?: string;
|
||||
type?: 'default' | 'keyShape' | 'delegate';
|
||||
size: number[];
|
||||
@ -26,11 +26,11 @@ interface IMiniMapConfig extends IPluginBaseConfig {
|
||||
}
|
||||
|
||||
export default class MiniMap extends Base {
|
||||
constructor(cfg: IMiniMapConfig) {
|
||||
constructor(cfg: MiniMapConfig) {
|
||||
super(cfg)
|
||||
}
|
||||
|
||||
public getDefaultCfgs(): IMiniMapConfig {
|
||||
public getDefaultCfgs(): MiniMapConfig {
|
||||
return {
|
||||
container: null,
|
||||
className: 'g6-minimap',
|
||||
@ -70,7 +70,7 @@ export default class MiniMap extends Base {
|
||||
}
|
||||
|
||||
private initViewport() {
|
||||
const cfgs:IMiniMapConfig = this._cfgs as IMiniMapConfig;
|
||||
const cfgs:MiniMapConfig = this._cfgs as MiniMapConfig;
|
||||
const size = cfgs.size;
|
||||
const graph = cfgs.graph;
|
||||
const canvas = this.get('canvas');
|
||||
|
@ -289,6 +289,9 @@ export const getAdjMatrix = (data: GraphData, directed: boolean): Matrix[] => {
|
||||
// map node with index in data.nodes
|
||||
const nodeMap = {};
|
||||
|
||||
if(!nodes) {
|
||||
throw new Error('invalid nodes data!')
|
||||
}
|
||||
if (nodes) {
|
||||
nodes.forEach((node, i) => {
|
||||
nodeMap[node.id] = i;
|
||||
|
@ -28,7 +28,7 @@ export const getSpline = (points: IPoint[]) => {
|
||||
const data: number[] = [];
|
||||
|
||||
if (points.length < 2) {
|
||||
console.warn(`point length must largn than 2, now it's ${points.length}`);
|
||||
throw new Error(`point length must largn than 2, now it's ${points.length}`);
|
||||
}
|
||||
for (const point of points) {
|
||||
const { x, y } = point;
|
||||
|
@ -28,7 +28,7 @@ G6.registerNode('circleNode', {
|
||||
}
|
||||
}, 'circle');
|
||||
|
||||
describe.only('signle layer group', () => {
|
||||
describe('signle layer group', () => {
|
||||
|
||||
it('render signle group test', () => {
|
||||
const graph = new G6.Graph({
|
||||
@ -605,8 +605,8 @@ describe.only('signle layer group', () => {
|
||||
expect(groups.length).toBe(4);
|
||||
|
||||
// 删除group1
|
||||
const customGroup = graph.get('customGroupControll');
|
||||
customGroup.remove('group1');
|
||||
// const customGroup = graph.get('customGroupControll');
|
||||
graph.remove('group1');
|
||||
|
||||
const groupNodes1 = graph.get('groupNodes');
|
||||
const keys1 = Object.keys(groupNodes1);
|
||||
@ -625,7 +625,7 @@ describe.only('signle layer group', () => {
|
||||
|
||||
});
|
||||
|
||||
describe.only('nesting layer group', () => {
|
||||
describe('nesting layer group', () => {
|
||||
it('render nesting layer group', () => {
|
||||
const data = {
|
||||
nodes: [
|
||||
@ -924,7 +924,7 @@ describe.only('nesting layer group', () => {
|
||||
});
|
||||
|
||||
// 手动创建分子
|
||||
describe.only('create node group', () => {
|
||||
describe('create node group', () => {
|
||||
it('use addItem create group', () => {
|
||||
const data = {
|
||||
nodes: [
|
||||
|
@ -1,15 +1,10 @@
|
||||
import G6 from '../../../../src'
|
||||
import { timerOut } from '../../util/timeOut'
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.id = 'state-controller';
|
||||
document.body.appendChild(div);
|
||||
|
||||
function timerGame(callback, time = 50) {
|
||||
setTimeout(() => {
|
||||
callback();
|
||||
}, time);
|
||||
}
|
||||
|
||||
describe('graph state controller', () => {
|
||||
const graph = new G6.Graph({
|
||||
container: div,
|
||||
@ -18,7 +13,7 @@ describe('graph state controller', () => {
|
||||
});
|
||||
const data = {
|
||||
nodes: [
|
||||
{ id: 'node1', x: 100, y: 100 },
|
||||
{ id: 'node1', x: 100, y: 100, label: 'node1' },
|
||||
{ id: 'node2', x: 120, y: 80 },
|
||||
{ id: 'node3', x: 150, y: 150 }
|
||||
],
|
||||
@ -44,7 +39,7 @@ describe('graph state controller', () => {
|
||||
|
||||
graph.setItemState('node1', 'selected', true);
|
||||
|
||||
timerGame(() => {
|
||||
timerOut(() => {
|
||||
expect(itemCount).toBe(1);
|
||||
expect(graphCount).toBe(0);
|
||||
|
||||
@ -52,7 +47,7 @@ describe('graph state controller', () => {
|
||||
expect(graph.get('states').selected.length).toBe(1);
|
||||
expect(graph.get('states').selected[0]).toEqual(graph.findById('node1'));
|
||||
|
||||
timerGame(() => {
|
||||
timerOut(() => {
|
||||
graph.setItemState('node1', 'selected', false);
|
||||
graph.setItemState('node1', 'selected', true);
|
||||
graph.setItemState('node2', 'selected', true);
|
||||
@ -65,7 +60,7 @@ describe('graph state controller', () => {
|
||||
graph.setItemState('node2', 'selected', false);
|
||||
graph.setItemState('node3', 'selected', false);
|
||||
|
||||
timerGame(() => {
|
||||
timerOut(() => {
|
||||
expect(graph.get('states').selected.length).toBe(0);
|
||||
}, 90)
|
||||
}, 70)
|
||||
@ -86,4 +81,21 @@ describe('graph state controller', () => {
|
||||
expect(Object.keys(modes)).toEqual(['default'])
|
||||
expect(modes.default).toEqual([])
|
||||
});
|
||||
|
||||
it('updateGraphStates', () => {
|
||||
const node1 = graph.findById('node1')
|
||||
graph.setItemState(node1, 'selected', true)
|
||||
graph.setItemState(node1, 'hover', true)
|
||||
graph.setItemState('node2', 'hover', true)
|
||||
graph.on('node:mouseenter', () => {
|
||||
const states = graph.get('states')
|
||||
expect(states).not.toBe(undefined)
|
||||
expect(states.selected.length).toBe(1)
|
||||
expect(states.hover.length).toBe(2)
|
||||
})
|
||||
|
||||
timerOut(() => {
|
||||
graph.emit('node:mouseenter', { item: node1 })
|
||||
}, 20)
|
||||
})
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ import '../../../src/behavior'
|
||||
import { scale, translate } from '../../../src/util/math'
|
||||
import { GraphData, Item } from '../../../types';
|
||||
import Plugin from '../../../src/plugins'
|
||||
import { timerOut } from '../util/timeOut'
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.id = 'global-spec';
|
||||
@ -626,9 +627,13 @@ describe('all node link center', () => {
|
||||
graph.setItemState(node, 'a', true);
|
||||
graph.setItemState(node, 'b', true);
|
||||
|
||||
debugger
|
||||
graph.clearItemStates('a', ['a']);
|
||||
expect(graph.findAllByState('node', 'a').length).toBe(0);
|
||||
expect(graph.findAllByState('node', 'b').length).toBe(1);
|
||||
|
||||
graph.clearItemStates(node, 'b')
|
||||
expect(graph.findAllByState('node', 'b').length).toBe(0)
|
||||
});
|
||||
|
||||
it('default node & edge style', () => {
|
||||
@ -1004,4 +1009,57 @@ describe('plugins & layout', () => {
|
||||
graph.destroy()
|
||||
expect(graph.destroyed).toBe(true)
|
||||
})
|
||||
|
||||
it('graph animate', () => {
|
||||
const graph = new G6.Graph({
|
||||
container: div,
|
||||
height: 500,
|
||||
width: 500
|
||||
})
|
||||
|
||||
const data = {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node',
|
||||
label: 'node',
|
||||
groupId: 'g1'
|
||||
},{
|
||||
id: 'node1',
|
||||
groupId: 'g2'
|
||||
}
|
||||
],
|
||||
groups: [
|
||||
{
|
||||
id: 'g1',
|
||||
title: 'cokkdl'
|
||||
},
|
||||
{
|
||||
id: 'g2'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
graph.data(data)
|
||||
graph.render()
|
||||
|
||||
graph.stopAnimate()
|
||||
const isAnimating = graph.isAnimating()
|
||||
expect(isAnimating).toBe(false)
|
||||
|
||||
graph.collapseGroup('g1')
|
||||
|
||||
let gnode = graph.findById('node')
|
||||
|
||||
expect(gnode.get('visible')).toBe(false)
|
||||
|
||||
const g2Node = graph.findById('node1')
|
||||
expect(g2Node.get('visible')).toBe(true)
|
||||
|
||||
graph.expandGroup('g1')
|
||||
|
||||
timerOut(() => {
|
||||
gnode = graph.findById('node')
|
||||
expect(gnode.get('visible')).toBe(true)
|
||||
}, 500)
|
||||
})
|
||||
})
|
@ -1,16 +1,10 @@
|
||||
import Hierarchy from '@antv/hierarchy';
|
||||
import G6 from '../../../src';
|
||||
import { timerOut } from '../util/timeOut'
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.id = 'tree-spec';
|
||||
document.body.appendChild(div);
|
||||
|
||||
function timerGame(callback, time = 50) {
|
||||
setTimeout(() => {
|
||||
callback();
|
||||
}, time);
|
||||
}
|
||||
|
||||
describe('tree graph without animate', () => {
|
||||
let graph = new G6.TreeGraph({
|
||||
container: div,
|
||||
@ -166,7 +160,7 @@ describe('tree graph without animate', () => {
|
||||
});
|
||||
graph.addBehaviors('collapse-expand', 'default');
|
||||
graph.emit('node:click', { item: parent });
|
||||
timerGame(() => {
|
||||
timerOut(() => {
|
||||
collapsed = false;
|
||||
graph.emit('node:click', { item: parent });
|
||||
}, 600);
|
||||
@ -232,7 +226,7 @@ describe('tree graph without animate', () => {
|
||||
}
|
||||
});
|
||||
graph.emit('node:dblclick', { item: parent });
|
||||
timerGame(() => {
|
||||
timerOut(() => {
|
||||
collapsed = false;
|
||||
graph.emit('node:dblclick', { item: parent });
|
||||
}, 600);
|
||||
@ -446,7 +440,7 @@ describe('tree graph with animate', () => {
|
||||
graph.addBehaviors('collapse-expand', 'default');
|
||||
graph.emit('node:click', { item: parent });
|
||||
|
||||
timerGame(() => {
|
||||
timerOut(() => {
|
||||
collapsed = false;
|
||||
graph.emit('node:click', { item: parent });
|
||||
}, 600);
|
||||
@ -478,7 +472,7 @@ describe('tree graph with animate', () => {
|
||||
|
||||
graph.emit('node:dblclick', { item: parent });
|
||||
|
||||
timerGame(() => {
|
||||
timerOut(() => {
|
||||
collapsed = false;
|
||||
graph.emit('node:dblclick', { item: parent });
|
||||
}, 600);
|
||||
|
@ -6,7 +6,7 @@ const div = document.createElement('div');
|
||||
div.id = 'circular-layout';
|
||||
document.body.appendChild(div);
|
||||
|
||||
describe.only('circular layout', () => {
|
||||
describe('circular layout', () => {
|
||||
it('circular layout with default configs', () => {
|
||||
const graph = new G6.Graph({
|
||||
container: div,
|
||||
|
@ -7,7 +7,7 @@ const div = document.createElement('div');
|
||||
div.id = 'circular-layout-web-worker';
|
||||
document.body.appendChild(div);
|
||||
|
||||
describe.only('circular layout(web worker)', () => {
|
||||
describe('circular layout(web worker)', () => {
|
||||
it('circular layout(web worker) with default configs', (done) => {
|
||||
const graph = new G6.Graph({
|
||||
container: div,
|
||||
|
@ -6,7 +6,7 @@ const div = document.createElement('div');
|
||||
div.id = 'force-layout-web-worker';
|
||||
document.body.appendChild(div);
|
||||
|
||||
describe.only('force layout(web worker)', function() {
|
||||
describe('force layout(web worker)', function() {
|
||||
// this.timeout(10000);
|
||||
|
||||
it('force layout(web worker) with default configs', done => {
|
||||
|
@ -24,7 +24,7 @@ const div = document.createElement('div');
|
||||
div.id = 'grid-layout';
|
||||
document.body.appendChild(div);
|
||||
|
||||
describe.only('grid layout', () => {
|
||||
describe('grid layout', () => {
|
||||
it('grid layout with default configs', () => {
|
||||
const graph = new G6.Graph({
|
||||
container: div,
|
||||
|
@ -5,7 +5,7 @@ const div = document.createElement('div');
|
||||
div.id = 'mds-layout';
|
||||
document.body.appendChild(div);
|
||||
|
||||
describe.only('mds', () => {
|
||||
describe('mds', () => {
|
||||
it('mds layout with default configs', () => {
|
||||
const graph = new G6.Graph({
|
||||
container: div,
|
||||
|
@ -86,7 +86,7 @@ const data2 = {
|
||||
],
|
||||
};
|
||||
|
||||
describe.only('preset layout', () => {
|
||||
describe('preset layout', () => {
|
||||
it('new graph without layout, part of the data has position infor', () => {
|
||||
const graph = new G6.Graph({
|
||||
container: div,
|
||||
|
@ -16,7 +16,7 @@ const data: {nodes: object, edges: object} = {
|
||||
edges: [],
|
||||
};
|
||||
|
||||
describe.only('random', () => {
|
||||
describe('random', () => {
|
||||
it('new graph without layout, random by default', () => {
|
||||
const graph = new G6.Graph({
|
||||
container: div,
|
||||
|
@ -9,7 +9,7 @@ document.body.appendChild(div);
|
||||
|
||||
// jest.setTimeout(10000)
|
||||
|
||||
describe.only('layout using web worker', function() {
|
||||
describe('layout using web worker', function() {
|
||||
it('change layout', function(done) {
|
||||
const node = data.nodes[0];
|
||||
const graph = new G6.Graph({
|
||||
|
@ -7,8 +7,7 @@ const div = document.createElement('div');
|
||||
div.id = 'force-layout';
|
||||
document.body.appendChild(div);
|
||||
|
||||
describe.skip('edge bundling', () => {
|
||||
// TODO Wait for layout
|
||||
describe('edge bundling', () => {
|
||||
const graph = new G6.Graph({
|
||||
container: div,
|
||||
width: 500,
|
||||
@ -31,6 +30,7 @@ describe.skip('edge bundling', () => {
|
||||
|
||||
expect(graphData.edges[0].shape).toEqual('polyline');
|
||||
expect(graphData.edges[0].controlPoints.length > 2).toEqual(true);
|
||||
bundle.destroy()
|
||||
});
|
||||
|
||||
it('bundling on circular with fixed bundleThreshold and iterations', () => {
|
||||
@ -45,6 +45,7 @@ describe.skip('edge bundling', () => {
|
||||
|
||||
expect(graphData.edges[0].shape).toEqual('polyline');
|
||||
expect(graphData.edges[0].controlPoints.length > 2).toEqual(true);
|
||||
bundle.destroy()
|
||||
});
|
||||
|
||||
it('bundling update', () => {
|
||||
@ -80,16 +81,27 @@ describe.skip('edge bundling', () => {
|
||||
|
||||
expect(data2.edges[0].shape).toEqual('polyline');
|
||||
expect(data2.edges[0].controlPoints.length > 2).toEqual(true);
|
||||
bundle.destroy()
|
||||
});
|
||||
|
||||
it('bundling no position info, throw error', () => {
|
||||
const bundle = new Bundling();
|
||||
bundle.initPlugin(graph);
|
||||
|
||||
const data2: GraphData = {
|
||||
nodes: [
|
||||
{ id: 'n0' }, { id: 'n1' }
|
||||
],
|
||||
edges: [
|
||||
{ source: 'n0', target: 'n1' }
|
||||
]
|
||||
};
|
||||
|
||||
function fn() {
|
||||
bundle.bundling(data);
|
||||
bundle.bundling(data2);
|
||||
}
|
||||
expect(fn).toThrowError('please layout the graph or assign x and y for nodes first');
|
||||
bundle.destroy()
|
||||
graph.destroy();
|
||||
});
|
||||
});
|
||||
|
@ -18,6 +18,7 @@ describe('menu', () => {
|
||||
onShow(e) {
|
||||
expect(isNaN(e.canvasX)).toBe(false);
|
||||
expect(isNaN(e.canvasY)).toBe(false);
|
||||
return true
|
||||
},
|
||||
onHide() {
|
||||
count++;
|
||||
@ -80,13 +81,19 @@ describe('menu', () => {
|
||||
const menu = new Menu({
|
||||
createDOM: false,
|
||||
menu: outDiv,
|
||||
getContent(e) {
|
||||
expect(e).not.toBe(undefined);
|
||||
return 'test menu';
|
||||
},
|
||||
onShow(e) {
|
||||
outDiv.style.left = e.canvasX + 'px';
|
||||
outDiv.style.top = e.canvasY + 'px';
|
||||
outDiv.style.visibility = 'visible';
|
||||
return true
|
||||
},
|
||||
onHide() {
|
||||
outDiv.style.visibility = 'hidden';
|
||||
return false
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
import G6 from '../../../src'
|
||||
import Minimap from '../../../src/plugins/minimap'
|
||||
import Simulate from 'event-simulate'
|
||||
import { timerOut } from '../util/timeOut'
|
||||
|
||||
const div = document.createElement('div');
|
||||
div.id = 'minimap';
|
||||
@ -8,12 +9,6 @@ document.body.appendChild(div);
|
||||
const container = document.createElement('div');
|
||||
div.appendChild(container);
|
||||
|
||||
function timerGame(callback, time = 50) {
|
||||
setTimeout(() => {
|
||||
callback();
|
||||
}, time);
|
||||
}
|
||||
|
||||
describe('minimap', () => {
|
||||
const minimap = new Minimap({ size: [ 200, 200 ] });
|
||||
const graph = new G6.Graph({
|
||||
@ -111,7 +106,7 @@ describe('minimap', () => {
|
||||
clientY: 120
|
||||
});
|
||||
|
||||
timerGame(() => {
|
||||
timerOut(() => {
|
||||
expect(viewport.style.left).toEqual('20px');
|
||||
expect(viewport.style.top).toEqual('20px');
|
||||
expect(viewport.style.width).toEqual('0px');
|
||||
@ -134,7 +129,7 @@ describe('minimap', () => {
|
||||
clientY: 0
|
||||
});
|
||||
|
||||
timerGame(() => {
|
||||
timerOut(() => {
|
||||
expect(viewport.style.left).toEqual('0px');
|
||||
expect(viewport.style.top).toEqual('0px');
|
||||
expect(viewport.style.width).toEqual('100px');
|
||||
|
34
tests/unit/util/base-spec.ts
Normal file
34
tests/unit/util/base-spec.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { formatPadding, isViewportChanged } from '../../../src/util/base'
|
||||
|
||||
describe('base util', () => {
|
||||
it('formatPadding', () => {
|
||||
let padding = formatPadding(5)
|
||||
expect(padding).toEqual([5, 5, 5, 5])
|
||||
|
||||
padding = formatPadding('10')
|
||||
expect(padding).toEqual([10, 10, 10, 10])
|
||||
|
||||
padding = formatPadding([5])
|
||||
expect(padding).toEqual([5, 5, 5, 5])
|
||||
|
||||
padding = formatPadding([5, 10])
|
||||
expect(padding).toEqual([5, 10, 5, 10])
|
||||
|
||||
padding = formatPadding([5, 10, 15])
|
||||
expect(padding).toEqual([5, 10, 15, 10])
|
||||
|
||||
padding = formatPadding([5, 10, 15, 20])
|
||||
expect(padding).toEqual([5, 10, 15, 20])
|
||||
})
|
||||
|
||||
it('isViewportChanged', () => {
|
||||
let isChanged = isViewportChanged(null)
|
||||
expect(isChanged).toBe(false)
|
||||
|
||||
isChanged = isViewportChanged([1, 0, 0, 0, 1, 0, 0, 0, 1])
|
||||
expect(isChanged).toBe(false)
|
||||
|
||||
isChanged = isViewportChanged([1, 0, 0, 0.5, 1, 0, 0, 0, 1])
|
||||
expect(isChanged).toBe(true)
|
||||
})
|
||||
})
|
@ -227,6 +227,42 @@ describe('math util test', () => {
|
||||
expect(directedMatrix[1]).toEqual([])
|
||||
})
|
||||
|
||||
it('getAdjMatrix without nodes', () => {
|
||||
const data = {
|
||||
edges: [
|
||||
{
|
||||
source: 'node1',
|
||||
target: 'node2'
|
||||
},
|
||||
{
|
||||
source: 'node1',
|
||||
target: 'node1'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
expect(() => {getAdjMatrix(data, false)}).toThrowError('invalid nodes data!')
|
||||
})
|
||||
|
||||
it('getAdjMatrix without edges', () => {
|
||||
const data1 = {
|
||||
nodes: [
|
||||
{
|
||||
id: 'node1',
|
||||
label: 'node1'
|
||||
},
|
||||
{
|
||||
id: 'node2',
|
||||
label: 'node2'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const directedMatrix = getAdjMatrix(data1, true)
|
||||
expect(directedMatrix[0]).toEqual([])
|
||||
expect(directedMatrix[1]).toEqual([])
|
||||
})
|
||||
|
||||
it('floydWarshall', () => {
|
||||
const matrix = [
|
||||
[1, 1, 2],
|
||||
|
@ -39,6 +39,17 @@ describe('Path Util Test', () => {
|
||||
expect(three[6]).toEqual(7)
|
||||
})
|
||||
|
||||
it('getSpline thorw new error', () => {
|
||||
const points = [
|
||||
{
|
||||
x: 10,
|
||||
y: 12
|
||||
}
|
||||
]
|
||||
|
||||
expect(() => getSpline(points)).toThrowError(`point length must largn than 2, now it's ${points.length}`)
|
||||
})
|
||||
|
||||
it('getControlPoint horizontal', () => {
|
||||
const start = { x: 0, y: 0 };
|
||||
const end = { x: 100, y: 0 };
|
||||
@ -81,6 +92,19 @@ describe('Path Util Test', () => {
|
||||
expect(point.y).toEqual(50 - sqrt2 * 10 / 2);
|
||||
})
|
||||
|
||||
it('getControlPoint percent is 0', () => {
|
||||
const start = { x: 100, y: 100 };
|
||||
const end = { x: 50, y: 20 };
|
||||
const point = getControlPoint(start, end);
|
||||
expect(point.x).toEqual(100);
|
||||
expect(point.y).toEqual(100);
|
||||
})
|
||||
|
||||
it('pointsToPolygon points.length = 0', () => {
|
||||
const polygonPoint = pointsToPolygon([])
|
||||
expect(polygonPoint).toEqual('')
|
||||
})
|
||||
|
||||
it('pointsToPolygon z = false', () => {
|
||||
const points = [
|
||||
{
|
||||
@ -112,4 +136,17 @@ describe('Path Util Test', () => {
|
||||
const polygonPoint = pointsToPolygon(points, true)
|
||||
expect(polygonPoint).toEqual('M1 2L5 5Z')
|
||||
})
|
||||
|
||||
it('pointsToPolygon substitute', () => {
|
||||
const points = [
|
||||
{
|
||||
x: 1,
|
||||
y: 2
|
||||
},
|
||||
''
|
||||
]
|
||||
|
||||
const polygonPoint = pointsToPolygon(points, true)
|
||||
expect(polygonPoint).toEqual('M1 2L{x} {y}Z')
|
||||
})
|
||||
})
|
10
tests/unit/util/timeOut.ts
Normal file
10
tests/unit/util/timeOut.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* 在 jest 中使用 setTimeout 功能
|
||||
* @param callback 回调函数
|
||||
* @param time 延迟的时间
|
||||
*/
|
||||
export const timerOut = (callback, time = 50) => {
|
||||
setTimeout(() => {
|
||||
callback();
|
||||
}, time);
|
||||
}
|
@ -201,8 +201,8 @@ export interface NodeConfig extends ModelConfig {
|
||||
|
||||
export interface EdgeConfig extends ModelConfig {
|
||||
id?: string;
|
||||
source: string;
|
||||
target: string;
|
||||
source?: string;
|
||||
target?: string;
|
||||
label?: string;
|
||||
labelCfg?: {
|
||||
style?: object;
|
||||
|
Loading…
Reference in New Issue
Block a user