UNPKG

@hkvstore/taco-cli

Version:

taco-cli is a command-line interface for rapid Apache Cordova development (forked from Microsoft taco-cli)

457 lines (455 loc) 18.2 kB
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for details. /// <reference path="../../typings/mocha.d.ts" /> /// <reference path="../../typings/node.d.ts" /> /// <reference path="../../typings/should.d.ts" /> /// <reference path="../../typings/cordovaExtensions.d.ts" /> /// <reference path="../../typings/del.d.ts" /> /// <reference path="../../typings/remoteBuild.d.ts" /> "use strict"; /* tslint:disable:no-var-requires */ // var require needed for should module to work correctly // Note not import: We don't want to refer to shouldModule, but we need the require to occur since it modifies the prototype of Object. var shouldModule = require("should"); var del = require("del"); var fs = require("fs"); var http = require("http"); var os = require("os"); var path = require("path"); var Q = require("q"); var querystring = require("querystring"); var rimraf = require("rimraf"); var util = require("util"); var buildAndRunTelemetry = require("./buildAndRunTelemetry"); var Build = require("../cli/build"); var kitHelper = require("../cli/utils/kitHelper"); var RemoteMock = require("./utils/remoteMock"); var ServerMock = require("./utils/serverMock"); var TacoUtility = require("taco-utils"); var BuildInfo = TacoUtility.BuildInfo; var Command = buildAndRunTelemetry.Command; var utils = TacoUtility.UtilHelper; var CommandHelper = require("./utils/commandHelper"); var build = CommandHelper.getCommand("build"); var create = CommandHelper.getCommand("create"); describe("taco build", function () { var _this = this; var testHttpServer; var tacoHome = path.join(os.tmpdir(), "taco-cli", "build"); var originalCwd; var vcordova = "4.0.0"; var projectPath = path.join(tacoHome, "example"); function createCleanProject() { // Create a dummy test project with no platforms added utils.createDirectoryIfNecessary(tacoHome); process.chdir(tacoHome); return Q.denodeify(del)("example").then(function () { var args = ["example", "--cordova", vcordova]; return create.run(args); }).then(function () { process.chdir(projectPath); }); } var remoteServerConfiguration = { host: "localhost", port: 3000, secure: false, mountPoint: "cordova" }; before(function (mocha) { originalCwd = process.cwd(); // Set up mocked out resources process.env["TACO_UNIT_TEST"] = true; // Use a dummy home location so we don't trash any real configurations process.env["TACO_HOME"] = tacoHome; // Force KitHelper to fetch the package fresh kitHelper.kitPackagePromise = null; // Create a mocked out remote server so we can specify how it reacts testHttpServer = http.createServer(); var port = 3000; testHttpServer.listen(port); // Reduce the delay when polling for a change in status Build.remoteBuild.PING_INTERVAL = 10; // Configure a dummy platform "test" to use the mocked out remote server RemoteMock.saveConfig("test", remoteServerConfiguration).done(function () { return mocha(); }, mocha); }); after(function (done) { process.chdir(originalCwd); kitHelper.kitPackagePromise = null; testHttpServer.close(); rimraf(tacoHome, function (err) { done(); }); // ignore errors }); beforeEach(function (mocha) { Q.fcall(createCleanProject) .done(function () { return mocha(); }, mocha); }); afterEach(function (mocha) { // Remove the project that we operated on process.chdir(tacoHome); del("example", mocha); }); var buildRun = function (args) { return build.run(args); }; it("should make the correct sequence of calls for 'taco build --remote test'", function (mocha) { var buildArguments = ["--remote", "test"]; var configuration = "debug"; var buildNumber = 12340; // Mock out the server on the other side var sequence = [ { expectedUrl: "/cordova/build/tasks?" + querystring.stringify({ command: "build", vcordova: vcordova, vcli: require(path.join(__dirname, "..", "package.json")).version, cfg: configuration, platform: "test" }), head: { "Content-Type": "application/json", "Content-Location": "http://localhost:3000/cordova/build/tasks/" + buildNumber }, statusCode: 202, response: JSON.stringify(new BuildInfo({ status: BuildInfo.UPLOADING, buildNumber: buildNumber })), waitForPayload: true }, { expectedUrl: "/cordova/build/tasks/" + buildNumber, head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify(new BuildInfo({ status: BuildInfo.UPLOADED, buildNumber: buildNumber })), waitForPayload: false }, { expectedUrl: "/cordova/build/tasks/" + buildNumber + "/log?offset=0", head: { "Content-Type": "application/json" }, statusCode: 200, response: "1", waitForPayload: false }, { expectedUrl: "/cordova/build/tasks", head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify({ queued: 0, queuedBuilds: [] }), waitForPayload: false }, { expectedUrl: "/cordova/build/tasks/" + buildNumber, head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify(new BuildInfo({ status: BuildInfo.COMPLETE, buildNumber: buildNumber })), waitForPayload: false }, { expectedUrl: "/cordova/build/tasks/" + buildNumber + "/log?offset=1", head: { "Content-Type": "application/json" }, statusCode: 200, response: "2", waitForPayload: false }, { expectedUrl: util.format("/cordova/files/%d/cordovaApp/plugins/%s.json", buildNumber, "test"), head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify({}), waitForPayload: false }, ]; var serverFunction = ServerMock.generateServerFunction(mocha, sequence); testHttpServer.on("request", serverFunction); Q(buildArguments).then(buildRun).finally(function () { testHttpServer.removeListener("request", serverFunction); }).done(function () { mocha(); }, function (err) { mocha(err); }); }); it("should report an error if the remote build fails", function (mocha) { var buildArguments = ["--remote", "test"]; var configuration = "debug"; var buildNumber = 12341; // Mock out the server on the other side var sequence = [ { expectedUrl: "/cordova/build/tasks?" + querystring.stringify({ command: "build", vcordova: vcordova, vcli: require(path.join(__dirname, "..", "package.json")).version, cfg: configuration, platform: "test" }), head: { "Content-Type": "application/json", "Content-Location": "http://localhost:3000/cordova/build/tasks/" + buildNumber }, statusCode: 202, response: JSON.stringify(new BuildInfo({ status: BuildInfo.UPLOADING, buildNumber: buildNumber })), waitForPayload: true }, { expectedUrl: "/cordova/build/tasks/" + buildNumber, head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify(new BuildInfo({ status: BuildInfo.UPLOADED, buildNumber: buildNumber })) }, { expectedUrl: "/cordova/build/tasks/" + buildNumber + "/log?offset=0", head: { "Content-Type": "application/json" }, statusCode: 200, response: "1", waitForPayload: false }, { expectedUrl: "/cordova/build/tasks", head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify({ queued: 0, queuedBuilds: [] }), waitForPayload: false }, { expectedUrl: "/cordova/build/tasks/" + buildNumber, head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify(new BuildInfo({ status: BuildInfo.ERROR, buildNumber: buildNumber })) }, { expectedUrl: "/cordova/build/tasks/" + buildNumber + "/log?offset=1", head: { "Content-Type": "text/plain" }, statusCode: 200, response: "Logfile contents" } ]; var serverFunction = ServerMock.generateServerFunction(mocha, sequence); testHttpServer.on("request", serverFunction); Q(buildArguments).then(buildRun).finally(function () { testHttpServer.removeListener("request", serverFunction); }).done(function () { mocha(new Error("The build failing should result in an error")); }, function (err) { mocha(); }); }); it("should attempt incremental builds where possible", function (mocha) { var buildArguments = ["--remote", "test"]; var configuration = "debug"; var buildNumber = 12342; var buildInfoDir = path.join("remote", "test", configuration); utils.createDirectoryIfNecessary(buildInfoDir); fs.writeFileSync(path.join(buildInfoDir, "buildInfo.json"), JSON.stringify(new BuildInfo({ status: BuildInfo.COMPLETE, buildNumber: buildNumber }))); // Mock out the server on the other side // Since this test is only whether we attempt incremental builds, we'll let the build fail to make the test shorter var sequence = [ { expectedUrl: "/cordova/build/" + buildNumber, head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify(new BuildInfo({ status: BuildInfo.COMPLETE, buildNumber: buildNumber })) }, { expectedUrl: "/cordova/build/tasks?" + querystring.stringify({ command: "build", vcordova: vcordova, vcli: require(path.join(__dirname, "..", "package.json")).version, cfg: configuration, platform: "test", buildNumber: buildNumber.toString() }), head: { "Content-Type": "application/json", "Content-Location": "http://localhost:3000/cordova/build/tasks/" + buildNumber }, statusCode: 202, response: JSON.stringify(new BuildInfo({ status: BuildInfo.UPLOADING, buildNumber: buildNumber })), waitForPayload: true }, { expectedUrl: "/cordova/build/tasks/" + buildNumber, head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify(new BuildInfo({ status: BuildInfo.ERROR, buildNumber: buildNumber })) }, { expectedUrl: "/cordova/build/tasks/" + buildNumber + "/log?offset=0", head: { "Content-Type": "text/plain" }, statusCode: 200, response: "Logfile contents" } ]; var serverFunction = ServerMock.generateServerFunction(mocha, sequence); testHttpServer.on("request", serverFunction); Q(buildArguments).then(buildRun).finally(function () { testHttpServer.removeListener("request", serverFunction); }).done(function () { mocha(new Error("The build failing should result in an error")); }, function (err) { mocha(); }); }); it("should make the correct sequence of calls for 'taco build --remote test --device'", function (mocha) { var buildArguments = ["--remote", "test", "--device"]; var configuration = "debug"; var buildNumber = 12340; var testZipFile = path.resolve(__dirname, "resources", "empty.zip"); // Mock out the server on the other side var sequence = [ { expectedUrl: "/cordova/build/tasks?" + querystring.stringify({ command: "build", vcordova: vcordova, vcli: require(path.join(__dirname, "..", "package.json")).version, cfg: configuration, platform: "test", options: "--device" }), head: { "Content-Type": "application/json", "Content-Location": "http://localhost:3000/cordova/build/tasks/" + buildNumber }, statusCode: 202, response: JSON.stringify(new BuildInfo({ status: BuildInfo.UPLOADING, buildNumber: buildNumber })), waitForPayload: true }, { expectedUrl: "/cordova/build/tasks/" + buildNumber, head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify(new BuildInfo({ status: BuildInfo.UPLOADED, buildNumber: buildNumber })), waitForPayload: false }, { expectedUrl: "/cordova/build/tasks/" + buildNumber + "/log?offset=0", head: { "Content-Type": "application/json" }, statusCode: 200, response: "1", waitForPayload: false }, { expectedUrl: "/cordova/build/tasks", head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify({ queued: 0, queuedBuilds: [] }), waitForPayload: false }, { expectedUrl: "/cordova/build/tasks/" + buildNumber, head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify(new BuildInfo({ status: BuildInfo.COMPLETE, buildNumber: buildNumber })), waitForPayload: false }, { expectedUrl: "/cordova/build/tasks/" + buildNumber + "/log?offset=1", head: { "Content-Type": "application/json" }, statusCode: 200, response: "2", waitForPayload: false }, { expectedUrl: util.format("/cordova/files/%d/cordovaApp/plugins/%s.json", buildNumber, "test"), head: { "Content-Type": "application/json" }, statusCode: 200, response: JSON.stringify({}), waitForPayload: false }, { expectedUrl: util.format("/cordova/build/%d/download", buildNumber), head: { "Content-Type": "application/zip" }, statusCode: 200, response: JSON.stringify({}), waitForPayload: false, fileToSend: testZipFile }, ]; var serverFunction = ServerMock.generateServerFunction(mocha, sequence); testHttpServer.on("request", serverFunction); Q(buildArguments).then(buildRun).finally(function () { testHttpServer.removeListener("request", serverFunction); }).done(function () { mocha(); }, function (err) { mocha(err); }); }); describe("telemetry", function () { buildAndRunTelemetry.createBuildAndRunTelemetryTests.call(_this, buildRun, Command.Build); }); }); //# sourceMappingURL=build.js.map