@stryker-mutator/util
Advanced tools
Comparing version 4.3.1 to 4.4.0
@@ -22,4 +22,4 @@ { | ||
"outFiles": [ | ||
"${workspaceRoot}/test/**/*.js", | ||
"${workspaceRoot}/src/**/*.js" | ||
"${workspaceFolder}/test/**/*.js", | ||
"${workspaceFolder}/src/**/*.js" | ||
] | ||
@@ -41,4 +41,4 @@ }, | ||
"outFiles": [ | ||
"${workspaceRoot}/test/**/*.js", | ||
"${workspaceRoot}/src/**/*.js" | ||
"${workspaceFolder}/test/**/*.js", | ||
"${workspaceFolder}/src/**/*.js" | ||
] | ||
@@ -45,0 +45,0 @@ } |
@@ -6,2 +6,10 @@ # Change Log | ||
# [4.4.0](https://github.com/stryker-mutator/stryker/compare/v4.3.1...v4.4.0) (2021-01-24) | ||
**Note:** Version bump only for package @stryker-mutator/util | ||
## [4.3.1](https://github.com/stryker-mutator/stryker/compare/v4.3.0...v4.3.1) (2020-12-25) | ||
@@ -8,0 +16,0 @@ |
{ | ||
"name": "@stryker-mutator/util", | ||
"version": "4.3.1", | ||
"version": "4.4.0", | ||
"description": "Contains utilities for Stryker, the mutation testing framework for JavaScript and friends", | ||
@@ -37,3 +37,3 @@ "main": "src/index.js", | ||
}, | ||
"gitHead": "0806eb62eefb02a5fad1477db61de6d8c4250bd4" | ||
"gitHead": "59933f5c3fb567142eab1c66d603802fab941b5e" | ||
} |
@@ -11,8 +11,3 @@ /** | ||
private cache; | ||
private initFiles?; | ||
private rootModuleId; | ||
init({ initFiles, rootModuleId }: { | ||
initFiles: readonly string[]; | ||
rootModuleId: string; | ||
}): void; | ||
private parents; | ||
/** | ||
@@ -19,0 +14,0 @@ * Records the files required in the current working directory (excluding node_modules) |
@@ -5,2 +5,3 @@ "use strict"; | ||
const path = require("path"); | ||
const not_empty_1 = require("./not-empty"); | ||
/** | ||
@@ -15,6 +16,2 @@ * A helper class that can be used by test runners. | ||
class DirectoryRequireCache { | ||
init({ initFiles, rootModuleId }) { | ||
this.initFiles = initFiles; | ||
this.rootModuleId = rootModuleId; | ||
} | ||
/** | ||
@@ -27,19 +24,23 @@ * Records the files required in the current working directory (excluding node_modules) | ||
const cwd = process.cwd(); | ||
this.cache = new Set(this.initFiles); | ||
this.cache = new Set(); | ||
Object.keys(require.cache) | ||
.filter((fileName) => fileName.startsWith(`${cwd}${path.sep}`) && !fileName.startsWith(path.join(cwd, 'node_modules'))) | ||
.forEach((file) => this.cache.add(file)); | ||
this.parents = new Set(Array.from(this.cache) | ||
// `module.parent` is deprecated, but seems to work fine, might never be removed. | ||
// See https://nodejs.org/api/modules.html#modules_module_parent | ||
.map((fileName) => { var _a, _b; return (_b = (_a = require.cache[fileName]) === null || _a === void 0 ? void 0 : _a.parent) === null || _b === void 0 ? void 0 : _b.filename; }) | ||
.filter(not_empty_1.notEmpty) | ||
// Filter out any parents that are in the current cache, since they will be removed anyway | ||
.filter((parentFileName) => !this.cache.has(parentFileName))); | ||
} | ||
} | ||
clear() { | ||
if (this.cache) { | ||
if (this.rootModuleId) { | ||
const rootModule = require.cache[this.rootModuleId]; | ||
if (rootModule) { | ||
rootModule.children = rootModule.children.filter((childModule) => !this.cache.has(childModule.id)); | ||
if (this.cache && this.parents) { | ||
this.parents.forEach((parent) => { | ||
const parentModule = require.cache[parent]; | ||
if (parentModule) { | ||
parentModule.children = parentModule.children.filter((childModule) => !this.cache.has(childModule.id)); | ||
} | ||
else { | ||
throw new Error(`Could not find "${this.rootModuleId}" in require cache.`); | ||
} | ||
} | ||
}); | ||
this.cache.forEach((fileName) => delete require.cache[fileName]); | ||
@@ -46,0 +47,0 @@ } |
import path = require('path'); | ||
import { notEmpty } from './not-empty'; | ||
/** | ||
@@ -13,10 +15,4 @@ * A helper class that can be used by test runners. | ||
private cache: Set<string>; | ||
private initFiles?: readonly string[]; | ||
private rootModuleId: string; | ||
private parents: Set<string>; | ||
public init({ initFiles, rootModuleId }: { initFiles: readonly string[]; rootModuleId: string }) { | ||
this.initFiles = initFiles; | ||
this.rootModuleId = rootModuleId; | ||
} | ||
/** | ||
@@ -29,6 +25,16 @@ * Records the files required in the current working directory (excluding node_modules) | ||
const cwd = process.cwd(); | ||
this.cache = new Set(this.initFiles); | ||
this.cache = new Set(); | ||
Object.keys(require.cache) | ||
.filter((fileName) => fileName.startsWith(`${cwd}${path.sep}`) && !fileName.startsWith(path.join(cwd, 'node_modules'))) | ||
.forEach((file) => this.cache.add(file)); | ||
this.parents = new Set( | ||
Array.from(this.cache) | ||
// `module.parent` is deprecated, but seems to work fine, might never be removed. | ||
// See https://nodejs.org/api/modules.html#modules_module_parent | ||
.map((fileName) => require.cache[fileName]?.parent?.filename) | ||
.filter(notEmpty) | ||
// Filter out any parents that are in the current cache, since they will be removed anyway | ||
.filter((parentFileName) => !this.cache.has(parentFileName)) | ||
); | ||
} | ||
@@ -38,11 +44,9 @@ } | ||
public clear() { | ||
if (this.cache) { | ||
if (this.rootModuleId) { | ||
const rootModule = require.cache[this.rootModuleId]; | ||
if (rootModule) { | ||
rootModule.children = rootModule.children.filter((childModule) => !this.cache.has(childModule.id)); | ||
} else { | ||
throw new Error(`Could not find "${this.rootModuleId}" in require cache.`); | ||
if (this.cache && this.parents) { | ||
this.parents.forEach((parent) => { | ||
const parentModule = require.cache[parent]; | ||
if (parentModule) { | ||
parentModule.children = parentModule.children.filter((childModule) => !this.cache.has(childModule.id)); | ||
} | ||
} | ||
}); | ||
this.cache.forEach((fileName) => delete require.cache[fileName]); | ||
@@ -49,0 +53,0 @@ } |
@@ -13,3 +13,3 @@ "use strict"; | ||
beforeEach(() => { | ||
loadedFiles = new Map(); | ||
loadedFiles = new Set(); | ||
workingDirectory = path.join('stub', 'working', 'dir'); | ||
@@ -23,104 +23,162 @@ const cwdStub = sinon.stub(process, 'cwd').returns(workingDirectory); | ||
afterEach(() => { | ||
for (const fileName of loadedFiles.keys()) { | ||
for (const fileName of loadedFiles) { | ||
delete require.cache[fileName]; | ||
} | ||
delete require.cache.root; | ||
}); | ||
function fakeRequireFile(fileName, content = fileName, requiredBy = rootModule) { | ||
loadedFiles.set(fileName, content); | ||
const child = createModule(content, fileName); | ||
function fakeRequireFile(fileName, content = fileName, parent = rootModule) { | ||
loadedFiles.add(fileName); | ||
const child = createModule(content, fileName, parent); | ||
require.cache[fileName] = child; | ||
requiredBy.children.push(child); | ||
parent === null || parent === void 0 ? void 0 : parent.children.push(child); | ||
return child; | ||
} | ||
describe(src_1.DirectoryRequireCache.prototype.clear.name, () => { | ||
it('should clear the init files', () => { | ||
var _a; | ||
// Arrange | ||
const dir2 = path.join('stub', 'working', 'dir2'); | ||
const fooFileName = path.join(dir2, 'foo.js'); | ||
const barFileName = path.join(dir2, 'bar.js'); | ||
const bazFileName = path.join(dir2, 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(barFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
sut.init({ initFiles: [fooFileName, barFileName], rootModuleId: 'root' }); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(require.cache[fooFileName]).undefined; | ||
chai_1.expect(require.cache[barFileName]).undefined; | ||
chai_1.expect((_a = require.cache[bazFileName]) === null || _a === void 0 ? void 0 : _a.exports).eq('baz'); | ||
}); | ||
it('should clear recorded files', () => { | ||
var _a; | ||
// Arrange | ||
const dir2 = path.join('stub', 'working', 'dir2'); | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
const bazFileName = path.join(dir2, 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(barFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(require.cache[fooFileName]).undefined; | ||
chai_1.expect(require.cache[barFileName]).undefined; | ||
chai_1.expect((_a = require.cache[bazFileName]) === null || _a === void 0 ? void 0 : _a.exports).eq('baz'); | ||
}); | ||
it('should clear recorded children from the root', () => { | ||
// Arrange | ||
const dir2 = path.join('stub', 'working', 'dir2'); | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
const bazFileName = path.join(dir2, 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(barFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
chai_1.expect(rootModule.children).lengthOf(3); | ||
sut.init({ initFiles: [], rootModuleId: 'root' }); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(rootModule.children).lengthOf(1); | ||
chai_1.expect(rootModule.children[0].filename).eq(bazFileName); | ||
}); | ||
it("should throw when the root module wasn't loaded", () => { | ||
// Arrange | ||
sut.init({ initFiles: [], rootModuleId: 'not-exists' }); | ||
sut.record(); | ||
// Act | ||
chai_1.expect(() => sut.clear()).throws('Could not find "not-exists" in require cache.'); | ||
}); | ||
it('should not clear files from node_modules', () => { | ||
var _a; | ||
// Arrange | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const bazFileName = path.join(workingDirectory, 'node_modules', 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(require.cache[fooFileName]).undefined; | ||
chai_1.expect((_a = require.cache[bazFileName]) === null || _a === void 0 ? void 0 : _a.exports).eq('baz'); | ||
}); | ||
it('should clear recorded files', () => { | ||
var _a; | ||
// Arrange | ||
const dir2 = path.join('stub', 'working', 'dir2'); | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
const bazFileName = path.join(dir2, 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(barFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(require.cache[fooFileName]).undefined; | ||
chai_1.expect(require.cache[barFileName]).undefined; | ||
chai_1.expect((_a = require.cache[bazFileName]) === null || _a === void 0 ? void 0 : _a.exports).eq('baz'); | ||
}); | ||
it('should only record the first time (perf optimization)', () => { | ||
// Arrange | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
sut.record(); | ||
fakeRequireFile(barFileName, 'bar'); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(require.cache[fooFileName]).undefined; | ||
chai_1.expect(require.cache[barFileName]).not.undefined; | ||
chai_1.expect(rootModule.children).lengthOf(1); | ||
}); | ||
it('should clear recorded children from their respective parent', () => { | ||
// Arrange | ||
const dir2 = path.join('stub', 'working', 'dir2'); | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
const bazFileName = path.join(dir2, 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(barFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
chai_1.expect(rootModule.children).lengthOf(3); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(rootModule.children).lengthOf(1); | ||
chai_1.expect(rootModule.children[0].filename).eq(bazFileName); | ||
}); | ||
it('should clear recorded separate unique parents', () => { | ||
// Arrange | ||
const fooParent = fakeRequireFile('parent1'); | ||
const barParent = fakeRequireFile('parent2'); | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
fakeRequireFile(fooFileName, 'foo', fooParent); | ||
fakeRequireFile(barFileName, 'bar', barParent); | ||
chai_1.expect(fooParent.children).lengthOf(1); | ||
chai_1.expect(barParent.children).lengthOf(1); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(fooParent.children).lengthOf(0); | ||
chai_1.expect(barParent.children).lengthOf(0); | ||
}); | ||
it('should not break when clearing a graph', () => { | ||
// Arrange | ||
const grandParentFileName = 'grandparent.js'; | ||
const parentFileName = path.join(workingDirectory, 'child.spec.js'); | ||
const childFileName = path.join(workingDirectory, 'child.js'); | ||
const grandparentModule = fakeRequireFile(grandParentFileName); | ||
const parentModule = fakeRequireFile(parentFileName, 'parent', grandparentModule); | ||
fakeRequireFile(childFileName, 'foo', parentModule); | ||
chai_1.expect(grandparentModule.children).lengthOf(1); | ||
chai_1.expect(parentModule.children).lengthOf(1); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(grandparentModule.children).lengthOf(0); | ||
chai_1.expect(require.cache[childFileName]).undefined; | ||
chai_1.expect(require.cache[parentFileName]).undefined; | ||
chai_1.expect(require.cache[grandParentFileName]).eq(grandparentModule); | ||
}); | ||
it('should not throw when the parent module was unloaded', () => { | ||
// Arrange | ||
fakeRequireFile(path.join(workingDirectory, 'foo.js')); | ||
sut.record(); | ||
delete require.cache[rootModule.filename]; | ||
// Act & assert | ||
sut.clear(); | ||
}); | ||
it('should not throw when the parent module is one of the modules to being cleared', () => { | ||
// Arrange | ||
const fooSpec = path.join(workingDirectory, 'foo.spec.js'); | ||
const foo = path.join(workingDirectory, 'foo.js'); | ||
const app = path.join(workingDirectory, 'app.js'); | ||
const fooSpecModule = fakeRequireFile(fooSpec); | ||
const fooModule = fakeRequireFile(foo, 'foo', fooSpecModule); | ||
fakeRequireFile(app, 'app', fooModule); | ||
// Act | ||
sut.record(); | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(require.cache[fooSpec]).undefined; | ||
chai_1.expect(require.cache[app]).undefined; | ||
chai_1.expect(require.cache[foo]).undefined; | ||
}); | ||
it('should not clear files from node_modules', () => { | ||
var _a; | ||
// Arrange | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const bazFileName = path.join(workingDirectory, 'node_modules', 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(require.cache[fooFileName]).undefined; | ||
chai_1.expect((_a = require.cache[bazFileName]) === null || _a === void 0 ? void 0 : _a.exports).eq('baz'); | ||
}); | ||
it("should not fail when recorded file doesn't have a parent", () => { | ||
// Arrange | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
fakeRequireFile(fooFileName, 'foo', null); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
chai_1.expect(require.cache[fooFileName]).undefined; | ||
}); | ||
function createModule(content, fileName, parent = rootModule) { | ||
return { | ||
exports: content, | ||
children: [], | ||
filename: fileName, | ||
id: fileName, | ||
loaded: true, | ||
parent, | ||
paths: [], | ||
require, | ||
path: '', | ||
}; | ||
} | ||
}); | ||
function createModule(content, fileName) { | ||
return { | ||
exports: content, | ||
children: [], | ||
filename: fileName, | ||
id: fileName, | ||
loaded: true, | ||
parent: null, | ||
paths: [], | ||
require, | ||
path: '', | ||
}; | ||
} | ||
//# sourceMappingURL=directory-require-cache.spec.js.map |
@@ -12,7 +12,7 @@ import path = require('path'); | ||
let sut: DirectoryRequireCache; | ||
let loadedFiles: Map<string, string>; | ||
let loadedFiles: Set<string>; | ||
let rootModule: NodeModule; | ||
beforeEach(() => { | ||
loadedFiles = new Map(); | ||
loadedFiles = new Set(); | ||
workingDirectory = path.join('stub', 'working', 'dir'); | ||
@@ -27,115 +27,186 @@ const cwdStub = sinon.stub(process, 'cwd').returns(workingDirectory); | ||
afterEach(() => { | ||
for (const fileName of loadedFiles.keys()) { | ||
for (const fileName of loadedFiles) { | ||
delete require.cache[fileName]; | ||
} | ||
delete require.cache.root; | ||
}); | ||
function fakeRequireFile(fileName: string, content = fileName, requiredBy = rootModule) { | ||
loadedFiles.set(fileName, content); | ||
const child = createModule(content, fileName); | ||
function fakeRequireFile(fileName: string, content = fileName, parent: NodeModule | null = rootModule) { | ||
loadedFiles.add(fileName); | ||
const child = createModule(content, fileName, parent); | ||
require.cache[fileName] = child; | ||
requiredBy.children.push(child); | ||
parent?.children.push(child); | ||
return child; | ||
} | ||
describe(DirectoryRequireCache.prototype.clear.name, () => { | ||
it('should clear the init files', () => { | ||
// Arrange | ||
const dir2 = path.join('stub', 'working', 'dir2'); | ||
const fooFileName = path.join(dir2, 'foo.js'); | ||
const barFileName = path.join(dir2, 'bar.js'); | ||
const bazFileName = path.join(dir2, 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(barFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
sut.init({ initFiles: [fooFileName, barFileName], rootModuleId: 'root' }); | ||
sut.record(); | ||
it('should clear recorded files', () => { | ||
// Arrange | ||
const dir2 = path.join('stub', 'working', 'dir2'); | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
const bazFileName = path.join(dir2, 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(barFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
expect(require.cache[fooFileName]).undefined; | ||
expect(require.cache[barFileName]).undefined; | ||
expect(require.cache[bazFileName]?.exports).eq('baz'); | ||
}); | ||
// Assert | ||
expect(require.cache[fooFileName]).undefined; | ||
expect(require.cache[barFileName]).undefined; | ||
expect(require.cache[bazFileName]?.exports).eq('baz'); | ||
}); | ||
it('should clear recorded files', () => { | ||
// Arrange | ||
const dir2 = path.join('stub', 'working', 'dir2'); | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
const bazFileName = path.join(dir2, 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(barFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
sut.record(); | ||
it('should only record the first time (perf optimization)', () => { | ||
// Arrange | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
sut.record(); | ||
fakeRequireFile(barFileName, 'bar'); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
expect(require.cache[fooFileName]).undefined; | ||
expect(require.cache[barFileName]).undefined; | ||
expect(require.cache[bazFileName]?.exports).eq('baz'); | ||
}); | ||
// Assert | ||
expect(require.cache[fooFileName]).undefined; | ||
expect(require.cache[barFileName]).not.undefined; | ||
expect(rootModule.children).lengthOf(1); | ||
}); | ||
it('should clear recorded children from the root', () => { | ||
// Arrange | ||
const dir2 = path.join('stub', 'working', 'dir2'); | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
const bazFileName = path.join(dir2, 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(barFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
expect(rootModule.children).lengthOf(3); | ||
sut.init({ initFiles: [], rootModuleId: 'root' }); | ||
sut.record(); | ||
it('should clear recorded children from their respective parent', () => { | ||
// Arrange | ||
const dir2 = path.join('stub', 'working', 'dir2'); | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
const bazFileName = path.join(dir2, 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(barFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
expect(rootModule.children).lengthOf(3); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
expect(rootModule.children).lengthOf(1); | ||
expect(rootModule.children[0].filename).eq(bazFileName); | ||
}); | ||
// Assert | ||
expect(rootModule.children).lengthOf(1); | ||
expect(rootModule.children[0].filename).eq(bazFileName); | ||
}); | ||
it("should throw when the root module wasn't loaded", () => { | ||
// Arrange | ||
sut.init({ initFiles: [], rootModuleId: 'not-exists' }); | ||
sut.record(); | ||
it('should clear recorded separate unique parents', () => { | ||
// Arrange | ||
const fooParent = fakeRequireFile('parent1'); | ||
const barParent = fakeRequireFile('parent2'); | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const barFileName = path.join(workingDirectory, 'bar.js'); | ||
fakeRequireFile(fooFileName, 'foo', fooParent); | ||
fakeRequireFile(barFileName, 'bar', barParent); | ||
expect(fooParent.children).lengthOf(1); | ||
expect(barParent.children).lengthOf(1); | ||
sut.record(); | ||
// Act | ||
expect(() => sut.clear()).throws('Could not find "not-exists" in require cache.'); | ||
}); | ||
// Act | ||
sut.clear(); | ||
it('should not clear files from node_modules', () => { | ||
// Arrange | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const bazFileName = path.join(workingDirectory, 'node_modules', 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
sut.record(); | ||
// Assert | ||
expect(fooParent.children).lengthOf(0); | ||
expect(barParent.children).lengthOf(0); | ||
}); | ||
// Act | ||
sut.clear(); | ||
it('should not break when clearing a graph', () => { | ||
// Arrange | ||
const grandParentFileName = 'grandparent.js'; | ||
const parentFileName = path.join(workingDirectory, 'child.spec.js'); | ||
const childFileName = path.join(workingDirectory, 'child.js'); | ||
const grandparentModule = fakeRequireFile(grandParentFileName); | ||
const parentModule = fakeRequireFile(parentFileName, 'parent', grandparentModule); | ||
fakeRequireFile(childFileName, 'foo', parentModule); | ||
expect(grandparentModule.children).lengthOf(1); | ||
expect(parentModule.children).lengthOf(1); | ||
sut.record(); | ||
// Assert | ||
expect(require.cache[fooFileName]).undefined; | ||
expect(require.cache[bazFileName]?.exports).eq('baz'); | ||
}); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
expect(grandparentModule.children).lengthOf(0); | ||
expect(require.cache[childFileName]).undefined; | ||
expect(require.cache[parentFileName]).undefined; | ||
expect(require.cache[grandParentFileName]).eq(grandparentModule); | ||
}); | ||
it('should not throw when the parent module was unloaded', () => { | ||
// Arrange | ||
fakeRequireFile(path.join(workingDirectory, 'foo.js')); | ||
sut.record(); | ||
delete require.cache[rootModule.filename]; | ||
// Act & assert | ||
sut.clear(); | ||
}); | ||
it('should not throw when the parent module is one of the modules to being cleared', () => { | ||
// Arrange | ||
const fooSpec = path.join(workingDirectory, 'foo.spec.js'); | ||
const foo = path.join(workingDirectory, 'foo.js'); | ||
const app = path.join(workingDirectory, 'app.js'); | ||
const fooSpecModule = fakeRequireFile(fooSpec); | ||
const fooModule = fakeRequireFile(foo, 'foo', fooSpecModule); | ||
fakeRequireFile(app, 'app', fooModule); | ||
// Act | ||
sut.record(); | ||
sut.clear(); | ||
// Assert | ||
expect(require.cache[fooSpec]).undefined; | ||
expect(require.cache[app]).undefined; | ||
expect(require.cache[foo]).undefined; | ||
}); | ||
it('should not clear files from node_modules', () => { | ||
// Arrange | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
const bazFileName = path.join(workingDirectory, 'node_modules', 'baz.js'); | ||
fakeRequireFile(fooFileName, 'foo'); | ||
fakeRequireFile(bazFileName, 'baz'); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
expect(require.cache[fooFileName]).undefined; | ||
expect(require.cache[bazFileName]?.exports).eq('baz'); | ||
}); | ||
it("should not fail when recorded file doesn't have a parent", () => { | ||
// Arrange | ||
const fooFileName = path.join(workingDirectory, 'foo.js'); | ||
fakeRequireFile(fooFileName, 'foo', null); | ||
sut.record(); | ||
// Act | ||
sut.clear(); | ||
// Assert | ||
expect(require.cache[fooFileName]).undefined; | ||
}); | ||
function createModule(content: string, fileName: string, parent: NodeModule | null = rootModule): NodeModule { | ||
return { | ||
exports: content, | ||
children: [], | ||
filename: fileName, | ||
id: fileName, | ||
loaded: true, | ||
parent, | ||
paths: [], | ||
require, | ||
path: '', | ||
}; | ||
} | ||
}); | ||
function createModule(content: string, fileName: string): NodeModule { | ||
return { | ||
exports: content, | ||
children: [], | ||
filename: fileName, | ||
id: fileName, | ||
loaded: true, | ||
parent: null, | ||
paths: [], | ||
require, | ||
path: '', | ||
}; | ||
} |
@@ -19,3 +19,5 @@ "use strict"; | ||
it('should be able to point to a path', () => { | ||
chai_1.expect(src_1.PropertyPathBuilder.create().prop('bar').prop('baz').build()).eq('bar.baz'); | ||
const path = src_1.PropertyPathBuilder.create().prop('bar').prop('baz'); | ||
chai_1.expect(path.build()).eq('bar.baz'); | ||
chai_1.expect(path.toString()).eq('bar.baz'); | ||
}); | ||
@@ -22,0 +24,0 @@ }); |
@@ -31,3 +31,5 @@ import { expect } from 'chai'; | ||
it('should be able to point to a path', () => { | ||
expect(PropertyPathBuilder.create<Foo>().prop('bar').prop('baz').build()).eq('bar.baz'); | ||
const path = PropertyPathBuilder.create<Foo>().prop('bar').prop('baz'); | ||
expect(path.build()).eq('bar.baz'); | ||
expect(path.toString()).eq('bar.baz'); | ||
}); | ||
@@ -34,0 +36,0 @@ }); |
@@ -69,3 +69,3 @@ import { expect } from 'chai'; | ||
// Arrange | ||
const expectedTimer = 234; | ||
const expectedTimer = (234 as unknown) as NodeJS.Timeout; | ||
const setTimeoutStub = sinon.stub(global, 'setTimeout'); | ||
@@ -72,0 +72,0 @@ const clearTimeoutStub = sinon.stub(global, 'clearTimeout'); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
294091
2148