UNPKG

@nielse63/generate-tests

Version:

Automatically generate jest specs for uncovered source files

113 lines (111 loc) 4.47 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GenerateTests = exports.defaults = void 0; const fast_glob_1 = __importDefault(require("fast-glob")); const fs_extra_1 = __importDefault(require("fs-extra")); const ignore_1 = __importDefault(require("ignore")); const camelCase_1 = __importDefault(require("lodash/camelCase")); const npmlog_1 = __importDefault(require("npmlog")); const os_1 = __importDefault(require("os")); const path_1 = __importDefault(require("path")); npmlog_1.default.enableColor(); exports.defaults = { glob: '**/src/**.{js,ts}', }; class GenerateTests { constructor(options) { const config = typeof options === 'string' ? { ...exports.defaults, glob: options, } : { ...exports.defaults, ...options, }; this.cwd = config.cwd || process.cwd(); this.glob = config.glob; this.fileobjects = []; this.ignoredPatterns = []; this.ignore = (0, ignore_1.default)(); } async run() { const files = await this.findFiles(); this.fileobjects = this.createFileObjects(files); await this.ensureFiles(); await this.writeFiles(); return this.fileobjects; } async findGitignoreFiles(filepath = this.cwd) { const gitignoreFile = path_1.default.join(filepath, '.gitignore'); if (fs_extra_1.default.existsSync(gitignoreFile)) { const content = await fs_extra_1.default.readFile(gitignoreFile, 'utf-8'); const lines = content.split('\n').filter((line) => { return line && !line.startsWith('#') && ignore_1.default.isPathValid(line); }); this.ignore.add(lines); this.ignoredPatterns.push(...lines); } if (filepath === '/' || filepath === os_1.default.homedir()) { return this.ignoredPatterns; } return this.findGitignoreFiles(path_1.default.dirname(filepath)); } async findFiles() { await this.findGitignoreFiles(); const files = await (0, fast_glob_1.default)([this.glob], { cwd: this.cwd, ignore: ['**/node_modules', '**/flow-typed', '**/coverage', '**/.git'], }); const filteredFiles = files.filter((file) => !this.ignore.ignores(file)); return filteredFiles; } createFileObjects(files) { const fileobjects = files .map((file) => { const abspath = path_1.default.resolve(this.cwd, file); const basename = path_1.default.basename(abspath); const dirname = path_1.default.dirname(abspath); const extension = path_1.default.extname(abspath); const extrgx = new RegExp(`${extension}$`); const classname = basename.replace(extrgx, ''); const testpath = path_1.default .join(dirname, '__tests__', basename) .replace(extrgx, `.spec${extension}`); return { file, abspath, testpath, basename, classname }; }) .filter(({ testpath, classname }) => !fs_extra_1.default.existsSync(testpath) && classname !== 'index'); if (!fileobjects.length) { npmlog_1.default.warn('generate-tests', 'No tests to generate'); return []; } return fileobjects; } async ensureFiles() { const promises = this.fileobjects.map(async ({ testpath }) => fs_extra_1.default.ensureFile(testpath)); await Promise.all(promises); } async writeFiles() { const promises = this.fileobjects.map(async ({ classname, testpath }) => { const template = GenerateTests.createTestTemplate(classname); return fs_extra_1.default.writeFile(testpath, template, 'utf8'); }); await Promise.all(promises); } static createTestTemplate(classname) { const importName = classname.includes('-') ? (0, camelCase_1.default)(classname) : classname; return `import ${importName} from '../${classname}'; describe('${classname}', () => { it('needs tests', () => { expect(${importName}).toBeDefined(); }); }); `; } } exports.GenerateTests = GenerateTests;