Best JavaScript code snippet using stryker-parent
project-reader.ts
Source:project-reader.ts
1import path from 'path';2import { isDeepStrictEqual } from 'util';3import minimatch, { type Minimatch as IMinimatch } from 'minimatch';4import { StrykerOptions, FileDescriptions, FileDescription, Location, Position } from '@stryker-mutator/api/core';5import { Logger } from '@stryker-mutator/api/logging';6import { commonTokens, tokens } from '@stryker-mutator/api/plugin';7import { ERROR_CODES, I, isErrnoException } from '@stryker-mutator/util';8import type { MutationTestResult } from 'mutation-testing-report-schema/api';9import { OpenEndLocation } from 'mutation-testing-report-schema';10import { defaultOptions, FileMatcher } from '../config/index.js';11import { coreTokens } from '../di/index.js';12import { Project } from './project.js';13import { FileSystem } from './file-system.js';14const { Minimatch } = minimatch;15const ALWAYS_IGNORE = Object.freeze(['node_modules', '.git', '/reports', '*.tsbuildinfo', '/stryker.log']);16export const IGNORE_PATTERN_CHARACTER = '!';17/**18 * @see https://stryker-mutator.io/docs/stryker-js/configuration/#mutate-string19 * @example20 * * "src/app.js:1-11" will mutate lines 1 through 11 inside app.js.21 * * "src/app.js:5:4-6:4" will mutate from line 5, column 4 through line 6 column 4 inside app.js (columns 4 are included).22 * * "src/app.js:5-6:4" will mutate from line 5, column 0 through line 6 column 4 inside app.js (column 4 is included).23 */24export const MUTATION_RANGE_REGEX = /(.*?):((\d+)(?::(\d+))?-(\d+)(?::(\d+))?)$/;25export class ProjectReader {26 private readonly mutatePatterns: readonly string[];27 private readonly ignoreRules: readonly string[];28 private readonly incremental: boolean;29 private readonly force: boolean;30 private readonly incrementalFile: string;31 public static inject = tokens(coreTokens.fs, commonTokens.logger, commonTokens.options);32 constructor(33 private readonly fs: I<FileSystem>,34 private readonly log: Logger,35 { mutate, tempDirName, ignorePatterns, incremental, incrementalFile, force }: StrykerOptions36 ) {37 this.mutatePatterns = mutate;38 this.ignoreRules = [...ALWAYS_IGNORE, tempDirName, ...ignorePatterns];39 this.incremental = incremental;40 this.incrementalFile = incrementalFile;41 this.force = force;42 }43 public async read(): Promise<Project> {44 const inputFileNames = await this.resolveInputFileNames();45 const fileDescriptions = this.resolveFileDescriptions(inputFileNames);46 const project = new Project(this.fs, fileDescriptions, await this.readIncrementalReport());47 project.logFiles(this.log, this.ignoreRules, this.force);48 return project;49 }50 /**51 * Takes the list of file names and creates file description object from it, containing logic about wether or not it needs to be mutated.52 * If a mutate pattern starts with a `!`, it negates the pattern.53 * @param inputFileNames the file names to filter54 */55 private resolveFileDescriptions(inputFileNames: string[]): FileDescriptions {56 // Only log about useless patterns when the user actually configured it57 const logAboutUselessPatterns = !isDeepStrictEqual(this.mutatePatterns, defaultOptions.mutate);58 // Start out without files to mutate59 const mutateInputFileMap = new Map<string, FileDescription>();60 inputFileNames.forEach((fileName) => mutateInputFileMap.set(fileName, { mutate: false }));61 // Now lets see what we need to mutate62 for (const pattern of this.mutatePatterns) {63 if (pattern.startsWith(IGNORE_PATTERN_CHARACTER)) {64 const files = this.filterMutatePattern(mutateInputFileMap.keys(), pattern.substring(1));65 if (logAboutUselessPatterns && files.size === 0) {66 this.log.warn(`Glob pattern "${pattern}" did not exclude any files.`);67 }68 for (const fileName of files.keys()) {69 mutateInputFileMap.set(fileName, { mutate: false });70 }71 } else {72 const files = this.filterMutatePattern(inputFileNames, pattern);73 if (logAboutUselessPatterns && files.size === 0) {74 this.log.warn(`Glob pattern "${pattern}" did not result in any files.`);75 }76 for (const [fileName, file] of files) {77 mutateInputFileMap.set(fileName, this.mergeFileDescriptions(file, mutateInputFileMap.get(fileName)));78 }79 }80 }81 return Object.fromEntries(mutateInputFileMap);82 }83 private mergeFileDescriptions(first: FileDescription, second?: FileDescription): FileDescription {84 if (second) {85 if (Array.isArray(first.mutate) && Array.isArray(second.mutate)) {86 return { mutate: [...second.mutate, ...first.mutate] };87 } else if (first.mutate && !second.mutate) {88 return first;89 } else if (!first.mutate && second.mutate) {90 return second;91 } else {92 return { mutate: false };93 }94 }95 return first;96 }97 /**98 * Filters a given list of file names given a mutate pattern.99 * @param fileNames the file names to match to the pattern100 * @param mutatePattern the pattern to match with101 */102 private filterMutatePattern(fileNames: Iterable<string>, mutatePattern: string): Map<string, FileDescription> {103 const mutationRangeMatch = MUTATION_RANGE_REGEX.exec(mutatePattern);104 let mutate: FileDescription['mutate'] = true;105 if (mutationRangeMatch) {106 const [_, newPattern, _mutationRange, startLine, startColumn = '0', endLine, endColumn = Number.MAX_SAFE_INTEGER.toString()] =107 mutationRangeMatch;108 mutatePattern = newPattern;109 mutate = [110 {111 start: { line: parseInt(startLine) - 1, column: parseInt(startColumn) },112 end: { line: parseInt(endLine) - 1, column: parseInt(endColumn) },113 },114 ];115 }116 const matcher = new FileMatcher(mutatePattern);117 const inputFiles = new Map<string, FileDescription>();118 for (const fileName of fileNames) {119 if (matcher.matches(fileName)) {120 inputFiles.set(fileName, { mutate });121 }122 }123 return inputFiles;124 }125 private async resolveInputFileNames(): Promise<string[]> {126 const ignoreRules = this.ignoreRules.map((pattern) => new Minimatch(pattern, { dot: true, flipNegate: true, nocase: true }));127 /**128 * Rewrite of: https://github.com/npm/ignore-walk/blob/0e4f87adccb3e16f526d2e960ed04bdc77fd6cca/index.js#L213-L215129 */130 const matchesDirectoryPartially = (entryPath: string, rule: IMinimatch) => {131 return rule.match(`/${entryPath}`, true) || rule.match(entryPath, true);132 };133 // Inspired by https://github.com/npm/ignore-walk/blob/0e4f87adccb3e16f526d2e960ed04bdc77fd6cca/index.js#L124134 const matchesDirectory = (entryName: string, entryPath: string, rule: IMinimatch) => {135 return (136 matchesFile(entryName, entryPath, rule) ||137 rule.match(`/${entryPath}/`) ||138 rule.match(`${entryPath}/`) ||139 (rule.negate && matchesDirectoryPartially(entryPath, rule))140 );141 };142 // Inspired by https://github.com/npm/ignore-walk/blob/0e4f87adccb3e16f526d2e960ed04bdc77fd6cca/index.js#L123143 const matchesFile = (entryName: string, entryPath: string, rule: IMinimatch) => {144 return rule.match(entryName) || rule.match(entryPath) || rule.match(`/${entryPath}`);145 };146 const crawlDir = async (dir: string, rootDir = dir): Promise<string[]> => {147 const dirEntries = await this.fs.readdir(dir, { withFileTypes: true });148 const relativeName = path.relative(rootDir, dir);149 const files = await Promise.all(150 dirEntries151 .filter((dirEntry) => {152 let included = true;153 const entryPath = `${relativeName.length ? `${relativeName}/` : ''}${dirEntry.name}`;154 ignoreRules.forEach((rule) => {155 if (rule.negate !== included) {156 const match = dirEntry.isDirectory() ? matchesDirectory(dirEntry.name, entryPath, rule) : matchesFile(dirEntry.name, entryPath, rule);157 if (match) {158 included = rule.negate;159 }160 }161 });162 return included;163 })164 .map(async (dirent) => {165 if (dirent.isDirectory()) {166 return crawlDir(path.resolve(rootDir, relativeName, dirent.name), rootDir);167 } else {168 return path.resolve(rootDir, relativeName, dirent.name);169 }170 })171 );172 return files.flat();173 };174 const files = await crawlDir(process.cwd());175 return files;176 }177 private async readIncrementalReport(): Promise<MutationTestResult | undefined> {178 if (!this.incremental) {179 return;180 }181 try {182 // TODO: Validate against the schema or stryker version?183 const contents = await this.fs.readFile(this.incrementalFile, 'utf-8');184 const result: MutationTestResult = JSON.parse(contents);185 return {186 ...result,187 files: Object.fromEntries(188 Object.entries(result.files).map(([fileName, file]) => [189 fileName,190 { ...file, mutants: file.mutants.map((mutant) => ({ ...mutant, location: reportLocationToStrykerLocation(mutant.location) })) },191 ])192 ),193 testFiles:194 result.testFiles &&195 Object.fromEntries(196 Object.entries(result.testFiles).map(([fileName, file]) => [197 fileName,198 {199 ...file,200 tests: file.tests.map((test) => ({ ...test, location: test.location && reportOpenEndLocationToStrykerLocation(test.location) })),201 },202 ])203 ),204 };205 } catch (err: unknown) {206 if (isErrnoException(err) && err.code === ERROR_CODES.NoSuchFileOrDirectory) {207 this.log.info('No incremental result file found at %s, a full mutation testing run will be performed.', this.incrementalFile);208 return;209 }210 // Whoops, didn't mean to catch this one!211 throw err;212 }213 }214}215function reportOpenEndLocationToStrykerLocation({ start, end }: OpenEndLocation): OpenEndLocation {216 return {217 start: reportPositionToStrykerPosition(start),218 end: end && reportPositionToStrykerPosition(end),219 };220}221function reportLocationToStrykerLocation({ start, end }: Location): Location {222 return {223 start: reportPositionToStrykerPosition(start),224 end: reportPositionToStrykerPosition(end),225 };226}227function reportPositionToStrykerPosition({ line, column }: Position): Position {228 // stryker's positions are 0-based229 return {230 line: line - 1,231 column: column - 1,232 };...
Using AI Code Generation
1const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;2const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;3const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;4const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;5const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;6const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;7const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;8const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;9const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;10const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;11const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;12const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;13const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;14const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;15const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;16const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;
Using AI Code Generation
1var stryker = require('stryker-parent');2var mutationRangeMatch = stryker.mutationRangeMatch;3var match = mutationRangeMatch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);4console.log(match);5var stryker = require('stryker-parent');6var mutationRangeMatch = stryker.mutationRangeMatch;7var match = mutationRangeMatch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]);8console.log(match);9var stryker = require('stryker-parent');10var mutationRangeMatch = stryker.mutationRangeMatch;11var match = mutationRangeMatch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);12console.log(match);13var stryker = require('stryker-parent');14var mutationRangeMatch = stryker.mutationRangeMatch;15var match = mutationRangeMatch([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9]);16console.log(match);17var stryker = require('stryker-parent');
Using AI Code Generation
1const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;2const fileName = 'test.js';3const range = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];4const actual = mutationRangeMatch(fileName, range);5console.log(actual);6const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;7module.exports = function(config) {8 config.set({9 mutate: mutationRangeMatch('stryker.conf.js', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])10 });11};12### mutationRangeMatch(fileName, range)13MIT © [Karan Gohil](
Using AI Code Generation
1const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;2const { expect } = require('chai');3describe('mutationRangeMatch', () => {4 it('should match the range', () => {5 expect(mutationRangeMatch(2, 3, '1-3')).to.be.true;6 });7 it('should not match the range', () => {8 expect(mutationRangeMatch(1, 3, '2-3')).to.be.false;9 });10});11module.exports = {12};13function mutationRangeMatch(start, end, range) {14 const [startRange, endRange] = range.split('-');15 const startRangeInt = parseInt(startRange);16 const endRangeInt = parseInt(endRange);17 return start >= startRangeInt && end <= endRangeInt;18}
Using AI Code Generation
1const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;2const range = [1, 5];3const shouldMutate = mutationRangeMatch(range);4const mutationRangeMatch = require('stryker-child').mutationRangeMatch;5const range = [1, 5];6const shouldMutate = mutationRangeMatch(range);7const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;8const range = [1, 5];9const shouldMutate = mutationRangeMatch(range);10const mutationRangeMatch = require('stryker-child').mutationRangeMatch;11const range = [1, 5];12const shouldMutate = mutationRangeMatch(range);13const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;14const range = [1, 5];15const shouldMutate = mutationRangeMatch(range);16const mutationRangeMatch = require('stryker-child').mutationRangeMatch;17const range = [1, 5];18const shouldMutate = mutationRangeMatch(range);19const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;20const range = [1, 5];21const shouldMutate = mutationRangeMatch(range);22const mutationRangeMatch = require('stryker-child').mutationRangeMatch;23const range = [1, 5];24const shouldMutate = mutationRangeMatch(range);25const mutationRangeMatch = require('stryker-parent').mutationRangeMatch;26const range = [1, 5];27const shouldMutate = mutationRangeMatch(range);28const mutationRangeMatch = require('stryker-child').mutationRangeMatch;29const range = [1, 5];30const shouldMutate = mutationRangeMatch(range);
Using AI Code Generation
1var stryker = require('stryker-parent');2var range = stryker.mutationRangeMatch('1-2,5,8-9');3console.log(range);4module.exports = {5 mutationRangeMatch: function (range) {6 var mutationRange = range.split(',').map(function (range) {7 var rangeSplit = range.split('-');8 if (rangeSplit.length === 2) {9 return rangeSplit.map(function (n) {10 return parseInt(n, 10);11 });12 } else {13 return parseInt(rangeSplit[0], 10);14 }15 });16 var result = [];17 mutationRange.forEach(function (range) {18 if (Array.isArray(range)) {19 for (var i = range[0]; i <= range[1]; i++) {20 result.push(i);21 }22 } else {23 result.push(range);24 }25 });26 return result;27 }28};
Using AI Code Generation
1const { mutationRangeMatch } = require('stryker-parent');2const files = ['foo.js', 'bar.js'];3const mutator = 'javascript';4const range = { start: 12, end: 15 };5const result = mutationRangeMatch(files, mutator, range);6console.log(result);7{ file: 'foo.js', mutator: 'javascript', range: { start: 12, end: 15 } }8const { mutationRangeMatch } = require('stryker-parent');9const files = ['foo.js', 'bar.js'];10const mutators = ['javascript', 'typescript'];11const range = { start: 12, end: 15 };12const result = mutationRangeMatch(files, mutators, range);13console.log(result);14{ file: 'foo.js', mutator: 'javascript', range: { start: 12, end: 15 } }15const { mutationRangeMatch } = require('stryker-parent');16const files = ['foo.js', 'bar.js'];17const mutators = ['javascript', 'typescript'];18const ranges = [{ start: 12, end: 15 }, { start: 20, end: 23 }];19const result = mutationRangeMatch(files, mutators, ranges);20console.log(result);21{ file: 'foo.js', mutator: 'javascript', range: { start: 12, end: 15 } }
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!