diff --git a/scripts/create-test/test-boilerplate.ts b/scripts/create-test/boilerplates/default.ts similarity index 100% rename from scripts/create-test/test-boilerplate.ts rename to scripts/create-test/boilerplates/default.ts diff --git a/scripts/create-test/create-test.js b/scripts/create-test/create-test.js index c0f27f8891e..765993959d1 100644 --- a/scripts/create-test/create-test.js +++ b/scripts/create-test/create-test.js @@ -17,15 +17,20 @@ const version = "2.0.1"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const projectRoot = path.join(__dirname, "..", ".."); -const boilerplateFilePath = path.join(__dirname, "test-boilerplate.ts"); -const choices = [ - { label: "Move", dir: "moves" }, - { label: "Ability", dir: "abilities" }, - { label: "Item", dir: "items" }, - { label: "Mystery Encounter", dir: "mystery-encounter/encounters" }, - { label: "Utils", dir: "utils" }, - { label: "UI", dir: "ui" }, -]; + +const choices = /** @type {const} */ (["Move", "Ability", "Item", "Reward", "Mystery Encounter", "Utils", "UI"]); +/** @typedef {choices[number]} choiceType */ + +/** @satisfies {{[k in choiceType]: string}} */ +const choicesToDirs = /** @type {const} */ ({ + Move: "moves", + Ability: "abilities", + Item: "items", + Reward: "rewards", + "Mystery Encounter": "mystery-encounter/encounters", + Utils: "utils", + UI: "ui", +}); //#endregion //#region Functions @@ -41,48 +46,47 @@ function getTestFolderPath(...folders) { /** * Prompts the user to select a type via list. - * @returns {Promise<{selectedOption: {label: string, dir: string}}>} the selected type + * @returns {Promise} the selected type */ async function promptTestType() { - const typeAnswer = await inquirer + /** @type {choiceType | "EXIT"} */ + const choice = await inquirer .prompt([ { type: "list", name: "selectedOption", message: "What type of test would you like to create?", - choices: [...choices.map(choice => ({ name: choice.label, value: choice })), { name: "EXIT", value: "N/A" }], + choices: [...choices, "EXIT"], }, ]) - .then(ans => ans.selectedOption); + .then(ta => ta.selectedOption); - if (typeAnswer.name === "EXIT") { + if (choice === "EXIT") { console.log("Exiting..."); return process.exit(0); } - if (!choices.some(choice => choice.dir === typeAnswer.dir)) { - console.error(`Please provide a valid type: (${choices.map(choice => choice.label).join(", ")})!`); - return await promptTestType(); - } - return typeAnswer; + return choice; } /** * Prompts the user to provide a file name. - * @param {string} selectedType - * @returns {Promise<{userInput: string}>} the selected file name + * @param {choiceType} selectedType The chosen string (used to display console logs) + * @returns {Promise} the selected file name */ async function promptFileName(selectedType) { - /** @type {{userInput: string}} */ - const fileNameAnswer = await inquirer.prompt([ - { - type: "input", - name: "userInput", - message: `Please provide the name of the ${selectedType}:`, - }, - ]); + /** @type {string} */ + const fileNameAnswer = await inquirer + .prompt([ + { + type: "input", + name: "userInput", + message: `Please provide the name of the ${selectedType}.`, + }, + ]) + .then(fa => fa.userInput); - if (!fileNameAnswer.userInput || fileNameAnswer.userInput.trim().length === 0) { + if (fileNameAnswer.trim().length === 0) { console.error("Please provide a valid file name!"); return await promptFileName(selectedType); } @@ -90,51 +94,66 @@ async function promptFileName(selectedType) { return fileNameAnswer; } +/** + * Obtain the path to the boilerplate file based on the current option. + * @param {choiceType} choiceType The choice selected + * @returns {string} The path to the boilerplate file + */ +function getBoilerplatePath(choiceType) { + switch (choiceType) { + // case "Reward": + // return path.join(__dirname, "boilerplates/reward.ts"); + default: + return path.join(__dirname, "boilerplates/default.ts"); + } +} + /** * Runs the interactive test:create "CLI" * @returns {Promise} */ async function runInteractive() { - console.group(chalk.grey(`Create Test - v${version}\n`)); + console.group(chalk.grey(`๐Ÿงช Create Test - v${version}\n`)); try { - const typeAnswer = await promptTestType(); - const fileNameAnswer = await promptFileName(typeAnswer.selectedOption.label); + const choice = await promptTestType(); + const fileNameAnswer = await promptFileName(choice); - const type = typeAnswer.selectedOption; // Convert fileName from snake_case or camelCase to kebab-case - const fileName = fileNameAnswer.userInput + const fileName = fileNameAnswer .replace(/_+/g, "-") // Convert snake_case (underscore) to kebab-case (dashes) .replace(/([a-z])([A-Z])/g, "$1-$2") // Convert camelCase to kebab-case .replace(/\s+/g, "-") // Replace spaces with dashes .toLowerCase(); // Ensure all lowercase - // Format the description for the test case + // Format the description for the test case in Title Case const formattedName = fileName.replace(/-/g, " ").replace(/\b\w/g, char => char.toUpperCase()); + const description = `${choice} - ${formattedName}`; + // Determine the directory based on the type - const dir = getTestFolderPath(type.dir); - const description = `${type.label} - ${formattedName}`; + const localDir = choicesToDirs[choice]; + const absoluteDir = getTestFolderPath(localDir); // Define the content template - const content = fs.readFileSync(boilerplateFilePath, "utf8").replace("{{description}}", description); + const content = fs.readFileSync(getBoilerplatePath(choice), "utf8").replace("{{description}}", description); // Ensure the directory exists - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); + if (!fs.existsSync(absoluteDir)) { + fs.mkdirSync(absoluteDir, { recursive: true }); } // Create the file with the given name - const filePath = path.join(dir, `${fileName}.test.ts`); + const filePath = path.join(absoluteDir, `${fileName}.test.ts`); if (fs.existsSync(filePath)) { - console.error(chalk.red.bold(`\nโœ— File "${fileName}.test.ts" already exists!\n`)); + console.error(chalk.red.bold(`โœ— File "${fileName}.test.ts" already exists!\n`)); process.exit(1); } // Write the template content to the file fs.writeFileSync(filePath, content, "utf8"); - console.log(chalk.green.bold(`\nโœ” File created at: test/${type.dir}/${fileName}.test.ts\n`)); + console.log(chalk.green.bold(`โœ” File created at: test/${localDir}/${fileName}.test.ts\n`)); console.groupEnd(); } catch (err) { console.error(chalk.red("โœ— Error: ", err.message));