You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2015/12/11 10:02:43 UTC
[04/49] cordova-windows git commit: CB-9828 Implement and expose
PlatformApi for Windows
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/node_modules/winjs/package.json
----------------------------------------------------------------------
diff --git a/node_modules/winjs/package.json b/node_modules/winjs/package.json
index 50dd0d2..938812a 100644
--- a/node_modules/winjs/package.json
+++ b/node_modules/winjs/package.json
@@ -2,7 +2,7 @@
"name": "winjs",
"title": "Windows Library for JavaScript (WinJS)",
"description": "WinJS is a set of JavaScript toolkits that allow developers to build applications using HTML/JS/CSS technology.",
- "version": "4.0.1",
+ "version": "4.4.0",
"main": "js/ui.js",
"homepage": "http://try.buildwinjs.com/",
"author": {
@@ -11,7 +11,7 @@
},
"repository": {
"type": "git",
- "url": "https://github.com/winjs/winjs"
+ "url": "git+https://github.com/winjs/winjs.git"
},
"licenses": [
{
@@ -23,11 +23,13 @@
"url": "https://github.com/winjs/winjs/issues"
},
"devDependencies": {
+ "bowser": "~1.0.0",
"chalk": "~0.5.1",
"fs-extra": "^0.10.0",
"glob": "^4.0.5",
"grunt": "~0.4.5",
"grunt-contrib-clean": "~0.6.0",
+ "grunt-contrib-compress": "^0.13.0",
"grunt-contrib-concat": "~0.5.0",
"grunt-contrib-connect": "^0.8.0",
"grunt-contrib-copy": "~0.5.0",
@@ -36,7 +38,10 @@
"grunt-contrib-less": "~0.11.4",
"grunt-contrib-requirejs": "^0.4.4",
"grunt-contrib-uglify": "^0.5.1",
- "grunt-jscs": "^0.6.2",
+ "grunt-git": "^0.3.5",
+ "grunt-github-releaser": "^0.1.17",
+ "grunt-jscs": "^1.8.0",
+ "grunt-nuget": "^0.1.4",
"grunt-replace": "~0.7.8",
"grunt-saucelabs": "git+https://github.com/xirzec/grunt-saucelabs.git#debug",
"grunt-shell": "~0.7.0",
@@ -51,24 +56,33 @@
"typescript": "1.4.1",
"websocket": "^1.0.8"
},
- "_id": "winjs@4.0.1",
+ "_id": "winjs@4.4.0",
"scripts": {},
- "_shasum": "7bf65fadab719fec2bed306540e2cf69948e2e30",
- "_from": "winjs@>=4.0.0",
- "_npmVersion": "2.7.4",
- "_nodeVersion": "0.12.2",
+ "_shasum": "ca43f1d75eefa6e04e995262bb0e76ac51160c9a",
+ "_from": "winjs@>=4.4.0 <5.0.0",
+ "_resolved": "https://registry.npmjs.org/winjs/-/winjs-4.4.0.tgz",
+ "_npmVersion": "2.14.0",
+ "_nodeVersion": "4.1.1",
"_npmUser": {
- "name": "rigdern",
- "email": "adam.comella@outlook.com"
+ "name": "amazingjaze",
+ "email": "AmazingJaze@gmail.com"
},
"dist": {
- "shasum": "7bf65fadab719fec2bed306540e2cf69948e2e30",
- "tarball": "http://registry.npmjs.org/winjs/-/winjs-4.0.1.tgz"
+ "shasum": "ca43f1d75eefa6e04e995262bb0e76ac51160c9a",
+ "tarball": "http://registry.npmjs.org/winjs/-/winjs-4.4.0.tgz"
},
"maintainers": [
{
- "name": "xirzec",
- "email": "xirzec@xirzec.com"
+ "name": "amazingjaze",
+ "email": "AmazingJaze@gmail.com"
+ },
+ {
+ "name": "jdalton",
+ "email": "john.david.dalton@gmail.com"
+ },
+ {
+ "name": "jseanxu",
+ "email": "jseanxu@live.com"
},
{
"name": "phosphoer",
@@ -77,9 +91,16 @@
{
"name": "rigdern",
"email": "adam.comella@outlook.com"
+ },
+ {
+ "name": "winjs",
+ "email": "joshrenn@microsoft.com"
+ },
+ {
+ "name": "xirzec",
+ "email": "xirzec@xirzec.com"
}
],
"directories": {},
- "_resolved": "https://registry.npmjs.org/winjs/-/winjs-4.0.1.tgz",
"readme": "ERROR: No README data found!"
}
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 265bc88..4054421 100644
--- a/package.json
+++ b/package.json
@@ -1,46 +1,50 @@
{
- "name": "cordova-windows",
- "version": "4.3.0-dev",
- "description": "cordova-windows release",
- "main": "bin/create",
- "repository": {
- "type": "git",
- "url": "https://github.com/apache/cordova-windows"
- },
- "keywords": [
- "windows",
- "cordova",
- "apache"
- ],
- "scripts": {
- "test": "npm run jshint && npm run test-unit && npm run test-e2e",
- "test-unit": "node node_modules/jasmine-node/lib/jasmine-node/cli.js --captureExceptions spec/unit",
- "test-e2e": "node node_modules/jasmine-node/lib/jasmine-node/cli.js --captureExceptions spec/e2e",
- "cover": "node node_modules/istanbul/lib/cli.js cover --root template --print detail node_modules/jasmine-node/bin/jasmine-node -- spec/unit",
- "jshint": "node node_modules/jshint/bin/jshint bin && node node_modules/jshint/bin/jshint template && node node_modules/jshint/bin/jshint spec"
- },
- "dependencies": {
- "elementtree": "~0.1.5",
- "node-uuid": "~1.4",
- "nopt": "~3",
- "q": ">0.9.0",
- "shelljs": "~0.3",
- "winjs": "^4.0.0"
- },
- "devDependencies": {
- "jasmine-node": "1.14.5",
- "jshint": "^2.6.0",
- "rewire": ">=2.1.3",
- "istanbul": "^0.3.4"
- },
- "bundledDependencies": [
- "q",
- "nopt",
- "node-uuid",
- "shelljs",
- "elementtree",
- "winjs"
- ],
- "author": "Apache Software Foundation",
- "license": "Apache Version 2.0"
-}
\ No newline at end of file
+ "name": "cordova-windows",
+ "version": "4.3.0-dev",
+ "description": "cordova-windows release",
+ "bin": "bin/create",
+ "main": "template/cordova/Api.js",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/apache/cordova-windows"
+ },
+ "keywords": [
+ "windows",
+ "cordova",
+ "apache"
+ ],
+ "scripts": {
+ "test": "npm run jshint && npm run test-unit && npm run test-e2e",
+ "test-unit": "jasmine-node --captureExceptions spec/unit",
+ "test-e2e": "jasmine-node --captureExceptions spec/e2e",
+ "cover": "istanbul cover --root template --print detail node_modules/jasmine-node/bin/jasmine-node -- spec/unit",
+ "jshint": "jshint bin && jshint template && jshint spec"
+ },
+ "dependencies": {
+ "cordova-common": "^1.0.0",
+ "elementtree": "^0.1.6",
+ "node-uuid": "^1.4.3",
+ "nopt": "^3.0.4",
+ "q": "^1.4.1",
+ "semver": "^5.0.3",
+ "shelljs": "^0.5.3",
+ "winjs": "^4.4.0"
+ },
+ "devDependencies": {
+ "istanbul": "^0.4.0",
+ "jasmine-node": "1.14.5",
+ "jshint": "^2.8.0",
+ "rewire": "^2.1.3"
+ },
+ "bundledDependencies": [
+ "cordova-common",
+ "elementtree",
+ "node-uuid",
+ "nopt",
+ "q",
+ "shelljs",
+ "winjs"
+ ],
+ "author": "Apache Software Foundation",
+ "license": "Apache-2.0"
+}
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/spec/unit/AppxManifest.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/AppxManifest.spec.js b/spec/unit/AppxManifest.spec.js
new file mode 100644
index 0000000..d158144
--- /dev/null
+++ b/spec/unit/AppxManifest.spec.js
@@ -0,0 +1,102 @@
+/**
+ 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 rewire = require('rewire');
+var et = require('elementtree');
+var xml = require('cordova-common').xmlHelpers;
+var AppxManifest = rewire('../../template/cordova/lib/AppxManifest');
+var Win10AppxManifest = AppxManifest.__get__('Win10AppxManifest');
+
+var WINDOWS_MANIFEST = 'template/package.windows.appxmanifest';
+var WINDOWS_PHONE_MANIFEST = 'template/package.phone.appxmanifest';
+
+describe('AppxManifest', function () {
+
+ var XMLS = {
+ '/no/prefixed': new et.ElementTree(et.XML('<?xml version="1.0" encoding="UTF-8"?><Package/>')),
+ '/uap/prefixed': new et.ElementTree(et.XML('<?xml version="1.0" encoding="UTF-8"?><Package xmlns:uap=""/>'))
+ };
+
+ beforeEach(function () {
+ var parseElementtreeSyncOrig = xml.parseElementtreeSync;
+ spyOn(xml, 'parseElementtreeSync').andCallFake(function (manifestPath) {
+ return XMLS[manifestPath] || parseElementtreeSyncOrig(manifestPath);
+ });
+ });
+
+ describe('constructor', function () {
+
+ it('should create a new AppxManifest instance', function () {
+ var manifest;
+ expect(function () { manifest = new AppxManifest(WINDOWS_MANIFEST); }).not.toThrow();
+ expect(manifest instanceof AppxManifest).toBe(true);
+ });
+
+ it('should throw if first parameter is not a file', function () {
+ expect(function () { new AppxManifest('/invalid/path'); }).toThrow();
+ });
+
+ it('should throw if first parameter is not a valid manifest file (no "Package" tag)', function () {
+ expect(function () { new AppxManifest('/invalid/manifest'); }).toThrow();
+ });
+
+ it('should add ":" to manifest prefix if needed', function () {
+ expect(new AppxManifest(WINDOWS_MANIFEST, 'prefix').prefix).toEqual('prefix:');
+ });
+ });
+
+ describe('static get() method', function () {
+
+ it('should return an AppxManifest instance', function () {
+ expect(AppxManifest.get(WINDOWS_MANIFEST) instanceof AppxManifest).toBe(true);
+ });
+
+ it('should detect manifest prefix based on "Package" element attributes', function () {
+ expect(AppxManifest.get(WINDOWS_MANIFEST).prefix).toEqual('m2:');
+ expect(AppxManifest.get(WINDOWS_PHONE_MANIFEST).prefix).toEqual('m3:');
+ });
+
+ it('should instantiate either AppxManifest or Windows 10 AppxManifest based on manifest prefix', function () {
+ expect(AppxManifest.get('/no/prefixed').prefix).toEqual('');
+ expect(AppxManifest.get('/no/prefixed') instanceof AppxManifest).toBe(true);
+ expect(AppxManifest.get('/no/prefixed') instanceof Win10AppxManifest).toBe(false);
+
+ expect(AppxManifest.get('/uap/prefixed').prefix).toEqual('uap:');
+ expect(AppxManifest.get('/uap/prefixed') instanceof Win10AppxManifest).toBe(true);
+ });
+ });
+
+ describe('instance get* methods', function () {
+ var methods = ['getPhoneIdentity','getIdentity','getProperties','getApplication','getVisualElements'];
+
+ it('should exists', function () {
+ var manifest = AppxManifest.get(WINDOWS_PHONE_MANIFEST);
+ var emptyManifest = AppxManifest.get('/no/prefixed');
+
+ methods.forEach(function (method) {
+ expect(manifest[method]).toBeDefined();
+ expect(manifest[method]).toEqual(jasmine.any(Function));
+ expect(function () { manifest[method](); }).not.toThrow();
+ expect(function () { emptyManifest[method](); }).toThrow();
+ expect(manifest[method]()).toBeDefined();
+ });
+ });
+ });
+});
+
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/spec/unit/MSBuildTools.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/MSBuildTools.spec.js b/spec/unit/MSBuildTools.spec.js
index d9ed253..4850946 100644
--- a/spec/unit/MSBuildTools.spec.js
+++ b/spec/unit/MSBuildTools.spec.js
@@ -16,12 +16,12 @@
specific language governing permissions and limitations
under the License.
*/
-var Q = require('q'),
- shell = require('shelljs'),
- rewire = require('rewire'),
- platformRoot = '../../template',
- buildTools = rewire(platformRoot + '/cordova/lib/MSBuildTools.js'),
- Version = require(platformRoot + '/cordova/lib/Version.js');
+var Q = require('q');
+var shell = require('shelljs');
+var rewire = require('rewire');
+var platformRoot = '../../template';
+var buildTools = rewire(platformRoot + '/cordova/lib/MSBuildTools.js');
+var Version = require(platformRoot + '/cordova/lib/Version.js');
var fakeToolsPath = function (version) {
return 'C:\\Program Files (x86)\\MSBuild\\' + version;
@@ -89,23 +89,26 @@ describe('findAvailableVersion method', function(){
});
describe('checkMSBuildVersion method', function(){
- var checkMSBuildVersion = buildTools.__get__('checkMSBuildVersion'),
- execOriginal;
+ var checkMSBuildVersion = buildTools.__get__('checkMSBuildVersion');
+
+ var spawnOriginal = buildTools.__get__('spawn');
+ var spawnSpy = jasmine.createSpy('spawn');
beforeEach(function () {
- execOriginal = buildTools.__get__('exec');
+ buildTools.__set__('spawn', spawnSpy);
});
afterEach(function () {
- buildTools.__set__('exec', execOriginal);
+ buildTools.__set__('spawn', spawnOriginal);
});
it('spec.6 should return valid version and path', function(){
var version = '14.0';
- buildTools.__set__('exec', function(cmd) {
- return Q.resolve('\r\nHKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\12.0\r\n\tMSBuildToolsPath\tREG_SZ\t' + fakeToolsPath(version) + '\r\n\r\n');
- });
+ spawnSpy.andReturn(Q.resolve(
+ '\r\nHKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\12.0\r\n\t' +
+ 'MSBuildToolsPath\tREG_SZ\t' + fakeToolsPath(version) + '\r\n\r\n')
+ );
checkMSBuildVersion(version).then(function (actual) {
expect(actual.version).toBe(version);
@@ -114,37 +117,24 @@ describe('checkMSBuildVersion method', function(){
});
it('spec.7 should return null if no tools found for version', function(){
- buildTools.__set__('exec', function(cmd) {
- return Q.resolve('ERROR: The system was unable to find the specified registry key or value.');
- });
+ spawnSpy.andReturn(Q.resolve('ERROR: The system was unable to find the specified registry key or value.'));
checkMSBuildVersion('14.0').then(function (actual) {
- expect(actual).toBeNull();
+ expect(actual).not.toBeDefined();
});
});
it('spec.8 should return null on internal error', function(){
- buildTools.__set__('exec', function(cmd) {
- return Q.reject();
- });
+ spawnSpy.andReturn(Q.reject());
checkMSBuildVersion('14.0').then(function (actual) {
- expect(actual).toBeNull();
+ expect(actual).not.toBeDefined();
});
});
});
describe('MSBuildTools object', function(){
- var MSBuildTools = buildTools.__get__('MSBuildTools'),
- spawnOriginal;
-
- beforeEach(function () {
- spawnOriginal = buildTools.__get__('spawn');
- });
-
- afterEach(function () {
- buildTools.__set__('spawn', spawnOriginal);
- });
+ var MSBuildTools = buildTools.__get__('MSBuildTools');
it('spec.9 should have fields and methods defined', function() {
var version = '14.0',
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/spec/unit/Prepare.Win10.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/Prepare.Win10.spec.js b/spec/unit/Prepare.Win10.spec.js
index dc1568d..caa2e3b 100644
--- a/spec/unit/Prepare.Win10.spec.js
+++ b/spec/unit/Prepare.Win10.spec.js
@@ -19,100 +19,22 @@
var rewire = require('rewire'),
prepare = rewire('../../template/cordova/lib/prepare'),
- Version = require('../../template/cordova/lib/Version'),
- et = require('elementtree'),
+ AppxManifest = require('../../template/cordova/lib/AppxManifest'),
+ ConfigParser = require('../../template/cordova/lib/ConfigParser'),
fs = require('fs'),
- getAllMinMaxUAPVersions = prepare.__get__('getAllMinMaxUAPVersions'),
+ et = require('elementtree'),
+ events = require('cordova-common').events,
+ xml = require('cordova-common').xmlHelpers,
+ updateManifestFile = prepare.__get__('updateManifestFile'),
applyCoreProperties = prepare.__get__('applyCoreProperties'),
applyAccessRules = prepare.__get__('applyAccessRules'),
- checkForRestrictedCaps = prepare.__get__('checkForRestrictedCapabilities'),
- ensureUapPrefixedCapabilities = prepare.__get__('ensureUapPrefixedCapabilities');
+ applyNavigationWhitelist = prepare.__get__('applyNavigationWhitelist'),
+ applyStartPage = prepare.__get__('applyStartPage');
var Win10ManifestPath = 'template/package.windows10.appxmanifest',
Win81ManifestPath = 'template/package.windows.appxmanifest';
/***
- * Unit tests for validating that min/max versions are correctly obtained
- * (for the function getAllMinMaxUAPVersions) from prepare.js.
- **/
-describe('Min/Max UAP versions are correctly read from the config file.', function() {
-
- var mockConfig = {
- getMatchingPreferences: function(regexp) {
- return [
- { name: 'Windows.Universal-MinVersion', value: '10.0.9910.0' },
- { name: 'Windows.Universal-MaxVersionTested', value: '10.0.9917.0' },
- { name: 'Windows.Desktop-MinVersion', value: '10.0.9910.0' },
- { name: 'Microsoft.Xbox-MaxVersionTested', value: '10.0.9917.0' }
- ];
- }
- };
-
- it('Should correctly transform all versions as a baseline.', function() {
- var versionSet = getAllMinMaxUAPVersions(mockConfig);
- var ver9910 = new Version(10, 0, 9910, 0);
- var ver9917 = new Version(10, 0, 9917, 0);
-
- expect(versionSet['Windows.Universal']).toBeDefined();
- expect(ver9910.eq(versionSet['Windows.Universal'].MinVersion)).toBe(true);
- expect(ver9917.eq(versionSet['Windows.Universal'].MaxVersionTested)).toBe(true);
-
- expect(versionSet['Windows.Desktop']).toBeDefined();
- expect(ver9910.eq(versionSet['Windows.Desktop'].MinVersion)).toBe(true);
- expect(ver9910.eq(versionSet['Windows.Desktop'].MaxVersionTested)).toBe(true);
-
- expect(versionSet['Microsoft.Xbox']).toBeDefined();
- expect(ver9917.eq(versionSet['Microsoft.Xbox'].MinVersion)).toBe(true);
- expect(ver9917.eq(versionSet['Microsoft.Xbox'].MaxVersionTested)).toBe(true);
-
- expect(Object.keys(versionSet).length).toBe(3);
- });
-
-});
-
-describe('Min/Max UAP versions are produced correctly even when the config file has no settings.', function() {
- var mockConfig = {
- getMatchingPreferences: function(regexp) {
- return [];
- }
- };
-
- it('Should correctly transform all versions as a baseline.', function() {
- var versionSet = getAllMinMaxUAPVersions(mockConfig);
- var verBaseline = prepare.__get__('BASE_UAP_VERSION');
-
- expect(versionSet['Windows.Universal']).toBeDefined();
- expect(verBaseline.eq(versionSet['Windows.Universal'].MinVersion)).toBe(true);
- expect(verBaseline.eq(versionSet['Windows.Universal'].MaxVersionTested)).toBe(true);
-
- expect(Object.keys(versionSet).length).toBe(1);
- });
-});
-
-describe('Min/Max UAP versions are correctly read from the config file.', function() {
-
- var mockConfig = {
- getMatchingPreferences: function(regexp) {
- return [
- { name: 'Windows.Universal-MinVersion', value: '10.0.9910.f' },
- { name: 'Windows.Universal-MaxVersionTested', value: '10.0.9917.0' },
- ];
- }
- };
-
- it('Should fail to produce min/max versions with a RangeError.', function() {
- try {
- getAllMinMaxUAPVersions(mockConfig);
- expect(false).toBe(true);
- }
- catch (ex) {
- expect(ex.constructor).toBe(RangeError);
- }
- });
-
-});
-
-/***
* Unit tests for validating default ms-appx-web:// URI scheme in Win10
* (for the function applyCoreProperties) from prepare.js.
**/
@@ -124,6 +46,7 @@ var PreferencesBaseline = {
WindowsStorePublisherName: null,
WindowsStoreIdentityName: null
};
+
function createMockConfigAndManifestForApplyCoreProperties(startPage, preferences, win10, winPackageVersion) {
if (!preferences) {
preferences = { };
@@ -148,128 +71,135 @@ function createMockConfigAndManifestForApplyCoreProperties(startPage, preference
};
var filePath = win10 ? Win10ManifestPath : Win81ManifestPath;
- var fileContents = fs.readFileSync(filePath, 'utf-8');
- var manifest = new et.ElementTree(et.XML(fileContents.trim()));
+ var manifest = AppxManifest.get(filePath);
+ spyOn(fs, 'writeFileSync');
return { config: config, manifest: manifest };
}
function addCapabilityDeclarationToMockManifest(manifest, capability) {
- var capRoot = manifest.find('.//Capabilities');
+ var capRoot = manifest.doc.find('.//Capabilities');
var cap = new et.Element('Capability');
cap.attrib.Name = capability;
capRoot.append(cap);
}
-describe('A Windows 8.1 project should not have an HTTP or HTTPS scheme for its startup URI.', function() {
+describe('Windows 8.1 project', function() {
- // arrange
- var mockConfig = createMockConfigAndManifestForApplyCoreProperties('index.html', { 'WindowsDefaultUriPrefix': 'http://' }, false);
+ it('should not have an HTTP or HTTPS scheme for its startup URI.', function() {
- // act
- applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'm2:', false);
+ // arrange
+ var mockConfig = createMockConfigAndManifestForApplyCoreProperties('index.html', { 'WindowsDefaultUriPrefix': 'http://' }, false);
- var app = mockConfig.manifest.find('.//Application');
- expect(app.attrib.StartPage).toBe('www/index.html');
-});
+ // act
+ applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'm2:', false);
-describe('A Windows 8.1 project should not have any scheme for its startup URI.', function() {
+ var app = mockConfig.manifest.doc.find('.//Application');
+ expect(app.attrib.StartPage).toBe('www/index.html');
+ });
- // arrange
- var mockConfig = createMockConfigAndManifestForApplyCoreProperties('index.html', { 'WindowsDefaultUriPrefix': 'ms-appx://' }, false);
+ it('should not have any scheme for its startup URI.', function() {
- // act
- applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'm2:', false);
+ // arrange
+ var mockConfig = createMockConfigAndManifestForApplyCoreProperties('index.html', { 'WindowsDefaultUriPrefix': 'ms-appx://' }, false);
- var app = mockConfig.manifest.find('.//Application');
- expect(app.attrib.StartPage).toBe('www/index.html');
+ // act
+ applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'm2:', false);
+
+ var app = mockConfig.manifest.doc.find('.//Application');
+ expect(app.attrib.StartPage).toBe('www/index.html');
+ });
});
-describe('A Windows 10 project default to ms-appx-web for its startup URI.', function() {
+describe('Windows 10 project', function() {
+ it('should default to ms-appx-web for its startup URI.', function() {
- // arrange
- var mockConfig = createMockConfigAndManifestForApplyCoreProperties('index.html', { }, true);
+ // arrange
+ var mockConfig = createMockConfigAndManifestForApplyCoreProperties('index.html', { }, true);
- // act
- applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true);
+ // act
+ applyStartPage(mockConfig.config, mockConfig.manifest, true);
- var app = mockConfig.manifest.find('.//Application');
- expect(app.attrib.StartPage).toBe('ms-appx-web:///www/index.html');
-});
+ var app = mockConfig.manifest.doc.find('.//Application');
+ expect(app.attrib.StartPage).toBe('ms-appx-web:///www/index.html');
+ });
-describe('A Windows 10 project should allow ms-appx as its startup URI, and it gets removed from the final output.', function() {
+ it ('should allow ms-appx as its startup URI, and it gets removed from the final output.', function() {
- // arrange
- var mockConfig = createMockConfigAndManifestForApplyCoreProperties('index.html', { 'WindowsDefaultUriPrefix': 'ms-appx://' }, true);
+ // arrange
+ var mockConfig = createMockConfigAndManifestForApplyCoreProperties('index.html', { 'WindowsDefaultUriPrefix': 'ms-appx://' }, true);
- // act
- applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true);
+ // act
+ applyStartPage(mockConfig.config, mockConfig.manifest, true);
- var app = mockConfig.manifest.find('.//Application');
- expect(app.attrib.StartPage).toBe('www/index.html');
-});
+ var app = mockConfig.manifest.doc.find('.//Application');
+ expect(app.attrib.StartPage).toBe('www/index.html');
+ });
-describe('A Windows 10 project should allow an HTTP or HTTPS scheme for its startup URI.', function() {
+ it('should allow an HTTP or HTTPS scheme for its startup URI.', function() {
- // arrange
- var mockConfig = createMockConfigAndManifestForApplyCoreProperties('www.contoso.com/', { 'WindowsDefaultUriPrefix': 'http://' }, true);
+ // arrange
+ var mockConfig = createMockConfigAndManifestForApplyCoreProperties('www.contoso.com/', { 'WindowsDefaultUriPrefix': 'http://' }, true);
- // act
- applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true);
+ // act
+ applyStartPage(mockConfig.config, mockConfig.manifest, true);
- var app = mockConfig.manifest.find('.//Application');
- expect(app.attrib.StartPage).toBe('http://www.contoso.com/');
+ var app = mockConfig.manifest.doc.find('.//Application');
+ expect(app.attrib.StartPage).toBe('http://www.contoso.com/');
+ });
});
-describe('An app specifying a Store DisplayName in its config.xml should have it reflected in the manifest.', function() {
- // arrange
- var mockConfig = createMockConfigAndManifestForApplyCoreProperties('www.contoso.com/', { 'WindowsDefaultUriPrefix': 'http://', 'WindowsStoreDisplayName': 'ContosoApp' }, true);
+describe('Windows Store preference', function () {
- // act
- applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true);
+ it('"WindowsStoreDisplayName" should be reflected in the manifest.', function() {
- var app = mockConfig.manifest.find('.//Properties/DisplayName');
- expect(app.text).toBe('ContosoApp');
-});
+ // arrange
+ var mockConfig = createMockConfigAndManifestForApplyCoreProperties('www.contoso.com/', { 'WindowsDefaultUriPrefix': 'http://', 'WindowsStoreDisplayName': 'ContosoApp' }, true);
-describe('An app specifying a Store PublisherName in its config.xml should have it reflected in the manifest.', function() {
+ // act
+ applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true);
- // arrange
- var mockConfig = createMockConfigAndManifestForApplyCoreProperties('www.contoso.com/', { 'WindowsDefaultUriPrefix': 'http://', 'WindowsStorePublisherName': 'Contoso Inc' }, true);
+ var app = mockConfig.manifest.doc.find('.//Properties/DisplayName');
+ expect(app.text).toBe('ContosoApp');
+ });
+
+ it('"WindowsStorePublisherName" should be reflected in the manifest.', function() {
- // act
- applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true);
+ // arrange
+ var mockConfig = createMockConfigAndManifestForApplyCoreProperties('www.contoso.com/', { 'WindowsDefaultUriPrefix': 'http://', 'WindowsStorePublisherName': 'Contoso Inc' }, true);
- var app = mockConfig.manifest.find('.//Properties/PublisherDisplayName');
- expect(app.text).toBe('Contoso Inc');
+ // act
+ applyCoreProperties(mockConfig.config, mockConfig.manifest, 'fake-path', 'uap:', true);
+
+ var app = mockConfig.manifest.doc.find('.//Properties/PublisherDisplayName');
+ expect(app.text).toBe('Contoso Inc');
+ });
});
describe('A Windows 10 project should warn if it supports remote mode and restricted capabilities.', function() {
// arrange
- var mockConfig = createMockConfigAndManifestForApplyAccessRules(true, 'http://www.bing.com/*');
- addCapabilityDeclarationToMockManifest(mockConfig.manifest, 'documentsLibrary');
-
+ var mockConfig;
var stringFound = false,
- searchStr = ' documentsLibrary',
- oldConsoleWarn = console.warn;
+ searchStr = 'documentsLibrary';
beforeEach(function() {
+ mockConfig = createMockConfigAndManifestForApplyAccessRules(true, 'http://www.bing.com/*');
+ addCapabilityDeclarationToMockManifest(mockConfig.manifest, 'documentsLibrary');
+
+ spyOn(AppxManifest, 'get').andReturn(mockConfig.manifest);
+
stringFound = false;
- spyOn(console, 'warn').andCallFake(function(msg) {
- if (msg === searchStr)
+ events.on('warn', function (msg) {
+ if (msg.indexOf(searchStr) >= 0)
stringFound = true;
});
});
- afterEach(function() {
- console.warn = oldConsoleWarn;
- });
-
it('asserts that the documentsLibrary capability is restricted', function() {
// act
- checkForRestrictedCaps(mockConfig.config, mockConfig.manifest);
+ updateManifestFile(mockConfig.config, '/manifest/path');
// assert
expect(stringFound).toBe(true);
@@ -287,143 +217,158 @@ function createMockConfigAndManifestForApplyAccessRules(isWin10) {
rules.push(arguments[i]);
}
- var config = {
- version: function() { return '1.0.0.0'; },
- name: function() { return 'HelloCordova'; },
- packageName: function() { return 'org.apache.cordova.HelloCordova'; },
- author: function() { return 'Apache'; },
- startPage: function() { return 'index.html'; },
- getPreference: function(preferenceName) {
- if (preferenceName === 'WindowsDefaultUriPrefix') {
- return isWin10 ? 'ms-appx-web://' : 'ms-appx://';
- }
- else {
- throw new RangeError('Unexpected call to config.getPreference in unit test.');
- }
- },
- getAccessRules: function() {
- if (isWin10) {
- return [];
- }
+ var TEST_XML = '<?xml version="1.0" encoding="UTF-8"?>\n' +
+ '<widget xmlns = "http://www.w3.org/ns/widgets"\n' +
+ ' xmlns:cdv = "http://cordova.apache.org/ns/1.0"\n' +
+ ' id = "org.apache.cordova.HelloCordova"\n' +
+ ' version = "1.0.0.0">\n' +
+ ' <name>HelloCordova</name>\n' +
+ ' <author href="http://cordova.io" email="dev@cordova.apache.org">\n' +
+ ' Apache\n' +
+ ' </author>\n' +
+ ' <content src="index.html" />\n' +
+ '</widget>\n';
+
+ var origParseElementtreeSync = xml.parseElementtreeSync;
+ spyOn(xml, 'parseElementtreeSync').andCallFake(function(path) {
+ if (path ==='config.xml') return new et.ElementTree(et.XML(TEST_XML));
+ return origParseElementtreeSync(path);
+ });
- return rules;
- },
- getNavigationWhitelistRules: function() {
- if (isWin10) {
- return rules;
- }
+ var config = new ConfigParser('config.xml');
+
+ var origGetPreference = config.getPreference;
+ spyOn(config, 'getPreference').andCallFake(function (prefName) {
+ if (prefName === 'WindowsDefaultUriPrefix') {
+ return isWin10 ? 'ms-appx-web://' : 'ms-appx://';
+ }
+ return origGetPreference.call(config, prefName);
+ });
+
+ config.getAccesses = function() {
+ if (isWin10) {
return [];
}
+
+ return rules.map(function (rule) {
+ return { 'origin': rule };
+ });
+ };
+
+ config.getAllowNavigations = function() {
+ if (isWin10) {
+ return rules.map(function (rule) {
+ return { 'href': rule };
+ });
+ }
+
+ return [];
};
var filePath = isWin10 ? Win10ManifestPath : Win81ManifestPath;
- var fileContents = fs.readFileSync(filePath, 'utf-8');
- var manifest = new et.ElementTree(et.XML(fileContents.trim()));
+ var manifest = AppxManifest.get(filePath);
+ spyOn(fs, 'writeFileSync');
return { config: config, manifest: manifest };
}
-describe('A Windows 8.1 project should not have WindowsRuntimeAccess attributes in access rules.', function() {
+describe('Access rules management', function () {
+ // body...
+ it('A Windows 8.1 project should not have WindowsRuntimeAccess attributes in access rules.', function() {
- var mockConfig = createMockConfigAndManifestForApplyAccessRules(false, 'https://www.contoso.com');
+ var mockConfig = createMockConfigAndManifestForApplyAccessRules(false, 'https://www.contoso.com');
- applyAccessRules(mockConfig.config, mockConfig.manifest, false);
+ applyAccessRules(mockConfig.config, mockConfig.manifest);
- var app = mockConfig.manifest.find('.//Application'),
- accessRules = app.find('.//ApplicationContentUriRules');
+ var app = mockConfig.manifest.doc.find('.//Application'),
+ accessRules = app.find('.//ApplicationContentUriRules');
- expect(accessRules).toBeDefined();
- expect(accessRules.len()).toBe(1);
+ expect(accessRules).toBeDefined();
+ expect(accessRules.len()).toBe(1);
- var rule = accessRules.getItem(0);
- expect(rule).toBeDefined();
- expect(rule.attrib.WindowsRuntimeAccess).toBeUndefined();
+ var rule = accessRules.getItem(0);
+ expect(rule).toBeDefined();
+ expect(rule.attrib.WindowsRuntimeAccess).toBeUndefined();
-});
+ });
-describe('A Windows 10 project should have WindowsRuntimeAccess attributes in access rules.', function() {
+ it('A Windows 10 project should have WindowsRuntimeAccess attributes in access rules.', function() {
- var mockConfig = createMockConfigAndManifestForApplyAccessRules(true, 'https://www.contoso.com');
+ var mockConfig = createMockConfigAndManifestForApplyAccessRules(true, 'https://www.contoso.com');
- applyAccessRules(mockConfig.config, mockConfig.manifest, true);
+ applyNavigationWhitelist(mockConfig.config, mockConfig.manifest, true);
- var app = mockConfig.manifest.find('.//Application'),
- accessRules = app.find('.//uap:ApplicationContentUriRules');
+ var app = mockConfig.manifest.doc.find('.//Application'),
+ accessRules = app.find('.//uap:ApplicationContentUriRules');
- expect(accessRules).toBeDefined();
- expect(accessRules.len()).toBe(2);
+ expect(accessRules).toBeDefined();
+ expect(accessRules.len()).toBe(2);
- var rule = accessRules.getItem(0);
- expect(rule).toBeDefined();
- expect(rule.attrib.WindowsRuntimeAccess).toBeDefined();
- expect(rule.attrib.WindowsRuntimeAccess).toBe('all');
+ var rule = accessRules.getItem(0);
+ expect(rule).toBeDefined();
+ expect(rule.attrib.WindowsRuntimeAccess).toBeDefined();
+ expect(rule.attrib.WindowsRuntimeAccess).toBe('all');
-});
+ });
-describe('A Windows 8.1 project should reject http:// URI scheme rules.', function() {
-
- var stringIndex = -1,
- searchStr = 'Access rules must begin with "https://", the following rule will be ignored: ',
- oldConsoleWarn = console.warn;
- beforeEach(function() {
- spyOn(console, 'warn').andCallFake(function(msg) {
- stringIndex = msg.indexOf(searchStr);
+ describe('A Windows 8.1 project should reject http:// URI scheme rules.', function() {
+
+ var stringIndex = -1,
+ searchStr = 'Access rules must begin with "https://", the following rule will be ignored: ';
+
+ beforeEach(function() {
+ require('cordova-common').events.on('warn', function (evt) {
+ stringIndex = evt.indexOf(searchStr);
+ });
});
- });
- afterEach(function() {
- console.warn = oldConsoleWarn;
- });
-
- it('applies access rules and verifies at least one was rejected', function() {
- var mockConfig = createMockConfigAndManifestForApplyAccessRules(false, 'http://www.contoso.com');
- applyAccessRules(mockConfig.config, mockConfig.manifest, false);
- expect(stringIndex).toBe(0);
+ it('applies access rules and verifies at least one was rejected', function() {
+ var mockConfig = createMockConfigAndManifestForApplyAccessRules(false, 'http://www.contoso.com');
+ applyAccessRules(mockConfig.config, mockConfig.manifest, false);
+
+ expect(stringIndex).toBe(0);
+ });
});
-});
-describe('A Windows 10 project should accept http:// URI access rules.', function() {
+ describe('A Windows 10 project should accept http:// URI access rules.', function() {
- var stringIndex = -1,
- searchStr = 'The following navigation rule had an invalid URI scheme and is ignored:',
- oldConsoleWarn = console.warn;
- beforeEach(function() {
- spyOn(console, 'warn').andCallFake(function(msg) {
- stringIndex = msg.indexOf(searchStr);
+ var stringIndex = -1,
+ searchStr = 'The following navigation rule had an invalid URI scheme and is ignored:';
+ beforeEach(function() {
+ require('cordova-common').events.on('warn', function (evt) {
+ stringIndex = evt.indexOf(searchStr);
+ });
});
- });
- afterEach(function() {
- console.warn = oldConsoleWarn;
- });
- it('applies access rules and verifies they were accepted', function() {
- var mockConfig = createMockConfigAndManifestForApplyAccessRules(true, 'http://www.contoso.com');
- applyAccessRules(mockConfig.config, mockConfig.manifest, true);
+ it('applies access rules and verifies they were accepted', function() {
+ var mockConfig = createMockConfigAndManifestForApplyAccessRules(true, 'http://www.contoso.com');
+ applyAccessRules(mockConfig.config, mockConfig.manifest, true);
- expect(stringIndex).toBe(-1);
+ expect(stringIndex).toBe(-1);
+ });
});
-
});
describe('A Windows 10 project should apply the uap: namespace prefix to certain capabilities.', function() {
-
- var element = null;
+
+ var manifest;
beforeEach(function() {
- element = new et.Element('Capabilities');
+ manifest = createMockConfigAndManifestForApplyAccessRules(true, 'https://www.contoso.com').manifest;
+ var element = manifest.doc.find('.//Capabilities');
+ element.clear();
element.append(new et.Element('Capability', { Name: 'internetClient' }));
element.append(new et.Element('Capability', { Name: 'documentsLibrary' }));
element.append(new et.Element('DeviceCapability', { Name: 'location' }));
+ manifest.write();
});
it('Applies the uap: prefix to the documentsLibrary capability.', function() {
- ensureUapPrefixedCapabilities(element);
- var children = element.getchildren();
var testResults = {};
// map capabilities to tag
- children.forEach(function(child) {
- testResults[child.attrib.Name] = child.tag;
+ manifest.getCapabilities().forEach(function(child) {
+ testResults[child.name] = child.type;
});
expect(testResults.internetClient).toBe('Capability');
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/spec/unit/Version.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/Version.spec.js b/spec/unit/Version.spec.js
index 074afb2..4ee16a8 100644
--- a/spec/unit/Version.spec.js
+++ b/spec/unit/Version.spec.js
@@ -19,29 +19,30 @@
var Version = require('../../template/cordova/lib/Version.js');
-describe('Version constructors behave correctly.', function() {
-
- var v1 = new Version(1);
- expect(v1.major).toBe(1);
- expect(v1.minor).toBe(0);
- expect(v1.build).toBe(0);
- expect(v1.qfe).toBe(0);
- var v2 = new Version(1, 2);
- expect(v2.major).toBe(1);
- expect(v2.minor).toBe(2);
- expect(v2.build).toBe(0);
- expect(v2.qfe).toBe(0);
- var v3 = new Version(1, 2, 4);
- expect(v3.major).toBe(1);
- expect(v3.minor).toBe(2);
- expect(v3.build).toBe(4);
- expect(v3.qfe).toBe(0);
- var v4 = new Version(1, 2, 4, 7);
- expect(v4.major).toBe(1);
- expect(v4.minor).toBe(2);
- expect(v4.build).toBe(4);
- expect(v4.qfe).toBe(7);
-
+describe('Version constructor', function () {
+
+ it('should behave correctly', function () {
+ var v1 = new Version(1);
+ expect(v1.major).toBe(1);
+ expect(v1.minor).toBe(0);
+ expect(v1.build).toBe(0);
+ expect(v1.qfe).toBe(0);
+ var v2 = new Version(1, 2);
+ expect(v2.major).toBe(1);
+ expect(v2.minor).toBe(2);
+ expect(v2.build).toBe(0);
+ expect(v2.qfe).toBe(0);
+ var v3 = new Version(1, 2, 4);
+ expect(v3.major).toBe(1);
+ expect(v3.minor).toBe(2);
+ expect(v3.build).toBe(4);
+ expect(v3.qfe).toBe(0);
+ var v4 = new Version(1, 2, 4, 7);
+ expect(v4.major).toBe(1);
+ expect(v4.minor).toBe(2);
+ expect(v4.build).toBe(4);
+ expect(v4.qfe).toBe(7);
+ });
});
describe('Version parse functions work as expected.', function() {
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/spec/unit/WindowsConfigParser.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/WindowsConfigParser.spec.js b/spec/unit/WindowsConfigParser.spec.js
new file mode 100644
index 0000000..a4b1bd3
--- /dev/null
+++ b/spec/unit/WindowsConfigParser.spec.js
@@ -0,0 +1,104 @@
+/**
+ 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 rewire = require('rewire');
+var et = require('elementtree');
+var xml = require('cordova-common').xmlHelpers;
+var ConfigParser = require('../../template/cordova/lib/ConfigParser');
+var ConfigParserOrig = require('cordova-common').ConfigParser;
+
+var TEST_XML = '<?xml version="1.0" encoding="UTF-8"?><widget/>';
+
+describe('Windows ConfigParser', function () {
+ it('should extend ConfigParser from cordova-common', function () {
+ expect(ConfigParser.prototype instanceof ConfigParserOrig).toBe(true);
+ });
+});
+
+/***
+ * Unit tests for validating that min/max versions are correctly obtained
+ * (for the function getAllMinMaxUAPVersions) from prepare.js.
+ **/
+
+describe('getAllMinMaxUAPVersions method', function () {
+
+ var mockConfig;
+ beforeEach(function () {
+ spyOn(xml, 'parseElementtreeSync').andReturn(new et.ElementTree(et.XML(TEST_XML)));
+
+ mockConfig = new ConfigParser('/some/file');
+ });
+
+ it('should correctly transform all versions as a baseline.', function() {
+ spyOn(mockConfig, 'getMatchingPreferences').andReturn([
+ { name: 'Windows.Universal-MinVersion', value: '10.0.9910.0' },
+ { name: 'Windows.Universal-MaxVersionTested', value: '10.0.9917.0' },
+ { name: 'Windows.Desktop-MinVersion', value: '10.0.9910.0' },
+ { name: 'Microsoft.Xbox-MaxVersionTested', value: '10.0.9917.0' }
+ ]);
+
+ var versionSet = mockConfig.getAllMinMaxUAPVersions();
+ var ver9910 = '10.0.9910.0';
+ var ver9917 = '10.0.9917.0';
+
+ expect(versionSet.length).toBe(3);
+
+ expect(versionSet[0].Name).toBe('Windows.Universal');
+ expect(versionSet[0].MinVersion).toBe(ver9910);
+ expect(versionSet[0].MaxVersionTested).toBe(ver9917);
+
+ expect(versionSet[1].Name).toBe('Windows.Desktop');
+ expect(versionSet[1].MinVersion).toBe(ver9910);
+ expect(versionSet[1].MaxVersionTested).toBe(ver9910);
+
+ expect(versionSet[2].Name).toBe('Microsoft.Xbox');
+ expect(versionSet[2].MinVersion).toBe(ver9917);
+ expect(versionSet[2].MaxVersionTested).toBe(ver9917);
+ });
+
+ it('should produce versions correctly even when the config file has no settings.', function() {
+ spyOn(mockConfig, 'getMatchingPreferences').andReturn([]);
+
+ var versionSet = mockConfig.getAllMinMaxUAPVersions();
+ var verBaseline = rewire('../../template/cordova/lib/ConfigParser')
+ .__get__('BASE_UAP_VERSION').toString();
+
+ expect(versionSet.length).toBe(1);
+ expect(versionSet[0].Name).toBe('Windows.Universal');
+ expect(versionSet[0].MinVersion).toBe(verBaseline);
+ expect(versionSet[0].MaxVersionTested).toBe(verBaseline);
+
+ });
+
+ it('should fail with a RangeError if version specified incorrectly', function() {
+ spyOn(mockConfig, 'getMatchingPreferences')
+ .andReturn([
+ { name: 'Windows.Universal-MinVersion', value: '10.0.9910.f' },
+ { name: 'Windows.Universal-MaxVersionTested', value: '10.0.9917.0' },
+ ]);
+
+ try {
+ mockConfig.getAllMinMaxUAPVersions();
+ expect(false).toBe(true);
+ }
+ catch (ex) {
+ expect(ex.constructor).toBe(RangeError);
+ }
+ });
+});
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/spec/unit/build.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/build.spec.js b/spec/unit/build.spec.js
index e87ca3e..5638d63 100644
--- a/spec/unit/build.spec.js
+++ b/spec/unit/build.spec.js
@@ -157,7 +157,7 @@ describe('run method', function() {
createFindAllAvailableVersionsMock([{version: '14.0', buildProject: buildSpy, path: testPath }]);
build.__set__('prepare.applyPlatformConfig', function() {} );
- build.run([ 'node', buildPath, '--release' ])
+ build.run({ release: true })
.finally(function() {
expect(buildSpy).toHaveBeenCalled();
done();
@@ -189,7 +189,7 @@ describe('run method', function() {
createFindAllAvailableVersionsMock([{version: '14.0', buildProject: buildSpy, path: testPath }]);
build.__set__('prepare.applyPlatformConfig', function() {} );
- build.run([ 'node', buildPath, '--archs=arm' ])
+ build.run({argv: ['--archs=arm'] })
.finally(function() {
expect(buildSpy).toHaveBeenCalled();
done();
@@ -230,7 +230,7 @@ describe('run method', function() {
}]);
build.__set__('prepare.applyPlatformConfig', function() {} );
- build.run([ 'node', buildPath, '--archs=arm x86 x64 anycpu', '--phone' ])
+ build.run({ argv: ['--archs=arm x86 x64 anycpu', '--phone'] })
.finally(function() {
expect(armBuild).toHaveBeenCalled();
expect(x86Build).toHaveBeenCalled();
@@ -248,7 +248,7 @@ describe('run method', function() {
build.__set__('prepare.applyPlatformConfig', function() {} );
createConfigParserMock('8.0');
- build.run([ 'node', buildPath, '--win' ])
+ build.run({argv: ['--win']})
.finally(function() {
expect(buildSpy).toHaveBeenCalled();
done();
@@ -263,7 +263,7 @@ describe('run method', function() {
build.__set__('prepare.applyPlatformConfig', function() {} );
createConfigParserMock('8.1');
- build.run([ 'node', buildPath, '--win' ])
+ build.run({argv: ['--win']})
.finally(function() {
expect(buildSpy).toHaveBeenCalled();
done();
@@ -279,7 +279,7 @@ describe('run method', function() {
build.__set__('prepare.applyPlatformConfig', function() {} );
createConfigParserMock('unsupported value here');
- build.run([ 'node', buildPath, '--win' ])
+ build.run({argv: ['--win']})
.fail(function(error) {
errorSpy();
expect(error).toBeDefined();
@@ -299,7 +299,7 @@ describe('run method', function() {
build.__set__('prepare.applyPlatformConfig', function() {} );
createConfigParserMock(null, '8.1');
- build.run([ 'node', buildPath, '--phone' ])
+ build.run({argv: ['--phone']})
.finally(function() {
expect(buildSpy).toHaveBeenCalled();
done();
@@ -315,7 +315,7 @@ describe('run method', function() {
build.__set__('prepare.applyPlatformConfig', function() {} );
createConfigParserMock(null, 'unsupported value here');
- build.run([ 'node', buildPath, '--phone' ])
+ build.run({argv: ['--phone']})
.fail(function(error) {
errorSpy();
expect(error).toBeDefined();
@@ -339,7 +339,7 @@ describe('run method', function() {
// provision config to target Windows 8.1
createConfigParserMock('8.1', '8.1');
// explicitly specify Windows 10 as target
- build.run([ 'node', buildPath, '--appx=uap' ])
+ build.run({argv: ['--appx=uap']})
.finally(function() {
expect(buildSpy).toHaveBeenCalled();
done();
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/spec/unit/deployment.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/deployment.spec.js b/spec/unit/deployment.spec.js
index 46393bb..97365fb 100644
--- a/spec/unit/deployment.spec.js
+++ b/spec/unit/deployment.spec.js
@@ -19,10 +19,8 @@
var rewire = require('rewire'),
deployment = rewire('../../template/cordova/lib/deployment'),
- run = deployment.__get__('run'),
Q = require('q'),
path = require('path'),
-
AppDeployCmdTool = deployment.__get__('AppDeployCmdTool'),
WinAppDeployCmdTool = deployment.__get__('WinAppDeployCmdTool');
@@ -44,12 +42,11 @@ describe('The correct version of the app deployment tool is obtained.', function
expect(tool instanceof WinAppDeployCmdTool).toBe(true);
});
-
});
describe('Windows 10 deployment interacts with the file system as expected.', function() {
- function runMock(cmd, args, cwd) {
+ function fakeSpawn(cmd, args, cwd) {
expect(cmd).toBe(path.join('c:/Program Files (x86)/Windows Kits/10/bin/x86/WinAppDeployCmd.exe'));
switch (args[0]) {
case 'devices':
@@ -70,13 +67,16 @@ describe('Windows 10 deployment interacts with the file system as expected.', fu
}
}
+ var mockedSpawn = deployment.__get__('spawn');
var mockedProgramFiles = process.env['ProgramFiles(x86)'];
+
beforeEach(function() {
- deployment.__set__('run', runMock);
+ deployment.__set__('spawn', fakeSpawn);
process.env['ProgramFiles(x86)'] = path.join('c:/Program Files (x86)');
});
+
afterEach(function() {
- deployment.__set__('run', run);
+ deployment.__set__('spawn', mockedSpawn);
if (mockedProgramFiles) {
process.env['ProgramFiles(x86)'] = mockedProgramFiles;
} else {
@@ -93,7 +93,7 @@ describe('Windows 10 deployment interacts with the file system as expected.', fu
expect(deviceList[0].name).toBe('Lumia 1520 (RM-940)');
expect(deviceList[0].index).toBe(0);
expect(deviceList[0].type).toBe('device');
-
+
done = true;
});
@@ -107,7 +107,7 @@ describe('Windows 10 deployment interacts with the file system as expected.', fu
deploymentTool.enumerateDevices().then(function(deviceList) {
deploymentTool.installAppPackage(TEST_APP_PACKAGE_NAME, deviceList[0], /*shouldLaunch*/ false, /*shouldUpdate*/ false).then(function() {
- // expect() calls are in the runMock function
+ // expect() calls are in the fakeSpawn function
done = true;
});
@@ -122,7 +122,7 @@ describe('Windows 10 deployment interacts with the file system as expected.', fu
deploymentTool.enumerateDevices().then(function(deviceList) {
deploymentTool.installAppPackage(TEST_APP_PACKAGE_NAME, deviceList[0], /*shouldLaunch*/ false, /*shouldUpdate*/ true).then(function() {
- // expect() calls are in the runMock function
+ // expect() calls are in the fakeSpawn function
done = true;
});
@@ -137,7 +137,7 @@ describe('Windows 10 deployment interacts with the file system as expected.', fu
deploymentTool.enumerateDevices().then(function(deviceList) {
deploymentTool.uninstallAppPackage(TEST_APP_PACKAGE_ID, deviceList[2]).then(function() {
- // expect() calls are in the runMock function
+ // expect() calls are in the fakeSpawn function
done = true;
});
@@ -145,12 +145,11 @@ describe('Windows 10 deployment interacts with the file system as expected.', fu
waitsFor(function() { return done; });
});
-
});
describe('Windows 8.1 deployment interacts with the file system as expected.', function() {
- function runMock(cmd, args, cwd) {
+ function fakeSpawn(cmd, args, cwd) {
expect(cmd).toBe(path.join('c:/Program Files (x86)/Microsoft SDKs/Windows Phone/v8.1/Tools/AppDeploy/AppDeployCmd.exe'));
switch (args[0]) {
case '/EnumerateDevices':
@@ -176,13 +175,16 @@ describe('Windows 8.1 deployment interacts with the file system as expected.', f
}
}
+ var mockedSpawn = deployment.__get__('spawn');
var mockedProgramFiles = process.env['ProgramFiles(x86)'];
+
beforeEach(function() {
- deployment.__set__('run', runMock);
+ deployment.__set__('spawn', fakeSpawn);
process.env['ProgramFiles(x86)'] = path.join('c:/Program Files (x86)');
});
+
afterEach(function() {
- deployment.__set__('run', run);
+ deployment.__set__('spawn', mockedSpawn);
if (mockedProgramFiles) {
process.env['ProgramFiles(x86)'] = mockedProgramFiles;
} else {
@@ -216,7 +218,7 @@ describe('Windows 8.1 deployment interacts with the file system as expected.', f
deploymentTool.enumerateDevices().then(function(deviceList) {
deploymentTool.installAppPackage(TEST_APP_PACKAGE_NAME, deviceList[0], /*shouldLaunch*/ false, /*shouldUpdate*/ false).then(function() {
- // expect() calls are in the runMock function
+ // expect() calls are in the fakeSpawn function
done = true;
});
@@ -230,7 +232,7 @@ describe('Windows 8.1 deployment interacts with the file system as expected.', f
deploymentTool.enumerateDevices().then(function(deviceList) {
deploymentTool.installAppPackage(TEST_APP_PACKAGE_NAME, deviceList[0], /*shouldLaunch*/ false, /*shouldUpdate*/ true).then(function() {
- // expect() calls are in the runMock function
+ // expect() calls are in the fakeSpawn function
done = true;
});
@@ -244,7 +246,7 @@ describe('Windows 8.1 deployment interacts with the file system as expected.', f
deploymentTool.enumerateDevices().then(function(deviceList) {
deploymentTool.installAppPackage(TEST_APP_PACKAGE_NAME, deviceList[0], /*shouldLaunch*/ true, /*shouldUpdate*/ false).then(function() {
- // expect() calls are in the runMock function
+ // expect() calls are in the fakeSpawn function
done = true;
});
@@ -258,7 +260,7 @@ describe('Windows 8.1 deployment interacts with the file system as expected.', f
deploymentTool.enumerateDevices().then(function(deviceList) {
deploymentTool.installAppPackage(TEST_APP_PACKAGE_NAME, deviceList[0], /*shouldLaunch*/ true, /*shouldUpdate*/ true).then(function() {
- // expect() calls are in the runMock function
+ // expect() calls are in the fakeSpawn function
done = true;
});
@@ -272,12 +274,11 @@ describe('Windows 8.1 deployment interacts with the file system as expected.', f
deploymentTool.enumerateDevices().then(function(deviceList) {
deploymentTool.uninstallAppPackage(TEST_APP_PACKAGE_ID, deviceList[5]).then(function() {
- // expect() calls are in the runMock function
+ // expect() calls are in the fakeSpawn function
done = true;
});
});
waitsFor(function() { return done; });
});
-
-});
\ No newline at end of file
+});
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/spec/unit/run.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/run.spec.js b/spec/unit/run.spec.js
index 3171dfb..179c4a7 100644
--- a/spec/unit/run.spec.js
+++ b/spec/unit/run.spec.js
@@ -89,7 +89,7 @@ describe('run method', function() {
return Q.reject(); // rejecting to break run chain
});
- run.run([ 'node', buildPath, '--release', '--debug' ])
+ run.run({ release: true, debug: true })
.finally(function() {
expect(buildRun).not.toHaveBeenCalled();
done();
@@ -105,7 +105,7 @@ describe('run method', function() {
return Q.reject(); // rejecting to break run chain
});
- run.run([ 'node', buildPath, '--device', '--emulator' ])
+ run.run({ device: true, emulator: true })
.finally(function() {
expect(buildRun).not.toHaveBeenCalled();
done();
@@ -121,7 +121,7 @@ describe('run method', function() {
return Q.reject(); // rejecting to break run chain
});
- run.run([ 'node', buildPath, '--device', '--target=sometargethere' ])
+ run.run({ device: true, target: 'sometargethere' })
.finally(function() {
expect(buildRun).not.toHaveBeenCalled();
done();
@@ -237,7 +237,7 @@ describe('run method', function() {
return Q();
});
- run.run([ 'node', buildPath, '--nobuild' ])
+ run.run({ nobuild: true })
.finally(function() {
expect(deployToDesktop).toHaveBeenCalled();
expect(build).not.toHaveBeenCalled();
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/template/cordova/Api.js
----------------------------------------------------------------------
diff --git a/template/cordova/Api.js b/template/cordova/Api.js
new file mode 100644
index 0000000..5803817
--- /dev/null
+++ b/template/cordova/Api.js
@@ -0,0 +1,470 @@
+/**
+ 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 path = require('path');
+var shell = require('shelljs');
+
+var JsprojManager = require('./lib/JsprojManager');
+var PluginHandler = require('./lib/PluginHandler');
+var ConsoleLogger = require('./lib/ConsoleLogger');
+var ActionStack = require('cordova-common').ActionStack;
+var CordovaError = require('cordova-common').CordovaError;
+var PlatformJson = require('cordova-common').PlatformJson;
+var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
+var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
+
+var PLATFORM = 'windows';
+
+/**
+ * Class, that acts as abstraction over particular platform. Encapsulates the
+ * platform's properties and methods.
+ *
+ * Platform that implements own PlatformApi instance _should implement all
+ * prototype methods_ of this class to be fully compatible with cordova-lib.
+ *
+ * The PlatformApi instance also should define the following field:
+ *
+ * * platform: String that defines a platform name.
+ */
+function Api(platform, platformRootDir, events) {
+ this.platform = PLATFORM;
+ this.root = path.resolve(__dirname, '..');
+ this.events = events || ConsoleLogger.get();
+ // NOTE: trick to share one EventEmitter instance across all js code
+ require('cordova-common').events = this.events;
+
+ this._platformJson = PlatformJson.load(this.root, platform);
+ this._pluginInfoProvider = new PluginInfoProvider();
+ this._munger = new PlatformMunger(this.platform, this.root, this._platformJson, this._pluginInfoProvider);
+
+ var self = this;
+
+ this.locations = {
+ root: self.root,
+ www: path.join(self.root, 'www'),
+ platformWww: path.join(self.root, 'platform_www'),
+ configXml: path.join(self.root, 'config.xml'),
+ defaultConfigXml: path.join(self.root, 'cordova/defaults.xml'),
+ // NOTE: Due to platformApi spec we need to return relative paths here
+ cordovaJs: 'template/www/cordova.js',
+ cordovaJsSrc: 'cordova-js-src'
+ };
+}
+
+/**
+ * Installs platform to specified directory and creates a platform project.
+ *
+ * @param {String} destinationDir A directory, where platform should be
+ * created/installed.
+ * @param {ConfigParser} [projectConfig] A ConfigParser instance, used to get
+ * some application properties for new platform like application name, package
+ * id, etc. If not defined, this means that platform is used as standalone
+ * project and is not a part of cordova project, so platform will use some
+ * default values.
+ * @param {Object} [options] An options object. The most common options are:
+ * @param {String} [options.customTemplate] A path to custom template, that
+ * should override the default one from platform.
+ * @param {Boolean} [options.link=false] Flag that indicates that platform's
+ * sources will be linked to installed platform instead of copying.
+ *
+ * @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
+ * instance or rejected with CordovaError.
+ */
+Api.createPlatform = function (destinationDir, projectConfig, options, events) {
+ return require('../../bin/lib/create')
+ .create(destinationDir, projectConfig, options, events || ConsoleLogger.get())
+ .then(function () {
+ var PlatformApi = require(path.resolve(destinationDir, 'cordova/Api'));
+ return new PlatformApi(PLATFORM, destinationDir, events);
+ });
+};
+
+/**
+ * Updates already installed platform.
+ *
+ * @param {String} destinationDir A directory, where existing platform
+ * installed, that should be updated.
+ * @param {Object} [options] An options object. The most common options are:
+ * @param {String} [options.customTemplate] A path to custom template, that
+ * should override the default one from platform.
+ * @param {Boolean} [options.link=false] Flag that indicates that platform's sources
+ * will be linked to installed platform instead of copying.
+ *
+ * @return {Promise<PlatformApi>} Promise either fulfilled with PlatformApi
+ * instance or rejected with CordovaError.
+ */
+Api.updatePlatform = function (destinationDir, options, events) {
+ return require('../../bin/lib/update')
+ .update(destinationDir, options, events || ConsoleLogger.get())
+ .then(function () {
+ var PlatformApi = require(path.resolve(destinationDir, 'cordova/Api'));
+ return new PlatformApi(PLATFORM, destinationDir, events);
+ });
+};
+
+/**
+ * Gets a CordovaPlatform object, that represents the platform structure.
+ *
+ * @return {CordovaPlatform} A structure that contains the description of
+ * platform's file structure and other properties of platform.
+ */
+Api.prototype.getPlatformInfo = function () {
+
+ var result = {};
+ result.locations = this.locations;
+ result.root = this.root;
+ result.name = this.platform;
+ result.version = require('./version');
+ result.projectConfig = this._config;
+
+ return result;
+};
+
+/**
+ * Updates installed platform with provided www assets and new app
+ * configuration. This method is required for CLI workflow and will be called
+ * each time before build, so the changes, made to app configuration and www
+ * code, will be applied to platform.
+ *
+ * @param {CordovaProject} cordovaProject A CordovaProject instance, that defines a
+ * project structure and configuration, that should be applied to platform
+ * (contains project's www location and ConfigParser instance for project's
+ * config).
+ *
+ * @return {Promise} Return a promise either fulfilled, or rejected with
+ * CordovaError instance.
+ */
+Api.prototype.prepare = function (cordovaProject) {
+ return require('./lib/prepare').prepare.call(this, cordovaProject);
+};
+
+/**
+ * Installs a new plugin into platform. This method only copies non-www files
+ * (sources, libs, etc.) to platform. It also doesn't resolves the
+ * dependencies of plugin. Both of handling of www files, such as assets and
+ * js-files and resolving dependencies are the responsibility of caller.
+ *
+ * @param {PluginInfo} plugin A PluginInfo instance that represents plugin
+ * that will be installed.
+ * @param {Object} installOptions An options object. Possible options below:
+ * @param {Boolean} installOptions.link: Flag that specifies that plugin
+ * sources will be symlinked to app's directory instead of copying (if
+ * possible).
+ * @param {Object} installOptions.variables An object that represents
+ * variables that will be used to install plugin. See more details on plugin
+ * variables in documentation:
+ * https://cordova.apache.org/docs/en/4.0.0/plugin_ref_spec.md.html
+ *
+ * @return {Promise} Return a promise either fulfilled, or rejected with
+ * CordovaError instance.
+ */
+Api.prototype.addPlugin = function (plugin, installOptions) {
+
+ if (!plugin || plugin.constructor.name !== 'PluginInfo')
+ return Q.reject(new CordovaError('The parameter is incorrect. The first parameter ' +
+ 'should be valid PluginInfo instance'));
+
+ installOptions = installOptions || {};
+ installOptions.variables = installOptions.variables || {};
+
+ var self = this;
+ var actions = new ActionStack();
+ var jsProject = JsprojManager.getProject(this.root);
+
+ // Add PACKAGE_NAME variable into vars
+ if (!installOptions.variables.PACKAGE_NAME) {
+ installOptions.variables.PACKAGE_NAME = jsProject.getPackageName();
+ }
+
+ // gather all files needs to be handled during install
+ plugin.getFilesAndFrameworks(this.platform)
+ .concat(plugin.getAssets(this.platform))
+ .concat(plugin.getJsModules(this.platform))
+ .forEach(function(item) {
+ actions.push(actions.createAction(
+ PluginHandler.getInstaller(item.itemType), [item, plugin, jsProject, installOptions],
+ PluginHandler.getUninstaller(item.itemType), [item, plugin, jsProject, installOptions]));
+ });
+
+ // run through the action stack
+ return actions.process(this.platform)
+ .then(function () {
+ jsProject.write();
+
+ self._munger
+ // Ignore passed `is_top_level` option since platform itself doesn't know
+ // anything about managing dependencies - it's responsibility of caller.
+ .add_plugin_changes(plugin, installOptions.variables, /*is_top_level=*/true, /*should_increment=*/true)
+ .save_all();
+
+ var targetDir = installOptions.usePlatformWww ?
+ self.getPlatformInfo().locations.platformWww :
+ self.getPlatformInfo().locations.www;
+
+ self._addModulesInfo(plugin, targetDir);
+ });
+};
+
+/**
+ * Removes an installed plugin from platform.
+ *
+ * Since method accepts PluginInfo instance as input parameter instead of plugin
+ * id, caller shoud take care of managing/storing PluginInfo instances for
+ * future uninstalls.
+ *
+ * @param {PluginInfo} plugin A PluginInfo instance that represents plugin
+ * that will be installed.
+ *
+ * @return {Promise} Return a promise either fulfilled, or rejected with
+ * CordovaError instance.
+ */
+Api.prototype.removePlugin = function (plugin, uninstallOptions) {
+
+ var self = this;
+ var actions = new ActionStack();
+ var projectFile = JsprojManager.getProject(this.root);
+
+ // queue up plugin files
+ plugin.getFilesAndFrameworks(this.platform)
+ .concat(plugin.getAssets(this.platform))
+ .concat(plugin.getJsModules(this.platform))
+ .forEach(function(item) {
+ actions.push(actions.createAction(
+ PluginHandler.getUninstaller(item.itemType), [item, plugin, projectFile, uninstallOptions],
+ PluginHandler.getInstaller(item.itemType), [item, plugin, projectFile, uninstallOptions]));
+ });
+
+ // run through the action stack
+ return actions.process(this.platform)
+ .then(function() {
+ projectFile.write();
+
+ self._munger
+ // Ignore passed `is_top_level` option since platform itself doesn't know
+ // anything about managing dependencies - it's responsibility of caller.
+ .remove_plugin_changes(plugin, /*is_top_level=*/true)
+ .save_all();
+
+ var targetDir = uninstallOptions.usePlatformWww ?
+ self.getPlatformInfo().locations.platformWww :
+ self.getPlatformInfo().locations.www;
+
+ self._removeModulesInfo(plugin, targetDir);
+ // Remove stale plugin directory
+ shell.rm('-rf', path.resolve(self.root, 'Plugins', plugin.id));
+ });
+};
+
+
+/**
+ * Builds an application package for current platform.
+ *
+ * @param {Object} buildOptions A build options. This object's structure is
+ * highly depends on platform's specific. The most common options are:
+ * @param {Boolean} buildOptions.debug Indicates that packages should be
+ * built with debug configuration. This is set to true by default unless the
+ * 'release' option is not specified.
+ * @param {Boolean} buildOptions.release Indicates that packages should be
+ * built with release configuration. If not set to true, debug configuration
+ * will be used.
+ * @param {Boolean} buildOptions.device Specifies that built app is intended
+ * to run on device
+ * @param {Boolean} buildOptions.emulator: Specifies that built app is
+ * intended to run on emulator
+ * @param {String} buildOptions.target Specifies the device id that will be
+ * used to run built application.
+ * @param {Boolean} buildOptions.nobuild Indicates that this should be a
+ * dry-run call, so no build artifacts will be produced.
+ * @param {String[]} buildOptions.archs Specifies chip architectures which
+ * app packages should be built for. List of valid architectures is depends on
+ * platform.
+ * @param {String} buildOptions.buildConfig The path to build configuration
+ * file. The format of this file is depends on platform.
+ * @param {String[]} buildOptions.argv Raw array of command-line arguments,
+ * passed to `build` command. The purpose of this property is to pass a
+ * platform-specific arguments, and eventually let platform define own
+ * arguments processing logic.
+ *
+ * @return {Promise<Object[]>} A promise either fulfilled with an array of build
+ * artifacts (application packages) if package was built successfully,
+ * or rejected with CordovaError. The resultant build artifact objects is not
+ * strictly typed and may conatin arbitrary set of fields as in sample below.
+ *
+ * {
+ * architecture: 'x86',
+ * buildType: 'debug',
+ * path: '/path/to/build',
+ * type: 'app'
+ * }
+ *
+ * The return value in most cases will contain only one item but in some cases
+ * there could be multiple items in output array, e.g. when multiple
+ * arhcitectures is specified.
+ */
+Api.prototype.build = function(buildOptions) {
+ // TODO: Should we run check_reqs first? Android does this, but Windows appears doesn't.
+ return require('./lib/build').run.call(this, buildOptions)
+ .then(function (result) {
+ // Wrap result into array according to PlatformApi spec
+ return [result];
+ });
+};
+
+/**
+ * Builds an application package for current platform and runs it on
+ * specified/default device. If no 'device'/'emulator'/'target' options are
+ * specified, then tries to run app on default device if connected, otherwise
+ * runs the app on emulator.
+ *
+ * @param {Object} runOptions An options object. The structure is the same
+ * as for build options.
+ *
+ * @return {Promise} A promise either fulfilled if package was built and ran
+ * successfully, or rejected with CordovaError.
+ */
+Api.prototype.run = function(runOptions) {
+ // TODO: Should we run check_reqs first? Android does this, but Windows appears doesn't.
+ return require('./lib/run').run.call(this, runOptions);
+};
+
+/**
+ * Cleans out the build artifacts from platform's directory.
+ *
+ * @return {Promise} Return a promise either fulfilled, or rejected with
+ * CordovaError.
+ */
+Api.prototype.clean = function(cleanOpts) {
+ return require('./lib/build').clean.call(this, cleanOpts);
+};
+
+/**
+ * Performs a requirements check for current platform. Each platform defines its
+ * own set of requirements, which should be resolved before platform can be
+ * built successfully.
+ *
+ * @return {Promise<Requirement[]>} Promise, resolved with set of Requirement
+ * objects for current platform.
+ */
+Api.prototype.requirements = function() {
+ return require('./lib/check_reqs').check_all();
+};
+
+module.exports = Api;
+
+/**
+ * Removes the specified modules from list of installed modules and updates
+ * platform_json and cordova_plugins.js on disk.
+ *
+ * @param {PluginInfo} plugin PluginInfo instance for plugin, which modules
+ * needs to be added.
+ * @param {String} targetDir The directory, where updated cordova_plugins.js
+ * should be written to.
+ */
+Api.prototype._addModulesInfo = function(plugin, targetDir) {
+ var installedModules = this._platformJson.root.modules || [];
+
+ var installedPaths = installedModules.map(function (installedModule) {
+ return installedModule.file;
+ });
+
+ var modulesToInstall = plugin.getJsModules(this.platform)
+ .filter(function (moduleToInstall) {
+ return installedPaths.indexOf(moduleToInstall.file) === -1;
+ }).map(function (moduleToInstall) {
+ var moduleName = plugin.id + '.' + ( moduleToInstall.name || moduleToInstall.src.match(/([^\/]+)\.js/)[1] );
+ var obj = {
+ file: ['plugins', plugin.id, moduleToInstall.src].join('/'),
+ id: moduleName,
+ pluginId: plugin.id
+ };
+ if (moduleToInstall.clobbers.length > 0) {
+ obj.clobbers = moduleToInstall.clobbers.map(function(o) { return o.target; });
+ }
+ if (moduleToInstall.merges.length > 0) {
+ obj.merges = moduleToInstall.merges.map(function(o) { return o.target; });
+ }
+ if (moduleToInstall.runs) {
+ obj.runs = true;
+ }
+
+ return obj;
+ });
+
+ this._platformJson.root.modules = installedModules.concat(modulesToInstall);
+ this._writePluginModules(targetDir);
+ this._platformJson.save();
+};
+
+/**
+ * Removes the specified modules from list of installed modules and updates
+ * platform_json and cordova_plugins.js on disk.
+ *
+ * @param {PluginInfo} plugin PluginInfo instance for plugin, which modules
+ * needs to be removed.
+ * @param {String} targetDir The directory, where updated cordova_plugins.js
+ * should be written to.
+ */
+Api.prototype._removeModulesInfo = function(plugin, targetDir) {
+ var installedModules = this._platformJson.root.modules || [];
+ var modulesToRemove = plugin.getJsModules(this.platform)
+ .map(function (jsModule) {
+ return ['plugins', plugin.id, jsModule.src].join('/');
+ });
+
+ var updatedModules = installedModules
+ .filter(function (installedModule) {
+ return (modulesToRemove.indexOf(installedModule.file) === -1);
+ });
+
+ this._platformJson.root.modules = updatedModules;
+ this._writePluginModules(targetDir);
+ this._platformJson.save();
+};
+
+/**
+ * Fetches all installed modules, generates cordova_plugins contents and writes
+ * it to file.
+ *
+ * @param {String} targetDir Directory, where write cordova_plugins.js to.
+ * Ususally it is either <platform>/www or <platform>/platform_www
+ * directories.
+ */
+Api.prototype._writePluginModules = function (targetDir) {
+ var self = this;
+ // Write out moduleObjects as JSON wrapped in a cordova module to cordova_plugins.js
+ var final_contents = 'cordova.define(\'cordova/plugin_list\', function(require, exports, module) {\n';
+ final_contents += 'module.exports = ' + JSON.stringify(this._platformJson.root.modules, null, ' ') + ';\n';
+ final_contents += 'module.exports.metadata = \n';
+ final_contents += '// TOP OF METADATA\n';
+
+ var pluginMetadata = Object.keys(this._platformJson.root.installed_plugins)
+ .reduce(function (metadata, plugin) {
+ metadata[plugin] = self._platformJson.root.installed_plugins[plugin].version;
+ return metadata;
+ }, {});
+
+ final_contents += JSON.stringify(pluginMetadata, null, ' ') + '\n';
+ final_contents += '// BOTTOM OF METADATA\n';
+ final_contents += '});'; // Close cordova.define.
+
+ shell.mkdir('-p', targetDir);
+ fs.writeFileSync(path.join(targetDir, 'cordova_plugins.js'), final_contents, 'utf-8');
+};
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/template/cordova/build
----------------------------------------------------------------------
diff --git a/template/cordova/build b/template/cordova/build
index 8fbceae..181cd63 100644
--- a/template/cordova/build
+++ b/template/cordova/build
@@ -19,16 +19,62 @@
under the License.
*/
-var build = require('./lib/build'),
- args = process.argv;
-
-// Handle help flag
-if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(args[2]) > -1) {
- build.help();
-} else {
- build.run(args).done(null, function(err) {
- var errorMessage = (err && err.stack) ? err.stack : err;
- console.error('ERROR: ' + errorMessage);
- process.exit(2);
- });
-}
\ No newline at end of file
+var Api = require('./Api');
+var nopt = require('nopt');
+var path = require('path');
+
+// Support basic help commands
+if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
+ console.log('');
+ console.log('Usage: build [--debug | --release] [--phone | --win] [--bundle]');
+ console.log(' [--archs="<list of architectures...>"');
+ console.log(' [--packageCertificateKeyFile="key path"]');
+ console.log(' [--packageThumbprint="thumbprint"] [--publisherId]');
+ console.log(' [--buildConfig="file path"]');
+ console.log(' --help : Displays this dialog.');
+ console.log(' --debug : Builds project in debug mode. (Default).');
+ console.log(' --release (-r) : Builds project in release mode.');
+ console.log(' --phone, --win : Specifies, what type of project to build.');
+ console.log(' --bundle : Tells the compiler to create a .appxbundle.');
+ console.log(' Bundling is disabled when `anycpu` is built.');
+ console.log(' --archs : Builds project binaries for specific chip');
+ console.log(' architectures (`anycpu`, `arm`, `x86`, `x64`).');
+ console.log(' Separate multiple choices with spaces and if');
+ console.log(' passing multiple choices, enclose with " ".');
+ console.log(' --appx=<8.1-win|8.1-phone|uap>');
+ console.log(' : Overrides windows-target-version to build');
+ console.log(' Windows 8.1, Windows Phone 8.1, or');
+ console.log(' Windows 10 Universal.');
+ console.log(' --packageCertificateKeyFile : Builds the project using provided certificate.');
+ console.log(' --packageThumbprint : Thumbprint associated with the certificate.');
+ console.log(' --publisherId : Sets publisher id field in manifest.');
+ console.log(' --buildConfig : Sets build settings from configuration file.');
+ console.log('');
+ console.log('examples:');
+ console.log(' build ');
+ console.log(' build --debug');
+ console.log(' build --release');
+ console.log(' build --release --archs="arm x86" --bundle');
+ console.log(' build --appx=8.1-phone -r');
+ console.log(' build --packageCertificateKeyFile="CordovaApp_TemporaryKey.pfx"');
+ console.log(' build --publisherId="CN=FakeCorp, C=US"');
+ console.log(' build --buildConfig="build.json"');
+ console.log('');
+
+ process.exit(0);
+}
+
+// Do some basic argument parsing
+var buildOpts = nopt({
+ 'silent' : Boolean,
+ 'verbose' : Boolean,
+ 'debug' : Boolean,
+ 'release' : Boolean,
+ 'nobuild': Boolean,
+ 'buildConfig' : path
+}, { d : '--verbose', r: '--release' });
+
+// Make buildOptions compatible with PlatformApi build method spec
+buildOpts.argv = buildOpts.argv.original;
+
+new Api().build(buildOpts).done();
http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/58047a3d/template/cordova/clean
----------------------------------------------------------------------
diff --git a/template/cordova/clean b/template/cordova/clean
index 71877fe..2964746 100644
--- a/template/cordova/clean
+++ b/template/cordova/clean
@@ -19,9 +19,13 @@
under the License.
*/
-var clean = require('./lib/clean');
+var Api = require('./Api');
-clean.run(process.argv).done(null, function(err) {
- console.error('ERROR: ' + err);
- process.exit(2);
-});
\ No newline at end of file
+// Support basic help commands
+if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
+ console.log('Usage: \n clean\n');
+ console.log('Cleans the project directory.');
+ process.exit(0);
+}
+
+new Api().clean().done();
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org