Return-Path: X-Original-To: apmail-cordova-commits-archive@www.apache.org Delivered-To: apmail-cordova-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id C259310CD5 for ; Wed, 2 Sep 2015 11:31:44 +0000 (UTC) Received: (qmail 58401 invoked by uid 500); 2 Sep 2015 11:31:39 -0000 Delivered-To: apmail-cordova-commits-archive@cordova.apache.org Received: (qmail 58266 invoked by uid 500); 2 Sep 2015 11:31:39 -0000 Mailing-List: contact commits-help@cordova.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Delivered-To: mailing list commits@cordova.apache.org Received: (qmail 58019 invoked by uid 99); 2 Sep 2015 11:31:39 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 02 Sep 2015 11:31:39 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 6752DE0007; Wed, 2 Sep 2015 11:31:39 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: an-selm@apache.org To: commits@cordova.apache.org Date: Wed, 02 Sep 2015 11:31:43 -0000 Message-Id: <3372d93bebdf4dd7896b8b7ecf924543@git.apache.org> In-Reply-To: <806fa06ff8e54b64953b8cc7a48e8da5@git.apache.org> References: <806fa06ff8e54b64953b8cc7a48e8da5@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [5/5] cordova-lib git commit: CB-9597 Initial Implementation of PlatformApiPoly CB-9597 Initial Implementation of PlatformApiPoly This implements PlatformApiPoly class according to PlatformApi spec, which allows to: * create/update platform * execute platform's actions (build/run/add/update) * do a prepare (needed for CLI workflow only) * install/uninstall plugins Other noticeable changes: * removes `getPlatformProject` and PlatformProject method/class in favor of PlatformApiPoly/getPlatformApi * make assets and js-modules installing/uninstalling through ActionStack * refactor configChanges to not require plugins_dir in constructor * moves mergeXml helper to xml-helpers This should be used along with cordova-cli/platformApi branch Project: http://git-wip-us.apache.org/repos/asf/cordova-lib/repo Commit: http://git-wip-us.apache.org/repos/asf/cordova-lib/commit/07271a5c Tree: http://git-wip-us.apache.org/repos/asf/cordova-lib/tree/07271a5c Diff: http://git-wip-us.apache.org/repos/asf/cordova-lib/diff/07271a5c Branch: refs/heads/master Commit: 07271a5c6162c0b2bee55e1ea23f91ebdfbbb34c Parents: b0c1965 Author: Vladimir Kotikov Authored: Thu Jul 9 16:55:31 2015 +0300 Committer: Vladimir Kotikov Committed: Wed Sep 2 14:24:03 2015 +0300 ---------------------------------------------------------------------- cordova-lib/spec-cordova/cofdova-lib.spec.js | 23 - cordova-lib/spec-cordova/compile.spec.js | 36 +- cordova-lib/spec-cordova/cordova-lib.spec.js | 23 + cordova-lib/spec-cordova/emulate.spec.js | 48 +- .../platforms/android/AndroidManifest.xml | 14 + .../platformApi/platforms/android/android.json | 11 + .../platforms/android/res/xml/config.xml | 17 + .../platforms/windows/cordova/Api.js | 3 + .../metadata/android_parser.spec.js | 12 +- .../metadata/blackberry_parser.spec.js | 12 +- .../metadata/browser_parser.spec.js | 10 +- .../metadata/firefoxos_parser.spec.js | 10 +- .../spec-cordova/metadata/ios_parser.spec.js | 12 +- .../spec-cordova/metadata/webos_parser.spec.js | 6 +- .../metadata/windows8_parser.spec.js | 12 +- .../spec-cordova/metadata/wp8_parser.spec.js | 12 +- .../platforms/PlatformApiPoly.spec.js | 315 +++++++++ .../spec-cordova/platforms/platforms.spec.js | 72 ++ cordova-lib/spec-cordova/prepare.spec.js | 159 +---- cordova-lib/spec-cordova/run.spec.js | 26 +- cordova-lib/spec-cordova/save.spec.js | 31 +- cordova-lib/spec-cordova/xml-helpers.spec.js | 132 ++++ .../spec-plugman/install-browserify.spec.js | 519 -------------- cordova-lib/spec-plugman/install.spec.js | 224 +++--- cordova-lib/spec-plugman/prepare.spec.js | 73 -- .../spec-plugman/projects/wp8/config.xml | 12 + .../spec-plugman/uninstall-browserify.spec.js | 315 --------- cordova-lib/spec-plugman/uninstall.spec.js | 117 ++- .../spec-plugman/util/action-stack.spec.js | 14 +- .../spec-plugman/util/config-changes.spec.js | 96 ++- cordova-lib/src/PluginInfo.js | 7 +- cordova-lib/src/cordova/clean.js | 20 +- cordova-lib/src/cordova/compile.js | 27 +- cordova-lib/src/cordova/emulate.js | 18 +- cordova-lib/src/cordova/platform.js | 161 ++--- cordova-lib/src/cordova/plugin.js | 107 ++- cordova-lib/src/cordova/prepare.js | 205 +----- cordova-lib/src/cordova/requirements.js | 42 +- cordova-lib/src/cordova/run.js | 17 +- cordova-lib/src/cordova/serve.js | 19 +- cordova-lib/src/cordova/targets.js | 7 +- cordova-lib/src/cordova/util.js | 9 +- cordova-lib/src/platforms/PlatformApiPoly.js | 706 +++++++++++++++++++ cordova-lib/src/platforms/platforms.js | 107 +-- cordova-lib/src/plugman/browserify.js | 181 +++++ cordova-lib/src/plugman/install.js | 45 +- cordova-lib/src/plugman/platforms/common.js | 30 +- cordova-lib/src/plugman/plugman.js | 3 +- cordova-lib/src/plugman/prepare-browserify.js | 214 ------ cordova-lib/src/plugman/prepare.js | 159 ----- cordova-lib/src/plugman/uninstall.js | 57 +- cordova-lib/src/plugman/util/ConfigFile.js | 2 +- cordova-lib/src/plugman/util/PlatformJson.js | 20 + cordova-lib/src/plugman/util/action-stack.js | 22 +- cordova-lib/src/plugman/util/config-changes.js | 71 +- cordova-lib/src/util/xml-helpers.js | 72 ++ 56 files changed, 2268 insertions(+), 2426 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/cofdova-lib.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/cofdova-lib.spec.js b/cordova-lib/spec-cordova/cofdova-lib.spec.js deleted file mode 100644 index 7f734b4..0000000 --- a/cordova-lib/spec-cordova/cofdova-lib.spec.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - 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. -*/ - -/* jshint unused:false */ - -// Verify that cordova-lib.js can be loaded -var cordovaLib = require('../cordova-lib'); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/compile.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/compile.spec.js b/cordova-lib/spec-cordova/compile.spec.js index ea69743..67a8968 100644 --- a/cordova-lib/spec-cordova/compile.spec.js +++ b/cordova-lib/spec-cordova/compile.spec.js @@ -18,9 +18,7 @@ */ var cordova = require('../src/cordova/cordova'), platforms = require('../src/platforms/platforms'), - path = require('path'), HooksRunner = require('../src/hooks/HooksRunner'), - superspawn = require('../src/cordova/superspawn'), util = require('../src/cordova/util'), Q = require('q'); @@ -28,7 +26,7 @@ var supported_platforms = Object.keys(platforms).filter(function(p) { return p ! describe('compile command', function() { - var is_cordova, list_platforms, fire, result, cd_project_root; + var is_cordova, list_platforms, fire, result, cd_project_root, fail, platformApi, getPlatformApi; var project_dir = '/some/path'; function wrapper(f, post) { @@ -43,7 +41,9 @@ describe('compile command', function() { cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir); list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms); fire = spyOn(HooksRunner.prototype, 'fire').andReturn(Q()); - spyOn(superspawn, 'spawn').andCallFake(function() { return Q(); }); + platformApi = { build: jasmine.createSpy('build').andReturn(Q()) }; + getPlatformApi = spyOn(platforms, 'getPlatformApi').andReturn(platformApi); + fail = function (err) { expect(err.stack).not.toBeDefined(); }; }); describe('failure', function() { it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function() { @@ -63,17 +63,21 @@ describe('compile command', function() { describe('success', function() { it('should run inside a Cordova-based project with at least one added platform and shell out to build', function(done) { cordova.raw.compile(['android','ios']).then(function() { - expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'build'), [], jasmine.any(Object)); - expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'build'), [], jasmine.any(Object)); - done(); - }); + expect(getPlatformApi).toHaveBeenCalledWith('android'); + expect(getPlatformApi).toHaveBeenCalledWith('ios'); + expect(platformApi.build).toHaveBeenCalled(); + }) + .fail(fail) + .fin(done); }); it('should pass down optional parameters', function (done) { - cordova.raw.compile({platforms:['blackberry10'], options:['--release']}).then(function () { - expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'blackberry10', 'cordova', 'build'), ['--release'], jasmine.any(Object)); - done(); - }); + cordova.raw.compile({platforms:['blackberry10'], options:{release: true}}).then(function () { + expect(getPlatformApi).toHaveBeenCalledWith('blackberry10'); + expect(platformApi.build).toHaveBeenCalledWith({release: true}); + }) + .fail(fail) + .fin(done); }); }); @@ -83,13 +87,17 @@ describe('compile command', function() { cordova.raw.compile(['android', 'ios']).then(function() { expect(fire).toHaveBeenCalledWith('before_compile', {verbose: false, platforms:['android', 'ios'], options: []}); done(); - }); + }) + .fail(fail) + .fin(done); }); it('should fire after hooks through the hooker module', function(done) { cordova.raw.compile('android').then(function() { expect(fire).toHaveBeenCalledWith('after_compile', {verbose: false, platforms:['android'], options: []}); done(); - }); + }) + .fail(fail) + .fin(done); }); }); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/cordova-lib.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/cordova-lib.spec.js b/cordova-lib/spec-cordova/cordova-lib.spec.js new file mode 100644 index 0000000..7f734b4 --- /dev/null +++ b/cordova-lib/spec-cordova/cordova-lib.spec.js @@ -0,0 +1,23 @@ +/** + 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. +*/ + +/* jshint unused:false */ + +// Verify that cordova-lib.js can be loaded +var cordovaLib = require('../cordova-lib'); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/emulate.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/emulate.spec.js b/cordova-lib/spec-cordova/emulate.spec.js index 9561447..e38715f 100644 --- a/cordova-lib/spec-cordova/emulate.spec.js +++ b/cordova-lib/spec-cordova/emulate.spec.js @@ -18,8 +18,6 @@ */ var cordova = require('../src/cordova/cordova'), platforms = require('../src/platforms/platforms'), - superspawn = require('../src/cordova/superspawn'), - path = require('path'), HooksRunner = require('../src/hooks/HooksRunner'), Q = require('q'), util = require('../src/cordova/util'); @@ -27,9 +25,9 @@ var cordova = require('../src/cordova/cordova'), var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; }); describe('emulate command', function() { - var is_cordova, cd_project_root, list_platforms, fire, result; + var is_cordova, cd_project_root, list_platforms, fire, result, fail; var project_dir = '/some/path'; - var prepare_spy; + var prepare_spy, platformApi, getPlatformApi; function wrapper(f, post) { runs(function() { @@ -45,7 +43,9 @@ describe('emulate command', function() { list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms); fire = spyOn(HooksRunner.prototype, 'fire').andReturn(Q()); prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q()); - spyOn(superspawn, 'spawn').andCallFake(Q); + fail = function (err) { expect(err.stack).not.toBeDefined(); }; + platformApi = { run: jasmine.createSpy('run').andReturn(Q()) }; + getPlatformApi = spyOn(platforms, 'getPlatformApi').andReturn(platformApi); }); describe('failure', function() { it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function() { @@ -66,19 +66,21 @@ describe('emulate command', function() { it('should run inside a Cordova-based project with at least one added platform and call prepare and shell out to the emulate script', function(done) { cordova.raw.emulate(['android','ios']).then(function(err) { expect(prepare_spy).toHaveBeenCalledWith(['android', 'ios']); - expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'run'), ['--emulator'], jasmine.any(Object)); - expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), ['--emulator'], jasmine.any(Object)); - - done(); - }); + expect(getPlatformApi).toHaveBeenCalledWith('android'); + expect(getPlatformApi).toHaveBeenCalledWith('ios'); + expect(platformApi.run).toHaveBeenCalled(); + }) + .fail(fail) + .fin(done); }); it('should pass down options', function(done) { - cordova.raw.emulate({platforms: ['ios'], options:['--optionTastic']}).then(function(err) { + cordova.raw.emulate({platforms: ['ios'], options: {optionTastic: true }}).then(function(err) { expect(prepare_spy).toHaveBeenCalledWith(['ios']); - expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), ['--emulator', '--optionTastic'], jasmine.any(Object)); - - done(); - }); + expect(getPlatformApi).toHaveBeenCalledWith('ios'); + expect(platformApi.run).toHaveBeenCalledWith({ device: false, emulator: true, optionTastic: true }); + }) + .fail(fail) + .fin(done); }); }); @@ -86,15 +88,19 @@ describe('emulate command', function() { describe('when platforms are added', function() { it('should fire before hooks through the hooker module', function(done) { cordova.raw.emulate(['android', 'ios']).then(function() { - expect(fire).toHaveBeenCalledWith('before_emulate', {verbose: false, platforms:['android', 'ios'], options: []}); - done(); - }); + expect(fire).toHaveBeenCalledWith('before_emulate', + jasmine.objectContaining({verbose: false, platforms:['android', 'ios'], options: jasmine.any(Object)})); + }) + .fail(fail) + .fin(done); }); it('should fire after hooks through the hooker module', function(done) { cordova.raw.emulate('android').then(function() { - expect(fire).toHaveBeenCalledWith('after_emulate', {verbose: false, platforms:['android'], options: []}); - done(); - }); + expect(fire).toHaveBeenCalledWith('after_emulate', + jasmine.objectContaining({verbose: false, platforms:['android'], options: jasmine.any(Object)})); + }) + .fail(fail) + .fin(done); }); }); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/AndroidManifest.xml ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/AndroidManifest.xml b/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/AndroidManifest.xml new file mode 100644 index 0000000..be3f245 --- /dev/null +++ b/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/AndroidManifest.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/android.json ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/android.json b/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/android.json new file mode 100644 index 0000000..07c3697 --- /dev/null +++ b/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/android.json @@ -0,0 +1,11 @@ +{ + "prepare_queue": { + "installed": [], + "uninstalled": [] + }, + "config_munge": { + "files": {} + }, + "installed_plugins": {}, + "dependent_plugins": {} +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/res/xml/config.xml ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/res/xml/config.xml b/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/res/xml/config.xml new file mode 100644 index 0000000..645eeb5 --- /dev/null +++ b/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/android/res/xml/config.xml @@ -0,0 +1,17 @@ + + + + A sample Apache Cordova application that responds to the deviceready event. + + Hello Cordova + + A sample Apache Cordova application that responds to the deviceready event. + + + Apache Cordova Team + + + + + + http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/windows/cordova/Api.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/windows/cordova/Api.js b/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/windows/cordova/Api.js new file mode 100644 index 0000000..bb56cda --- /dev/null +++ b/cordova-lib/spec-cordova/fixtures/projects/platformApi/platforms/windows/cordova/Api.js @@ -0,0 +1,3 @@ +module.exports = function PlatformApi (argument) { + this.platform = 'windows'; +}; http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/metadata/android_parser.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/metadata/android_parser.spec.js b/cordova-lib/spec-cordova/metadata/android_parser.spec.js index fd29806..1f56628 100644 --- a/cordova-lib/spec-cordova/metadata/android_parser.spec.js +++ b/cordova-lib/spec-cordova/metadata/android_parser.spec.js @@ -19,7 +19,7 @@ /* jshint boss:true */ -var platforms = require('../../src/platforms/platforms'), +var androidParser = require('../../src/cordova/metadata/android_parser'), util = require('../../src/cordova/util'), path = require('path'), shell = require('shelljs'), @@ -65,12 +65,12 @@ describe('android project parser', function() { it('should throw if provided directory does not contain an AndroidManifest.xml', function() { exists.andReturn(false); expect(function() { - new platforms.android.parser(android_proj); + new androidParser(android_proj); }).toThrow(); }); it('should create an instance with path, strings, manifest and android_config properties', function() { expect(function() { - var p = new platforms.android.parser(android_proj); + var p = new androidParser(android_proj); expect(p.path).toEqual(android_proj); expect(p.strings).toEqual(path.join(android_proj, 'res', 'values', 'strings.xml')); expect(p.manifest).toEqual(path.join(android_proj, 'AndroidManifest.xml')); @@ -78,11 +78,11 @@ describe('android project parser', function() { }).not.toThrow(); }); it('should be an instance of Parser', function() { - expect(new platforms.android.parser(android_proj) instanceof Parser).toBe(true); + expect(new androidParser(android_proj) instanceof Parser).toBe(true); }); it('should call super with the correct arguments', function() { var call = spyOn(Parser, 'call'); - var p = new platforms.android.parser(android_proj); + var p = new androidParser(android_proj); expect(call).toHaveBeenCalledWith(p, 'android', android_proj); }); }); @@ -94,7 +94,7 @@ describe('android project parser', function() { beforeEach(function() { stringsRoot = null; manifestRoot = null; - p = new platforms.android.parser(android_proj); + p = new androidParser(android_proj); cp = spyOn(shell, 'cp'); rm = spyOn(shell, 'rm'); is_cordova = spyOn(util, 'isCordova').andReturn(android_proj); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js b/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js index aea0a49..7df3e24 100644 --- a/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js +++ b/cordova-lib/spec-cordova/metadata/blackberry_parser.spec.js @@ -17,7 +17,7 @@ under the License. */ -var platforms = require('../../src/platforms/platforms'), +var blackberryParser = require('../../src/cordova/metadata/blackberry10_parser'), util = require('../../src/cordova/util'), path = require('path'), shell = require('shelljs'), @@ -76,22 +76,22 @@ describe('blackberry10 project parser', function() { it('should throw an exception with a path that is not a native blackberry project', function() { exists.andReturn(false); expect(function() { - new platforms.blackberry10.parser(proj); + new blackberryParser(proj); }).toThrow(); }); it('should accept a proper native blackberry project path as construction parameter', function() { var project; expect(function() { - project = new platforms.blackberry10.parser(proj); + project = new blackberryParser(proj); }).not.toThrow(); expect(project).toBeDefined(); }); it('should be an instance of Parser', function() { - expect(new platforms.blackberry10.parser(proj) instanceof Parser).toBe(true); + expect(new blackberryParser(proj) instanceof Parser).toBe(true); }); it('should call super with the correct arguments', function() { var call = spyOn(Parser, 'call'); - var p = new platforms.blackberry10.parser(proj); + var p = new blackberryParser(proj); expect(call).toHaveBeenCalledWith(p, 'blackberry10', proj); }); }); @@ -100,7 +100,7 @@ describe('blackberry10 project parser', function() { var p, cp, rm, mkdir, is_cordova, write, read; var bb_proj = path.join(proj, 'platforms', 'blackberry10'); beforeEach(function() { - p = new platforms.blackberry10.parser(bb_proj); + p = new blackberryParser(bb_proj); cp = spyOn(shell, 'cp'); rm = spyOn(shell, 'rm'); mkdir = spyOn(shell, 'mkdir'); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/metadata/browser_parser.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/metadata/browser_parser.spec.js b/cordova-lib/spec-cordova/metadata/browser_parser.spec.js index 2677103..a44d7d3 100644 --- a/cordova-lib/spec-cordova/metadata/browser_parser.spec.js +++ b/cordova-lib/spec-cordova/metadata/browser_parser.spec.js @@ -17,7 +17,7 @@ under the License. */ -var platforms = require('../../src/platforms/platforms'), +var browserParser = require('../../src/cordova/metadata/browser_parser'), util = require('../../src/cordova/util'), path = require('path'), shell = require('shelljs'), @@ -35,16 +35,16 @@ describe('browser project parser', function() { describe('constructions', function() { it('should create an instance with a path', function() { expect(function() { - var p = new platforms.browser.parser(proj); + var p = new browserParser(proj); expect(p.path).toEqual(proj); }).not.toThrow(); }); it('should be an instance of Parser', function() { - expect(new platforms.browser.parser(proj) instanceof Parser).toBe(true); + expect(new browserParser(proj) instanceof Parser).toBe(true); }); it('should call super with the correct arguments', function() { var call = spyOn(Parser, 'call'); - var p = new platforms.browser.parser(proj); + var p = new browserParser(proj); expect(call).toHaveBeenCalledWith(p, 'browser', proj); }); }); @@ -54,7 +54,7 @@ describe('browser project parser', function() { var browser_proj = path.join(proj, 'platforms', 'browser'); beforeEach(function() { - p = new platforms.browser.parser(browser_proj); + p = new browserParser(browser_proj); cp = spyOn(shell, 'cp'); rm = spyOn(shell, 'rm'); mkdir = spyOn(shell, 'mkdir'); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js b/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js index c918d16..e4a7eaa 100644 --- a/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js +++ b/cordova-lib/spec-cordova/metadata/firefoxos_parser.spec.js @@ -19,7 +19,7 @@ /* jshint boss:true */ -var platforms = require('../../src/platforms/platforms'), +var firefoxosParser = require('../../src/cordova/metadata/firefoxos_parser'), util = require('../../src/cordova/util'), path = require('path'), shell = require('shelljs'), @@ -53,18 +53,18 @@ describe('firefoxos project parser', function() { describe('constructions', function() { it('should create an instance with a path', function() { expect(function() { - var p = new platforms.firefoxos.parser(proj); + var p = new firefoxosParser(proj); expect(p.path).toEqual(proj); expect(p.config_path).toEqual(path.join(proj, 'config.xml')); expect(p.manifest_path).toEqual(path.join(p.www_dir(), 'manifest.webapp')); }).not.toThrow(); }); it('should be an instance of Parser', function() { - expect(new platforms.firefoxos.parser(proj) instanceof Parser).toBe(true); + expect(new firefoxosParser(proj) instanceof Parser).toBe(true); }); it('should call super with the correct arguments', function() { var call = spyOn(Parser, 'call'); - var p = new platforms.firefoxos.parser(proj); + var p = new firefoxosParser(proj); expect(call).toHaveBeenCalledWith(p, 'firefoxos', proj); }); }); @@ -74,7 +74,7 @@ describe('firefoxos project parser', function() { var ff_proj = path.join(proj, 'platforms', 'firefoxos'); var manifestJson = null; beforeEach(function() { - p = new platforms.firefoxos.parser(ff_proj); + p = new firefoxosParser(ff_proj); cp = spyOn(shell, 'cp'); rm = spyOn(shell, 'rm'); is_cordova = spyOn(util, 'isCordova').andReturn(proj); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/metadata/ios_parser.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/metadata/ios_parser.spec.js b/cordova-lib/spec-cordova/metadata/ios_parser.spec.js index 6ab42da..d7ae6f0 100644 --- a/cordova-lib/spec-cordova/metadata/ios_parser.spec.js +++ b/cordova-lib/spec-cordova/metadata/ios_parser.spec.js @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -var platforms = require('../../src/platforms/platforms'), +var iosParser = require('../../src/cordova/metadata/ios_parser'), util = require('../../src/cordova/util'), path = require('path'), shell = require('shelljs'), @@ -55,23 +55,23 @@ describe('ios project parser', function () { it('should throw if provided directory does not contain an xcodeproj file', function() { readdir.andReturn(['noxcodehere']); expect(function() { - new platforms.ios.parser(proj); + new iosParser(proj); }).toThrow(); }); it('should create an instance with path, pbxproj, xcodeproj, originalName and cordovaproj properties', function() { expect(function() { - var p = new platforms.ios.parser(proj); + var p = new iosParser(proj); expect(p.path).toEqual(proj); expect(p.pbxproj).toEqual(path.join(proj, 'test.xcodeproj', 'project.pbxproj')); expect(p.xcodeproj).toEqual(path.join(proj, 'test.xcodeproj')); }).not.toThrow(); }); it('should be an instance of Parser', function() { - expect(new platforms.ios.parser(proj) instanceof Parser).toBe(true); + expect(new iosParser(proj) instanceof Parser).toBe(true); }); it('should call super with the correct arguments', function() { var call = spyOn(Parser, 'call'); - var p = new platforms.ios.parser(proj); + var p = new iosParser(proj); expect(call).toHaveBeenCalledWith(p, 'ios', proj); }); }); @@ -80,7 +80,7 @@ describe('ios project parser', function () { var p, cp, rm, mkdir, is_cordova, write, read, getOrientation; var ios_proj = path.join(proj, 'platforms', 'ios'); beforeEach(function() { - p = new platforms.ios.parser(ios_proj); + p = new iosParser(ios_proj); cp = spyOn(shell, 'cp'); rm = spyOn(shell, 'rm'); mkdir = spyOn(shell, 'mkdir'); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/metadata/webos_parser.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/metadata/webos_parser.spec.js b/cordova-lib/spec-cordova/metadata/webos_parser.spec.js index 59010c4..c8b1b9b 100755 --- a/cordova-lib/spec-cordova/metadata/webos_parser.spec.js +++ b/cordova-lib/spec-cordova/metadata/webos_parser.spec.js @@ -16,7 +16,7 @@ specific language governing permissions and limitations under the License. */ -var platforms = require('../../src/platforms/platforms'), +var webosParser = require('../../src/cordova/metadata/webos_parser'), util = require('../../src/cordova/util'), path = require('path'), shell = require('shelljs'), @@ -39,7 +39,7 @@ describe('webos project parser', function() { describe('constructions', function() { it('should create an instance with a path', function() { expect(function() { - var p = new platforms.android.parser(proj); + var p = new webosParser(proj); expect(p.path).toEqual(proj); }).not.toThrow(); }); @@ -49,7 +49,7 @@ describe('webos project parser', function() { var p, cp, rm, is_cordova, write, read; var wos_proj = path.join(proj, 'platforms', 'webos'); beforeEach(function() { - p = new platforms.webos.parser(wos_proj); + p = new webosParser(wos_proj); cp = spyOn(shell, 'cp'); rm = spyOn(shell, 'rm'); is_cordova = spyOn(util, 'isCordova').andReturn(proj); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js b/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js index f8371d5..d26b5b3 100644 --- a/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js +++ b/cordova-lib/spec-cordova/metadata/windows8_parser.spec.js @@ -19,7 +19,7 @@ /* jshint boss:true */ -var platforms = require('../../src/platforms/platforms'), +var windowsParser = require('../../src/cordova/metadata/windows_parser'), util = require('../../src/cordova/util'), path = require('path'), shell = require('shelljs'), @@ -81,22 +81,22 @@ describe('windows8 project parser', function() { it('should throw if provided directory does not contain a jsproj file', function() { readdir.andReturn([]); expect(function() { - new platforms.windows8.parser(proj); + new windowsParser(proj); }).toThrow(); }); it('should create an instance with path, manifest properties', function() { expect(function() { - var parser = new platforms.windows8.parser(proj); + var parser = new windowsParser(proj); expect(parser.projDir).toEqual(proj); expect(parser.manifestPath).toEqual(path.join(proj, 'package.appxmanifest')); }).not.toThrow(); }); it('should be an instance of Parser', function() { - expect(new platforms.windows8.parser(proj) instanceof Parser).toBe(true); + expect(new windowsParser(proj) instanceof Parser).toBe(true); }); it('should call super with the correct arguments', function() { var call = spyOn(Parser, 'call'); - var p = new platforms.windows8.parser(proj); + var p = new windowsParser(proj); expect(call).toHaveBeenCalledWith(p, 'windows8', proj); }); }); @@ -105,7 +105,7 @@ describe('windows8 project parser', function() { var parser, cp, rm, is_cordova, write, read, mv, mkdir; var windows8_proj = path.join(proj, 'platforms', 'windows8'); beforeEach(function() { - parser = new platforms.windows8.parser(windows8_proj); + parser = new windowsParser(windows8_proj); cp = spyOn(shell, 'cp'); rm = spyOn(shell, 'rm'); mv = spyOn(shell, 'mv'); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js b/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js index 5228fa7..aae2643 100644 --- a/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js +++ b/cordova-lib/spec-cordova/metadata/wp8_parser.spec.js @@ -19,7 +19,7 @@ /* jshint boss:true, sub:true */ -var platforms = require('../../src/platforms/platforms'), +var wp8Parser = require('../../src/cordova/metadata/wp8_parser'), util = require('../../src/cordova/util'), path = require('path'), shell = require('shelljs'), @@ -105,22 +105,22 @@ describe('wp8 project parser', function() { it('should throw if provided directory does not contain a csproj file', function() { readdir.andReturn([]); expect(function() { - new platforms.wp8.parser(proj); + new wp8Parser(proj); }).toThrow(); }); it('should create an instance with path, manifest properties', function() { expect(function() { - var p = new platforms.wp8.parser(proj); + var p = new wp8Parser(proj); expect(p.wp8_proj_dir).toEqual(proj); expect(p.manifest_path).toEqual(path.join(proj, 'Properties', 'WMAppManifest.xml')); }).not.toThrow(); }); it('should be an instance of Parser', function() { - expect(new platforms.wp8.parser(proj) instanceof Parser).toBe(true); + expect(new wp8Parser(proj) instanceof Parser).toBe(true); }); it('should call super with the correct arguments', function() { var call = spyOn(Parser, 'call'); - var p = new platforms.wp8.parser(proj); + var p = new wp8Parser(proj); expect(call).toHaveBeenCalledWith(p, 'wp8', proj); }); }); @@ -129,7 +129,7 @@ describe('wp8 project parser', function() { var p, cp, rm, is_cordova, write, read, mv, mkdir, getOrientation; var wp8_proj = path.join(proj, 'platforms', 'wp8'); beforeEach(function() { - p = new platforms.wp8.parser(wp8_proj); + p = new wp8Parser(wp8_proj); cp = spyOn(shell, 'cp'); rm = spyOn(shell, 'rm'); mv = spyOn(shell, 'mv'); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/platforms/PlatformApiPoly.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/platforms/PlatformApiPoly.spec.js b/cordova-lib/spec-cordova/platforms/PlatformApiPoly.spec.js new file mode 100644 index 0000000..0f60dd8 --- /dev/null +++ b/cordova-lib/spec-cordova/platforms/PlatformApiPoly.spec.js @@ -0,0 +1,315 @@ +/** + 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 Q = require('q'); +var fs = require('fs'); +var et = require('elementtree'); +var path = require('path'); +var shell = require('shelljs'); +var xmlHelpers = require('../../src/util/xml-helpers'); +var ActionStack = require('../../src/plugman/util/action-stack'); +var superspawn = require('../../src/cordova/superspawn'); +var PluginInfo = require('../../src/PluginInfo'); +var ConfigParser = require('../../src/configparser/ConfigParser'); +var knownPlatforms = require('../../src/platforms/platforms'); +var PlatformApiPoly = require('../../src/platforms/PlatformApiPoly'); + +var PLATFORM = 'android'; +var PLATFORM_VERSION = '3.7.0'; +var PLATFORM_LIB = '/some/platform/lib'; +var CORDOVA_ROOT = path.join(__dirname, '../fixtures/projects/platformApi'); +var PLATFORM_ROOT = path.join(CORDOVA_ROOT, 'platforms/android'); +var DUMMY_PLUGIN = path.join(__dirname, '../fixtures/plugins/test'); +var TEST_XML = '\n' + + '\n' + + ' Hello Cordova\n' + + ' \n' + + ' A sample Apache Cordova application that responds to the deviceready event.\n' + + ' \n' + + ' \n' + + ' Apache Cordova Team\n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + '\n'; + +var platformApiPolyPublicMethods = [ + 'getPlatformInfo', + 'prepare', + 'addPlugin', + 'removePlugin', + 'updatePlugin', + 'build', + 'run', + 'clean', + 'requirements' +]; + +describe('PlatformApi polyfill', function () { + var platformApi; + + beforeEach(function () { + var originalParseElementtreeSync = xmlHelpers.parseElementtreeSync; + spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function (configPath) { + return /config\.xml$/.test(configPath) ? new et.ElementTree(et.XML(TEST_XML)) : + originalParseElementtreeSync(configPath); + }); + + platformApi = new PlatformApiPoly(PLATFORM, PLATFORM_ROOT); + }); + + it('should be constructable', function () { + var api; + expect(function(){api = new PlatformApiPoly(PLATFORM, PLATFORM_ROOT);}).not.toThrow(); + expect(api).toEqual(jasmine.any(PlatformApiPoly)); + }); + + it('should fail when unknown platform is specified', function () { + var api; + expect(function(){api = new PlatformApiPoly('fakePlatform', PLATFORM_ROOT);}).toThrow(); + }); + + it('should fail when mandatory argument is not specified', function () { + var api; + expect(function(){api = new PlatformApiPoly(PLATFORM);}).toThrow(); + expect(function(){api = new PlatformApiPoly(null, PLATFORM_ROOT);}).toThrow(); + }); + + it('should have fields defined', function () { + expect(platformApi.platform).toBe(PLATFORM); + expect(platformApi.root).toBe(PLATFORM_ROOT); + }); + + it('should have \'static\' methods defined', function () { + expect(platformApi.constructor.createPlatform).toEqual(jasmine.any(Function)); + expect(platformApi.constructor.updatePlatform).toEqual(jasmine.any(Function)); + }); + + it('should have methods defined', function () { + platformApiPolyPublicMethods.forEach(function (methodName) { + expect(platformApi[methodName]).toEqual(jasmine.any(Function)); + }); + }); + + describe('methods:', function () { + + var FAKE_PROJECT, OPTIONS, getPlatformApi, fail, success; + + beforeEach(function () { + getPlatformApi = spyOn(knownPlatforms, 'getPlatformApi').andReturn(platformApi); + + spyOn(shell, 'cp'); + spyOn(shell, 'rm'); + spyOn(shell, 'mkdir'); + spyOn(fs, 'writeFileSync'); + + fail = jasmine.createSpy('fail'); + success = jasmine.createSpy('success'); + + FAKE_PROJECT = {locations: {platforms: path.dirname(PLATFORM_ROOT), www: path.join(CORDOVA_ROOT, 'www')}, projectConfig: new ConfigParser('/fake/config.xml')}; + OPTIONS = {platformDetails: {libDir: PLATFORM_LIB, platform: PLATFORM, version: PLATFORM_VERSION}}; + }); + + describe('static create/updatePlatform methods', function () { + var spawn; + + beforeEach(function () { + spawn = spyOn(superspawn, 'spawn').andReturn(Q()); + }); + + it('should create/update platform through running platforms\' scripts', function (done) { + Q.all([PlatformApiPoly.createPlatform(FAKE_PROJECT, OPTIONS), + PlatformApiPoly.updatePlatform(FAKE_PROJECT, OPTIONS)]) + .then(function () { + expect(spawn).toHaveBeenCalled(); + expect(spawn.calls.length).toBe(2); + }).fail(function (err) { + expect(err).not.toBeDefined(); + }).fin(done); + }); + + it('should pass down arguments to platforms\' scripts', function (done) { + Q.all([PlatformApiPoly.createPlatform(FAKE_PROJECT, OPTIONS), + PlatformApiPoly.updatePlatform(FAKE_PROJECT, OPTIONS)]) + .then(function () { + expect(spawn).toHaveBeenCalled(); + expect(spawn.calls.length).toBe(2); + expect(spawn.calls[0].args[0]).toBe(path.join(PLATFORM_LIB, 'bin/create')); + expect(spawn.calls[0].args[1]).toContain(PLATFORM_ROOT); + expect(spawn.calls[1].args[0]).toBe(path.join(PLATFORM_LIB, 'bin/update')); + expect(spawn.calls[1].args[1]).toContain(PLATFORM_ROOT); + }).fail(function (err) { + expect(err).not.toBeDefined(); + }).fin(done); + }); + + it('should copy cordova JS sources into created platform', function (done) { + Q.all([PlatformApiPoly.createPlatform(FAKE_PROJECT, OPTIONS), + PlatformApiPoly.updatePlatform(FAKE_PROJECT, OPTIONS)]) + .then(function () { + expect(shell.cp).toHaveBeenCalled(); + expect(shell.cp.calls.length).toBe(2); + }).fail(fail) + .fin(function () { + expect(fail).not.toHaveBeenCalled(); + done(); + }); + }); + + it('should fail immediately if options.platformInfo is not specified', function (done) { + Q.all([PlatformApiPoly.createPlatform(FAKE_PROJECT), + PlatformApiPoly.updatePlatform(FAKE_PROJECT)]) + .then(success) + .fail(fail) + .fin(function function_name (argument) { + expect(success).not.toHaveBeenCalled(); + expect(fail).toHaveBeenCalled(); + expect(spawn).not.toHaveBeenCalled(); + done(); + }); + }); + }); + + describe('prepare method', function () { + beforeEach(function () { + spyOn(platformApi._parser, 'update_www'); + spyOn(platformApi._parser, 'update_project').andReturn(Q()); + }); + + it('should return promise', function (done) { + var promise = platformApi.prepare(FAKE_PROJECT, OPTIONS); + expect(Q.isPromise(promise)).toBeTruthy(); + promise.fin(done); + }); + + it('should call parser\'s corresponding methods', function (done) { + platformApi.prepare(FAKE_PROJECT, OPTIONS) + .then(function () { + [platformApi._parser.update_www, platformApi._parser.update_project] + .forEach(function (method) { + expect(method).toHaveBeenCalled(); + }); + }) + .fail(fail) + .fin(function () { + expect(fail).not.toHaveBeenCalled(); + done(); + }); + }); + }); + + describe('pluginAdd method', function () { + var plugin, actionsProcess; + + beforeEach(function () { + plugin = new PluginInfo(DUMMY_PLUGIN); + actionsProcess = spyOn(ActionStack.prototype, 'process').andCallThrough(); + }); + + it('should return promise', function (done) { + var promise = platformApi.addPlugin(plugin); + expect(Q.isPromise(promise)).toBeTruthy(); + promise.fin(done); + }); + + it('should fail if plugin parameter is not specified', function (done) { + platformApi.addPlugin() + .then(success) + .fail(fail) + .fin(function () { + expect(success).not.toHaveBeenCalled(); + expect(fail).toHaveBeenCalled(); + done(); + }); + }); + + it('should process all plugin files through action stack', function (done) { + platformApi.addPlugin(plugin) + .then(success) + .fail(fail) + .fin(function () { + expect(actionsProcess).toHaveBeenCalled(); + expect(success).toHaveBeenCalled(); + expect(fail).not.toHaveBeenCalled(); + done(); + }); + }); + }); + + describe('platform actions', function () { + var spawnSpy; + + beforeEach(function () { + spawnSpy = spyOn(superspawn, 'spawn'); + }); + + it('should return promise', function (done) { + var ops = [ + platformApi.build(/*opts*/), + platformApi.run(/*opts*/), + platformApi.clean(/*opts*/), + platformApi.requirements() + ]; + + ops.forEach(function (op) { + expect(Q.isPromise(op)); + }); + Q.all(ops).fin(done); + }); + + it('should do their job through running platforms\' scripts', function (done) { + var ops = [ + platformApi.build(/*opts*/), + platformApi.run(/*opts*/), + platformApi.clean(/*opts*/) + ]; + + Q.all(ops) + .then(function () { + expect(spawnSpy).toHaveBeenCalled(); + expect(spawnSpy.calls.length).toEqual(3); + }).fin(done); + }); + + it('should convert and pass down options to platforms\' scripts', function (done) { + var options = { + release: true, + nobuild: true, + device: true, + target: 'FakeDevice', + archs: ['arm', 'x86'], + buildConfig: '/some/path' + }; + spawnSpy.andReturn(Q()); + platformApi.build(options) + .then(function () { + ['--release', '--nobuild', '--device', '--target=' + options.target, '--archs=arm,x86', '--buildConfig=' +options.buildConfig] + .forEach(function (arg) { + expect(spawnSpy.calls[0].args[1]).toContain(arg); + }); + }).fin(done); + }); + }); + }); +}); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/platforms/platforms.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/platforms/platforms.spec.js b/cordova-lib/spec-cordova/platforms/platforms.spec.js new file mode 100644 index 0000000..90b690c --- /dev/null +++ b/cordova-lib/spec-cordova/platforms/platforms.spec.js @@ -0,0 +1,72 @@ +/** + 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 path = require('path'); +var rewire = require('rewire'); + +var util = require('../../src/cordova/util'); +var platforms = rewire('../../src/platforms/platforms'); + +var CORDOVA_ROOT = path.join(__dirname, '../fixtures/projects/platformApi'); +var PLATFORM_WITH_API = path.join(CORDOVA_ROOT, 'platforms/windows'); +var PLATFORM_WOUT_API = path.join(CORDOVA_ROOT, 'platforms/android'); + +var MockPlatformApi = require(path.join(PLATFORM_WITH_API, 'cordova', 'Api')); +var PlatformApiPoly = require('../../src/platforms/PlatformApiPoly'); + +describe('getPlatformApi method', function () { + var isCordova; + + beforeEach(function () { + // reset api cache after each spec + platforms.__set__('cachedApis', {}); + isCordova = spyOn(util, 'isCordova').andReturn(CORDOVA_ROOT); + }); + + it('should return PlatformApi class defined by platform', function () { + var platformApi = platforms.getPlatformApi('windows', PLATFORM_WITH_API); + expect(platformApi).toEqual(jasmine.any(MockPlatformApi)); + }); + + it('should return PlatformApi polyfill if PlatformApi is not defined by platform', function () { + var platformApi = platforms.getPlatformApi('android', PLATFORM_WOUT_API); + expect(platformApi).toEqual(jasmine.any(PlatformApiPoly)); + }); + + it('should cache PlatformApi instance for further calls', function () { + var platformApi = platforms.getPlatformApi('windows', PLATFORM_WITH_API); + expect(platformApi.fakeProperty).not.toBeDefined(); + platformApi.fakeProperty = 'fakeValue'; + expect(platforms.getPlatformApi('windows', PLATFORM_WITH_API).fakeProperty).toBe('fakeValue'); + }); + + it('should succeed if called inside of cordova project w/out platformRoot param', function () { + var platformApi = platforms.getPlatformApi('windows'); + expect(platformApi instanceof MockPlatformApi).toBeTruthy(); + }); + + it('should throw if called outside of cordova project w/out platformRoot param', function () { + isCordova.andReturn(false); + expect(function () { platforms.getPlatformApi('windows'); }).toThrow(); + }); + + it('should throw for unknown platform', function () { + expect(function () { platforms.getPlatformApi('invalid_platform'); }).toThrow(); + }); +}); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/prepare.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/prepare.spec.js b/cordova-lib/spec-cordova/prepare.spec.js index 666394c..bf9d31a 100644 --- a/cordova-lib/spec-cordova/prepare.spec.js +++ b/cordova-lib/spec-cordova/prepare.spec.js @@ -18,7 +18,6 @@ */ var shell = require('shelljs'), - plugman = require('../src/plugman/plugman'), PlatformJson = require('../src/plugman/util/PlatformJson'), path = require('path'), util = require('../src/cordova/util'), @@ -59,35 +58,33 @@ describe('prepare command', function() { list_platforms, fire, parsers = {}, - plugman_prepare, find_plugins, cp, mkdir, - load; - beforeEach(function() { - is_cordova = spyOn(util, 'isCordova').andReturn(project_dir); - cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir); - list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms); - fire = spyOn(HooksRunner.prototype, 'fire').andReturn(Q()); + load, platformApi, getPlatformApi; - spyOn(platforms, 'getPlatformProject').andCallFake(function(platform, rootDir) { + beforeEach(function () { + getPlatformApi = spyOn(platforms, 'getPlatformApi').andCallFake(function (platform, rootDir) { return { - update_www: jasmine.createSpy(platform + ' update_www'), - cordovajs_path: function(libDir) { return 'path/to/cordova.js/in/.cordova/lib';}, - www_dir:function() { return path.join(project_dir, 'platforms', platform, 'www'); }, - config_xml: function () { return path.join(project_dir, 'platforms', platform, 'www', 'config.xml');}, - update_project: function () { return Q();}, + prepare: jasmine.createSpy('prepare').andReturn(Q()), + getPlatformInfo: jasmine.createSpy('getPlatformInfo').andReturn({ + locations: { + www: path.join(project_dir, 'platforms', platform, 'www') + } + }), }; }); + is_cordova = spyOn(util, 'isCordova').andReturn(project_dir); + cd_project_root = spyOn(util, 'cdProjectRoot').andReturn(project_dir); + list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms); + fire = spyOn(HooksRunner.prototype, 'fire').andReturn(Q()); - plugman_prepare = spyOn(plugman, 'prepare').andReturn(Q()); find_plugins = spyOn(util, 'findPlugins').andReturn([]); spyOn(PlatformJson, 'load').andReturn(new PlatformJson(null, null, {})); spyOn(PlatformJson.prototype, 'save'); load = spyOn(lazy_load, 'based_on_config').andReturn(Q()); cp = spyOn(shell, 'cp').andReturn(true); mkdir = spyOn(shell, 'mkdir'); - spyOn(prepare, '_mergeXml'); spyOn(ConfigParser.prototype, 'write'); spyOn(xmlHelpers, 'parseElementtreeSync').andCallFake(function() { return new et.ElementTree(et.XML(TEST_XML)); @@ -122,26 +119,17 @@ describe('prepare command', function() { expect(err).toBeUndefined(); }).fin(done); }); - it('should invoke each platform\'s parser\'s update_project method', function(done) { + it('should get PlatformApi instance for each platform and invoke its\' run method', function(done) { prepare().then(function() { supported_platforms.forEach(function(p) { expect(parsers[p]).toHaveBeenCalled(); + expect(getPlatformApi).toHaveBeenCalledWith(p); }); + expect(platformApi.run).toHaveBeenCalled(); }, function(err) { expect(err).toBeUndefined(); }).fin(done); }); - describe('plugman integration', function() { - it('should invoke plugman.prepare after update_project', function(done) { - prepare().then(function() { - supported_platforms.forEach(function(p) { - expect(plugman_prepare).toHaveBeenCalled(); - }); - }, function(err) { - expect(err).toBeUndefined(); - }).fin(done); - }); - }); }); describe('hooks', function() { @@ -178,118 +166,3 @@ describe('prepare command', function() { }); }); }); - -describe('prepare._mergeXml', function () { - var dstXml; - beforeEach(function() { - dstXml = et.XML(TEST_XML); - }); - it('should merge attributes and text of the root element without clobbering', function () { - var testXml = et.XML('TEXT'); - prepare._mergeXml(testXml, dstXml); - expect(dstXml.attrib.foo).toEqual('bar'); - expect(dstXml.attrib.id).not.toEqual('NOTANID'); - expect(dstXml.text).not.toEqual('TEXT'); - }); - - it('should merge attributes and text of the root element with clobbering', function () { - var testXml = et.XML('TEXT'); - prepare._mergeXml(testXml, dstXml, 'foo', true); - expect(dstXml.attrib.foo).toEqual('bar'); - expect(dstXml.attrib.id).toEqual('NOTANID'); - expect(dstXml.text).toEqual('TEXT'); - }); - - it('should not merge platform tags with the wrong platform', function () { - var testXml = et.XML('testTEXT'), - origCfg = et.tostring(dstXml); - - prepare._mergeXml(testXml, dstXml, 'foo', true); - expect(et.tostring(dstXml)).toEqual(origCfg); - }); - - it('should merge platform tags with the correct platform', function () { - var testXml = et.XML('testTEXT'), - origCfg = et.tostring(dstXml); - - prepare._mergeXml(testXml, dstXml, 'bar', true); - expect(et.tostring(dstXml)).not.toEqual(origCfg); - var testElement = dstXml.find('testElement'); - expect(testElement).toBeDefined(); - expect(testElement.attrib.testAttrib).toEqual('value'); - expect(testElement.text).toEqual('testTEXT'); - }); - - it('should merge singelton children without clobber', function () { - var testXml = et.XML('SUPER_AUTHOR'); - - prepare._mergeXml(testXml, dstXml); - var testElements = dstXml.findall('author'); - expect(testElements).toBeDefined(); - expect(testElements.length).toEqual(1); - expect(testElements[0].attrib.testAttrib).toEqual('value'); - expect(testElements[0].attrib.href).toEqual('http://cordova.io'); - expect(testElements[0].attrib.email).toEqual('dev@cordova.apache.org'); - expect(testElements[0].text).toContain('Apache Cordova Team'); - }); - - it('should clobber singelton children with clobber', function () { - var testXml = et.XML('SUPER_AUTHOR'); - - prepare._mergeXml(testXml, dstXml, '', true); - var testElements = dstXml.findall('author'); - expect(testElements).toBeDefined(); - expect(testElements.length).toEqual(1); - expect(testElements[0].attrib.testAttrib).toEqual('value'); - expect(testElements[0].attrib.href).toEqual('http://www.nowhere.com'); - expect(testElements[0].attrib.email).toEqual('dev@cordova.apache.org'); - expect(testElements[0].text).toEqual('SUPER_AUTHOR'); - }); - - it('should append non singelton children', function () { - var testXml = et.XML(' '); - - prepare._mergeXml(testXml, dstXml, '', true); - var testElements = dstXml.findall('preference'); - expect(testElements.length).toEqual(4); - }); - - it('should handle namespaced elements', function () { - var testXml = et.XML('testText'); - - prepare._mergeXml(testXml, dstXml, 'foo', true); - var testElement = dstXml.find('foo:bar'); - expect(testElement).toBeDefined(); - expect(testElement.attrib.testAttrib).toEqual('value'); - expect(testElement.text).toEqual('testText'); - }); - - it('should not append duplicate non singelton children', function () { - var testXml = et.XML(''); - - prepare._mergeXml(testXml, dstXml, '', true); - var testElements = dstXml.findall('preference'); - expect(testElements.length).toEqual(2); - }); - - it('should not skip partial duplicate non singelton children', function () { - //remove access tags from dstXML - var testElements = dstXml.findall('access'); - for(var i = 0; i < testElements.length; i++) { - dstXml.remove(testElements[i]); - } - testElements = dstXml.findall('access'); - expect(testElements.length).toEqual(0); - //add an external whitelist access tag - var testXml = et.XML(''); - prepare._mergeXml(testXml, dstXml, '', true); - testElements = dstXml.findall('access'); - expect(testElements.length).toEqual(1); - //add an internal whitelist access tag - testXml = et.XML(''); - prepare._mergeXml(testXml, dstXml, '', true); - testElements = dstXml.findall('access'); - expect(testElements.length).toEqual(2); - - }); -}); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/run.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/run.spec.js b/cordova-lib/spec-cordova/run.spec.js index 6271cfe..627451b 100644 --- a/cordova-lib/spec-cordova/run.spec.js +++ b/cordova-lib/spec-cordova/run.spec.js @@ -18,8 +18,6 @@ */ var cordova = require('../src/cordova/cordova'), platforms = require('../src/platforms/platforms'), - superspawn = require('../src/cordova/superspawn'), - path = require('path'), HooksRunner = require('../src/hooks/HooksRunner'), Q = require('q'), util = require('../src/cordova/util'); @@ -27,7 +25,7 @@ var cordova = require('../src/cordova/cordova'), var supported_platforms = Object.keys(platforms).filter(function(p) { return p != 'www'; }); describe('run command', function() { - var is_cordova, cd_project_root, list_platforms, fire; + var is_cordova, cd_project_root, list_platforms, fire, platformApi, getPlatformApi; var project_dir = '/some/path'; var prepare_spy; @@ -37,7 +35,8 @@ describe('run command', function() { list_platforms = spyOn(util, 'listPlatforms').andReturn(supported_platforms); fire = spyOn(HooksRunner.prototype, 'fire').andReturn(Q()); prepare_spy = spyOn(cordova.raw, 'prepare').andReturn(Q()); - spyOn(superspawn, 'spawn').andReturn(Q); + platformApi = { run: jasmine.createSpy('run').andReturn(Q()) }; + getPlatformApi = spyOn(platforms, 'getPlatformApi').andReturn(platformApi); }); describe('failure', function() { it('should not run inside a Cordova-based project with no added platforms by calling util.listPlatforms', function(done) { @@ -61,19 +60,26 @@ describe('run command', function() { }); describe('success', function() { - it('should run inside a Cordova-based project with at least one added platform and call prepare and shell out to the run script', function(done) { + it('should call prepare before actually run platform ', function(done) { cordova.raw.run(['android','ios']).then(function() { expect(prepare_spy).toHaveBeenCalledWith({ platforms: [ 'android', 'ios' ], verbose: false, options: [] }); - expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'android', 'cordova', 'run'), [], jasmine.any(Object)); - expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'ios', 'cordova', 'run'), [], jasmine.any(Object)); + }, function(err) { + expect(err).toBeUndefined(); + }).fin(done); + }); + it('should get PlatformApi instance for each platform and call its\' run method', function(done) { + cordova.raw.run(['android','ios']).then(function() { + expect(getPlatformApi).toHaveBeenCalledWith('android'); + expect(getPlatformApi).toHaveBeenCalledWith('ios'); + expect(platformApi.run).toHaveBeenCalled(); }, function(err) { expect(err).toBeUndefined(); }).fin(done); }); it('should pass down parameters', function(done) { - cordova.raw.run({platforms: ['blackberry10'], options:['--password', '1q1q']}).then(function() { - expect(prepare_spy).toHaveBeenCalledWith({ platforms: [ 'blackberry10' ], options: [ '--password', '1q1q' ], verbose: false }); - expect(superspawn.spawn).toHaveBeenCalledWith(path.join(project_dir, 'platforms', 'blackberry10', 'cordova', 'run'), ['--password', '1q1q'], jasmine.any(Object)); + cordova.raw.run({platforms: ['blackberry10'], options:{password: '1q1q'}}).then(function() { + expect(prepare_spy).toHaveBeenCalledWith({ platforms: [ 'blackberry10' ], options: { password: '1q1q' }, verbose: false }); + expect(platformApi.run).toHaveBeenCalledWith({password: '1q1q'}); }, function(err) { expect(err).toBeUndefined(); }).fin(done); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/save.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/save.spec.js b/cordova-lib/spec-cordova/save.spec.js index a04dc4b..24a6128 100644 --- a/cordova-lib/spec-cordova/save.spec.js +++ b/cordova-lib/spec-cordova/save.spec.js @@ -23,9 +23,11 @@ describe('(save flag)', function () { helpers = require('./helpers'), path = require('path'), Q = require('q'), + fs = require('fs'), shell = require('shelljs'), util = require('../src/cordova/util'), prepare = require('../src/cordova/prepare'), + PlatformApi = require('../src/platforms/PlatformApiPoly'), platform = rewire('../src/cordova/platform'); var appName = 'testApp', @@ -54,9 +56,8 @@ describe('(save flag)', function () { timeout = 60 * 1000; //mock variables - var revert_copy_cordova_js, - revert_copy_cordovajs_src, - revert_install_plugins_for_new_platform; + var revert_install_plugins_for_new_platform, + createPlatformOrig = PlatformApi.createPlatform; beforeEach(function (done) { // initial cleanup @@ -68,9 +69,10 @@ describe('(save flag)', function () { spyOn(util, 'cdProjectRoot').andReturn(appPath); spyOn(cordova.raw, 'prepare').andReturn(Q()); + spyOn(PlatformApi, 'createPlatform').andReturn(Q()); + spyOn(PlatformApi, 'updatePlatform').andReturn(Q()); + //rewire mocks - revert_copy_cordova_js = platform.__set__('copy_cordova_js', function () {}); - revert_copy_cordovajs_src = platform.__set__('copy_cordovajs_src', function () {}); revert_install_plugins_for_new_platform = platform.__set__('installPluginsForNewPlatform', function () { return Q(); }); //creating test app @@ -86,8 +88,6 @@ describe('(save flag)', function () { }, timeout); afterEach(function () { - revert_copy_cordova_js(); - revert_copy_cordovajs_src(); revert_install_plugins_for_new_platform(); }); @@ -232,7 +232,11 @@ describe('(save flag)', function () { helpers.setEngineSpec(appPath, platformName, platformVersionNew); platform('add', platformName + '@' + platformVersionNew) .then(function () { - return cordova.raw.platform('update', platformName + '@' + platformVersionOld, { 'save': true }); + var fsExistsSync = fs.existsSync.bind(fs); + spyOn(fs, 'existsSync').andCallFake(function (somePath) { + return (somePath === path.join(appPath, 'platforms', platformName)) || fsExistsSync(somePath); + }); + return platform('update', platformName + '@' + platformVersionOld, { 'save': true }); }).then(function () { expect(helpers.getEngineSpec(appPath, platformName)).toBe('~' + platformVersionOld); done(); @@ -247,7 +251,11 @@ describe('(save flag)', function () { helpers.setEngineSpec(appPath, platformName, platformVersionNew); platform('add', platformName + '@' + platformVersionNew) .then(function () { - return cordova.raw.platform('update', platformGitUrl, { 'save': true }); + var fsExistsSync = fs.existsSync.bind(fs); + spyOn(fs, 'existsSync').andCallFake(function (somePath) { + return (somePath === path.join(appPath, 'platforms', platformName)) || fsExistsSync(somePath); + }); + return platform('update', platformGitUrl, { 'save': true }); }).then(function () { var spec = helpers.getEngineSpec(appPath, platformName); expect(spec).not.toBe(null); @@ -437,6 +445,11 @@ describe('(save flag)', function () { }); describe('prepare', function () { + beforeEach(function () { + // Restore back mocked createPlatform functionality + PlatformApi.createPlatform = createPlatformOrig; + }); + it('spec.23 should restore all platforms and plugins', function (done) { helpers.setEngineSpec(appPath, platformName, platformLocalPath); helpers.setPluginSpec(appPath, localPluginName, localPluginPath); http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/07271a5c/cordova-lib/spec-cordova/xml-helpers.spec.js ---------------------------------------------------------------------- diff --git a/cordova-lib/spec-cordova/xml-helpers.spec.js b/cordova-lib/spec-cordova/xml-helpers.spec.js index 25e6c8f..ade3c47 100644 --- a/cordova-lib/spec-cordova/xml-helpers.spec.js +++ b/cordova-lib/spec-cordova/xml-helpers.spec.js @@ -34,6 +34,23 @@ var path = require('path') , goodbyeTag = et.XML('

GOODBYE

') , helloTagTwo = et.XML('

HELLO

'); +var TEST_XML = '\n' + + '\n' + + ' Hello Cordova\n' + + ' \n' + + ' A sample Apache Cordova application that responds to the deviceready event.\n' + + ' \n' + + ' \n' + + ' Apache Cordova Team\n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + '\n'; describe('xml-helpers', function(){ describe('parseElementtreeSync', function() { @@ -136,4 +153,119 @@ describe('xml-helpers', function(){ expect(config_xml.findall('access').length).toEqual(3); }); }); + + describe('mergeXml', function () { + var dstXml; + beforeEach(function() { + dstXml = et.XML(TEST_XML); + }); + it('should merge attributes and text of the root element without clobbering', function () { + var testXml = et.XML('TEXT'); + xml_helpers.mergeXml(testXml, dstXml); + expect(dstXml.attrib.foo).toEqual('bar'); + expect(dstXml.attrib.id).not.toEqual('NOTANID'); + expect(dstXml.text).not.toEqual('TEXT'); + }); + + it('should merge attributes and text of the root element with clobbering', function () { + var testXml = et.XML('TEXT'); + xml_helpers.mergeXml(testXml, dstXml, 'foo', true); + expect(dstXml.attrib.foo).toEqual('bar'); + expect(dstXml.attrib.id).toEqual('NOTANID'); + expect(dstXml.text).toEqual('TEXT'); + }); + + it('should not merge platform tags with the wrong platform', function () { + var testXml = et.XML('testTEXT'), + origCfg = et.tostring(dstXml); + + xml_helpers.mergeXml(testXml, dstXml, 'foo', true); + expect(et.tostring(dstXml)).toEqual(origCfg); + }); + + it('should merge platform tags with the correct platform', function () { + var testXml = et.XML('testTEXT'), + origCfg = et.tostring(dstXml); + + xml_helpers.mergeXml(testXml, dstXml, 'bar', true); + expect(et.tostring(dstXml)).not.toEqual(origCfg); + var testElement = dstXml.find('testElement'); + expect(testElement).toBeDefined(); + expect(testElement.attrib.testAttrib).toEqual('value'); + expect(testElement.text).toEqual('testTEXT'); + }); + + it('should merge singelton children without clobber', function () { + var testXml = et.XML('SUPER_AUTHOR'); + + xml_helpers.mergeXml(testXml, dstXml); + var testElements = dstXml.findall('author'); + expect(testElements).toBeDefined(); + expect(testElements.length).toEqual(1); + expect(testElements[0].attrib.testAttrib).toEqual('value'); + expect(testElements[0].attrib.href).toEqual('http://cordova.io'); + expect(testElements[0].attrib.email).toEqual('dev@cordova.apache.org'); + expect(testElements[0].text).toContain('Apache Cordova Team'); + }); + + it('should clobber singelton children with clobber', function () { + var testXml = et.XML('SUPER_AUTHOR'); + + xml_helpers.mergeXml(testXml, dstXml, '', true); + var testElements = dstXml.findall('author'); + expect(testElements).toBeDefined(); + expect(testElements.length).toEqual(1); + expect(testElements[0].attrib.testAttrib).toEqual('value'); + expect(testElements[0].attrib.href).toEqual('http://www.nowhere.com'); + expect(testElements[0].attrib.email).toEqual('dev@cordova.apache.org'); + expect(testElements[0].text).toEqual('SUPER_AUTHOR'); + }); + + it('should append non singelton children', function () { + var testXml = et.XML(' '); + + xml_helpers.mergeXml(testXml, dstXml, '', true); + var testElements = dstXml.findall('preference'); + expect(testElements.length).toEqual(4); + }); + + it('should handle namespaced elements', function () { + var testXml = et.XML('testText'); + + xml_helpers.mergeXml(testXml, dstXml, 'foo', true); + var testElement = dstXml.find('foo:bar'); + expect(testElement).toBeDefined(); + expect(testElement.attrib.testAttrib).toEqual('value'); + expect(testElement.text).toEqual('testText'); + }); + + it('should not append duplicate non singelton children', function () { + var testXml = et.XML(''); + + xml_helpers.mergeXml(testXml, dstXml, '', true); + var testElements = dstXml.findall('preference'); + expect(testElements.length).toEqual(2); + }); + + it('should not skip partial duplicate non singelton children', function () { + //remove access tags from dstXML + var testElements = dstXml.findall('access'); + for(var i = 0; i < testElements.length; i++) { + dstXml.remove(testElements[i]); + } + testElements = dstXml.findall('access'); + expect(testElements.length).toEqual(0); + //add an external whitelist access tag + var testXml = et.XML(''); + xml_helpers.mergeXml(testXml, dstXml, '', true); + testElements = dstXml.findall('access'); + expect(testElements.length).toEqual(1); + //add an internal whitelist access tag + testXml = et.XML(''); + xml_helpers.mergeXml(testXml, dstXml, '', true); + testElements = dstXml.findall('access'); + expect(testElements.length).toEqual(2); + + }); + }); }); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org For additional commands, e-mail: commits-help@cordova.apache.org