UNPKG

@fgv/ts-utils-jest

Version:
149 lines 6.06 kB
"use strict"; /* * Copyright (c) 2020 Erik Fortune * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MockFileSystem = exports.ReadWriteSpies = void 0; const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); /** * @public */ class ReadWriteSpies { constructor(read, write) { this.read = read; this.write = write; } clear() { this.read.mockClear(); this.write.mockClear(); } restore() { this.read.mockRestore(); this.write.mockRestore(); } } exports.ReadWriteSpies = ReadWriteSpies; /** * @public */ class MockFileSystem { constructor(configs, options) { this._extraWrites = []; this._config = new Map(); this._data = new Map(); this._options = options; this._realReadFileSync = fs_1.default.readFileSync; for (const config of configs) { const fullPath = path_1.default.resolve(config.path); this._config.set(fullPath, config); if (config.backingFile) { this.readMockFileSync(fullPath); } else if (config.payload) { this._data.set(fullPath, config.payload); } } } readMockFileSync(wanted) { var _a; const fullPathWanted = path_1.default.resolve(wanted); if (!this._data.has(fullPathWanted)) { const config = this._config.get(fullPathWanted); if ((config === null || config === void 0 ? void 0 : config.backingFile) === undefined) { if (((_a = this._options) === null || _a === void 0 ? void 0 : _a.mockWriteOnly) !== true) { throw new Error(`Mock file not found: ${wanted}`); } const body = this._realReadFileSync(fullPathWanted).toString(); this._data.set(fullPathWanted, body); } else { const fullBackingPath = path_1.default.resolve(config.backingFile); const body = this._realReadFileSync(fullBackingPath).toString(); this._data.set(fullPathWanted, body); } } const payload = this._data.get(fullPathWanted); // not actually reproducible right now /* c8 ignore next 3 */ if (payload === undefined) { throw new Error(`Mock file ${wanted} payload is undefined.`); } return payload; } writeMockFileSync(wanted, body) { var _a; const fullPathWanted = path_1.default.resolve(wanted); const config = this._config.get(fullPathWanted); if (config === undefined) { if (((_a = this._options) === null || _a === void 0 ? void 0 : _a.allowUnknownMockWrite) !== true) { throw new Error(`Mock path not found: ${wanted}`); } this._extraWrites.push(fullPathWanted); } else if (config.writable !== true) { throw new Error(`Mock permission denied: ${wanted}`); } this._data.set(fullPathWanted, body); } getExtraFilesWritten() { return Array.from(this._extraWrites); } tryGetPayload(want) { return this._data.get(path_1.default.resolve(want)); } reset() { const writable = Array.from(this._config.values()).filter((c) => c.writable === true); for (const config of writable) { this._data.delete(path_1.default.resolve(config.path)); if (config.backingFile) { this.readMockFileSync(path_1.default.resolve(config.path)); } else if (config.payload) { this._data.set(path_1.default.resolve(config.path), config.payload); } } for (const path of this._extraWrites) { this._data.delete(path); } this._extraWrites.splice(0, this._extraWrites.length); } startSpies(fsModule) { // Dynamic import of fs at runtime to avoid babel instrumentation timing issues const fsToMock = fsModule || require('fs'); return new ReadWriteSpies(jest.spyOn(fsToMock, 'readFileSync').mockImplementation((wanted) => { if (typeof wanted !== 'string') { throw new Error('readFileSync mock supports only string parameters'); } return this.readMockFileSync(wanted); }), jest.spyOn(fsToMock, 'writeFileSync').mockImplementation((wanted, payload) => { if (typeof wanted !== 'string' || typeof payload !== 'string') { throw new Error('writeFileSync mock supports only string parameters'); } return this.writeMockFileSync(wanted, payload); })); } } exports.MockFileSystem = MockFileSystem; //# sourceMappingURL=fsHelpers.js.map