UNPKG

testify-universal-cli

Version:

Universal interactive CLI tool for scanning and executing tests across multiple programming languages

162 lines (146 loc) 4.54 kB
import { execa } from 'execa'; import fs from 'node:fs/promises'; /** * Get a Go test runner * * @param {string} customRunner - Custom test runner * @returns {object} - Go test runner */ export function getGoRunner(customRunner) { return { /** * Run all tests * * @param {Array<{filePath: string, relativePath: string, markers: string[]}>} testFiles - Test files * @param {string} cwd - Current working directory * @param {string[]} markers - Test markers * @returns {Promise<{stdout: string, failed: boolean}>} - Test results */ async runAll(testFiles, cwd, markers = []) { try { // Build command for Go tests const args = ['test', './...', '-v']; // Add marker/tag filtering if provided if (markers.length > 0) { // Go tests use -run to filter by pattern args.push('-run', markers.map(m => `Test.*${m}.*`).join('|')); } const { stdout, stderr, exitCode } = await execa('go', args, { cwd, all: true, reject: false, }); return { stdout: stdout || stderr, failed: exitCode !== 0, }; } catch (error) { return { stdout: error.message, failed: true, }; } }, /** * Run a single test file * * @param {object} testFile - Test file * @param {string} testFile.filePath - Path to test file * @param {string[]} testFile.markers - Test markers * @param {string} cwd - Current working directory * @returns {Promise<{stdout: string, failed: boolean}>} - Test results */ async runFile(testFile, cwd) { try { // Get the package directory from file path const packageDir = getPackageDir(testFile.filePath, cwd); // Run the tests for that package const { stdout, stderr, exitCode } = await execa('go', ['test', packageDir, '-v'], { cwd, all: true, reject: false, }); return { stdout: stdout || stderr, failed: exitCode !== 0, }; } catch (error) { return { stdout: error.message, failed: true, }; } }, }; } /** * Get the package directory from a file path * * @param {string} filePath - Path to test file * @param {string} cwd - Current working directory * @returns {string} - Go package path */ function getPackageDir(filePath, cwd) { // Get the directory containing the test file const relativePath = filePath.replace(cwd, '').replace(/^\//, ''); const packageDir = relativePath.split('/').slice(0, -1).join('/'); // If it's in the current directory, use "." return packageDir || './'; } /** * Extract test markers from Go test files * * @param {string} filePath - Path to test file * @returns {Promise<string[]>} - Extracted markers */ export async function extractGoMarkers(filePath) { try { const content = await fs.readFile(filePath, 'utf8'); const markers = new Set(); // Common Go test patterns const patterns = [ // Find test functions /func\s+(Test[A-Za-z0-9_]+)/g, // Find test that use t.Run /t\.Run\(["']([A-Za-z0-9_]+)["']/g, // Check for parallel tests /t\.Parallel\(\)/g ]; // Extract test names let match; for (const pattern of patterns) { while ((match = pattern.exec(content)) !== null) { if (match[1]) { // Get individual components from camel case test name const parts = match[1].replace(/Test/, '') .replace(/([A-Z])/g, ' $1') .trim() .toLowerCase() .split(' '); // Add each part as a marker parts.forEach(part => { if (part && part.length > 2) { // Only add meaningful parts markers.add(part); } }); } else if (pattern.toString().includes('Parallel')) { markers.add('parallel'); } } } // Check for benchmarks if (content.includes('func Benchmark')) { markers.add('benchmark'); } // Look for common test categories const categories = ['unit', 'integration', 'e2e', 'api', 'ui', 'smoke', 'regression']; categories.forEach(category => { if (content.toLowerCase().includes(category)) { markers.add(category); } }); return [...markers]; } catch (error) { return []; } }