From 0977140a2441824d9a77e6a8aeefd29d3a33fe19 Mon Sep 17 00:00:00 2001 From: Vladimir Kotikov Date: Tue, 26 Jan 2016 13:35:17 +0300 Subject: [PATCH] CB-10394 Do not cache manifest file while getting package name --- spec/unit/AppxManifest.spec.js | 32 ++++++++++++++ spec/unit/JsprojManager.spec.js | 63 +++++++++++++++++++++++++++ template/cordova/lib/AppxManifest.js | 15 +++++-- template/cordova/lib/JsprojManager.js | 4 +- 4 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 spec/unit/JsprojManager.spec.js diff --git a/spec/unit/AppxManifest.spec.js b/spec/unit/AppxManifest.spec.js index d158144b..c79d9f22 100644 --- a/spec/unit/AppxManifest.spec.js +++ b/spec/unit/AppxManifest.spec.js @@ -38,6 +38,8 @@ describe('AppxManifest', function () { spyOn(xml, 'parseElementtreeSync').andCallFake(function (manifestPath) { return XMLS[manifestPath] || parseElementtreeSyncOrig(manifestPath); }); + + AppxManifest.__set__('manifestCache', {}); }); describe('constructor', function () { @@ -80,6 +82,36 @@ describe('AppxManifest', function () { expect(AppxManifest.get('/uap/prefixed').prefix).toEqual('uap:'); expect(AppxManifest.get('/uap/prefixed') instanceof Win10AppxManifest).toBe(true); }); + + it('should cache AppxManifest instances by default', function () { + var manifest = AppxManifest.get('/no/prefixed'); + expect(xml.parseElementtreeSync.calls.length).toBe(2); + + var manifest2 = AppxManifest.get('/no/prefixed'); + expect(xml.parseElementtreeSync.calls.length).toBe(2); + + expect(manifest).toBe(manifest2); + }); + + it('should not use cache to get AppxManifest instances when "ignoreCache" is specified', function () { + var manifest = AppxManifest.get('/no/prefixed'); + expect(xml.parseElementtreeSync.calls.length).toBe(2); + + var manifest2 = AppxManifest.get('/no/prefixed', true); + expect(xml.parseElementtreeSync.calls.length).toBe(4); + + expect(manifest).not.toBe(manifest2); + }); + + it('should not cache AppxManifest instances when "ignoreCache" is specified', function () { + var manifest = AppxManifest.get('/no/prefixed', true); + expect(xml.parseElementtreeSync.calls.length).toBe(2); + + var manifest2 = AppxManifest.get('/no/prefixed'); + expect(xml.parseElementtreeSync.calls.length).toBe(4); + + expect(manifest).not.toBe(manifest2); + }); }); describe('instance get* methods', function () { diff --git a/spec/unit/JsprojManager.spec.js b/spec/unit/JsprojManager.spec.js new file mode 100644 index 00000000..0fc6c65f --- /dev/null +++ b/spec/unit/JsprojManager.spec.js @@ -0,0 +1,63 @@ +/** + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +var et = require('elementtree'); +var shell = require('shelljs'); +var rewire = require('rewire'); +var xml = require('cordova-common').xmlHelpers; +var AppxManifest = require('../../template/cordova/lib/AppxManifest'); +var JsprojManager = rewire('../../template/cordova/lib/JsprojManager'); + +var PROJECT_PATH = 'spec/unit/fixtures/EmptyProject'; +var FAKE_MANIFEST = new et.ElementTree(et.XML( + '' + + '' + + '' + + 'HelloCordova'+ + '' + + '')); + +describe('JsprojManager', function () { + + var project; + var origProj = JsprojManager.__get__('proj'); + + beforeEach(function () { + + JsprojManager.__set__('proj', jasmine.createSpy('proj')); + + spyOn(shell, 'ls').andReturn([PROJECT_PATH + '/EmptyProject.projitems']); + spyOn(xml, 'parseElementtreeSync').andReturn(FAKE_MANIFEST); + spyOn(AppxManifest, 'get').andCallThrough(); + + project = JsprojManager.getProject(PROJECT_PATH); + }); + + afterEach(function () { + JsprojManager.__set__('proj', origProj); + }); + + it('should use AppxManifest class to get package name', function () { + expect(project.getPackageName()).toBe('HelloCordova'); + expect(AppxManifest.get).toHaveBeenCalled(); + // Should pass 'ignoreCache' option to 'get' method + expect(AppxManifest.get.calls[0].args[1]).toBe(true); + }); +}); + diff --git a/template/cordova/lib/AppxManifest.js b/template/cordova/lib/AppxManifest.js index 461ac645..3dc618dc 100644 --- a/template/cordova/lib/AppxManifest.js +++ b/template/cordova/lib/AppxManifest.js @@ -80,11 +80,14 @@ function AppxManifest(path, prefix) { * constructor to use based on xmlns attributes of Package node * * @param {String} fileName File to create manifest for + * @param {Boolean} [ignoreCache=false] Specifies, whether manifest cache will be + * used to return resultant object + * * @return {AppxManifest|Win10AppxManifest} Manifest instance */ -AppxManifest.get = function (fileName) { +AppxManifest.get = function (fileName, ignoreCache) { - if (manifestCache[fileName]) { + if (!ignoreCache && manifestCache[fileName]) { return manifestCache[fileName]; } @@ -100,7 +103,13 @@ AppxManifest.get = function (fileName) { var prefix = prefixes[prefixes.length - 1]; var Manifest = prefix === 'uap' ? Win10AppxManifest : AppxManifest; - return (manifestCache[fileName] = new Manifest(fileName, prefix)); + var result = new Manifest(fileName, prefix); + + if (!ignoreCache) { + manifestCache[fileName] = result; + } + + return result; }; AppxManifest.prototype.getPhoneIdentity = function () { diff --git a/template/cordova/lib/JsprojManager.js b/template/cordova/lib/JsprojManager.js index 714c7ebb..941e4f86 100644 --- a/template/cordova/lib/JsprojManager.js +++ b/template/cordova/lib/JsprojManager.js @@ -73,7 +73,9 @@ jsprojManager.prototype = { _projects: null, getPackageName: function() { - return AppxManifest.get(path.join(this.root, 'package.windows.appxmanifest')) + // CB-10394 Do not cache manifest file while getting package name to avoid problems + // with windows.appxmanifest cached twice (here and in ConfigFile module) + return AppxManifest.get(path.join(this.root, 'package.windows.appxmanifest'), /*ignoreCache=*/true) .getProperties().getDisplayName(); },