@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
JavaScript
// 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" />
;
/* 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