[Dev] Added ability to pass in test type to create-test script from CLI (#6601)

This commit is contained in:
Bertie690 2025-09-28 00:40:56 -04:00 committed by GitHub
parent cfd81db6ee
commit 322f18387d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -11,21 +11,26 @@
*/ */
import fs from "node:fs"; import fs from "node:fs";
import path from "node:path"; import path, { join } from "node:path";
import { fileURLToPath } from "node:url";
import chalk from "chalk"; import chalk from "chalk";
import inquirer from "inquirer"; import inquirer from "inquirer";
//#region Constants //#region Constants
const version = "2.0.1"; const version = "2.0.2";
// Get the directory name of the current module file // Get the directory name of the current module file
const __filename = fileURLToPath(import.meta.url); const __dirname = import.meta.dirname;
const __dirname = path.dirname(__filename);
const projectRoot = path.join(__dirname, "..", ".."); const projectRoot = path.join(__dirname, "..", "..");
const choices = /** @type {const} */ (["Move", "Ability", "Item", "Reward", "Mystery Encounter", "Utils", "UI"]); const choices = /** @type {const} */ (["Move", "Ability", "Item", "Reward", "Mystery Encounter", "Utils", "UI"]);
/** @typedef {choices[number]} choiceType */ /** @typedef {typeof choices[number]} choiceType */
/**
* Object mapping choice types to extra names they can be used with from CLI.
* @satisfies {Partial<Record<choiceType, readonly string[]>>}
*/
const cliAliases = {
"Mystery Encounter": ["ME"],
};
/** @satisfies {{[k in choiceType]: string}} */ /** @satisfies {{[k in choiceType]: string}} */
const choicesToDirs = /** @type {const} */ ({ const choicesToDirs = /** @type {const} */ ({
@ -56,8 +61,8 @@ function getTestFolderPath(...folders) {
*/ */
async function promptTestType() { async function promptTestType() {
/** @type {choiceType | "EXIT"} */ /** @type {choiceType | "EXIT"} */
const choice = await inquirer const choice = (
.prompt([ await inquirer.prompt([
{ {
type: "list", type: "list",
name: "selectedOption", name: "selectedOption",
@ -65,7 +70,7 @@ async function promptTestType() {
choices: [...choices, "EXIT"], choices: [...choices, "EXIT"],
}, },
]) ])
.then(ta => ta.selectedOption); ).selectedOption;
if (choice === "EXIT") { if (choice === "EXIT") {
console.log("Exiting..."); console.log("Exiting...");
@ -82,15 +87,15 @@ async function promptTestType() {
*/ */
async function promptFileName(selectedType) { async function promptFileName(selectedType) {
/** @type {string} */ /** @type {string} */
const fileNameAnswer = await inquirer const fileNameAnswer = (
.prompt([ await inquirer.prompt([
{ {
type: "input", type: "input",
name: "userInput", name: "userInput",
message: `Please provide the name of the ${selectedType}.`, message: `Please provide the name of the ${selectedType}.`,
}, },
]) ])
.then(fa => fa.userInput); ).userInput;
if (fileNameAnswer.trim().length === 0) { if (fileNameAnswer.trim().length === 0) {
console.error("Please provide a valid file name!"); console.error("Please provide a valid file name!");
@ -115,14 +120,58 @@ function getBoilerplatePath(choiceType) {
} }
/** /**
* Runs the interactive test:create "CLI" * Parse `process.argv` and get the test type if it exists.
* @returns {choiceType | undefined}
* The type of choice the CLI args corresponds to, or `undefined` if none were specified.
* Will set `process.exitCode` to a non-zero integer if args are invalid.
*/
function convertArgsToTestType() {
// If the first argument is a test name, use that as the test name
const args = process.argv.slice(2);
if (args[0] == null) {
return;
}
// Check for a direct match, falling back to alias checking.
const choiceName = choices.find(c => c.toLowerCase() === args[0].toLowerCase());
if (choiceName) {
return choiceName;
}
const alias = /** @type {(keyof cliAliases)[]} */ (Object.keys(cliAliases)).find(k =>
cliAliases[k].some(a => a.toLowerCase() === args[0].toLowerCase()),
);
if (alias) {
return alias;
}
console.error(
chalk.red.bold(`✗ Invalid type of test file specified: ${args[0]}!
Valid types: ${chalk.blue(choices.join(", "))}`),
);
process.exitCode = 1;
return;
}
/**
* Run the interactive `test:create` CLI.
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
async function runInteractive() { async function runInteractive() {
console.group(chalk.grey(`🧪 Create Test - v${version}\n`)); console.group(chalk.grey(`🧪 Create Test - v${version}\n`));
const cliTestType = convertArgsToTestType();
if (process.exitCode) {
return;
}
// TODO: Add a help command
try { try {
const choice = await promptTestType(); let choice;
if (cliTestType) {
console.log(chalk.blue(`Using ${cliTestType} as test type from CLI...`));
choice = cliTestType;
} else {
choice = await promptTestType();
}
const fileNameAnswer = await promptFileName(choice); const fileNameAnswer = await promptFileName(choice);
// Convert fileName from snake_case or camelCase to kebab-case // Convert fileName from snake_case or camelCase to kebab-case
@ -159,7 +208,7 @@ async function runInteractive() {
// Write the template content to the file // Write the template content to the file
fs.writeFileSync(filePath, content, "utf8"); fs.writeFileSync(filePath, content, "utf8");
console.log(chalk.green.bold(`✔ File created at: test/${localDir}/${fileName}.test.ts\n`)); console.log(chalk.green.bold(`✔ File created at: ${join("test", localDir, fileName)}.test.ts\n`));
console.groupEnd(); console.groupEnd();
} catch (err) { } catch (err) {
console.error(chalk.red("✗ Error: ", err)); console.error(chalk.red("✗ Error: ", err));