-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(js): Enhance unit test of topological sorting of project nodes
- Loading branch information
Showing
1 changed file
with
177 additions
and
96 deletions.
There are no files selected for viewing
273 changes: 177 additions & 96 deletions
273
packages/js/src/generators/release-version/utils/sort-projects-topologically.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,114 +1,195 @@ | ||
import { sortProjectsTopologically } from './sort-projects-topologically'; | ||
import { DependencyType, StaticDependency } from '@nx/devkit'; | ||
|
||
describe('sortProjectsTopologically', () => { | ||
it('should return empty array if no projects are provided', () => { | ||
const projectGraph = { | ||
dependencies: {}, | ||
nodes: {}, | ||
}; | ||
const projectNodes = []; | ||
const result = sortProjectsTopologically(projectGraph, projectNodes); | ||
expect(result).toEqual([]); | ||
}); | ||
describe('edge cases', () => { | ||
it('should return empty array if no projects are provided', () => { | ||
const projectGraph = { | ||
dependencies: {}, | ||
nodes: {}, | ||
}; | ||
const projectNodes = []; | ||
const result = sortProjectsTopologically(projectGraph, projectNodes); | ||
expect(result).toEqual([]); | ||
}); | ||
|
||
it('should return a single project if only one project is provided', () => { | ||
const projectGraph = { | ||
dependencies: {}, | ||
nodes: { | ||
project1: { | ||
name: 'project1', | ||
data: { | ||
root: '', | ||
it('should return a single project if only one project is provided', () => { | ||
const projectGraph = { | ||
dependencies: {}, | ||
nodes: { | ||
project1: { | ||
name: 'project1', | ||
data: { | ||
root: '', | ||
}, | ||
type: 'app' as const, | ||
}, | ||
type: 'app' as const, | ||
}, | ||
}, | ||
}; | ||
const projectNodes = [projectGraph.nodes.project1]; | ||
const result = sortProjectsTopologically(projectGraph, projectNodes); | ||
expect(result).toEqual([projectGraph.nodes.project1]); | ||
}); | ||
}; | ||
const projectNodes = [projectGraph.nodes.project1]; | ||
const result = sortProjectsTopologically(projectGraph, projectNodes); | ||
expect(result).toEqual([projectGraph.nodes.project1]); | ||
}); | ||
|
||
it('should return projects in the correct order', () => { | ||
const projectGraph = { | ||
dependencies: { | ||
project1: [ | ||
{ | ||
source: 'project1', | ||
target: 'project2', | ||
type: 'static', | ||
}, | ||
], | ||
project2: [], | ||
}, | ||
nodes: { | ||
project1: { | ||
name: 'project1', | ||
data: { | ||
root: '', | ||
}, | ||
type: 'app' as const, | ||
it('should return the original list of nodes if a circular dependency is present', () => { | ||
const projectGraph = { | ||
dependencies: { | ||
project1: [ | ||
{ | ||
source: 'project1', | ||
target: 'project2', | ||
type: 'static', | ||
}, | ||
], | ||
project2: [ | ||
{ | ||
source: 'project2', | ||
target: 'project1', | ||
type: 'static', | ||
}, | ||
], | ||
}, | ||
project2: { | ||
name: 'project2', | ||
data: { | ||
root: '', | ||
nodes: { | ||
project1: { | ||
name: 'project1', | ||
data: { | ||
root: '', | ||
}, | ||
type: 'app' as const, | ||
}, | ||
project2: { | ||
name: 'project2', | ||
data: { | ||
root: '', | ||
}, | ||
type: 'app' as const, | ||
}, | ||
type: 'app' as const, | ||
}, | ||
}, | ||
}; | ||
const projectNodes = [ | ||
projectGraph.nodes.project1, | ||
projectGraph.nodes.project2, | ||
]; | ||
const result = sortProjectsTopologically(projectGraph, projectNodes); | ||
expect(result).toEqual([ | ||
projectGraph.nodes.project2, | ||
projectGraph.nodes.project1, | ||
]); | ||
}; | ||
const projectNodes = [ | ||
projectGraph.nodes.project1, | ||
projectGraph.nodes.project2, | ||
]; | ||
const result = sortProjectsTopologically(projectGraph, projectNodes); | ||
expect(result).toEqual(projectNodes); | ||
}); | ||
}); | ||
|
||
it('should return the original list of nodes if a circular dependency is present', () => { | ||
const projectGraph = { | ||
dependencies: { | ||
project1: [ | ||
{ | ||
source: 'project1', | ||
target: 'project2', | ||
type: 'static', | ||
}, | ||
], | ||
project2: [ | ||
{ | ||
source: 'project2', | ||
target: 'project1', | ||
type: 'static', | ||
describe('complex sorting cases', () => { | ||
it('should return [B,A] if A depends on B', () => { | ||
const projectGraph = { | ||
dependencies: { | ||
project1: [ | ||
{ | ||
source: 'project1', | ||
target: 'project2', | ||
type: 'static', | ||
}, | ||
], | ||
project2: [], | ||
}, | ||
nodes: { | ||
project1: { | ||
name: 'project1', | ||
data: { | ||
root: '', | ||
}, | ||
type: 'app' as const, | ||
}, | ||
], | ||
}, | ||
nodes: { | ||
project1: { | ||
name: 'project1', | ||
data: { | ||
root: '', | ||
project2: { | ||
name: 'project2', | ||
data: { | ||
root: '', | ||
}, | ||
type: 'app' as const, | ||
}, | ||
type: 'app' as const, | ||
}, | ||
project2: { | ||
name: 'project2', | ||
data: { | ||
root: '', | ||
}, | ||
type: 'app' as const, | ||
}; | ||
const projectNodes = [ | ||
projectGraph.nodes.project1, | ||
projectGraph.nodes.project2, | ||
]; | ||
const result = sortProjectsTopologically(projectGraph, projectNodes); | ||
expect(result).toEqual([ | ||
projectGraph.nodes.project2, | ||
projectGraph.nodes.project1, | ||
]); | ||
}); | ||
it('should return [C,B,A] if A depends on B and B depends on C', () => { | ||
const graphNodes = Object.fromEntries( | ||
[1, 2, 3].map((n) => { | ||
return [ | ||
`project${n}`, | ||
{ | ||
name: `project${n}`, | ||
data: { root: '' }, | ||
type: 'app' as const, | ||
}, | ||
]; | ||
}) | ||
); | ||
const projectGraph = { | ||
dependencies: { | ||
project1: staticDependencies('project1', ['project2']), | ||
project2: staticDependencies('project2', ['project3']), | ||
}, | ||
}, | ||
}; | ||
const projectNodes = [ | ||
projectGraph.nodes.project1, | ||
projectGraph.nodes.project2, | ||
]; | ||
const result = sortProjectsTopologically(projectGraph, projectNodes); | ||
expect(result).toEqual(projectNodes); | ||
nodes: graphNodes, | ||
}; | ||
const projectNodes = [1, 2, 3].map( | ||
(n) => projectGraph.nodes[`project${n}`] | ||
); | ||
const result = sortProjectsTopologically(projectGraph, projectNodes); | ||
expect(result).toEqual( | ||
[3, 2, 1].map((n) => projectGraph.nodes[`project${n}`]) | ||
); | ||
}); | ||
|
||
it('should return [A,B,C,D] if A has 0 dependencies, B has 1, C has 2, and D has 3', () => { | ||
const graphNodes = Object.fromEntries( | ||
[1, 2, 3, 4].map((n) => { | ||
return [ | ||
`project${n}`, | ||
{ | ||
name: `project${n}`, | ||
data: { root: '' }, | ||
type: 'app' as const, | ||
}, | ||
]; | ||
}) | ||
); | ||
const projectGraph = { | ||
dependencies: { | ||
project1: [], | ||
project2: staticDependencies('project2', ['project1']), | ||
project3: staticDependencies('project3', ['project1', 'project2']), | ||
project4: staticDependencies('project4', [ | ||
'project1', | ||
'project2', | ||
'project3', | ||
]), | ||
}, | ||
nodes: graphNodes, | ||
}; | ||
const projectNodes = [1, 2, 3, 4].map( | ||
(n) => projectGraph.nodes[`project${n}`] | ||
); | ||
const result = sortProjectsTopologically(projectGraph, projectNodes); | ||
expect(result).toEqual( | ||
[1, 2, 3, 4].map((n) => projectGraph.nodes[`project${n}`]) | ||
); | ||
}); | ||
}); | ||
}); | ||
|
||
function staticDependencies( | ||
source: string, | ||
targets: string[] | ||
): StaticDependency[] { | ||
return targets.map((target) => { | ||
return { | ||
source, | ||
target, | ||
type: DependencyType.static, | ||
}; | ||
}); | ||
} |