import Graph from '../implement-graph' ; import { ICombo } from '../../../src/interface/item' ; import { GraphData } from '../../../src/types' ; import { clone } from '@antv/util' ; const div = document . createElement ( 'div' ) ; div . id = 'global-spec' ; document . body . appendChild ( div ) ; const data = { nodes : [ { id : '0' , label : '0' , comboId : 'a' , x : 100 , y : 100 , } , { id : '1' , label : '1' , comboId : 'a' , x : 150 , y : 140 , } , { id : '2' , label : '2' , comboId : 'b' , x : 300 , y : 200 , } , { id : '3' , label : '3' , comboId : 'b' , x : 370 , y : 260 , } , { id : '5' , label : '5' , comboId : 'e' , x : 220 , y : 240 , } , { id : '6' , label : '6' , comboId : 'e' , x : 250 , y : 250 , } , { id : '4' , label : '4' , comboId : 'c' , x : 360 , y : 510 , } , ] , edges : [ { source : '0' , target : '1' , } , { source : '1' , target : '2' , } , { source : '0' , target : '2' , } , { source : '3' , target : '0' , } , { source : '4' , target : '1' , } , { id : '5-6' , source : '5' , target : '6' , } , { id : '4-6' , source : '4' , target : '6' , } , ] , combos : [ { id : 'a' , label : 'combo a' , } , { id : 'b' , label : 'combo b' , } , { id : 'c' , label : 'combo c' , } , { id : 'e' , label : 'combo e' , parentId : 'b' , } , ] , } ; describe ( 'graph with combo' , ( ) => { it ( 'uncombo' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , } ) ; graph . read ( clone ( data ) ) ; graph . uncombo ( graph . findById ( 'a' ) as ICombo ) ; expect ( graph . getCombos ( ) . length ) . toBe ( 3 ) ; expect ( graph . get ( 'comboTrees' ) . length ) . toBe ( 2 ) ; graph . uncombo ( 'e' ) ; expect ( graph . getCombos ( ) . length ) . toBe ( 2 ) ; expect ( graph . get ( 'comboTrees' ) . length ) . toBe ( 2 ) ; graph . uncombo ( '0' ) ; expect ( graph . getCombos ( ) . length ) . toBe ( 2 ) ; expect ( graph . get ( 'comboTrees' ) . length ) . toBe ( 2 ) ; graph . uncombo ( 'invalidid' ) ; expect ( graph . getCombos ( ) . length ) . toBe ( 2 ) ; expect ( graph . get ( 'comboTrees' ) . length ) . toBe ( 2 ) ; graph . destroy ( ) ; } ) ; it ( 'uncombo subcombo' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , } ) ; graph . read ( clone ( data ) ) ; graph . uncombo ( graph . findById ( 'b' ) as ICombo ) ; expect ( graph . getCombos ( ) . length ) . toBe ( 3 ) ; expect ( graph . findById ( 'b' ) ) . toBe ( undefined ) ; graph . uncombo ( 'e' ) ; expect ( graph . getCombos ( ) . length ) . toBe ( 2 ) ; expect ( graph . findById ( 'e' ) ) . toBe ( undefined ) ; graph . destroy ( ) ; } ) ; it ( 'get combo children' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , } ) ; graph . read ( clone ( data ) ) ; const comboB = graph . findById ( 'b' ) as ICombo ; const comboBChildren = comboB . getChildren ( ) ; expect ( comboBChildren . nodes . length ) . toBe ( 2 ) ; expect ( comboBChildren . combos . length ) . toBe ( 1 ) ; expect ( comboBChildren . combos [ 0 ] . getChildren ( ) . nodes . length ) . toBe ( 2 ) ; graph . destroy ( ) ; } ) ; it ( 'hide and show a combo' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , } ) ; graph . read ( clone ( data ) ) ; const comboA = graph . findById ( 'a' ) as ICombo ; comboA . hide ( ) ; const aChildren = comboA . getNodes ( ) ; aChildren . forEach ( ( child ) => { expect ( child . isVisible ( ) ) . toBe ( true ) ; } ) ; const comboB = graph . findById ( 'b' ) as ICombo ; graph . hideItem ( 'b' ) ; const bChildren = comboB . getChildren ( ) ; graph . uncombo ( graph . findById ( 'a' ) as ICombo ) ; bChildren . nodes . forEach ( ( node ) => { expect ( node . isVisible ( ) ) . toBe ( false ) ; } ) ; bChildren . combos . forEach ( ( combo ) => { expect ( combo . isVisible ( ) ) . toBe ( false ) ; } ) ; expect ( graph . findById ( '5-6' ) . isVisible ( ) ) . toBe ( false ) ; expect ( graph . findById ( '4-6' ) . isVisible ( ) ) . toBe ( false ) ; graph . showItem ( 'b' ) ; expect ( graph . findById ( '5-6' ) . isVisible ( ) ) . toBe ( true ) ; expect ( graph . findById ( '4-6' ) . isVisible ( ) ) . toBe ( true ) ; graph . hideItem ( 'invalidid' ) ; graph . destroy ( ) ; } ) ; it ( 'collapse expand combo' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , defaultCombo : { size : 10 , padding : 1 , } , defaultEdge : { style : { endArrow : true , } , } , animate : true , } ) ; graph . read ( clone ( data ) ) ; graph . collapseCombo ( 'invalidid' ) ; graph . expandCombo ( 'invalidid' ) ; const comboE = graph . findById ( 'e' ) as ICombo ; graph . collapseCombo ( comboE ) ; comboE . getChildren ( ) . nodes . forEach ( ( node ) => { expect ( node . isVisible ( ) ) . toBe ( false ) ; } ) ; const comboB = graph . findById ( 'b' ) as ICombo ; graph . collapseCombo ( comboB ) ; comboB . getChildren ( ) . nodes . forEach ( ( node ) => { expect ( node . isVisible ( ) ) . toBe ( false ) ; } ) ; comboB . getChildren ( ) . combos . forEach ( ( combo ) => { expect ( combo . isVisible ( ) ) . toBe ( false ) ; } ) ; graph . expandCombo ( comboB ) ; comboB . getChildren ( ) . nodes . forEach ( ( node ) => { expect ( node . isVisible ( ) ) . toBe ( true ) ; } ) ; comboB . getChildren ( ) . combos . forEach ( ( combo ) => { expect ( combo . isVisible ( ) ) . toBe ( true ) ; } ) ; graph . collapseCombo ( 'b' ) ; graph . collapseExpandCombo ( 'a' ) ; const comboA = graph . findById ( 'a' ) as ICombo ; comboA . getChildren ( ) . nodes . forEach ( ( node ) => { expect ( node . isVisible ( ) ) . toBe ( false ) ; } ) ; graph . collapseExpandCombo ( comboA ) ; comboA . getChildren ( ) . nodes . forEach ( ( node ) => { expect ( node . isVisible ( ) ) . toBe ( true ) ; } ) ; graph . destroy ( ) ; } ) ; it ( 'combo mapper' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , groupByTypes : false , } ) ; graph . combo ( ( ) => { return { style : { fill : 'red' , stroke : 'blue' , lineWidth : 3 , } , } ; } ) ; graph . read ( clone ( data ) ) ; expect ( graph . getCombos ( ) [ 0 ] . getKeyShape ( ) . attr ( 'fill' ) ) . toBe ( 'red' ) ; expect ( graph . getCombos ( ) [ 0 ] . getKeyShape ( ) . attr ( 'stroke' ) ) . toBe ( 'blue' ) ; expect ( graph . getCombos ( ) [ 0 ] . getKeyShape ( ) . attr ( 'lineWidth' ) ) . toBe ( 3 ) ; graph . destroy ( ) ; } ) ; it ( 'getComboChildren' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , } ) ; graph . read ( clone ( data ) ) ; const childrenById = graph . getComboChildren ( 'b' ) ; const comboB = graph . findById ( 'b' ) as ICombo ; const childrenByItem = graph . getComboChildren ( comboB ) ; expect ( childrenById . nodes . length ) . toBe ( 2 ) ; expect ( childrenById . nodes . length ) . toBe ( childrenByItem . nodes . length ) ; expect ( childrenById . combos . length ) . toBe ( 1 ) ; expect ( childrenById . combos . length ) . toBe ( childrenByItem . combos . length ) ; const invalidCombo = graph . getComboChildren ( 'invalidid' ) ; expect ( invalidCombo ) . toBe ( undefined ) ; graph . destroy ( ) ; } ) ; it ( 'changeData with combos' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , layout : { type : 'comboForce' , } , modes : { default : [ 'drag-combo' ] , } , fitView : true , groupByTypes : false , } ) ; graph . read ( clone ( data ) ) ; const newData = { nodes : [ { id : 'new1' , label : 'new1' , comboId : 'a' , } , { id : 'new2' , label : 'new2' , comboId : 'a' , } , { id : '3' , } , { id : '4' , comboId : 'c' , } , { id : 'new5' , label : 'new5' , comboId : 'f' , } , ] , edges : [ { source : 'new1' , target : 'new2' , } , { source : '3' , target : 'new2' , } , { source : '3' , target : '4' , } , { source : 'new1' , target : 'new5' , } , ] , combos : [ { id : 'a' , label : 'c-a' , } , { id : 'b' , label : 'c-b' , } , { id : 'c' , parentId : 'a' , label : 'c-c' , } , { id : 'f' , parentId : 'a' , label : 'c-f' , } , ] , } ; } ) ; it ( 'updateComboTree' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , layout : { type : 'comboForce' , } , fitView : true , } ) ; graph . read ( clone ( data ) ) ; graph . updateComboTree ( '4' , 'b' ) ; graph . layout ( ) ; expect ( graph . get ( 'comboTrees' ) . length ) . toBe ( 3 ) ; const comboBChildren = ( graph . findById ( 'b' ) as ICombo ) . getChildren ( ) ; expect ( comboBChildren . nodes . length ) . toBe ( 3 ) ; expect ( comboBChildren . combos . length ) . toBe ( 1 ) ; const comboC = graph . findById ( 'c' ) as ICombo ; expect ( comboC . getChildren ( ) . nodes . length ) . toBe ( 0 ) ; const comboA = graph . findById ( 'a' ) as ICombo ; graph . updateComboTree ( comboA , 'c' ) ; expect ( comboA . getChildren ( ) . nodes . length ) . toBe ( 2 ) ; expect ( comboC . getChildren ( ) . nodes . length ) . toBe ( 0 ) ; expect ( comboC . getChildren ( ) . combos . length ) . toBe ( 1 ) ; graph . destroy ( ) ; } ) ; it ( 'add combo item' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , layout : { type : 'comboForce' , } , modes : { default : [ 'drag-canvas' , 'zoom-canvas' ] , } , fitView : true , } ) ; graph . read ( clone ( data ) ) ; const newComboItem = graph . addItem ( 'combo' , { id : 'new combo' , label : 'new combo' , } ) ; expect ( newComboItem . getChildren ( ) . nodes . length ) . toBe ( 0 ) ; expect ( newComboItem . getChildren ( ) . combos . length ) . toBe ( 0 ) ; expect ( graph . getCombos ( ) . length ) . toBe ( 5 ) ; expect ( graph . get ( 'comboTrees' ) . length ) . toBe ( 4 ) ; const newComboItem2 = graph . addItem ( 'combo' , { id : 'new combo 2' , label : 'new combo 2' , parentId : 'new combo' , } ) ; graph . addItem ( 'combo' , { id : 'new combo 3' , label : 'new combo 3' , parentId : 'new combo' , } ) ; expect ( newComboItem . getChildren ( ) . nodes . length ) . toBe ( 0 ) ; expect ( newComboItem . getChildren ( ) . combos . length ) . toBe ( 2 ) ; graph . addItem ( 'node' , { id : 'newsubnode1' , label : 'newsubnode1' , comboId : 'new combo' , } ) ; expect ( newComboItem . getChildren ( ) . nodes . length ) . toBe ( 1 ) ; expect ( newComboItem . getChildren ( ) . combos . length ) . toBe ( 2 ) ; graph . addItem ( 'node' , { id : 'newsubnode2' , label : 'newsubnode2' , comboId : 'new combo 2' , } ) ; graph . layout ( ) ; expect ( newComboItem2 . getChildren ( ) . nodes . length ) . toBe ( 1 ) ; expect ( newComboItem2 . getChildren ( ) . combos . length ) . toBe ( 0 ) ; graph . addItem ( 'combo' , { id : 'a' , } ) ; graph . addItem ( 'node' , { id : 'nodeWithInvalidComboId' , label : 'nodeWithInvalidComboId' , comboId : '4' , } ) ; graph . destroy ( ) ; } ) ; it ( 'graph.save with combos' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , layout : { type : 'comboForce' , } , modes : { default : [ 'drag-canvas' , 'zoom-canvas' ] , } , animate : true , } ) ; graph . read ( clone ( data ) ) ; const result = graph . save ( ) as GraphData ; expect ( result . combos ) . not . toBe ( undefined ) ; expect ( result . combos . length ) . toBe ( 4 ) ; graph . destroy ( ) ; } ) ; } ) ; describe ( 'empty combo' , ( ) => { const data = { nodes : [ { id : 'node1' , x : 250 , y : 150 , } , { id : 'node2' , x : 350 , y : 150 , } , ] , } ; it ( 'circle no label' , ( ) => { const graph = new Graph ( { container : div , width : 500 , height : 600 , modes : { default : [ 'drag-canvas' , 'drag-node' , 'drag-combo' , 'collapse-expand-combo' ] , } , } ) ; graph . on ( 'canvas:click' , ( e ) => { graph . createCombo ( 'combo1' , [ 'node1' , 'node2' ] ) ; } ) ; graph . data ( data ) ; graph . render ( ) ; } ) ; } ) ;