UNPKG

@minecraft/creator-tools

Version:

Minecraft Creator Tools command line and libraries.

577 lines (575 loc) 23.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const chai_1 = require("chai"); const Project_1 = require("../app/Project"); const CartoApp_1 = require("../app/CartoApp"); const NodeStorage_1 = require("../local/NodeStorage"); const Database_1 = require("../minecraft/Database"); const LocalEnvironment_1 = require("../local/LocalEnvironment"); const StorageUtilities_1 = require("../storage/StorageUtilities"); const child_process_1 = require("child_process"); const stringio_1 = require("@rauschma/stringio"); const fs = require("fs"); const Utilities_1 = require("../core/Utilities"); const ProjectInfoSet_1 = require("../info/ProjectInfoSet"); const IProjectInfoData_1 = require("../info/IProjectInfoData"); const ProjectUtilities_1 = require("../app/ProjectUtilities"); const axios_1 = require("axios"); CartoApp_1.default.hostType = CartoApp_1.HostType.testLocal; let carto = undefined; let localEnv = undefined; let scenariosFolder = undefined; let resultsFolder = undefined; let sampleFolder = undefined; localEnv = new LocalEnvironment_1.default(false); (async () => { CartoApp_1.default.localFolderExists = _localFolderExists; CartoApp_1.default.ensureLocalFolder = _ensureLocalFolder; const testRootPath = NodeStorage_1.default.ensureEndsWithDelimiter(__dirname) + "/../../test/"; const sampleContentRootPath = NodeStorage_1.default.ensureEndsWithDelimiter(__dirname) + "/../../../"; const scenariosStorage = new NodeStorage_1.default(testRootPath, "scenarios"); scenariosFolder = scenariosStorage.rootFolder; await scenariosFolder.ensureExists(); const resultsStorage = new NodeStorage_1.default(testRootPath, "results"); resultsFolder = resultsStorage.rootFolder; await resultsFolder.ensureExists(); const sampleContentStorage = new NodeStorage_1.default(sampleContentRootPath, "samplecontent"); sampleFolder = sampleContentStorage.rootFolder; await sampleFolder.ensureExists(); CartoApp_1.default.prefsStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "prefs" + NodeStorage_1.default.platformFolderDelimiter, ""); CartoApp_1.default.projectsStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "projects" + NodeStorage_1.default.platformFolderDelimiter, ""); CartoApp_1.default.packStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "packs" + NodeStorage_1.default.platformFolderDelimiter, ""); CartoApp_1.default.worldStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "worlds" + NodeStorage_1.default.platformFolderDelimiter, ""); CartoApp_1.default.deploymentStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "deployment" + NodeStorage_1.default.platformFolderDelimiter, ""); CartoApp_1.default.workingStorage = new NodeStorage_1.default(localEnv.utilities.testWorkingPath + "working" + NodeStorage_1.default.platformFolderDelimiter, ""); const coreStorage = new NodeStorage_1.default(__dirname + "/../../public/data/content/", ""); Database_1.default.contentFolder = coreStorage.rootFolder; await CartoApp_1.default.init(); // carto app init does something here that, if removed, causes these tests to fail. Also, await needs to be here. carto = CartoApp_1.default.carto; if (!carto) { return; } await carto.load(); run(); })(); function _ensureLocalFolder(path) { const ls = new NodeStorage_1.default(path, ""); return ls.rootFolder; } async function _localFolderExists(path) { const ls = new NodeStorage_1.default(path, ""); return await ls.rootFolder.exists(); } function removeResultFolder(scenarioName) { if (resultsFolder) { const path = StorageUtilities_1.default.ensureEndsWithDelimiter(resultsFolder.fullPath) + StorageUtilities_1.default.ensureEndsWithDelimiter(scenarioName); const exists = fs.existsSync(path); if (exists && !StorageUtilities_1.default.isPathRiskyForDelete(path)) try { fs.rmSync(path, { recursive: true, }); } catch (e) { console.log("Error occurred during rmSync on '" + path + "'"); throw e; } } } function ensureResultFolder(scenarioName) { if (resultsFolder) { const path = StorageUtilities_1.default.ensureEndsWithDelimiter(resultsFolder.fullPath) + StorageUtilities_1.default.ensureEndsWithDelimiter(scenarioName); if (!fs.existsSync(path)) // @ts-ignore fs.mkdirSync(path, { recursive: true, }); } } describe("worldCommand", async () => { let exitCode = null; const stdoutLines = []; const stderrLines = []; before(function (done) { this.timeout(10000); removeResultFolder("worldCommand"); ensureResultFolder("worldCommand"); const process = (0, child_process_1.spawn)("node", [ " ./../toolbuild/jsn/cli", "world", "set", "-i", "./test/results/worldCommand", "-betaapis", "-o", "./test/results/worldCommand/", ]); collectLines(process.stdout, stdoutLines); collectLines(process.stderr, stderrLines); process.on("exit", (code) => { exitCode = code; done(); }); }); it("should have no stderr lines", async () => { chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|"); }).timeout(10000); it("exit code should be zero", async () => { chai_1.assert.equal(exitCode, 0); }).timeout(10000); it("output matches", async () => { await folderMatches("worldCommand"); }); }); describe("serveCommandValidate", async () => { let exitCode = null; const stdoutLines = []; const stderrLines = []; let process = null; before(function (done) { this.timeout(20000); removeResultFolder("serveCommandValidate"); const passcode = Utilities_1.default.createUuid().substring(0, 8); if (!sampleFolder) { throw new Error("Sample folder does not exist."); } sampleFolder .ensureFileFromRelativePath("/addon/build/packages/aop_moremobs_animationmanifesterrors.zip") .then((sampleFile) => { console.log("Starting web server."); process = (0, child_process_1.spawn)("node", [ " ./../toolbuild/jsn/cli", "serve", "basicwebservices", "localhost", "6126", "-lv", "-once", "-updatepc", passcode, ]); collectLines(process.stdout, stdoutLines); collectLines(process.stderr, stderrLines); sampleFile.loadContent().then(() => { const content = sampleFile.content; Utilities_1.default.sleep(3000).then(() => { console.log("Making validation web request to http://localhost:6126/api/validate/ " + content?.length + " bytes"); axios_1.default .post("http://localhost:6126/api/validate/", content, { headers: { mctpc: passcode, "content-type": "application/zip" }, method: "POST", }) .then((response) => { ensureJsonMatchesScenario(response.data, "serveCommandValidate"); if (response === undefined) { throw new Error("Could not connect to server."); } if (process) { process.on("exit", (code) => { exitCode = code; process = null; done(); }); } }); }); }); }); }); it("should have no stderr lines", async () => { if (process) { process.kill(); process = null; } chai_1.assert.equal(stderrLines.length, 0, "Error: " + stderrLines.join("\n") + "|"); }).timeout(10000); it("exit code should be zero", async () => { if (process) { process.kill(); process = null; } chai_1.assert.equal(exitCode, 0); }).timeout(10000); it("output matches", async () => { await folderMatches("serveCommandValidate"); }); after(function () { if (process) { console.log("Ending web process in serverCommandValidate after function."); process.kill(); process = null; } }); }); describe("serveCommandValidateAddon", async () => { let exitCode = null; const stdoutLines = []; const stderrLines = []; let process = null; before(function (done) { this.timeout(20000); removeResultFolder("serveCommandValidateAddon"); const passcode = Utilities_1.default.createUuid().substring(0, 8); if (!sampleFolder) { throw new Error("Sample folder does not exist."); } sampleFolder .ensureFileFromRelativePath("/addon/build/packages/aop_moremobs_animationmanifesterrors.zip") .then((sampleFile) => { console.log("Starting web server."); process = (0, child_process_1.spawn)("node", [ " ./../toolbuild/jsn/cli", "serve", "basicwebservices", "localhost", "6126", "-lv", "-once", "-updatepc", passcode, ]); collectLines(process.stdout, stdoutLines); collectLines(process.stderr, stderrLines); sampleFile.loadContent().then(() => { const content = sampleFile.content; Utilities_1.default.sleep(3000).then(() => { console.log("Making validation web request to http://localhost:6126/api/validate/ " + content?.length + " bytes"); axios_1.default .post("http://localhost:6126/api/validate/", content, { headers: { mctpc: passcode, "content-type": "application/zip", mctsuite: "addon" }, method: "POST", }) .then((response) => { ensureJsonMatchesScenario(response.data, "serveCommandValidateAddon"); if (response === undefined) { throw new Error("Could not connect to server."); } if (process) { process.on("exit", (code) => { exitCode = code; process = null; done(); }); } }); }); }); }); }); it("should have no stderr lines", async () => { if (process) { process.kill(); process = null; } chai_1.assert.equal(stderrLines.length, 0, "Error: " + stderrLines.join("\n") + "|"); }).timeout(10000); it("exit code should be zero", async () => { if (process) { process.kill(); process = null; } chai_1.assert.equal(exitCode, 0); }).timeout(10000); it("output matches", async () => { await folderMatches("serveCommandValidateAddon"); }); after(function () { if (process) { console.log("Ending web process in serverCommandValidateAddon after function."); process.kill(); process = null; } }); }); describe("createCommandAddonStarter", async () => { let exitCode = null; const stdoutLines = []; const stderrLines = []; let project = null; let allProjectInfoSet = null; let addonProjectInfoSet = null; before(function (done) { this.timeout(10000); removeResultFolder("createCommandAddonStarter"); const process = (0, child_process_1.spawn)("node", [ " ./../toolbuild/jsn/cli", "create", "testerName", "addonStarter", "testerCreatorName", "testerDescription", "-o", "./test/results/createCommandAddonStarter/", ]); collectLines(process.stdout, stdoutLines); collectLines(process.stderr, stderrLines); process.on("exit", (code) => { exitCode = code; (0, chai_1.assert)(carto, "Carto is not properly initialized"); project = new Project_1.default(carto, "createCommandAddonStarter", null); allProjectInfoSet = new ProjectInfoSet_1.default(project, IProjectInfoData_1.ProjectInfoSuite.default); addonProjectInfoSet = new ProjectInfoSet_1.default(project, IProjectInfoData_1.ProjectInfoSuite.cooperativeAddOn); project.autoDeploymentMode = Project_1.ProjectAutoDeploymentMode.noAutoDeployment; project.localFolderPath = __dirname + "/../../test/results/createCommandAddonStarter/"; project.inferProjectItemsFromFiles().then(() => { (0, chai_1.assert)(project); ProjectUtilities_1.default.setIsAddon(project).then(() => { (0, chai_1.assert)(allProjectInfoSet); allProjectInfoSet.generateForProject().then(() => { (0, chai_1.assert)(addonProjectInfoSet); addonProjectInfoSet.generateForProject().then(() => { done(); }); }); }); }); }); }); it("should have no stderr lines", async () => { chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|"); }).timeout(10000); it("exit code should be zero", async () => { chai_1.assert.equal(exitCode, 0); }).timeout(10000); it("should have 17 project items", async () => { (0, chai_1.assert)(project); chai_1.assert.equal(project.items.length, 17); }).timeout(10000); it("main validation should have 0 errors, failures, or warnings", async () => { (0, chai_1.assert)(allProjectInfoSet); chai_1.assert.equal(allProjectInfoSet.errorFailWarnCount, 0, allProjectInfoSet.errorFailWarnString); }).timeout(10000); it("addon validation should have 0 errors, failures, or warnings", async () => { (0, chai_1.assert)(addonProjectInfoSet); chai_1.assert.equal(addonProjectInfoSet.errorFailWarnCount, 0, addonProjectInfoSet.errorFailWarnString); }).timeout(10000); it("output matches", async () => { await folderMatches("createCommandAddonStarter", ["manifest.json"]); }); }); describe("validateAddons1WellFormedCommand", async () => { let exitCode = null; const stdoutLines = []; const stderrLines = []; before(function (done) { this.timeout(10000); removeResultFolder("validateAddons1WellFormedCommand"); const process = (0, child_process_1.spawn)("node", [ " ./../toolbuild/jsn/cli", "val", "addon", "-i", "./../samplecontent/addon/build/content1", "-o", "./test/results/validateAddons1WellFormedCommand/", ]); collectLines(process.stdout, stdoutLines); collectLines(process.stderr, stderrLines); process.on("exit", (code) => { exitCode = code; done(); }); }); it("should have no stderr lines", function (done) { chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|"); done(); }).timeout(10000); it("exit code should be zero", function (done) { chai_1.assert.equal(exitCode, 0); done(); }).timeout(10000); it("output matches", async function () { await folderMatches("validateAddons1WellFormedCommand"); }).timeout(10000); }); describe("validateAddons2AnimationManifestErrorsCommand", async () => { let exitCode = null; const stdoutLines = []; const stderrLines = []; before(function (done) { this.timeout(10000); removeResultFolder("validateAddons2AnimationManifestErrorsCommand"); const process = (0, child_process_1.spawn)("node", [ " ./../toolbuild/jsn/cli", "val", "addon", "-i", "./../samplecontent/addon/build/content2", "-o", "./test/results/validateAddons2AnimationManifestErrorsCommand/", ]); collectLines(process.stdout, stdoutLines); collectLines(process.stderr, stderrLines); process.on("exit", (code) => { exitCode = code; done(); }); }); it("should have no stderr lines", async (done) => { chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|"); done(); }).timeout(10000); it("exit code should be zero", async (done) => { chai_1.assert.equal(exitCode, 0); done(); }).timeout(10000); it("output matches", async function () { await folderMatches("validateAddons2AnimationManifestErrorsCommand"); }).timeout(10000); }); describe("validateAddons3ExtraneousStuffUsesMinecraftCommand", async () => { let exitCode = null; const stdoutLines = []; const stderrLines = []; before(function (done) { this.timeout(20000); removeResultFolder("validateAddons3ExtraneousStuffUsesMinecraftCommand"); const process = (0, child_process_1.spawn)("node", [ " ./../toolbuild/jsn/cli", "val", "addon", "-i", "./../samplecontent/addon/build/content3", "-o", "./test/results/validateAddons3ExtraneousStuffUsesMinecraftCommand/", ]); collectLines(process.stdout, stdoutLines); collectLines(process.stderr, stderrLines); process.on("exit", (code) => { exitCode = code; done(); }); }); it("should have no stderr lines", async (done) => { chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|"); done(); }).timeout(10000); it("exit code should be zero", async (done) => { chai_1.assert.equal(exitCode, 0); done(); }).timeout(10000); it("output matches", async function () { await folderMatches("validateAddons3ExtraneousStuffUsesMinecraftCommand"); }); }); describe("validateAddons3PlatformVersions", async () => { let exitCode = null; const stdoutLines = []; const stderrLines = []; before(function (done) { this.timeout(20000); removeResultFolder("validateAddons3PlatformVersions"); const process = (0, child_process_1.spawn)("node", [ " ./../toolbuild/jsn/cli", "val", "currentplatform", "-i", "./../samplecontent/addon/build/content3", "-o", "./test/results/validateAddons3PlatformVersions/", ]); collectLines(process.stdout, stdoutLines); collectLines(process.stderr, stderrLines); process.on("exit", (code) => { exitCode = code; done(); }); }); it("should have no stderr lines", async (done) => { chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|"); done(); }).timeout(10000); it("exit code should be zero", async (done) => { chai_1.assert.equal(exitCode, 0); done(); }).timeout(10000); it("output matches", async function () { await folderMatches("validateAddons3PlatformVersions"); }); }); describe("validateLinkErrors", async () => { let exitCode = null; const stdoutLines = []; const stderrLines = []; before(function (done) { this.timeout(20000); removeResultFolder("validateLinkErrors"); const process = (0, child_process_1.spawn)("node", [ " ./../toolbuild/jsn/cli", "val", "all", "-i", "./../samplecontent/addon/build/content_linkerrors", "-o", "./test/results/validateLinkErrors/", ]); collectLines(process.stdout, stdoutLines); collectLines(process.stderr, stderrLines); process.on("exit", (code) => { exitCode = code; done(); }); }); it("should have no stderr lines", async (done) => { chai_1.assert.equal(stderrLines.length, 0, "Error: |" + stderrLines.join("\n") + "|"); done(); }).timeout(10000); it("exit code should be zero", async (done) => { chai_1.assert.equal(exitCode, 0); done(); }).timeout(10000); it("output matches", async function () { await folderMatches("validateLinkErrors"); }); }); async function collectLines(readable, data) { for await (const line of (0, stringio_1.chunksToLinesAsync)(readable)) { if (line !== undefined && line.length >= 0) { let lineUp = line.replace(/\\n/g, ""); lineUp = lineUp.replace(/\\r/g, ""); // ignore any lines about the debugger. if (lineUp.indexOf("ebugger") <= 0) { //console.log(lineUp); data.push(lineUp); } } } } async function folderMatches(scenarioName, excludeFileList) { if (!scenariosFolder || !resultsFolder) { chai_1.assert.fail("Not properly initialized"); } const scenarioOutFolder = resultsFolder.ensureFolder(scenarioName); await scenarioOutFolder.ensureExists(); const scenarioFolder = scenariosFolder.ensureFolder(scenarioName); const isEqual = await StorageUtilities_1.default.folderContentsEqual(scenarioFolder, scenarioOutFolder, excludeFileList, true, [ "generatorVersion", "uuid", "version", ]); (0, chai_1.assert)(isEqual.result, "Folder '" + scenarioFolder.fullPath + "' does not match for scenario '" + scenarioName + "', " + isEqual.reason); } // eslint-disable-next-line @typescript-eslint/no-unused-vars async function ensureJsonMatchesScenario(obj, scenarioName) { if (!scenariosFolder || !resultsFolder) { chai_1.assert.fail("Not properly initialized"); } const dataObjectStr = JSON.stringify(obj, null, 2); const scenarioOutFolder = resultsFolder.ensureFolder(scenarioName); await scenarioOutFolder.ensureExists(); const outFile = scenarioOutFolder.ensureFile("report.json"); outFile.setContent(dataObjectStr); await outFile.saveContent(); const scenarioFile = scenariosFolder.ensureFolder(scenarioName).ensureFile("report.json"); const exists = await scenarioFile.exists(); (0, chai_1.assert)(exists, "report.json file for scenario '" + scenarioName + "' does not exist."); const isEqual = await StorageUtilities_1.default.fileContentsEqual(scenarioFile, outFile, true, [ "generatorVersion", "uuid", "version", ]); (0, chai_1.assert)(isEqual, "report.json file '" + scenarioFile.fullPath + "' does not match for scenario '" + scenarioName + "'"); } //# sourceMappingURL=../maps/test/CommandLineTest.js.map