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 } }
Check out the latest blogs from LambdaTest on this topic:
Pair testing can help you complete your testing tasks faster and with higher quality. But who can do pair testing, and when should it be done? And what form of pair testing is best for your circumstance? Check out this blog for more information on how to conduct pair testing to optimize its benefits.
Agile project management is a great alternative to traditional methods, to address the customer’s needs and the delivery of business value from the beginning of the project. This blog describes the main benefits of Agile for both the customer and the business.
There is just one area where each member of the software testing community has a distinct point of view! Metrics! This contentious issue sparks intense disputes, and most conversations finish with no definitive conclusion. It covers a wide range of topics: How can testing efforts be measured? What is the most effective technique to assess effectiveness? Which of the many components should be quantified? How can we measure the quality of our testing performance, among other things?
As part of one of my consulting efforts, I worked with a mid-sized company that was looking to move toward a more agile manner of developing software. As with any shift in work style, there is some bewilderment and, for some, considerable anxiety. People are being challenged to leave their comfort zones and embrace a continuously changing, dynamic working environment. And, dare I say it, testing may be the most ‘disturbed’ of the software roles in agile development.
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!!