import { Logger } from '@stryker-mutator/api/logging'; import { FileDescriptions, StrykerOptions } from '@stryker-mutator/api/core'; import { I, normalizeWhitespaces, propertyPath } from '@stryker-mutator/util'; import { MutationTestResult } from 'mutation-testing-report-schema'; import { FileSystem } from './file-system.js'; import { ProjectFile } from './project-file.js'; /** * Represents the project that is under test by Stryker users. * This represents the files in the current working directory. * Each file can be read into memory when needed (via `readContent`) */ export class Project { public readonly files = new Map(); public readonly filesToMutate = new Map(); constructor( fs: I, public readonly fileDescriptions: FileDescriptions, public readonly incrementalReport?: MutationTestResult, ) { Object.entries(fileDescriptions).forEach(([name, desc]) => { const file = new ProjectFile(fs, name, desc.mutate); this.files.set(name, file); if (desc.mutate) { this.filesToMutate.set(name, file); } }); } public get isEmpty(): boolean { return this.files.size === 0; } public logFiles(log: Logger, ignoreRules: readonly string[], force: boolean, mutatePatterns: readonly string[]): void { if (this.isEmpty) { log.warn( normalizeWhitespaces(`No files found in directory ${process.cwd()} using ignore rules: ${JSON.stringify(ignoreRules)}. Make sure you run Stryker from the root directory of your project with the correct "${propertyPath()('ignorePatterns')}".`), ); } else { if (this.filesToMutate.size) { const incrementalInfo = this.incrementalReport ? ` using incremental report with ${Object.values(this.incrementalReport.files).reduce( (total, { mutants }) => total + mutants.length, 0, )} mutant(s), and ${Object.values(this.incrementalReport.testFiles ?? {}).reduce((total, { tests }) => total + tests.length, 0)} test(s)${ force ? '. Force mode is activated, all mutants will be retested' : '' }` : ''; log.info(`Found ${this.filesToMutate.size} of ${this.files.size} file(s) to be mutated${incrementalInfo}.`); } else { const msg = normalizeWhitespaces(`Warning: No files found for mutation with the given glob expressions. As a result, a dry-run will be performed without actually modifying anything. If you intended to mutate files, please check and adjust the configuration. Current glob pattern(s) used: ${mutatePatterns.map((pattern) => `"${pattern}"`).join(', ')}. To enable file mutation, consider configuring the \`${propertyPath()( 'mutate', )}\` property in your configuration file or using the --mutate option via the command line.`); log.warn(msg); } if (log.isDebugEnabled()) { log.debug(`All input files: ${JSON.stringify([...this.files.keys()], null, 2)}`); log.debug(`Files to mutate: ${JSON.stringify([...this.filesToMutate.keys()], null, 2)}`); } } } }