diff --git a/src/views/Graph.vue b/src/views/Graph.vue index 8d3c012d8..1bfb45323 100644 --- a/src/views/Graph.vue +++ b/src/views/Graph.vue @@ -622,17 +622,6 @@ export default { }) return nodesFiltered }, - checkForNode (nodeName, cyclePoint, nodes) { - // checks the 'edges' array to see if edge is present - const nodePath = this.workflowIDs[0] - const nodeId = `${nodePath}//${cyclePoint}/${nodeName}` - const nodeSearch = nodes.find((node) => { return node.id === nodeId }) - if (nodeSearch === -1) { - return null - } else { - return nodeSearch - } - }, createEdge (edgeType, sourceName, targetName, sourceCyclePoint, targetCyclePoint) { // adds a new edge object to 'edges' array const edgePath = this.workflowIDs[0] @@ -722,20 +711,6 @@ export default { }) return edgesFiltered }, - checkForEdge (sourceName, targetName, cyclePoint, edges) { - const edgePath = this.workflowIDs[0] - const edgeSearchTerm = `${edgePath}//$edge|${cyclePoint}/${sourceName}|${cyclePoint}/${targetName}` - - const edgeSearch = edges.filter((edge) => { - const stringSearch = edge.id.indexOf(edgeSearchTerm) - if (stringSearch === -1) { - return false - } else { - return true - } - }) - return edgeSearch - }, checkForEdgeBySource (sourceName, cyclePoint, edges) { const edgePath = this.workflowIDs[0] const edgeSearchTerm = `${edgePath}//${cyclePoint}/${sourceName}` @@ -915,11 +890,6 @@ export default { return x }, {}) }, - getNodeByFamilyAndCycle (family, cycle) { - Object.values(this.cylcTree.$index).find((node) => { - return node.name === family && node.tokens.cycle === cycle - }) - }, addSubgraph (dotcode, pointer, graphSections) { pointer.children.forEach((key, i) => { const value = key diff --git a/tests/unit/views/graphv2utils.js b/tests/unit/views/graph-utils.js similarity index 51% rename from tests/unit/views/graphv2utils.js rename to tests/unit/views/graph-utils.js index c7d6ad377..ee1d362b7 100644 --- a/tests/unit/views/graphv2utils.js +++ b/tests/unit/views/graph-utils.js @@ -1,17 +1,19 @@ import { Tokens } from '@/utils/uid' -const nodeSuceeded = +const nodeSucceeded = { - id: 'user/one/run1//1/succeeded', + id: 'user/one/run1//2/succeeded', name: 'succeeded', node: { + name: 'succeeded', firstParent: { - id: 'user/one/run1//1/SUCCEEDED' + id: 'user/one/run1//2/SUCCEEDED' } }, tokens: { cycle: '2' - } + }, + children: [] } const nodeRetrying = @@ -19,27 +21,40 @@ const nodeRetrying = id: 'user/one/run1//1/retrying', name: 'retrying', node: { + name: 'retrying', firstParent: { id: 'user/one/run1//1/BAD' } }, tokens: { cycle: '1' - } + }, + children: [ + { + id: 'user/one/run1//1/retrying/01', + name: 'retrying', + }, + { + id: 'user/one/run1//1/retrying/02', + name: 'retrying', + } + ] } const nodeSleepy = { - id: 'user/one/run1//1/sleepy', + id: 'user/one/run1//2/sleepy', name: 'sleepy', node: { + name: 'sleepy', firstParent: { id: 'user/one/run1//1/root' } }, tokens: { cycle: '2' - } + }, + children: [] } const nodeFailed = @@ -47,13 +62,14 @@ const nodeFailed = id: 'user/one/run1//1/failed', name: 'failed', node: { + name: 'failed', firstParent: { id: 'user/one/run1//1/BAD' } }, tokens: { cycle: '1' - } + }, } const nodeNamespaceRoot = @@ -61,10 +77,12 @@ const nodeNamespaceRoot = id: 'user/one/run1//$namespace|root', name: 'root', node: { + name: 'root', parents: [], childFamilies: [{ name: 'GOOD' }, { name: 'BAD' }], childTasks: [{ name: 'checkpoint' }, { name: 'sleepy' }, { name: 'waiting' }] - } + }, + tokens: { cycle: undefined } } const nodeNamespaceBad = @@ -72,10 +90,12 @@ const nodeNamespaceBad = id: 'user/one/run1//$namespace|BAD', name: 'BAD', node: { + name: 'root', parents: [{ name: 'root' }], childFamilies: [], childTasks: [{ name: 'retrying' }, { name: 'failed' }] - } + }, + tokens: { cycle: undefined } } const nodeNamespaceGood = @@ -83,10 +103,12 @@ const nodeNamespaceGood = id: 'user/one/run1//$namespace|GOOD', name: 'GOOD', node: { + name: 'GOOD', parents: [{ name: 'root' }], childFamilies: [{ name: 'SUCCEEDED' }], childTasks: [{ name: 'retrying' }, { name: 'failed' }] - } + }, + tokens: { cycle: undefined } } const nodeNamespaceSucceeded = @@ -94,41 +116,90 @@ const nodeNamespaceSucceeded = id: 'user/one/run1//$namespace|SUCCEEDED', name: 'SUCCEEDED', node: { + name: 'GOOD', parents: [{ name: 'GOOD' }], childFamilies: [], childTasks: [{ name: 'succeeded' }, { name: 'eventually_succeeded' }] - } + }, + tokens: { cycle: undefined } } const workflows = [ { id: '~user/one', + node: { + firstParent: { + id: '' + } + }, children: [ { id: '~user/one//1', + tokens: { cycle: 1 }, + node: { + firstParent: { + id: '' + } + }, children: [ { id: '~user/one//1/eventually_succeeded', + tokens: { cycle: 1 }, + node: { + firstParent: { + id: 'user/one/run1//1/SUCCEEDED' + } + }, children: [ { id: '~user/one//1/eventually_succeeded/3', + tokens: { cycle: 1 }, + node: { + firstParent: { + id: 'user/one/run1//1/SUCCEEDED' + } + }, children: [], }, { id: '~user/one//1/eventually_succeeded/2', + tokens: { cycle: 1 }, + node: { + firstParent: { + id: 'user/one/run1//1/SUCCEEDED' + } + }, children: [], }, { id: '~user/one//1/eventually_succeeded/1', + tokens: { cycle: 1 }, + node: { + firstParent: { + id: 'user/one/run1//1/SUCCEEDED' + } + }, children: [], }, ], }, { id: '~user/one//1/failed', + tokens: { cycle: 1 }, + node: { + firstParent: { + id: 'user/one/run1//1/BAD' + } + }, children: [ { id: '~user/one//1/failed/1', + tokens: { cycle: 1 }, + node: { + firstParent: { + id: 'user/one/run1//1/BAD' + } + }, children: [], }, ], @@ -150,13 +221,49 @@ const nodes = [ nodeFailed, nodeRetrying, nodeSleepy, - nodeSuceeded + nodeSucceeded +] + +const edges = [ + { + id: 'user/one/run1//$edge|1/succeeded|1/failed', + name: 'user/one/run1//$edge|1/succeeded|1/failed', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|1/succeeded|1/failed', + source: 'user/one/run1//1/succeeded', + target: 'user/one/run1//1/failed', + __typename: 'Edge' + } + }, + { + id: 'user/one/run1//$edge|1/failed|1/checkpoint', + name: 'user/one/run1//$edge|1/failed|1/checkpoint', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|1/failed|1/checkpoint', + source: 'user/one/run1//1/failed', + target: 'user/one/run1//1/checkpoint', + __typename: 'Edge' + } + }, + { + id: 'user/one/run1//$edge|2/sleepy|1/failed', + name: 'user/one/run1//$edge|2/sleepy|1/failed', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|2/sleepy|1/failed', + source: 'user/one/run1//2/sleepy', + target: 'user/one/run1//1/failed', + __typename: 'Edge' + } + } ] const cylcTree = { $index: { - 'user/one/run1//1/succeeded': nodeSuceeded, - 'user/one/run1//1/sleepy': nodeSleepy, + 'user/one/run1//1/succeeded': nodeSucceeded, + 'user/one/run1//2/sleepy': nodeSleepy, 'user/one/run1//1/retrying': nodeRetrying, 'user/one/run1//1/failed': nodeFailed, 'user/one/run1//$namespace|root': nodeNamespaceRoot, @@ -166,23 +273,6 @@ const cylcTree = { } } -// const getFamilies = (nodes) => { -// if (!groupFamily) return -// return nodes.reduce((x, y) => { -// if (y.node.firstParent) { -// (x[y.node.firstParent.id.split('/')[y.node.firstParent.id.split('/').length - 1]] ||= []).push(y) -// } -// return x -// }, {}) -// } - -const getCycles = (nodes) => { - return nodes.reduce((x, y) => { - (x[y.tokens.cycle] ||= []).push(y) - return x - }, {}) -} - const namespaces = () => { return workflows[0]?.$namespaces || [] } @@ -190,8 +280,7 @@ const namespaces = () => { export { workflows, nodes, + edges, cylcTree, - // getFamilies, - getCycles, namespaces } diff --git a/tests/unit/views/graph.vue.spec.js b/tests/unit/views/graph.vue.spec.js new file mode 100644 index 000000000..54caa161e --- /dev/null +++ b/tests/unit/views/graph.vue.spec.js @@ -0,0 +1,624 @@ +/* Copyright (C) NIWA & British Crown (Met Office) & Contributors. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ + +import { mount } from '@vue/test-utils' +import { createStore } from 'vuex' +import sinon from 'sinon' +import storeOptions from '@/store/options' +import Graph from '@/views/Graph.vue' +import User from '@/model/User.model' +import WorkflowService from '@/services/workflow.service' +import { workflows, cylcTree, nodes, edges, namespaces } from './graph-utils.js' + +chai.config.truncateThreshold = 0 + +describe('Graph view', () => { + let store, $workflowService + beforeEach(() => { + store = createStore(storeOptions) + const user = new User({ username: 'cylc', permissions: [], owner: 'owner' }) + store.commit('user/SET_USER', user) + $workflowService = sinon.createStubInstance(WorkflowService) + sinon.stub(Graph.methods, 'mountSVGPanZoom') + }) + afterEach(() => { sinon.restore() }) + + it('gets cycles', async () => { + const wrapper = mount(Graph, { + shallow: true, + global: { + plugins: [store], + mocks: { $workflowService } + }, + props: { + workflowName: 'one', + }, + computed: { + workflows () { + return workflows + }, + namespaces () { + return namespaces() + }, + cylcTree () { + return cylcTree + } + } + }) + + expect(wrapper.vm.getCycles(nodes)).toMatchObject( + { + 1: [ + { + id: 'user/one/run1//1/failed', + name: 'failed', + node: { + firstParent: { + id: 'user/one/run1//1/BAD' + } + }, + tokens: { + cycle: '1' + } + }, + { + id: 'user/one/run1//1/retrying', + name: 'retrying', + node: { + firstParent: { + id: 'user/one/run1//1/BAD' + } + }, + tokens: { + cycle: '1' + } + } + ], + 2: [ + { + id: 'user/one/run1//2/sleepy', + name: 'sleepy', + node: { + firstParent: { + id: 'user/one/run1//1/root' + } + }, + tokens: { + cycle: '2' + } + }, + { + id: 'user/one/run1//2/succeeded', + name: 'succeeded', + node: { + firstParent: { + id: 'user/one/run1//2/SUCCEEDED' + } + }, + tokens: { + cycle: '2' + } + } + ] + } + ) + }) + + it('it gets families', async () => { + const wrapper = mount(Graph, { + shallow: true, + global: { + plugins: [store], + mocks: { $workflowService } + }, + props: { + workflowName: 'one', + }, + computed: { + workflows () { + return workflows + }, + namespaces () { + return namespaces() + }, + cylcTree () { + return cylcTree + } + } + }) + + expect(wrapper.vm.getFamilies(nodes)).toMatchObject( + { + BAD: [ + { + id: 'user/one/run1//1/failed', + name: 'failed', + node: { + firstParent: { + id: 'user/one/run1//1/BAD' + } + }, + tokens: { + cycle: '1' + } + }, + { + id: 'user/one/run1//1/retrying', + name: 'retrying', + node: { + firstParent: { + id: 'user/one/run1//1/BAD' + } + }, + tokens: { + cycle: '1' + } + } + ], + SUCCEEDED: [ + { + id: 'user/one/run1//2/succeeded', + name: 'succeeded', + node: { + firstParent: { + id: 'user/one/run1//2/SUCCEEDED' + } + }, + tokens: { + cycle: '2' + } + } + ], + root: [ + { + id: 'user/one/run1//2/sleepy', + name: 'sleepy', + node: { + firstParent: { + id: 'user/one/run1//1/root' + } + }, + tokens: { + cycle: '2' + } + } + ] + } + ) + }) + + it('it gets all children look up object', async () => { + const wrapper = mount(Graph, { + shallow: true, + global: { + plugins: [store], + mocks: { $workflowService } + }, + props: { + workflowName: 'one', + }, + computed: { + workflows () { + return workflows + }, + namespaces () { + return namespaces() + }, + cylcTree () { + return cylcTree + } + } + }) + + wrapper.vm.getAllChildrenLookUp() + + expect(wrapper.vm.allChilderenLookUp).toMatchObject( + { + 'user/one/run1//$namespace|BAD': [ + { + children: undefined, + id: 'user/one/run1//$namespace|BAD', + name: 'BAD' + } + ], + 'user/one/run1//$namespace|GOOD': [ + { + children: undefined, + id: 'user/one/run1//$namespace|GOOD', + name: 'GOOD' + } + ], + 'user/one/run1//$namespace|SUCCEEDED': [ + { + children: undefined, + id: 'user/one/run1//$namespace|SUCCEEDED', + name: 'SUCCEEDED' + } + ], + 'user/one/run1//$namespace|root': [ + { + children: undefined, + id: 'user/one/run1//$namespace|root', + name: 'root' + } + ], + 'user/one/run1//1/failed': [ + { + children: undefined, + id: 'user/one/run1//1/failed', + name: 'failed' + } + ], + 'user/one/run1//1/retrying': [ + { + children: [ + { + id: 'user/one/run1//1/retrying/01', + name: 'retrying' + }, + { + id: 'user/one/run1//1/retrying/02', + name: 'retrying' + } + ], + id: 'user/one/run1//1/retrying', + name: 'retrying', + }, + { + id: 'user/one/run1//1/retrying/01', + name: 'retrying', + children: undefined + }, + { + id: 'user/one/run1//1/retrying/02', + name: 'retrying', + children: undefined + } + ] + } + ) + }) + + it('it gets all parents look up object', async () => { + const wrapper = mount(Graph, { + shallow: true, + global: { + plugins: [store], + mocks: { $workflowService } + }, + props: { + workflowName: 'one', + }, + computed: { + workflows () { + return workflows + }, + namespaces () { + return namespaces() + }, + cylcTree () { + return cylcTree + } + } + }) + + wrapper.vm.getAllParentLookUp() + + expect(wrapper.vm.allParentLookUp).toMatchObject( + { + BAD: ['root'], + GOOD: ['root'], + SUCCEEDED: ['GOOD', 'root'], + root: [] + } + ) + }) + + it('it gets tree', async () => { + const wrapper = mount(Graph, { + shallow: true, + global: { + plugins: [store], + mocks: { $workflowService } + }, + props: { + workflowName: 'one', + }, + computed: { + workflows () { + return workflows + }, + namespaces () { + return namespaces() + }, + cylcTree () { + return cylcTree + } + } + }) + + // wrapper.vm.nextTick() + expect(wrapper.vm.getTree()).toMatchObject( + [ + { + children: [ + { + children: [], + disabled: false, + id: 3, + name: 'SUCCEEDED', + }, + ], + disabled: false, + id: 2, + name: 'GOOD', + }, + { + children: [], + disabled: false, + id: 4, + name: 'BAD', + }, + ] + ) + }) + + it('it gets checks for edge by source', async () => { + const wrapper = mount(Graph, { + shallow: true, + global: { + plugins: [store], + mocks: { $workflowService } + }, + props: { + workflowName: 'one', + }, + computed: { + workflows () { + return workflows + }, + namespaces () { + return namespaces() + }, + cylcTree () { + return cylcTree + }, + workflowIDs () { + return ['user/one/run1'] + } + } + }) + expect(wrapper.vm.checkForEdgeBySource('failed', '1', edges)).toMatchObject( + [ + { + id: 'user/one/run1//$edge|1/failed|1/checkpoint', + name: 'user/one/run1//$edge|1/failed|1/checkpoint', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|1/failed|1/checkpoint', + source: 'user/one/run1//1/failed', + target: 'user/one/run1//1/checkpoint', + __typename: 'Edge' + } + } + ] + ) + }) + + it('it gets checks for edge by target', async () => { + const wrapper = mount(Graph, { + shallow: true, + global: { + plugins: [store], + mocks: { $workflowService } + }, + props: { + workflowName: 'one', + }, + computed: { + workflows () { + return workflows + }, + namespaces () { + return namespaces() + }, + cylcTree () { + return cylcTree + }, + workflowIDs () { + return ['user/one/run1'] + } + } + }) + expect(wrapper.vm.checkForEdgeByTarget('checkpoint', '1', edges)).toMatchObject( + [ + { + id: 'user/one/run1//$edge|1/failed|1/checkpoint', + name: 'user/one/run1//$edge|1/failed|1/checkpoint', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|1/failed|1/checkpoint', + source: 'user/one/run1//1/failed', + target: 'user/one/run1//1/checkpoint', + __typename: 'Edge' + } + } + ] + ) + }) + + it('it removes edge node by source', async () => { + const wrapper = mount(Graph, { + shallow: true, + global: { + plugins: [store], + mocks: { $workflowService } + }, + props: { + workflowName: 'one', + }, + computed: { + workflows () { + return workflows + }, + namespaces () { + return namespaces() + }, + cylcTree () { + return cylcTree + }, + workflowIDs () { + return ['user/one/run1'] + } + } + }) + // in this test we remove the first edge with a source of 'user/one/run1//1/sleepy' + wrapper.vm.getAllChildrenLookUp() + const config = wrapper.vm.allChilderenLookUp['user/one/run1//2/sleepy'][0] + const edgeCheckSource = wrapper.vm.checkForEdgeBySource(config.name, '2', edges) + const removedEdges = [] + + expect(wrapper.vm.removeEdgeBySource(edgeCheckSource, edges, removedEdges, config, '2')).toMatchObject( + [ + // the returned edges array with the edge removed + [ + { + id: 'user/one/run1//$edge|1/succeeded|1/failed', + name: 'user/one/run1//$edge|1/succeeded|1/failed', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|1/succeeded|1/failed', + source: 'user/one/run1//1/succeeded', + target: 'user/one/run1//1/failed', + __typename: 'Edge' + } + }, + { + id: 'user/one/run1//$edge|1/failed|1/checkpoint', + name: 'user/one/run1//$edge|1/failed|1/checkpoint', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|1/failed|1/checkpoint', + source: 'user/one/run1//1/failed', + target: 'user/one/run1//1/checkpoint', + __typename: 'Edge' + } + } + ], + // the returned removed edges array + [ + { + id: 'user/one/run1//$edge|2/sleepy|1/failed', + name: 'user/one/run1//$edge|2/sleepy|1/failed', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|2/sleepy|1/failed', + source: 'user/one/run1//2/sleepy', + target: 'user/one/run1//1/failed', + __typename: 'Edge' + } + } + ] + ] + ) + }) + + it('it removes edge node by target', async () => { + const wrapper = mount(Graph, { + shallow: true, + global: { + plugins: [store], + mocks: { $workflowService } + }, + props: { + workflowName: 'one', + }, + computed: { + workflows () { + return workflows + }, + namespaces () { + return namespaces() + }, + cylcTree () { + return cylcTree + }, + workflowIDs () { + return ['user/one/run1'] + } + } + }) + // in this test we remove the first edge with a target of 'user/one/run1//1/failed' + wrapper.vm.getAllChildrenLookUp() + const config = wrapper.vm.allChilderenLookUp['user/one/run1//1/failed'][0] + const edgeCheckTarget = wrapper.vm.checkForEdgeByTarget(config.name, '1', edges) + const removedEdges = [] + + expect(wrapper.vm.removeEdgeByTarget(edgeCheckTarget, edges, removedEdges)).toMatchObject( + [ + // the returned edges array with the edge removed + [ + { + id: 'user/one/run1//$edge|1/succeeded|1/failed', + name: 'user/one/run1//$edge|1/succeeded|1/failed', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|1/succeeded|1/failed', + source: 'user/one/run1//1/succeeded', + target: 'user/one/run1//1/failed', + __typename: 'Edge' + } + }, + { + id: 'user/one/run1//$edge|1/failed|1/checkpoint', + name: 'user/one/run1//$edge|1/failed|1/checkpoint', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|1/failed|1/checkpoint', + source: 'user/one/run1//1/failed', + target: 'user/one/run1//1/checkpoint', + __typename: 'Edge' + } + } + ], + // the returned removed edges array + [ + { + id: 'user/one/run1//$edge|1/succeeded|1/failed', + name: 'user/one/run1//$edge|1/succeeded|1/failed', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|1/succeeded|1/failed', + source: 'user/one/run1//1/succeeded', + target: 'user/one/run1//1/failed', + __typename: 'Edge' + } + }, + { + id: 'user/one/run1//$edge|2/sleepy|1/failed', + name: 'user/one/run1//$edge|2/sleepy|1/failed', + parent: 'user/one/run1', + node: { + id: 'user/one/run1//$edge|2/sleepy|1/failed', + source: 'user/one/run1//2/sleepy', + target: 'user/one/run1//1/failed', + __typename: 'Edge' + } + } + ] + ] + ) + }) +}) diff --git a/tests/unit/views/graphv2.vue.spec.js b/tests/unit/views/graphv2.vue.spec.js deleted file mode 100644 index 971705438..000000000 --- a/tests/unit/views/graphv2.vue.spec.js +++ /dev/null @@ -1,206 +0,0 @@ -/* Copyright (C) NIWA & British Crown (Met Office) & Contributors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . */ - -import { workflows, cylcTree, nodes, namespaces, getCycles } from './graphv2utils.js' - -chai.config.truncateThreshold = 0 - -let groupFamily -const getFamilies = (nodes) => { - if (!groupFamily) return - return nodes.reduce((x, y) => { - if (y.node.firstParent) { - (x[y.node.firstParent.id.split('/')[y.node.firstParent.id.split('/').length - 1]] ||= []).push(y) - } - return x - }, {}) -} - -let allParentLookUp = {} -const namespaces2 = namespaces() - -const getAllParentLookUp = () => { - allParentLookUp = {} - namespaces2.forEach((namespace) => { - const array = [] - let parents = namespace.node.parents - while (parents.length) { - parents.forEach((parent) => { - const childTokens = workflows[0].tokens.clone({ cycle: `$namespace|${parent.name}` }) - const childNode = cylcTree.$index[childTokens.id] - array.push(childNode.name) - parents = childNode.node.parents - }) - } - allParentLookUp[namespace.name] = array - }) - return allParentLookUp -} - -describe('Graph view', () => { - it('gets namespaces', async () => { - expect(namespaces()).toMatchObject([ - { - id: 'user/one/run1//$namespace|BAD', - name: 'BAD' - }, - { - id: 'user/one/run1//$namespace|GOOD', - name: 'GOOD' - }, - { - id: 'user/one/run1//$namespace|root', - name: 'root' - }, - { - id: 'user/one/run1//$namespace|SUCCEEDED', - name: 'SUCCEEDED' - }, - ]) - }) - - it('gets families', async () => { - expect(getFamilies(nodes)).toMatchObject(undefined) - groupFamily = ['GOOD'] - expect(getFamilies(nodes)).toMatchObject( - { - BAD: [ - { - id: 'user/one/run1//1/failed', - name: 'failed', - node: { - firstParent: { - id: 'user/one/run1//1/BAD' - } - }, - tokens: { - cycle: '1' - } - }, - { - id: 'user/one/run1//1/retrying', - name: 'retrying', - node: { - firstParent: { - id: 'user/one/run1//1/BAD' - } - }, - tokens: { - cycle: '1' - } - } - ], - SUCCEEDED: [ - { - id: 'user/one/run1//1/succeeded', - name: 'succeeded', - node: { - firstParent: { - id: 'user/one/run1//1/SUCCEEDED' - } - }, - tokens: { - cycle: '2' - } - } - ], - root: [ - { - id: 'user/one/run1//1/sleepy', - name: 'sleepy', - node: { - firstParent: { - id: 'user/one/run1//1/root' - } - }, - tokens: { - cycle: '2' - } - } - ] - } - ) - }) - - it('gets cycles', async () => { - expect(getCycles(nodes)).toMatchObject( - { - 1: [ - { - id: 'user/one/run1//1/failed', - name: 'failed', - node: { - firstParent: { - id: 'user/one/run1//1/BAD' - } - }, - tokens: { - cycle: '1' - } - }, - { - id: 'user/one/run1//1/retrying', - name: 'retrying', - node: { - firstParent: { - id: 'user/one/run1//1/BAD' - } - }, - tokens: { - cycle: '1' - } - } - ], - 2: [ - { - id: 'user/one/run1//1/sleepy', - name: 'sleepy', - node: { - firstParent: { - id: 'user/one/run1//1/root' - } - }, - tokens: { - cycle: '2' - } - }, - { - id: 'user/one/run1//1/succeeded', - name: 'succeeded', - node: { - firstParent: { - id: 'user/one/run1//1/SUCCEEDED' - } - }, - tokens: { - cycle: '2' - } - } - ] - }, - ) - }) - - it('gets allParentLookUp', async () => { - expect(getAllParentLookUp()).toMatchObject( - { - BAD: ['root'], - GOOD: ['root'], - root: [], - SUCCEEDED: ['GOOD', 'root'] - } - ) - }) -})