diff --git a/src/MPQEditor/MPQEditor.ts b/src/MPQEditor/MPQEditor.ts index f82e878a..17533c79 100644 --- a/src/MPQEditor/MPQEditor.ts +++ b/src/MPQEditor/MPQEditor.ts @@ -15,6 +15,7 @@ */ import * as fs from "fs"; +import * as glob from "glob"; import * as path from "path"; import * as vscode from "vscode"; @@ -74,6 +75,40 @@ export class MPQEditorProvider implements vscode.CustomTextEditorProvider { return undefined; } + /** + * @brief A helper function to find unoccupied mpq file-name + * @returns valid file name for mpq configuration or undefined on failure + * @throw Error, when input is invalid (e.g. baseMPQName is empty) + */ + public static findMPQName( + baseMPQName: string, + dirPath: string + ): string | undefined { + if (baseMPQName.length === 0) { + throw new Error("Invalid mixed precision quantization file name"); + } + + const baseName = baseMPQName; + let mpqName: string | undefined = undefined; + + const options = { cwd: dirPath }; + // set maximal trials as maximal quantity of files + 1 + const files = glob.sync("*" + MPQEditorProvider.fileExtension, options); + const maxMPQIndex = files.length + 1; + + for (let i = 0; i < maxMPQIndex; i++) { + mpqName = baseMPQName + MPQEditorProvider.fileExtension; + const mpqPath: string = path.join(dirPath, mpqName); + if (!fs.existsSync(mpqPath)) { + break; + } + baseMPQName = baseName + `(${i + 1})`; + mpqName = undefined; + } + + return mpqName; + } + constructor(private readonly context: vscode.ExtensionContext) {} /** diff --git a/src/Tests/MPQEditor/MPQEditor.test.ts b/src/Tests/MPQEditor/MPQEditor.test.ts index e0a83af5..51b1ae6c 100644 --- a/src/Tests/MPQEditor/MPQEditor.test.ts +++ b/src/Tests/MPQEditor/MPQEditor.test.ts @@ -59,5 +59,38 @@ suite("MPQEditor", function () { assert.isDefined(retValue); }); }); + + suite("#findMPQName", function () { + test("test findMPQName", function () { + const baseMPQName: string = "model"; + const dirPath: string = testBuilder.dirInTemp; + + const content = ` + empty content + `; + + let targetNames: string[] = [ + "model.mpq.json", + "model(1).mpq.json", + "model(2).mpq.json", + "model(3).mpq.json", + ]; + + for (let i = 0; i < targetNames.length; i++) { + // Get file paths inside the temp directory + const mpqName = MPQEditorProvider.findMPQName(baseMPQName, dirPath); + assert.isDefined(mpqName); + assert.strictEqual(mpqName, targetNames[i]); + + // create dummy mpq.json file + testBuilder.writeFileSync(mpqName!, content); + } + }); + + test("NEG: findMPQName throws on empty string", function () { + const dirPath: string = testBuilder.dirInTemp; + assert.throws(() => MPQEditorProvider.findMPQName("", dirPath)); + }); + }); }); });