UNPKG

@hkvstore/taco-cli

Version:

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

371 lines (369 loc) 16.5 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/archiver.d.ts"/> /// <reference path="../../typings/mocha.d.ts"/> /// <reference path="../../typings/rimraf.d.ts"/> /// <reference path="../../typings/should.d.ts"/> /// <reference path="../../typings/tacoKits.d.ts"/> /// <reference path="../../typings/tacoUtils.d.ts"/> /// <reference path="../../typings/wrench.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"); /* tslint:enable:no-var-requires */ var archiver = require("archiver"); var fs = require("fs"); var os = require("os"); var path = require("path"); var Q = require("q"); var rimraf = require("rimraf"); var wrench = require("wrench"); var TacoErrorCodes = require("../cli/tacoErrorCodes"); var tacoUtils = require("taco-utils"); var templateManager = require("../cli/utils/templateManager"); var utils = tacoUtils.UtilHelper; describe("TemplateManager", function () { // Template info var testTemplateId = "testTemplate"; var testTemplateId2 = "testTemplate2"; var testTemplateId3 = "testTemplate3"; var testKitId = "testKit"; var testDisplayName = "Blank template for the Default kit"; var testDisplayName2 = "Blank Typescript template for the Default kit"; var testDisplayName3 = "Azure conencted services template for the Default kit"; // Project info var testAppId = "testId"; var testAppName = "testAppName"; // Important paths var runFolder = path.resolve(os.tmpdir(), "taco_cli_templates_test_run"); var tacoHome = path.join(runFolder, "taco_home"); var testTemplateKitSrc = path.resolve(__dirname, "resources", "templates", testKitId); var testTemplateNoWwwPath = path.join(testTemplateKitSrc, testTemplateId); var testTemplateWithWwwPath = path.join(testTemplateKitSrc, testTemplateId2); var testTemplateWithGitFilesPath = path.join(testTemplateKitSrc, testTemplateId3); var testTemplateArchiveFolder = path.join(runFolder, "template-archives", testKitId); var testTemplateArchive = path.join(testTemplateArchiveFolder, testTemplateId + ".zip"); // ITemplateOverrideInfo objects var testTemplateOverrideInfo = { kitId: testKitId, templateId: testTemplateId, templateInfo: { name: testDisplayName, url: testTemplateArchive } }; var testTemplateOverrideInfo2 = { kitId: testKitId, templateId: testTemplateId2, templateInfo: { name: testDisplayName2, url: path.join(runFolder, "pathThatDoesntExist") } }; var testTemplateOverrideInfo3 = { kitId: testKitId, templateId: testTemplateId3, templateInfo: { name: testDisplayName3, url: path.join(runFolder, "pathThatDoesntExist") } }; // Mock for the KitHelper var mockKitHelper = { getTemplateOverrideInfo: function (kitId, templateId) { switch (templateId) { case testTemplateId2: return Q.resolve(testTemplateOverrideInfo2); case testTemplateId3: return Q.resolve(testTemplateOverrideInfo3); default: return Q.resolve(testTemplateOverrideInfo); } }, getTemplatesForKit: function (kitId) { var templateOverrides = [testTemplateOverrideInfo, testTemplateOverrideInfo2, testTemplateOverrideInfo3]; var kitTemplatesOverrideInfo = { kitId: testKitId, templates: templateOverrides }; return Q.resolve(kitTemplatesOverrideInfo); }, getAllTemplates: function () { var templateOverrides = [testTemplateOverrideInfo, testTemplateOverrideInfo2, testTemplateOverrideInfo3]; return Q.resolve(templateOverrides); } }; before(function (done) { // Set ResourcesManager to test mode process.env["TACO_UNIT_TEST"] = true; // Delete existing run folder if necessary rimraf(runFolder, function (err) { if (err) { done(err); } else { // Create the run folder for our tests wrench.mkdirSyncRecursive(runFolder, 511); // 511 decimal is 0777 octal // Prepare the test template (archive it) wrench.mkdirSyncRecursive(testTemplateArchiveFolder, 511); // 511 decimal is 0777 octal var archive = archiver("zip"); var outputStream = fs.createWriteStream(testTemplateArchive); archive.on("error", function (archiveError) { done(archiveError); }); outputStream.on("close", function () { done(); }); archive.pipe(outputStream); archive.bulk({ expand: true, cwd: testTemplateNoWwwPath, src: ["**"] }).finalize(); } }); }); after(function (done) { // Delete run folder rimraf(runFolder, done); }); describe("acquireFromTacoKits()", function () { it("should correctly extract a template to a temporary directory", function (done) { // Create a test TemplateManager var templates = new templateManager(mockKitHelper, runFolder); // Call acquireFromTacoKits() templates.acquireFromTacoKits(testTemplateId, testKitId) .then(function (tempTemplatePath) { // Verify the returned path is under the right folder tempTemplatePath.indexOf(runFolder).should.equal(0); // Verify the directory starts with the proper prefix path.basename(tempTemplatePath).indexOf("taco_template_").should.be.equal(0); // Verify the TemplateManager correctly extracted the template archive to the temporary location fs.existsSync(path.join(tempTemplatePath, "a.txt")).should.be.exactly(true, "The template was not correctly cached (missing some files)"); fs.existsSync(path.join(tempTemplatePath, "folder1", "b.txt")).should.be.exactly(true, "The template was not correctly cached (missing some files)"); done(); }) .catch(function (err) { done(new Error(err)); }); }); it("should return the appropriate error when templates are not available", function (done) { // Create a test TemplateManager var templates = new templateManager(mockKitHelper, runFolder); // Call acquireFromTacoKits() with a template ID that has an archive path pointing to a location that doesn't exist templates.acquireFromTacoKits(testTemplateId3, testKitId) .then(function (tempTemplatePath) { // The promise was resolved, this is an error done(new Error("The operation completed successfully when it should have returned an error")); }, function (error) { error.errorCode.should.equal(TacoErrorCodes.CommandCreateTemplatesUnavailable); done(); }) .catch(function (err) { done(new Error(err)); }); }); }); describe("performTokenReplacements()", function () { var replacedLines = [ "some text", testAppName, testAppId, "$appID$", "$randomToken$$$$", "more text", "<xml_node xml_attribute=\"" + testAppName + "\">" + testAppId + "</xml_node>" ]; function verifyFileContent(filePath) { var lr = new wrench.LineReader(filePath); var lineNumber = 0; while (lr.hasNextLine()) { var currentLine = lr.getNextLine().trim(); var correctLine = replacedLines[lineNumber]; if (currentLine !== correctLine) { fs.closeSync(lr.fd); throw new Error("Line wasn't correctly replaced"); } lineNumber++; } fs.closeSync(lr.fd); } it("should correctly replace all tokens in all files, recursively", function (done) { // Copy template items to a new folder var testProjectPath = path.join(runFolder, "testProject"); wrench.mkdirSyncRecursive(testProjectPath, 511); // 511 decimal is 0777 octal utils.copyRecursive(testTemplateNoWwwPath, testProjectPath) .then(function () { // Call performTokenReplacement() return templateManager.performTokenReplacements(testProjectPath, testAppId, testAppName); }) .then(function () { // Read both text files in the project and ensure replacements were correctly made var fileA = path.join(testProjectPath, "a.txt"); var fileB = path.join(testProjectPath, "folder1", "b.txt"); verifyFileContent(fileA); verifyFileContent(fileB); done(); }) .catch(function (err) { done(new Error(err)); }); }); }); describe("getTemplatesForKit()", function () { it("should return the correct list of templates", function (done) { // Create a test TemplateManager var templates = new templateManager(mockKitHelper, runFolder); // Build the expected result var expectedResult = { kitId: testKitId, templates: [ { id: testTemplateOverrideInfo.templateId, name: testTemplateOverrideInfo.templateInfo.name }, { id: testTemplateOverrideInfo2.templateId, name: testTemplateOverrideInfo2.templateInfo.name }, { id: testTemplateOverrideInfo3.templateId, name: testTemplateOverrideInfo3.templateInfo.name } ] }; var expectedResultStringified = JSON.stringify(expectedResult); templates.getTemplatesForKit(testKitId) .then(function (templateList) { JSON.stringify(templateList).should.equal(expectedResultStringified); done(); }) .catch(function (err) { done(new Error(err)); }); }); }); describe("getAllTemplates()", function () { it("should return all available templates", function (done) { // Create a test TemplateManager var templates = new templateManager(mockKitHelper, runFolder); // Build the expected result var expectedResult = { kitId: "", templates: [ { id: testTemplateOverrideInfo.templateId, name: testTemplateOverrideInfo.templateInfo.name }, { id: testTemplateOverrideInfo2.templateId, name: testTemplateOverrideInfo2.templateInfo.name }, { id: testTemplateOverrideInfo3.templateId, name: testTemplateOverrideInfo3.templateInfo.name } ] }; var expectedResultStringified = JSON.stringify(expectedResult); templates.getAllTemplates() .then(function (templateList) { JSON.stringify(templateList).should.equal(expectedResultStringified); done(); }) .catch(function (err) { done(new Error(err)); }); }); }); describe("getTemplateEntriesCount()", function () { it("should return the correct count of template entries", function (done) { // Create a test TemplateManager var templates = new templateManager(mockKitHelper, runFolder); // Count entries for the test template and make sure count is as expected templates.getTemplateEntriesCount(testKitId, testTemplateId) .then(function (count) { // We should have 3 items: "a.txt", "folder1" and "folder1/b.txt" try { count.should.equal(3); } catch (err) { done(err); } done(); }); }); }); describe("copyTemplateItemsToProject()", function () { var testProjectPath = path.join(runFolder, "testProject"); beforeEach(function () { rimraf.sync(testProjectPath); wrench.mkdirSyncRecursive(testProjectPath, 511); // 511 decimal is 0777 octal }); it("should copy items to the project when the template has a www folder", function (done) { var templates = new templateManager(mockKitHelper, runFolder); var cordovaParameters = { appId: "test", appName: "test", cordovaConfig: {}, projectPath: testProjectPath, copyFrom: testTemplateWithWwwPath }; templateManager.copyTemplateItemsToProject(cordovaParameters) .then(function () { // Since the template has a www folder, a copy should happen; there should be 4 items in the project: "www", "a.txt", "folder1", "b.txt" try { wrench.readdirSyncRecursive(testProjectPath).length.should.equal(4); } catch (assertException) { done(assertException); return; } done(); }); }); it("should skip the copy step when the template doesn't have a www folder", function (done) { var templates = new templateManager(mockKitHelper, runFolder); var cordovaParameters = { appId: "test", appName: "test", cordovaConfig: {}, projectPath: testProjectPath, copyFrom: testTemplateNoWwwPath }; templateManager.copyTemplateItemsToProject(cordovaParameters) .then(function () { // Template doesn't have a "www" folder, so the copy step should be skipped and resulting project should be empty try { wrench.readdirSyncRecursive(testProjectPath).length.should.equal(0); } catch (assertException) { done(assertException); return; } done(); }); }); it("should ignore git-specific files and .taco-ignore files", function (done) { var templates = new templateManager(mockKitHelper, runFolder); var cordovaParameters = { appId: "test", appName: "test", cordovaConfig: {}, projectPath: testProjectPath, copyFrom: testTemplateWithGitFilesPath }; templateManager.copyTemplateItemsToProject(cordovaParameters) .then(function () { // Since the template has a www folder, a copy should happen; the 3 git files should be ignored, so there should be 4 items in the project: "www", "a.txt", "folder1", "b.txt" try { wrench.readdirSyncRecursive(testProjectPath).length.should.equal(4); } catch (assertException) { done(assertException); return; } done(); }); }); }); }); //# sourceMappingURL=templateManager.js.map