diff --git a/libs/core/src/true-affected.spec.ts b/libs/core/src/true-affected.spec.ts index 3153868..35f6adb 100644 --- a/libs/core/src/true-affected.spec.ts +++ b/libs/core/src/true-affected.spec.ts @@ -459,6 +459,10 @@ describe('trueAffected', () => { filePath: 'proj1/index.ts', changedLines: [2], }, + { + filePath: 'proj2/index.ts', + changedLines: [6], + }, ]; jest.spyOn(git, 'getChangedFiles').mockReturnValue(changedFiles); @@ -512,10 +516,26 @@ describe('trueAffected', () => { `Added package proj1 to affected packages for changed line ${changedFiles[0].changedLines[0]} in ${changedFiles[0].filePath}` ); expect(debug).toHaveBeenCalledWith( - expect.stringMatching( - new RegExp(`^Found identifier .* in .*${changedFiles[0].filePath}$`) - ) + `Added package proj2 to affected packages for changed line ${changedFiles[1].changedLines[0]} in ${changedFiles[1].filePath}` + ); + + const project1VisitingLogs = debug.mock.calls.filter( + ([arg]) => expect.stringMatching( + new RegExp(`^Visiting .* in .*${changedFiles[0].filePath}$`) + ).asymmetricMatch(arg) ); + + expect(project1VisitingLogs).toHaveLength(1); + + const project2VisitingLogs = debug.mock.calls.filter( + ([arg]) => expect.stringMatching( + new RegExp(`^Visiting .* in .*${changedFiles[1].filePath}$`) + ).asymmetricMatch(arg) + ); + // would have duplicates if visited multiple times + const uniqueProject2VisitingLogs = new Set(project2VisitingLogs.map(([arg]) => arg)); + expect(uniqueProject2VisitingLogs.size).toBe(project2VisitingLogs.length); + expect(debug).toHaveBeenCalledWith( 'Added package proj2 to affected packages' ); diff --git a/libs/core/src/true-affected.ts b/libs/core/src/true-affected.ts index 8ccbde2..3acfdcf 100644 --- a/libs/core/src/true-affected.ts +++ b/libs/core/src/true-affected.ts @@ -240,7 +240,7 @@ export const trueAffected = async ({ } const affectedPackages = new Set(changedIncludedFilesPackages); - const visitedIdentifiers = new Map(); + const visitedIdentifiers = new Map>(); const findReferencesLibs = (node: Node) => { const rootNode = findRootNode(node); @@ -269,7 +269,6 @@ export const trueAffected = async ({ /* istanbul ignore next */ if (identifier == null) return; - const refs = identifier.findReferencesAsNodes(); const identifierName = identifier.getText(); const path = rootNode.getSourceFile().getFilePath(); @@ -278,8 +277,11 @@ export const trueAffected = async ({ ); if (identifierName && path) { - const visited = visitedIdentifiers.get(path) ?? []; - if (visited.includes(identifierName)) { + if (!visitedIdentifiers.has(path)) { + visitedIdentifiers.set(path, new Set()); + } + const visited = visitedIdentifiers.get(path)!; + if (visited.has(identifierName)) { logger.debug( `Already visited ${chalk.bold(identifierName)} in ${chalk.bold(path)}` ); @@ -287,13 +289,15 @@ export const trueAffected = async ({ return; } - visitedIdentifiers.set(path, [...visited, identifierName]); + visited.add(identifierName); logger.debug( `Visiting ${chalk.bold(identifierName)} in ${chalk.bold(path)}` ); } + const refs = identifier.findReferencesAsNodes(); + refs.forEach((node) => { const sourceFile = node.getSourceFile(); const pkg = getPackageNameByPath(sourceFile.getFilePath(), projects);