fix: 🐛 updated detectCircularDependency in DependencyGraph to return circular dependencies starting from the first node

Signed-off-by: Marley Powell <marley.powell@exclaimer.com>
This commit is contained in:
Marley Powell
2023-08-17 11:59:01 +01:00
parent 7a4ef5aff5
commit 1d12a7fa7d
2 changed files with 19 additions and 8 deletions
@@ -66,6 +66,17 @@ describe('DependencyGraph', () => {
).toEqual(['1', '2', '1']);
});
it('should detect a circular dep starting from the first node', async () => {
expect(
DependencyGraph.fromMap({
1: { provides: ['a'], consumes: ['b'] },
2: { provides: ['b'], consumes: ['c'] },
3: { provides: ['c'], consumes: ['d'] },
4: { provides: ['d'], consumes: ['a'] },
}).detectCircularDependency(),
).toEqual(['1', '2', '3', '4', '1']);
});
it('should detect a larger distant circular dep', async () => {
expect(
DependencyGraph.fromMap({
@@ -74,7 +85,7 @@ describe('DependencyGraph', () => {
3: { provides: ['c'], consumes: ['b'] },
4: { provides: ['d', 'e'], consumes: ['c', 'a'] },
}).detectCircularDependency(),
).toEqual(['2', '3', '4', '2']);
).toEqual(['2', '4', '3', '2']);
});
});
@@ -108,16 +108,16 @@ export class DependencyGraph<T> {
continue;
}
visited.add(node);
for (const produced of node.provides) {
const consumerNodes = this.#nodes.filter(other =>
other.consumes.has(produced),
for (const consumed of node.consumes) {
const providerNodes = this.#nodes.filter(other =>
other.provides.has(consumed),
);
for (const consumer of consumerNodes) {
if (consumer === startNode) {
for (const provider of providerNodes) {
if (provider === startNode) {
return [...path, startNode.value];
}
if (!visited.has(consumer)) {
stack.push([consumer, [...path, consumer.value]]);
if (!visited.has(provider)) {
stack.push([provider, [...path, provider.value]]);
}
}
}