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 { Stryker } = require('stryker-parent');2const stryker = new Stryker({3 commandRunner: {4 }5});6stryker.mutateInputFileMap({ 'test.js': { content: 'console.log("Hello world")' } })7 .then(result => {8 console.log(result);9 });10module.exports = function(config) {11 config.set({12 commandRunner: {13 }14 });15};16module.exports = function(config) {17 config.set({18 mochaOptions: {19 }20 });21};
Using AI Code Generation
1const { mutateInputFileMap } = require('stryker-parent');2const inputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };3const outputMap = mutateInputFileMap(inputMap);4console.log(outputMap);5const expectedOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };6const actualOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };7const expectedOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };8const actualOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };9const expectedOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };10const actualOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };11const expectedOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };12const actualOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };13const expectedOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };14const actualOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };15const expectedOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };16const actualOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };17const expectedOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };18const actualOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };19const expectedOutputMap = { 'foo.js': 'foo content', 'bar.js': 'bar content' };
Using AI Code Generation
1const { mutateInputFileMap } = require('stryker-parent');2const inputFileMap = {3};4const mutatedFiles = mutateInputFileMap(inputFileMap);5console.log(mutatedFiles);6const { mutateInputFileMap: mutateInputFileMapFromStryker } = require('stryker');7module.exports = {8};9module.exports = {10 mutateInputFileMap: function(inputFileMap) {11 return inputFileMap;12 }13};14module.exports = {15 mutateInputFileMap: function(inputFileMap) {16 return inputFileMap;17 }18};19module.exports = {20 mutateInputFileMap: function(inputFileMap) {21 return inputFileMap;22 }23};24module.exports = {25 mutateInputFileMap: function(inputFileMap) {26 return inputFileMap;27 }28};29module.exports = {30 mutateInputFileMap: function(inputFileMap) {31 return inputFileMap;32 }33};34module.exports = {35 mutateInputFileMap: function(inputFileMap) {
Using AI Code Generation
1const { mutateInputFileMap } = require('stryker-parent').stryker;2const inputFileMap = {3};4mutateInputFileMap(inputFileMap);5const mutatedInputFileMap = mutateInputFileMap(inputFileMap);6console.log(mutatedInputFileMap);
Using AI Code Generation
1var mutateInputFileMap = require('stryker-parent').mutateInputFileMap;2var inputFileMap = {3};4var mutatedFileMap = mutateInputFileMap(inputFileMap);5console.log(mutatedFileMap);6var mutateInputFileMap = require('stryker-parent').mutateInputFileMap;7var inputFileMap = {8};9var mutatedFileMap = mutateInputFileMap(inputFileMap, 'src/MyFile.js');10console.log(mutatedFileMap);11var mutateInputFileMap = require('stryker-parent').mutateInputFileMap;12var inputFileMap = {13};14var mutatedFileMap = mutateInputFileMap(inputFileMap, 'src/MyFile.js', 'src/MyFile.js');15console.log(mutatedFileMap);16var mutateInputFileMap = require('stryker
Using AI Code Generation
1const stryker = require('stryker-parent');2const fileMap = {3 'file1.js': 'var a = 1;',4 'file2.js': 'var b = 2;'5};6const mutatedFileMap = stryker.mutateInputFileMap(fileMap);7console.log(mutatedFileMap);8const stryker = require('stryker-parent');9const fileMap = {10 'file1.js': 'var a = 1;',11 'file2.js': 'var b = 2;'12};13const mutatedFileMap = stryker.mutateInputFileMap(fileMap);14console.log(mutatedFileMap);15const stryker = require('stryker-parent');16const fileMap = {17 'file1.js': 'var a = 1;',18 'file2.js': 'var b = 2;'19};20const mutatedFileMap = stryker.mutateInputFileMap(fileMap);21console.log(mutatedFileMap);22const stryker = require('stryker-parent');23const fileMap = {24 'file1.js': 'var a = 1;',25 'file2.js': 'var b = 2;'26};27const mutatedFileMap = stryker.mutateInputFileMap(fileMap);28console.log(mutatedFileMap);29const stryker = require('stryker-parent');30const fileMap = {31 'file1.js': 'var a = 1;',32 'file2.js': 'var b = 2;'33};34const mutatedFileMap = stryker.mutateInputFileMap(fileMap);35console.log(mutatedFileMap);36const stryker = require('stryker-parent');37const fileMap = {38 'file1.js': 'var a = 1;',39 'file2.js': 'var b = 2;'40};
Using AI Code Generation
1const { mutateInputFileMap } = require('stryker-parent');2const input = {3 'src/index.js': 'var x = 2;',4 'src/foo.js': 'var y = 2;'5};6const output = mutateInputFileMap(input, function (file) {7 return file.replace('2', '3');8});9console.log("output is ", output);10const { mutateInputFileMap } = require('stryker-parent');11const input = {12 'src/index.js': 'var x = 2;',13 'src/foo.js': 'var y = 2;'14};15const output = mutateInputFileMap(input, function (file) {16 return file.replace('2', '3');17});18console.log("output is ", output);19const { mutateInputFileMap } = require('stryker-parent');20const input = {21 'src/index.js': 'var x = 2;',22 'src/foo.js': 'var y = 2;'23};24const output = mutateInputFileMap(input, function (file) {25 return file.replace('2', '3');26});27console.log("output is ", output);28const { mutateInputFileMap } = require('stryker-parent');29const input = {30 'src/index.js': 'var x = 2;',31 'src/foo.js': 'var y = 2;'32};33const output = mutateInputFileMap(input, function (file) {34 return file.replace('2', '3');35});36console.log("output is ", output);37const { mutateInputFileMap } = require('stryker-parent');38const input = {
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!!