UNPKG

@magic/test

Version:

simple yet powerful unit testing library

98 lines (81 loc) 2.88 kB
import path from 'node:path' import fs from '@magic/fs' import is from '@magic/types' /** * @param {string} filePath * @returns {Promise<Test[] | (Record<string, unknown> & TestsWithHooks)>} */ const importFile = async filePath => { let mod = await import(filePath) // catch es6 export default if (is.module(mod)) { const m = { ...mod } if (is.ownProp(m, 'default')) { return /** @type {Test[] | (Record<string, unknown> & TestsWithHooks)} */ (m.default) } else { return m } } else { return mod } } /** * @param {string} [dir=''] * @returns {Promise<TestSuites>} */ export const readRecursive = async (dir = '') => { const testDir = path.join(process.cwd(), 'test') const targetDir = path.join(testDir, dir) /** @type {TestSuites} */ let tests = {} // first resolve test/{dir/?}index.js or index.ts // if they exist, we require them and expect export structures to be user defined. let indexFilePath = path.join(targetDir, 'index.js') let indexFileTsPath = path.join(targetDir, 'index.ts') if (await fs.exists(indexFileTsPath)) { indexFilePath = indexFileTsPath } if (await fs.exists(indexFilePath)) { // if index.js exists, we will simply import it as is and do no recursion. const fileP = indexFilePath.replace(testDir, '') if (path.sep === '\\') { indexFilePath = 'file:\\\\\\' + indexFilePath } const imported = await importFile(indexFilePath) tests[fileP] = /** @type {Test[] | (Record<string, unknown> & TestsWithHooks)} */ (imported) } else { // if dir/index.js does not exist, require all files and subdirectories of files const files = await fs.readdir(targetDir) // recursively find all files and push them into tests object await Promise.all( files .filter(f => !f.startsWith('.')) .map(async file => { let filePath = path.join(targetDir, file) const stat = await fs.stat(filePath) if (stat.isDirectory()) { const deepTests = await readRecursive(dir ? path.join(dir, file) : file) tests = { ...tests, ...deepTests, } } else if (stat.isFile()) { if (!file.endsWith('js') && !file.endsWith('mjs') && !file.endsWith('ts')) { // bail early if not js or TypeScript return } let fileP = filePath.replace(testDir, '') // windows fix if (path.sep === '\\') { filePath = 'file:\\\\\\' + filePath fileP = `/${fileP.substring(1)}` } const test = await importFile(filePath) // write current file to tests cache tests[fileP] = /** @type {Test[] | (Record<string, unknown> & TestsWithHooks)} */ (test) } }), ) } return tests }