| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| */ | |
| import ComponentModel, { ComponentModelConstructor } from '@/src/model/Component'; | |
| import { ComponentMainType } from '@/src/util/types'; | |
| const componentModelConstructor = ComponentModel as ComponentModelConstructor; | |
| function extendModel(type: string, dependencies?: string[]) { | |
| class SubModel extends ComponentModel { | |
| static type: string = type; | |
| type: string = type; | |
| static dependencies = dependencies || []; | |
| }; | |
| ComponentModel.registerClass(SubModel); | |
| return SubModel; | |
| } | |
| describe('componentDependency', function () { | |
| let idx = 0; | |
| function makeTypes(count: number): string[] { | |
| const arr = []; | |
| for (let i = 0; i < count; i++) { | |
| arr.push('type_' + idx++); | |
| } | |
| return arr; | |
| } | |
| type TopoResultItem = [ComponentMainType, ComponentMainType[]]; | |
| it('topologicalTravel_base', function () { | |
| const [m1, a1, a2] = makeTypes(3); | |
| extendModel(m1, [a1, a2]); | |
| extendModel(a1); | |
| extendModel(a2); | |
| const result: TopoResultItem[] = []; | |
| const allList = componentModelConstructor.getAllClassMainTypes(); | |
| componentModelConstructor.topologicalTravel( | |
| [m1, a1, a2], | |
| allList, | |
| function (componentType, dependencies) { | |
| result.push([componentType, dependencies]); | |
| } | |
| ); | |
| expect(result).toEqual([[a2, ['dataset']], [a1, ['dataset']], [m1, ['dataset', a1, a2]]]); | |
| }); | |
| it('topologicalTravel_a1IsAbsent', function () { | |
| const [m1, a1, a2] = makeTypes(3); | |
| extendModel(m1, [a1, a2]); | |
| extendModel(a2); | |
| const allList = componentModelConstructor.getAllClassMainTypes(); | |
| const result: TopoResultItem[] = []; | |
| componentModelConstructor.topologicalTravel( | |
| [m1, a2], | |
| allList, | |
| function (componentType, dependencies) { | |
| result.push([componentType, dependencies]); | |
| } | |
| ); | |
| expect(result).toEqual([[a2, ['dataset']], [m1, ['dataset', a1, a2]]]); | |
| }); | |
| it('topologicalTravel_empty', function () { | |
| const [m1, a1, a2] = makeTypes(3); | |
| extendModel(m1, [a1, a2]); | |
| extendModel(a1); | |
| extendModel(a2); | |
| const allList = componentModelConstructor.getAllClassMainTypes(); | |
| const result: TopoResultItem[] = []; | |
| componentModelConstructor.topologicalTravel( | |
| [], | |
| allList, | |
| function (componentType, dependencies) { | |
| result.push([componentType, dependencies]); | |
| } | |
| ); | |
| expect(result).toEqual([]); | |
| }); | |
| it('topologicalTravel_isolate', function () { | |
| const [m1, a1, a2] = makeTypes(3); | |
| extendModel(a2); | |
| extendModel(a1); | |
| extendModel(m1, [a2]); | |
| const allList = componentModelConstructor.getAllClassMainTypes(); | |
| const result: TopoResultItem[] = []; | |
| componentModelConstructor.topologicalTravel( | |
| [a1, a2, m1], | |
| allList, | |
| function (componentType, dependencies) { | |
| result.push([componentType, dependencies]); | |
| } | |
| ); | |
| expect(result).toEqual([[a1, ['dataset']], [a2, ['dataset']], [m1, ['dataset', a2]]]); | |
| }); | |
| it('topologicalTravel_diamond', function () { | |
| const [m1, a1, a2, a3] = makeTypes(4); | |
| extendModel(a1, []); | |
| extendModel(a2, [a1]); | |
| extendModel(a3, [a1]); | |
| extendModel(m1, [a2, a3]); | |
| const allList = componentModelConstructor.getAllClassMainTypes(); | |
| const result: TopoResultItem[] = []; | |
| componentModelConstructor.topologicalTravel( | |
| [m1, a1, a2, a3], | |
| allList, | |
| function (componentType, dependencies) { | |
| result.push([componentType, dependencies]); | |
| } | |
| ); | |
| expect(result).toEqual( | |
| [[a1, ['dataset']], | |
| [a3, ['dataset', a1]], | |
| [a2, ['dataset', a1]], | |
| [m1, ['dataset', a2, a3]] | |
| ]); | |
| }); | |
| it('topologicalTravel_loop', function () { | |
| const [m1, m2, a1, a2, a3] = makeTypes(5); | |
| extendModel(m1, [a1, a2]); | |
| extendModel(m2, [m1, a2]); | |
| extendModel(a1, [m2, a2, a3]); | |
| extendModel(a2); | |
| extendModel(a3); | |
| const allList = componentModelConstructor.getAllClassMainTypes(); | |
| expect(function () { | |
| componentModelConstructor.topologicalTravel( | |
| [m1, m2, a1], | |
| allList, | |
| () => {} | |
| ); | |
| }).toThrowError(/Circular/); | |
| }); | |
| it('topologicalTravel_multipleEchartsInstance', function () { | |
| const [m1, m2, a1, a2] = makeTypes(4); | |
| extendModel(m1, [a1, a2]); | |
| extendModel(a1); | |
| extendModel(a2); | |
| let allList = componentModelConstructor.getAllClassMainTypes(); | |
| let result: TopoResultItem[] = []; | |
| componentModelConstructor.topologicalTravel( | |
| [m1, a1, a2], | |
| allList, | |
| function (componentType, dependencies) { | |
| result.push([componentType, dependencies]); | |
| } | |
| ); | |
| expect(result).toEqual([[a2, ['dataset']], [a1, ['dataset']], [m1, ['dataset', a1, a2]]]); | |
| result = []; | |
| extendModel(m2, [a1, m1]); | |
| allList = componentModelConstructor.getAllClassMainTypes(); | |
| componentModelConstructor.topologicalTravel( | |
| [m2, m1, a1, a2], | |
| allList, | |
| function (componentType, dependencies) { | |
| result.push([componentType, dependencies]); | |
| } | |
| ); | |
| expect(result).toEqual( | |
| [[a2, ['dataset']], [a1, ['dataset']], [m1, ['dataset', a1, a2]], [m2, ['dataset', a1, m1]]] | |
| ); | |
| }); | |
| it('topologicalTravel_missingSomeNodeButHasDependencies', function () { | |
| const [m1, a1, a2, a3, a4] = makeTypes(5); | |
| extendModel(m1, [a1, a2]); | |
| extendModel(a2, [a3]); | |
| extendModel(a3); | |
| extendModel(a4); | |
| let result: TopoResultItem[] = []; | |
| let allList = componentModelConstructor.getAllClassMainTypes(); | |
| componentModelConstructor.topologicalTravel( | |
| [a3, m1], | |
| allList, | |
| function (componentType, dependencies) { | |
| result.push([componentType, dependencies]); | |
| } | |
| ); | |
| expect(result).toEqual([[a3, ['dataset']], [a2, ['dataset', a3]], [m1, ['dataset', a1, a2]]]); | |
| result = []; | |
| allList = componentModelConstructor.getAllClassMainTypes(); | |
| componentModelConstructor.topologicalTravel( | |
| [m1, a3], | |
| allList, | |
| function (componentType, dependencies) { | |
| result.push([componentType, dependencies]); | |
| } | |
| ); | |
| expect(result).toEqual([[a3, ['dataset']], [a2, ['dataset', a3]], [m1, ['dataset', a1, a2]]]); | |
| }); | |
| it('topologicalTravel_subType', function () { | |
| const [m1, a1, a2, a3, a4] = makeTypes(5); | |
| extendModel(m1, [a1, a2]); | |
| extendModel(a1 + '.aaa', [a2]); | |
| extendModel(a1 + '.bbb', [a3, a4]); | |
| extendModel(a2); | |
| extendModel(a3); | |
| extendModel(a4); | |
| const result: TopoResultItem[] = []; | |
| const allList = componentModelConstructor.getAllClassMainTypes(); | |
| componentModelConstructor.topologicalTravel( | |
| [m1, a1, a2, a4], | |
| allList, | |
| function (componentType, dependencies) { | |
| result.push([componentType, dependencies]); | |
| } | |
| ); | |
| expect(result).toEqual( | |
| [[a4, ['dataset']], | |
| [a2, ['dataset']], | |
| [a1, ['dataset', a2, a3, a4]], | |
| [m1, ['dataset', a1, a2]] | |
| ]); | |
| }); | |
| }); |