diff options
Diffstat (limited to 'spec/frontend/pipelines/components/dag/parsing_utils_spec.js')
-rw-r--r-- | spec/frontend/pipelines/components/dag/parsing_utils_spec.js | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/spec/frontend/pipelines/components/dag/parsing_utils_spec.js b/spec/frontend/pipelines/components/dag/parsing_utils_spec.js new file mode 100644 index 00000000000..d9a1296e572 --- /dev/null +++ b/spec/frontend/pipelines/components/dag/parsing_utils_spec.js @@ -0,0 +1,133 @@ +import { + createNodesStructure, + makeLinksFromNodes, + filterByAncestors, + parseData, + removeOrphanNodes, + getMaxNodes, +} from '~/pipelines/components/dag/parsing_utils'; + +import { createSankey } from '~/pipelines/components/dag/drawing_utils'; +import { mockBaseData } from './mock_data'; + +describe('DAG visualization parsing utilities', () => { + const { nodes, nodeDict } = createNodesStructure(mockBaseData.stages); + const unfilteredLinks = makeLinksFromNodes(nodes, nodeDict); + const parsed = parseData(mockBaseData.stages); + + const layoutSettings = { + width: 200, + height: 200, + nodeWidth: 10, + nodePadding: 20, + paddingForLabels: 100, + }; + + const sankeyLayout = createSankey(layoutSettings)(parsed); + + describe('createNodesStructure', () => { + const parallelGroupName = 'jest'; + const parallelJobName = 'jest 1/2'; + const singleJobName = 'frontend fixtures'; + + const { name, jobs, size } = mockBaseData.stages[0].groups[0]; + + it('returns the expected node structure', () => { + expect(nodes[0]).toHaveProperty('category', mockBaseData.stages[0].name); + expect(nodes[0]).toHaveProperty('name', name); + expect(nodes[0]).toHaveProperty('jobs', jobs); + expect(nodes[0]).toHaveProperty('size', size); + }); + + it('adds needs to top level of nodeDict entries', () => { + expect(nodeDict[parallelGroupName]).toHaveProperty('needs'); + expect(nodeDict[parallelJobName]).toHaveProperty('needs'); + expect(nodeDict[singleJobName]).toHaveProperty('needs'); + }); + + it('makes entries in nodeDict for jobs and parallel jobs', () => { + const nodeNames = Object.keys(nodeDict); + + expect(nodeNames.includes(parallelGroupName)).toBe(true); + expect(nodeNames.includes(parallelJobName)).toBe(true); + expect(nodeNames.includes(singleJobName)).toBe(true); + }); + }); + + describe('makeLinksFromNodes', () => { + it('returns the expected link structure', () => { + expect(unfilteredLinks[0]).toHaveProperty('source', 'frontend fixtures'); + expect(unfilteredLinks[0]).toHaveProperty('target', 'jest'); + expect(unfilteredLinks[0]).toHaveProperty('value', 10); + }); + }); + + describe('filterByAncestors', () => { + const allLinks = [ + { source: 'job1', target: 'job4' }, + { source: 'job1', target: 'job2' }, + { source: 'job2', target: 'job4' }, + ]; + + const dedupedLinks = [{ source: 'job1', target: 'job2' }, { source: 'job2', target: 'job4' }]; + + const nodeLookup = { + job1: { + name: 'job1', + }, + job2: { + name: 'job2', + needs: ['job1'], + }, + job4: { + name: 'job4', + needs: ['job1', 'job2'], + category: 'build', + }, + }; + + it('dedupes links', () => { + expect(filterByAncestors(allLinks, nodeLookup)).toMatchObject(dedupedLinks); + }); + }); + + describe('parseData parent function', () => { + it('returns an object containing a list of nodes and links', () => { + // an array of nodes exist and the values are defined + expect(parsed).toHaveProperty('nodes'); + expect(Array.isArray(parsed.nodes)).toBe(true); + expect(parsed.nodes.filter(Boolean)).not.toHaveLength(0); + + // an array of links exist and the values are defined + expect(parsed).toHaveProperty('links'); + expect(Array.isArray(parsed.links)).toBe(true); + expect(parsed.links.filter(Boolean)).not.toHaveLength(0); + }); + }); + + describe('removeOrphanNodes', () => { + it('removes sankey nodes that have no needs and are not needed', () => { + const cleanedNodes = removeOrphanNodes(sankeyLayout.nodes); + expect(cleanedNodes).toHaveLength(sankeyLayout.nodes.length - 1); + }); + }); + + describe('getMaxNodes', () => { + it('returns the number of nodes in the most populous generation', () => { + const layerNodes = [ + { layer: 0 }, + { layer: 0 }, + { layer: 1 }, + { layer: 1 }, + { layer: 0 }, + { layer: 3 }, + { layer: 2 }, + { layer: 4 }, + { layer: 1 }, + { layer: 3 }, + { layer: 4 }, + ]; + expect(getMaxNodes(layerNodes)).toBe(3); + }); + }); +}); |