Skip to content

Instantly share code, notes, and snippets.

@kadiks
Created April 11, 2023 14:45
Show Gist options
  • Save kadiks/76011e3bdbba26f62aee2a36af7c4971 to your computer and use it in GitHub Desktop.
Save kadiks/76011e3bdbba26f62aee2a36af7c4971 to your computer and use it in GitHub Desktop.
// @ts-nocheck
import * as ts from "ts-morph"
import * as fs from "fs"
import * as path from "path"
import * as glob from "glob"
import { exec } from "child_process"
import slugify from "slugify"
const project = new ts.Project({
tsConfigFilePath: "./tsconfig.json",
})
// Define input and output directories
const inputDir = "./tests/unit"
const outputDir = "./output/tests/unit"
// Recursively create all necessary directories under outputDir
const createOutputDir = (filePath) => {
fs.mkdirSync(
path
.dirname(filePath)
.replace(inputDir.replace("./", ""), outputDir.replace("./", "")),
{ recursive: true }
)
}
// Delete entire output directory before starting
const deleteOutputDir = (dirPath) => {
if (fs.existsSync(dirPath)) {
fs.readdirSync(dirPath).forEach((file) => {
const curPath = path.join(dirPath, file)
if (fs.lstatSync(curPath).isDirectory()) {
deleteOutputDir(curPath)
} else {
fs.unlinkSync(curPath)
}
})
fs.rmdirSync(dirPath)
}
}
// Define a function to run the commands sequentially
const runCommandsSequentially = (allCommands) => {
const startTime = Date.now()
const [command, ...remainingCommands] = allCommands
const remainingCommandsCount = remainingCommands.length
if (!command) {
const totalTime = Date.now() - startTime
console.log(`All commands have been executed. Total time: ${totalTime}ms`)
return
}
console.log(
`Executing command "${command}". ${remainingCommandsCount} commands remaining.`
)
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(`Error running command: ${command}`, error)
return
}
console.log(`Command output for "${command}":\n`, stdout)
runCommandsSequentially(remainingCommands)
})
}
deleteOutputDir(outputDir)
// Find all TypeScript files under the input directory
const filePaths = glob.sync(`${inputDir}/**/*.test.ts*`)
// console.log("filePaths", filePaths)
const testNames = []
// Process each file, extract test names, and copy file to output directory
for (const filePath of filePaths) {
// Create all necessary directories under output directory
createOutputDir(filePath)
// Extract test names
const sourceFile = project.addSourceFileAtPath(filePath)
const tests = sourceFile
.getDescendantsOfKind(ts.SyntaxKind.CallExpression)
.filter(
(callExpr) =>
callExpr.getExpression().getText() === "it" &&
callExpr.getArguments().length > 0 &&
callExpr.getArguments()[0].getKind() === ts.SyntaxKind.StringLiteral
)
.map((callExpr) => callExpr.getArguments()[0].getLiteralValue())
// console.log(`File ${filePath} contains ${tests.length} tests:`)
// console.log(tests)
tests.forEach((test) =>
testNames.push({
filePath,
testName: test,
output: `./output/${filePath
.replace(".test.tsx", "")
.replace(".test.ts", "")}`,
})
)
}
console.log("Test names:", testNames)
console.log("Total number of tests:", testNames.length)
const commands = testNames
.filter((test) => {
return !test.testName.includes("'") && !test.testName.includes(":")
})
.map(
(test) =>
`hyperfine 'npx vitest ${test.filePath} -t "${
test.testName
}" --watch=false' --export-json ${test.output}_${slugify(test.testName, {
remove: /[*+~.()'"!:@\\/]/g,
})}.json`
)
// Run the commands sequentially
runCommandsSequentially(commands)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment