UNPKG

@olton/latte

Version:

Simple test framework for JavaScript and TypeScript with DOM supports

223 lines (208 loc) 7.44 kB
import fs, { existsSync, writeFileSync } from 'fs' import yargs from 'yargs' import { hideBin } from 'yargs/helpers' import {term} from '@olton/terminal' export const LOGO = '🥛' export const BOT = '🤖' export const FAIL = '💀' export const SEARCH = '🔍' export const STOP = '⛔' export const FLAME = '🔥' export const DIVIDER = '-----------------------------------------------------------------' const defaultInclude = ['**/*.{test,spec}.{js,ts,jsx,tsx}'] const defaultExclude = ['node_modules/**'] export const defaultConfig = { verbose: false, dom: false, react: false, coverage: false, skipPassed: false, parallel: false, watch: false, debug: false, include: defaultInclude, exclude: defaultExclude, skip: '', test: '', suite: '', reportType: 'console', reportDir: 'coverage', reportFile: '', maxWorkers: 4, progress: 'default', skipConfigFile: false, idea: false, clearConsole: false, showStack: false, domEnv: 'jsdom', } export const updateConfig = (args) => { global.config = Object.assign({}, defaultConfig) const configFileName = args.config ?? 'latte.json' if (!args.skipConfigFile) { console.log(term(`${SEARCH} Searching for a config file...`, { color: 'gray' })) if (fs.existsSync(configFileName)) { console.log(term(`${BOT} Config file found!`, { color: 'green' })) console.log(term(` └── We use ${term(configFileName, { color: 'cyanBright' })} to configure Latte`, { color: 'gray' })) const userConfig = JSON.parse(fs.readFileSync(configFileName, 'utf-8')) Object.assign(config, userConfig) } else { console.log(term(`${BOT} Config file not found! We use default settings and CLI arguments!`, { color: 'gray' })) console.log(term(` └── You can create ${term(configFileName, { color: 'cyanBright' })} to configure Latte`, { color: 'gray' })) } } if (args.react && !args.dom) { console.log(term(`${BOT} Option --react requires --dom. Enabling DOM emulation automatically.`, { color: 'yellow' })) args.dom = true } if (args.dom) { config.dom = true } if (args.react) { config.dom = true; config.react = true } if (args.ts) { config.ts = true } if (args.coverage) { config.coverage = true } if (args.verbose) { config.verbose = true } if (args.skipPassed) { config.skipPassed = true } if (args.watch) { config.watch = true } if (args.debug) { config.debug = true } if (args.parallel) { config.parallel = true } if (args.test) { config.test = args.test } if (args.include) { config.include = args.include.split(';') } if (args.exclude !== undefined) { config.exclude = args.exclude.split(';') } if (args.skip) { config.skip = args.skip } if (args.reportType) { config.reportType = args.reportType } if (args.reportDir) { config.reportDir = args.reportDir } if (args.reportFile) { config.reportDir = args.reportFile } if (args.maxWorkers) { config.maxWorkers = args.maxWorkers } if (args.progress) { config.progress = args.progress } if (args.clearConsole) { config.clearConsole = true } if (args.idea) { config.idea = true } if (args.skipConfigFile) { config.skipConfigFile = true } if (args.showStack) { config.showStack = true } if (args.suite) { config.suite = args.suite } if (args.domEnv) { config.domEnv = args.domEnv } if (config.reportType && !['console', 'lcov', 'html', 'junit'].includes(config.reportType)) { console.log(term(`${BOT} Unknown type of report: ${config.reportType}. Console will be used.`, { color: 'yellow' })) config.reportType = 'console' } } export const createConfigFile = (configFileName = 'latte.json') => { // Проверка существования файла if (existsSync(configFileName)) { console.log(term(`${BOT} Config file ${term(configFileName, {color: 'cyanBright'})} already exists.`, { color: 'yellow' })) console.log(term(' └── If you want to create a new file, delete the existing one.', { color: 'gray' })) console.log('\n') return false } // Создание файла с настройками по умолчанию try { writeFileSync(configFileName, JSON.stringify(defaultConfig, null, 2), 'utf-8') console.log(term(`${BOT} Config file ${term(configFileName, {color: 'cyanBright'})} created successfully!`, { color: 'green' })) console.log(term(' └── Now you can change the settings in this file.', { color: 'gray' })) console.log('\n') return true } catch (error) { console.error(term(`${FAIL} Failed to create a configuration file: ${error.message}`, { color: 'red' })) console.log('\n') return false } } export const processArgv = () => { return yargs(hideBin(process.argv)) .option('watch', { alias: 'w', type: 'boolean', description: 'Run in observation mode' }) .option('parallel', { alias: 'p', type: 'boolean', description: 'Run in parallel mode' }) .option('dom', { alias: 'd', type: 'boolean', description: 'Enable DOM emulation' }) .option('dom-env', { type: 'string', description: 'DOM environment: \'jsdom\' or \'happy-dom\'' }) .option('react', { alias: 'r', type: 'boolean', description: 'Enable React testing support' }) .option('ts', { alias: 't', type: 'boolean', description: 'Enable TypeScript support' }) .option('debug', { alias: 'g', type: 'boolean', description: 'Run tests in debug mode' }) .option('verbose', { alias: 'v', type: 'boolean', description: 'Detailed report' }) .option('coverage', { alias: 'c', type: 'boolean', description: 'Code coverage report' }) .option('loader', { alias: 'l', type: 'boolean', description: 'Use experimental resolver for imports' }) .option('show-stack', { alias: 's', type: 'boolean', description: 'Show stack trace for failed tests (required verbose mode)' }) .option('max-workers', { type: 'string', description: 'Maximum number of parallel workers' }) .option('include', { type: 'string', description: 'Test files switching templates' }) .option('exclude', { type: 'string', description: 'Test file excluding templates' }) .option('report-type', { type: 'string', description: 'Report Type [\'console\', \'lcov\', \'html\', \'junit\']' }) .option('report-dir', { type: 'string', description: 'Reports Directory' }) .option('report-file', { type: 'string', description: 'Report File Name' }) .option('progress', { type: 'string', description: 'Progress Bar mode [\'default\', \'dots\', \'bar\']' }) .option('init', { type: 'boolean', description: 'Create a configuration file' }) .help() .argv } export const testJSX = () => { let requireTsx = false for (const ext of config.include) { if (ext.endsWith('.tsx') || ext.endsWith('.jsx') || ext.endsWith('.ts')) { requireTsx = true break } } return requireTsx }