@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
577 lines (575 loc) • 23.8 kB
JavaScript
;
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