test: refactor with minor fixes & improvements (#131)
* test (handler): refactor and minor fix
* test (parser): refactor and minor fix
* test (update): refactor
* test (PackageJsonParser): refactor and improvement
* test (ManifestJsonParser): refactor and improvement
* test (Api): refactor and improvements
* test (create): refactor and improvements
* test (nyc configure): require 100% coverage
* refactor: apply suggestions from code review
Co-Authored-By: Raphael von der Grün <raphinesse@gmail.com>
diff --git a/bin/lib/create.js b/bin/lib/create.js
index 7c3f1b2..3b95999 100644
--- a/bin/lib/create.js
+++ b/bin/lib/create.js
@@ -36,9 +36,6 @@
events.emit('log', '\tPath: ' + platform_dir);
events.emit('log', '\tName: ' + project_name);
- // Set default values for path, package and name
- platform_dir = platform_dir || 'CordovaExample';
-
// Check if project already exists
if (fs.existsSync(platform_dir)) {
events.emit('error', 'Oops, destination already exists! Delete it and try again');
diff --git a/bin/templates/cordova/Api.js b/bin/templates/cordova/Api.js
index 9198966..b705f08 100644
--- a/bin/templates/cordova/Api.js
+++ b/bin/templates/cordova/Api.js
@@ -23,16 +23,14 @@
*/
const path = require('path');
const fs = require('fs-extra');
-const CordovaCommon = require('cordova-common');
-const CordovaLogger = CordovaCommon.CordovaLogger;
-// const ConfigParser = CordovaCommon.ConfigParser;
-const ActionStack = CordovaCommon.ActionStack;
-const selfEvents = CordovaCommon.events;
-// const xmlHelpers = CordovaCommon.xmlHelpers;
-const PlatformJson = CordovaCommon.PlatformJson;
-const PlatformMunger = CordovaCommon.ConfigChanges.PlatformMunger;
-const PluginInfoProvider = CordovaCommon.PluginInfoProvider;
-
+const {
+ ActionStack,
+ ConfigChanges: { PlatformMunger },
+ CordovaLogger,
+ events: selfEvents,
+ PlatformJson,
+ PluginInfoProvider
+} = require('cordova-common');
const Parser = require('./parser');
function setupEvents (externalEventEmitter) {
@@ -95,7 +93,7 @@
addPlugin (pluginInfo, installOptions) {
if (!pluginInfo) {
- return Promise.reject(new Error('The parameter is incorrect. The first parameter should be valid PluginInfo instance'));
+ return Promise.reject(new Error('Missing plugin info parameter. The first parameter should contain a valid PluginInfo instance.'));
}
installOptions = installOptions || {};
@@ -143,7 +141,11 @@
});
}
- removePlugin (plugin, uninstallOptions) {
+ removePlugin (pluginInfo, uninstallOptions) {
+ if (!pluginInfo) {
+ return Promise.reject(new Error('Missing plugin info parameter. The first parameter should contain a valid PluginInfo instance.'));
+ }
+
uninstallOptions = uninstallOptions || {};
// CB-10108 platformVersion option is required for proper plugin installation
uninstallOptions.platformVersion = uninstallOptions.platformVersion || this.getPlatformInfo().version;
@@ -151,18 +153,18 @@
const actions = new ActionStack();
let platform = this.platform;
- if (!plugin.getPlatformsArray().includes(platform)) { // if `cordova-electron` is not defined in plugin.xml, `browser` is used instead.
+ if (!pluginInfo.getPlatformsArray().includes(platform)) { // if `cordova-electron` is not defined in plugin.xml, `browser` is used instead.
platform = 'browser';
}
// queue up plugin files
- plugin.getFilesAndFrameworks(platform)
- .concat(plugin.getAssets(platform))
- .concat(plugin.getJsModules(platform))
+ pluginInfo.getFilesAndFrameworks(platform)
+ .concat(pluginInfo.getAssets(platform))
+ .concat(pluginInfo.getJsModules(platform))
.forEach((item) => {
actions.push(actions.createAction(
- this._getUninstaller(item.itemType), [item, plugin.dir, plugin.id, uninstallOptions],
- this._getInstaller(item.itemType), [item, plugin.dir, plugin.id, uninstallOptions]));
+ this._getUninstaller(item.itemType), [item, pluginInfo.dir, pluginInfo.id, uninstallOptions],
+ this._getInstaller(item.itemType), [item, pluginInfo.dir, pluginInfo.id, uninstallOptions]));
});
// run through the action stack
@@ -171,17 +173,17 @@
this._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)
+ .remove_plugin_changes(pluginInfo, /* is_top_level= */true)
.save_all();
const targetDir = uninstallOptions.usePlatformWww
? this.getPlatformInfo().locations.platformWww
: this.getPlatformInfo().locations.www;
- this._removeModulesInfo(plugin, targetDir);
+ this._removeModulesInfo(pluginInfo, targetDir);
// Remove stale plugin directory
// @todo this should be done by plugin files uninstaller
- fs.removeSync(path.resolve(this.root, 'Plugins', plugin.id));
+ fs.removeSync(path.resolve(this.root, 'Plugins', pluginInfo.id));
});
}
diff --git a/bin/templates/cordova/handler.js b/bin/templates/cordova/handler.js
index 8d1e810..a1275c6 100644
--- a/bin/templates/cordova/handler.js
+++ b/bin/templates/cordova/handler.js
@@ -19,7 +19,7 @@
const path = require('path');
const fs = require('fs-extra');
-const events = require('cordova-common').events;
+const { events } = require('cordova-common');
module.exports = {
www_dir: (project_dir) => path.join(project_dir, 'www'),
@@ -77,12 +77,12 @@
install: (obj, plugin_dir, project_dir, plugin_id, options) => {
// var dest = path.join(obj.targetDir, path.basename(obj.src));
// common.copyFile(plugin_dir, obj.src, project_dir, dest);
- events.emit('verbose', 'source-file.install is currently not supported for electron');
+ events.emit('verbose', 'source-file.install is not supported for electron');
},
uninstall: (obj, project_dir, plugin_id, options) => {
// var dest = path.join(obj.targetDir, path.basename(obj.src));
// common.removeFile(project_dir, dest);
- events.emit('verbose', 'source-file.uninstall is currently not supported for electron');
+ events.emit('verbose', 'source-file.uninstall is not supported for electron');
}
},
'header-file': {
@@ -123,7 +123,7 @@
const dest = path.join(wwwDest, asset.target);
const destDir = path.parse(dest).dir;
- if (destDir) fs.ensureDirSync(destDir);
+ fs.ensureDirSync(destDir);
fs.copySync(src, dest);
},
uninstall: (asset, wwwDest, plugin_id) => {
diff --git a/bin/templates/cordova/lib/ManifestJsonParser.js b/bin/templates/cordova/lib/ManifestJsonParser.js
index 1b4989d..6b17088 100644
--- a/bin/templates/cordova/lib/ManifestJsonParser.js
+++ b/bin/templates/cordova/lib/ManifestJsonParser.js
@@ -61,7 +61,7 @@
sizes: `${icon.width}x${icon.height}`
}));
- if (icons) this.manifest.icons = icons;
+ if (icons.length) this.manifest.icons = icons;
return this;
}
diff --git a/bin/templates/cordova/parser.js b/bin/templates/cordova/parser.js
index 87bd8cd..4ee2ba2 100644
--- a/bin/templates/cordova/parser.js
+++ b/bin/templates/cordova/parser.js
@@ -44,15 +44,6 @@
return path.join(this.path, 'www');
}
- // Used for creating platform_www in projects created by older versions.
- // cordovajs_path (libDir) {
- // return path.resolve(path.join(libDir, 'cordova-lib', 'cordova.js'));
- // }
-
- // cordovajs_src_path (libDir) {
- // return path.resolve(path.join(libDir, 'cordova-js-src'));
- // }
-
// Replace the www dir with contents of platform_www and app www.
update_www (cordovaProject, opts) {
const platform_www = path.join(this.path, 'platform_www');
@@ -77,8 +68,6 @@
FileUpdater.mergeAndUpdateDir(sourceDirs, targetDir, { rootDir: cordovaProject.root }, logFileOp);
}
- // update_overrides () {}
-
config_xml () {
return path.join(this.path, 'config.xml');
}
diff --git a/package.json b/package.json
index e4622e7..c10c15f 100644
--- a/package.json
+++ b/package.json
@@ -51,6 +51,12 @@
},
"nyc": {
"all": true,
+ "check-coverage": true,
+ "per-file": true,
+ "lines": 100,
+ "statements": 100,
+ "functions": 100,
+ "branches": 100,
"exclude": [
".npm-scripts/",
"bin/templates/build-res/",
diff --git a/tests/spec/fixtures/test-browser-plugin/plugin.xml b/tests/spec/fixtures/test-browser-plugin/plugin.xml
new file mode 100644
index 0000000..2760357
--- /dev/null
+++ b/tests/spec/fixtures/test-browser-plugin/plugin.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="org.apache.testbrowserplugin"
+ version="1.0.0">
+
+ <name>Test Browser Plugin</name>
+
+ <platform name="browser">
+ <js-module src="www/plugin.js" name="TestBrowserPlugin">
+ <clobbers target="TestBrowserPlugin.clobbers" />
+ <merges target="TestBrowserPlugin.merges" />
+ <runs />
+ </js-module>
+ </platform>
+</plugin>
diff --git a/tests/spec/fixtures/test-browser-plugin/www/plugin.js b/tests/spec/fixtures/test-browser-plugin/www/plugin.js
new file mode 100644
index 0000000..2befe6a
--- /dev/null
+++ b/tests/spec/fixtures/test-browser-plugin/www/plugin.js
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+class TestBrowserPlugin {
+
+}
+
+module.exports = new TestBrowserPlugin();
diff --git a/tests/spec/fixtures/test-config-no-author-custom-email.xml b/tests/spec/fixtures/test-config-no-author-custom-email.xml
new file mode 100644
index 0000000..b1d3f0a
--- /dev/null
+++ b/tests/spec/fixtures/test-config-no-author-custom-email.xml
@@ -0,0 +1,57 @@
+<?xml version='1.0' encoding='utf-8'?>
+<!--
+ 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.
+-->
+
+<widget id="whatever" version="1.1.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+ <name>HelloWorld</name>
+ <description>
+ A sample Apache Cordova application.
+ </description>
+ <author email="dev@cordova.com" href="http://cordova.io"></author>
+ <license>Apache 2.0 License</license>
+ <preference name="Orientation" value="portrait" />
+ <content src="index.html" main="index.js" />
+ <plugin name="cordova-plugin-whitelist" spec="1" />
+ <access origin="*" />
+ <allow-intent href="http://*/*" />
+ <allow-intent href="https://*/*" />
+ <allow-intent href="tel:*" />
+ <allow-intent href="sms:*" />
+ <allow-intent href="mailto:*" />
+ <allow-intent href="geo:*" />
+ <platform name="android">
+ <allow-intent href="market:*" />
+ </platform>
+ <platform name="ios">
+ <allow-intent href="itms:*" />
+ <allow-intent href="itms-apps:*" />
+ </platform>
+ <icon src="res/electron/cordova.png" width="16" height="16"/>
+ <platform name="electron">
+ <icon src="res/electron/cordova.png"/>
+ <icon src="res/electron/cordova@1.5.png" />
+ <icon src="res/electron/cordova@2.png" />
+ <icon src="res/electron/cordova@3.png" />
+ <icon src="res/electron/cordova@4.png" />
+ <icon src="res/electron/cordova@8.png" />
+ <icon src="res/electron/cordova@16.png" />
+ <icon src="res/electron/cordova_512.png" target="installer" />
+ </platform>
+ <engine name="electron" spec="github:Apache/cordova-electron" />
+</widget>
diff --git a/tests/spec/fixtures/test-non-electron-plugin/plugin.xml b/tests/spec/fixtures/test-non-electron-plugin/plugin.xml
new file mode 100644
index 0000000..4f123cc
--- /dev/null
+++ b/tests/spec/fixtures/test-non-electron-plugin/plugin.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="org.apache.testnonelectronplugin"
+ version="1.0.0">
+
+ <name>Test Non Electron Plugin</name>
+
+ <platform name="android"></platform>
+</plugin>
diff --git a/tests/spec/fixtures/testplugin-empty-jsmodule/plugin.xml b/tests/spec/fixtures/testplugin-empty-jsmodule/plugin.xml
new file mode 100644
index 0000000..4d5f697
--- /dev/null
+++ b/tests/spec/fixtures/testplugin-empty-jsmodule/plugin.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="org.apache.testplugin2"
+ version="1.0.0">
+
+ <name>Test Electron Plugin</name>
+
+ <platform name="electron">
+ <js-module src="www/MyTestPlugin2.js">
+ </js-module>
+ </platform>
+</plugin>
diff --git a/tests/spec/fixtures/testplugin-empty-jsmodule/www/MyTestPlugin2.js b/tests/spec/fixtures/testplugin-empty-jsmodule/www/MyTestPlugin2.js
new file mode 100644
index 0000000..f9c22c7
--- /dev/null
+++ b/tests/spec/fixtures/testplugin-empty-jsmodule/www/MyTestPlugin2.js
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+class TestPlugin2 {
+
+}
+
+module.exports = new TestPlugin2();
diff --git a/tests/spec/fixtures/testplugin/plugin.xml b/tests/spec/fixtures/testplugin/plugin.xml
new file mode 100644
index 0000000..f6878aa
--- /dev/null
+++ b/tests/spec/fixtures/testplugin/plugin.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ id="org.apache.testplugin"
+ version="1.0.0">
+
+ <name>Test Electron Plugin</name>
+
+ <platform name="electron">
+ <js-module src="www/plugin.js" name="TestPlugin">
+ <clobbers target="TestPlugin.clobbers" />
+ <merges target="TestPlugin.merges" />
+ <runs />
+ </js-module>
+
+ <asset src="src/electron/sample.json" target="js/electron.json" />
+
+ <source-file src="src/electron/sample.json" target-dir="js" />
+ </platform>
+</plugin>
diff --git a/tests/spec/unit/Api.spec.js b/tests/spec/unit/Api.spec.js
index 48a2574..7a148d0 100644
--- a/tests/spec/unit/Api.spec.js
+++ b/tests/spec/unit/Api.spec.js
@@ -20,12 +20,20 @@
const fs = require('fs-extra');
const path = require('path');
const rewire = require('rewire');
+const { events, PluginInfo } = require('cordova-common');
+
const templateDir = path.resolve(__dirname, '..', '..', '..', 'bin', 'templates');
+
+const create = require(path.join(templateDir, '../lib/create'));
const Api = rewire(path.join(templateDir, 'cordova', 'Api'));
+
const tmpDir = path.join(__dirname, '../../../temp');
const apiRequire = Api.__get__('require');
const FIXTURES = path.join(__dirname, '..', 'fixtures');
const pluginFixture = path.join(FIXTURES, 'testplugin');
+const pluginFixtureEmptyJSModule = path.join(FIXTURES, 'testplugin-empty-jsmodule');
+const pluginNotElectronFixture = path.join(FIXTURES, 'test-non-electron-plugin');
+const pluginBrowserFixture = path.join(FIXTURES, 'test-browser-plugin');
const testProjectDir = path.join(tmpDir, 'testapp');
function dirExists (dir) {
@@ -36,60 +44,45 @@
return fs.existsSync(file) && fs.statSync(file).isFile();
}
-function readJson (file) {
- return JSON.parse(
- fs.readFileSync(
- file
- )
- );
-}
-
-function writeJson (file, json) {
- fs.writeFileSync(
- file,
- JSON.stringify(json, null, ' '),
- 'utf-8'
- );
-}
+const mockExpectedLocations = {
+ platformRootDir: testProjectDir,
+ root: testProjectDir,
+ www: path.join(testProjectDir, 'www'),
+ res: path.join(testProjectDir, 'res'),
+ platformWww: path.join(testProjectDir, 'platform_www'),
+ configXml: path.join(testProjectDir, 'config.xml'),
+ defaultConfigXml: path.join(testProjectDir, 'cordova/defaults.xml'),
+ build: path.join(testProjectDir, 'build'),
+ buildRes: path.join(testProjectDir, 'build-res'),
+ cache: path.join(testProjectDir, 'cache'),
+ cordovaJs: 'bin/templates/project/assets/www/cordova.js',
+ cordovaJsSrc: 'cordova-js-src'
+};
describe('Api class', () => {
- fs.ensureDirSync(tmpDir);
- fs.copySync(path.resolve(FIXTURES, 'testapp'), path.resolve(tmpDir, 'testapp'));
+ let api;
+ let apiEvents;
- const api = new Api(null, testProjectDir);
- const apiEvents = Api.__get__('selfEvents');
- apiEvents.removeAllListeners();
+ beforeAll(() => {
+ fs.ensureDirSync(tmpDir);
+ fs.copySync(path.resolve(FIXTURES, 'testapp'), path.resolve(tmpDir, 'testapp'));
- const rootDir = testProjectDir;
- const mockExpectedLocations = {
- platformRootDir: rootDir,
- root: rootDir,
- www: path.join(rootDir, 'www'),
- res: path.join(rootDir, 'res'),
- platformWww: path.join(rootDir, 'platform_www'),
- configXml: path.join(rootDir, 'config.xml'),
- defaultConfigXml: path.join(rootDir, 'cordova/defaults.xml'),
- build: path.join(rootDir, 'build'),
- buildRes: path.join(rootDir, 'build-res'),
- cache: path.join(rootDir, 'cache'),
- cordovaJs: 'bin/templates/project/assets/www/cordova.js',
- cordovaJsSrc: 'cordova-js-src'
- };
-
- it('should exist', () => {
- expect(Api).toBeDefined();
+ apiEvents = Api.__get__('selfEvents');
+ apiEvents.addListener('verbose', (data) => { });
});
- describe('Api constructor', () => {
- it('should be ale to construct.', () => {
+ afterAll(() => {
+ fs.removeSync(tmpDir);
+ apiEvents.removeAllListeners();
+ });
+
+ beforeEach(() => {
+ api = new Api(null, testProjectDir);
+ });
+
+ describe('constructor', () => {
+ it('should have been constructed with initial values.', () => {
expect(api).toBeDefined();
- });
-
- it('should have set platform as electron.', () => {
- expect(api.platform).toBe('electron');
- });
-
- it('should have set the root path.', () => {
/**
* In Unit Testing:
* The API file path is located in "cordova-electron/bin/templates/cordova".
@@ -99,397 +92,333 @@
* The API file path is actually located in "<project_dir>/platforms/electron/cordova".
* The expected path is "<project_dir>/platforms/electron" which is the electron's platform root dir
*/
- expect(api.root).toBe(rootDir);
- });
-
- it('should configure proper locations.', () => {
- expect(api.locations).toEqual(mockExpectedLocations);
+ expect(api.root).toEqual(testProjectDir);
+ expect(api.locations).toEqual(jasmine.objectContaining(mockExpectedLocations));
});
});
describe('getPlatformInfo method', () => {
- beforeEach(() => {
+ it('should return object containing platform information', () => {
// Mocking require that is called to get version.
Api.__set__('require', () => '1.0.0');
- });
- afterEach(() => {
- Api.__set__('require', apiRequire);
- });
-
- it('should return object containing platform information', () => {
- const actual = api.getPlatformInfo();
- const expected = {
+ expect(api.getPlatformInfo()).toEqual({
locations: mockExpectedLocations,
- root: rootDir,
+ root: testProjectDir,
name: 'electron',
version: '1.0.0',
projectConfig: undefined
- };
- expect(actual).toEqual(expected);
+ });
+
+ Api.__set__('require', apiRequire);
});
});
describe('prepare method', () => {
- const prepareSpy = jasmine.createSpy('prepare');
- beforeEach(() => {
- // Mocking require that is called to get version.
- Api.__set__('require', () => ({
- prepare: prepareSpy
- }));
- });
-
- afterEach(() => {
- Api.__set__('require', apiRequire);
- });
-
it('should return object containing platform information', () => {
+ const prepare = jasmine.createSpy('prepare');
+
+ Api.__set__('require', () => ({ prepare }));
api.prepare('', {});
- expect(prepareSpy).toHaveBeenCalledWith(jasmine.any(String), jasmine.any(Object));
+ expect(prepare).toHaveBeenCalledWith(jasmine.any(String), jasmine.any(Object));
+ Api.__set__('require', apiRequire);
});
});
describe('addPlugin method', () => {
- let logs = {};
beforeEach(() => {
+ spyOn(events, 'emit');
+
fs.removeSync(path.resolve(testProjectDir, 'electron.json'));
fs.removeSync(path.resolve(testProjectDir, 'www'));
- apiEvents.addListener('verbose', (data) => {
- logs.verbose.push(data);
- });
- logs = {
- verbose: []
- };
});
afterEach(() => {
+ fs.removeSync(path.resolve(testProjectDir, 'electron.json'));
+ fs.removeSync(path.resolve(testProjectDir, 'www'));
+
apiEvents.removeAllListeners();
});
- it('should reject when missing plugin information', () => {
- api.addPlugin().then(
+ it('should Promise reject when missing PluginInfo parameter.', () => {
+ return api.addPlugin().then(
+ () => {},
+ error => {
+ expect(error).toEqual(new Error('Missing plugin info parameter. The first parameter should contain a valid PluginInfo instance.'));
+ }
+ );
+ });
+
+ it('should error out when a PluginInfo parameter is not valid', () => {
+ class FakePluginInfo {}
+ return expect(() => {
+ api.addPlugin(new FakePluginInfo());
+ }).toThrowError();
+ });
+
+ describe('Use Electron Plugin with Default Install Options', () => {
+ beforeEach(() => {
+ const pluginInfo = new PluginInfo(pluginFixture);
+ return api.addPlugin(pluginInfo);
+ });
+
+ it('should add the plugins assets and meta data.', () => {
+ expect(dirExists(path.resolve(testProjectDir, 'www'))).toBeTruthy();
+ expect(fileExists(path.resolve(testProjectDir, 'electron.json'))).toBeTruthy();
+ expect(fileExists(path.resolve(testProjectDir, 'www/cordova_plugins.js'))).toBeTruthy();
+ expect(fileExists(path.resolve(testProjectDir, 'www/js/electron.json'))).toBeTruthy();
+ expect(fileExists(path.resolve(testProjectDir, 'www/plugins/org.apache.testplugin/www/plugin.js'))).toBeTruthy();
+ });
+
+ it('should emit that source-file is not supported.', () => {
+ expect(events.emit).toHaveBeenCalledWith(
+ 'verbose',
+ jasmine.stringMatching(/not supported/)
+ );
+ });
+
+ it('should add a second plugins assets', () => {
+ const pluginInfo2 = new PluginInfo(pluginBrowserFixture);
+ return api.addPlugin(pluginInfo2).then(() => {
+ expect(fileExists(path.resolve(testProjectDir, 'www/plugins/org.apache.testbrowserplugin/www/plugin.js'))).toBeTruthy();
+ });
+ });
+
+ it('should have "clobber", "merge", and "run" set when defined in "js-module".', () => {
+ const { modules } = fs.readJsonSync(path.resolve(testProjectDir, 'electron.json'));
+ expect(modules[0].clobbers).toBeDefined();
+ expect(modules[0].merges).toBeDefined();
+ expect(modules[0].runs).toBeDefined();
+ });
+
+ it('should have module id containing the name attribute value.', () => {
+ const { modules } = fs.readJsonSync(path.resolve(testProjectDir, 'electron.json'));
+ expect(modules[0].id).toBe('org.apache.testplugin.TestPlugin');
+ });
+ });
+
+ // usePlatformWww
+ describe('Use Empty JS-Module Plugin', () => {
+ beforeEach(() => {
+ const pluginInfo = new PluginInfo(pluginFixtureEmptyJSModule);
+ return api.addPlugin(pluginInfo);
+ });
+
+ it('should not have "clobber", "merge", and "run" set when not defined in "js-module".', () => {
+ const { modules } = fs.readJsonSync(path.resolve(testProjectDir, 'electron.json'));
+ expect(modules[0].clobbers).not.toBeDefined();
+ expect(modules[0].merges).not.toBeDefined();
+ expect(modules[0].runs).not.toBeDefined();
+ });
+
+ it('should use js filename for plugin id if name is missing.', () => {
+ const { modules } = fs.readJsonSync(path.resolve(testProjectDir, 'electron.json'));
+ expect(modules[0].id).toBe('org.apache.testplugin2.MyTestPlugin2');
+ });
+ });
+
+ describe('Use Electron Plugin with Custom Install Options', () => {
+ beforeEach(() => {
+ const pluginInfo = new PluginInfo(pluginFixture);
+ return api.addPlugin(pluginInfo, {
+ variables: { PACKAGE_NAME: 'com.foobar.newpackagename' },
+ usePlatformWww: true
+ });
+ });
+
+ it('should use custom package name.', () => {
+ const { installed_plugins } = fs.readJsonSync(path.resolve(testProjectDir, 'electron.json'));
+ expect(installed_plugins['org.apache.testplugin'].PACKAGE_NAME).toEqual('com.foobar.newpackagename');
+ });
+
+ it('should use platform www instead of www.', () => {
+ expect(fileExists(path.resolve(testProjectDir, 'www/cordova_plugins.js'))).toBeFalsy();
+ expect(fileExists(path.resolve(testProjectDir, 'platform_www/cordova_plugins.js'))).toBeTruthy();
+ });
+ });
+
+ /**
+ * @todo verfiy validity of an "unknown" itemType acgtually being able to be set.
+ */
+ it('should warn when unknown itemType is added.', () => {
+ const pluginInfo = new PluginInfo(pluginFixture);
+ pluginInfo.getAssets = () => [{ itemType: 'unknown' }];
+
+ return api.addPlugin(pluginInfo).then(
() => {
- fail('Unwanted code branch');
- },
- (error) => {
- expect(error).toEqual(new Error('The parameter is incorrect. The first parameter should be valid PluginInfo instance'));
+ expect(events.emit).toHaveBeenCalledWith(
+ 'warn',
+ jasmine.stringMatching(/Unrecognized type/)
+ );
}
);
});
- it('empty plugin', () => {
- return api.addPlugin({
- id: 'empty_plugin',
- getPlatformsArray: () => ['electron'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [],
- getJsModules: platform => [],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
+ it('should add browser plugins as well.', () => {
+ const pluginInfo = new PluginInfo(pluginBrowserFixture);
+ return api.addPlugin(pluginInfo).then(
+ () => {
expect(dirExists(path.resolve(testProjectDir, 'www'))).toBeTruthy();
expect(fileExists(path.resolve(testProjectDir, 'electron.json'))).toBeTruthy();
expect(fileExists(path.resolve(testProjectDir, 'www', 'cordova_plugins.js'))).toBeTruthy();
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
- }
- );
- });
-
- it('asset plugin', () => {
- return api.addPlugin({
- id: 'asset-plugin',
- dir: pluginFixture,
- getPlatformsArray: () => ['electron'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [{
- itemType: 'asset',
- src: 'src/electron/sample.json',
- target: 'js/sample.json'
- }],
- getJsModules: platform => [],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
- expect(fileExists(path.resolve(testProjectDir, 'www', 'js', 'sample.json'))).toBeTruthy();
- expect(readJson(path.resolve(testProjectDir, 'www', 'js', 'sample.json')).title).toEqual('sample');
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
- }
- );
- });
-
- it('js-module plugin', () => {
- return api.addPlugin({
- id: 'module-plugin',
- dir: pluginFixture,
- getPlatformsArray: () => ['electron'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [],
- getJsModules: platform => [{
- itemType: 'js-module',
- name: 'testmodule',
- src: 'www/plugin.js',
- clobbers: ['ModulePlugin.clobbers'],
- merges: ['ModulePlugin.merges'],
- runs: true
- }],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
- expect(fileExists(path.resolve(testProjectDir, 'www', 'plugins', 'module-plugin', 'www', 'plugin.js'))).toBeTruthy();
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
- }
- );
- });
-
- it('unrecognized type plugin', () => {
- const _events = api.events;
- const emitSpy = jasmine.createSpy('emit');
- api.events = {
- emit: emitSpy
- };
-
- return api.addPlugin({
- id: 'unrecognized-plugin',
- dir: pluginFixture,
- getPlatformsArray: () => ['electron'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [{
- itemType: 'unrecognized'
- }],
- getJsModules: platform => [],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(emitSpy.calls.argsFor(0)[1]).toContain('unrecognized');
- expect(result).not.toBeDefined();
- api.events = _events;
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
- api.events = _events;
- }
- );
- });
-
- it('source-file type plugin', () => {
- return api.addPlugin({
- id: 'source-file-plugin',
- dir: pluginFixture,
- getPlatformsArray: () => ['electron'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [{
- itemType: 'source-file'
- }],
- getJsModules: platform => [],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
- expect(logs.verbose.some(message => message === 'source-file.install is currently not supported for electron')).toBeTruthy();
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
- }
- );
- });
-
- it('empty plugin with browser platform', () => {
- return api.addPlugin({
- id: 'empty_plugin',
- getPlatformsArray: () => ['browser'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [],
- getJsModules: platform => [],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
- expect(dirExists(path.resolve(testProjectDir, 'www'))).toBeTruthy();
- expect(fileExists(path.resolve(testProjectDir, 'electron.json'))).toBeTruthy();
- expect(fileExists(path.resolve(testProjectDir, 'www', 'cordova_plugins.js'))).toBeTruthy();
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
}
);
});
});
- /**
- * @todo Add useful tests.
- */
describe('removePlugin method', () => {
- let logs = {};
beforeEach(() => {
+ spyOn(events, 'emit');
+
fs.removeSync(path.resolve(testProjectDir, 'electron.json'));
fs.removeSync(path.resolve(testProjectDir, 'www'));
- apiEvents.addListener('verbose', (data) => {
- logs.verbose.push(data);
- });
- logs = {
- verbose: []
- };
});
afterEach(() => {
+ fs.removeSync(path.resolve(testProjectDir, 'electron.json'));
+ fs.removeSync(path.resolve(testProjectDir, 'www'));
+
apiEvents.removeAllListeners();
});
- it('should exist', () => {
- expect(api.removePlugin).toBeDefined();
- expect(typeof api.removePlugin).toBe('function');
- });
-
- it('remove empty plugin', () => {
- return api.removePlugin({
- id: 'empty_plugin',
- getPlatformsArray: () => ['electron'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [],
- getJsModules: platform => [],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
+ it('should Promise reject when missing PluginInfo parameter.', () => {
+ return api.removePlugin().then(
+ () => {},
+ error => {
+ expect(error).toEqual(new Error('Missing plugin info parameter. The first parameter should contain a valid PluginInfo instance.'));
}
);
});
- it('asset plugin', () => {
- fs.ensureDirSync(path.resolve(testProjectDir, 'www', 'js'));
- writeJson(path.resolve(testProjectDir, 'www', 'js', 'sample.json'), { title: 'sample' });
- return api.removePlugin({
- id: 'empty_plugin',
- dir: pluginFixture,
- getPlatformsArray: () => ['electron'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [{
- itemType: 'asset',
- src: 'src/electron/sample.json',
- target: 'js/sample.json'
- }],
- getJsModules: platform => [],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
- expect(fileExists(path.resolve(testProjectDir, 'www', 'js', 'sample.json'))).toBeFalsy();
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
- }
- );
+ it('should error out when a PluginInfo parameter is not valid.', () => {
+ class FakePluginInfo {}
+ return expect(() => {
+ api.removePlugin(new FakePluginInfo());
+ }).toThrowError();
});
- it('js-module plugin', () => {
- fs.ensureDirSync(path.resolve(testProjectDir, 'www', 'plugins', 'module-plugin', 'www'));
- fs.copySync(path.resolve(pluginFixture, 'www', 'plugin.js'), path.resolve(testProjectDir, 'www', 'plugins', 'module-plugin', 'www', 'plugin.js'));
- expect(fileExists(path.resolve(testProjectDir, 'www', 'plugins', 'module-plugin', 'www', 'plugin.js'))).toBeTruthy();
- return api.removePlugin({
- id: 'module-plugin',
- dir: pluginFixture,
- getPlatformsArray: () => ['electron'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [],
- getJsModules: platform => [{
- itemType: 'js-module',
- name: 'testmodule',
- src: 'www/plugin.js',
- clobbers: ['ModulePlugin.clobbers'],
- merges: ['ModulePlugin.merges'],
- runs: true
- }],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
- expect(fileExists(path.resolve(testProjectDir, 'www', 'plugins', 'module-plugin', 'www', 'plugin.js'))).toBeFalsy();
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
- }
- );
+ describe('Use Electron Plugin with Default Install Options', () => {
+ let pluginInfo;
+
+ beforeEach(() => {
+ pluginInfo = new PluginInfo(pluginFixture);
+ return api.addPlugin(pluginInfo);
+ });
+
+ it('should remove the empty plugin data from electron.json.', () => {
+ return api.removePlugin(pluginInfo).then(
+ () => {
+ const { plugin_metadata, modules, installed_plugins } = fs.readJsonSync(path.resolve(testProjectDir, 'electron.json'));
+ expect(plugin_metadata).toEqual({});
+ expect(modules).toEqual([]);
+ expect(installed_plugins).toEqual({});
+ }
+ );
+ });
+
+ it('should remove the added plugin assets, source files, and meta data.', () => {
+ return api.removePlugin(pluginInfo).then(() => {
+ expect(dirExists(path.resolve(testProjectDir, 'www'))).toBeTruthy();
+ expect(fileExists(path.resolve(testProjectDir, 'electron.json'))).toBeTruthy();
+ expect(fileExists(path.resolve(testProjectDir, 'www/cordova_plugins.js'))).toBeTruthy();
+ expect(fileExists(path.resolve(testProjectDir, 'www/js/electron.json'))).toBeFalsy();
+ expect(fileExists(path.resolve(testProjectDir, 'www/plugins/org.apache.testplugin/www/plugin.js'))).toBeFalsy();
+
+ const cordovaPluginContent = fs.readFileSync(path.resolve(testProjectDir, 'www/cordova_plugins.js'), 'utf8');
+ expect(cordovaPluginContent).not.toContain(/org.apache.testplugin/);
+ });
+ });
});
- it('unrecognized type plugin', () => {
- return api.removePlugin({
- id: 'unrecognized-plugin',
- dir: pluginFixture,
- getPlatformsArray: () => ['electron'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [{
- itemType: 'unrecognized'
- }],
- getJsModules: platform => [],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
- }
- );
+ it('should remove the added plugin assets, from the platform www.', () => {
+ const pluginInfo = new PluginInfo(pluginFixture);
+ return api.addPlugin(pluginInfo, { usePlatformWww: true })
+ .then(() => api.removePlugin(pluginInfo, { usePlatformWww: true }))
+ .then(() => {
+ expect(fileExists(path.resolve(testProjectDir, 'www/cordova_plugins.js'))).toBeFalsy();
+ expect(fileExists(path.resolve(testProjectDir, 'platform_www/cordova_plugins.js'))).toBeTruthy();
+ });
});
- it('source-file type plugin', () => {
- return api.removePlugin({
- id: 'source-file-plugin',
- dir: pluginFixture,
- getPlatformsArray: () => ['electron'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [{
- itemType: 'source-file'
- }],
- getJsModules: platform => [],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
- expect(logs.verbose.some(message => message === 'source-file.uninstall is currently not supported for electron')).toBeTruthy();
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
- }
- );
+ /**
+ * @todo verfiy validity of an "unknown" itemType acgtually being able to be set.
+ */
+ it('should remove the plugin assets and source files.', () => {
+ const pluginInfo = new PluginInfo(pluginFixture);
+ pluginInfo.getAssets = () => [{ itemType: 'unknown' }];
+
+ return api.removePlugin(pluginInfo).then(() => {
+ expect(events.emit).toHaveBeenCalledWith(
+ 'warn',
+ jasmine.stringMatching(/unrecognized type/)
+ );
+ });
});
- it('remove empty plugin with browser platform', () => {
- return api.removePlugin({
- id: 'empty_plugin',
- getPlatformsArray: () => ['browser'],
- getFilesAndFrameworks: platform => [],
- getAssets: platform => [],
- getJsModules: platform => [],
- getConfigFiles: platform => []
- }, { }).then(
- (result) => {
- expect(result).not.toBeDefined();
- },
- (error) => {
- fail(`Unwanted code branch: ${error}`);
- }
- );
+ it('should remove the empty non-electron plugin using platform www as target.', () => {
+ const pluginInfo = new PluginInfo(pluginNotElectronFixture);
+ return api.addPlugin(pluginInfo, { usePlatformWww: true })
+ .then(() => api.removePlugin(pluginInfo, { usePlatformWww: true }))
+ .then(() => {
+ const cordovaPluginContent = fs.readFileSync(path.resolve(testProjectDir, 'platform_www/cordova_plugins.js'), 'utf8');
+ expect(cordovaPluginContent).not.toContain(/org.apache.testnonelectronplugin/);
+ });
});
});
+ describe('build method', () => {
+ it('should execute build', () => {
+ const call = jasmine.createSpy('run');
+ const mockBuildOptions = { foo: 'bar' };
+
+ Api.__set__('require', () => ({ run: { call: call } }));
+ api.build(mockBuildOptions);
+ expect(call).toHaveBeenCalledWith(api, mockBuildOptions, api);
+ Api.__set__('require', apiRequire);
+ });
+ });
+
+ describe('run method', () => {
+ it('should execute run', () => {
+ const run = jasmine.createSpy('run');
+ const mockRunOptions = { foo: 'bar' };
+
+ Api.__set__('require', () => ({ run }));
+ api.run(mockRunOptions);
+ expect(run).toHaveBeenCalledWith(mockRunOptions);
+ Api.__set__('require', apiRequire);
+ });
+ });
+
+ describe('clean method', () => {
+ it('should execute clean', () => {
+ const run = jasmine.createSpy('clean');
+ const mockCleanOptions = { foo: 'bar' };
+
+ Api.__set__('require', () => ({ run }));
+ api.clean(mockCleanOptions);
+ expect(run).toHaveBeenCalledWith(mockCleanOptions);
+ Api.__set__('require', apiRequire);
+ });
+ });
+
+ describe('requirements method', () => {
+ it('should execute requirements', () => {
+ const run = jasmine.createSpy('requirements');
+
+ Api.__set__('require', () => ({ run }));
+ api.requirements();
+ expect(run).toHaveBeenCalled();
+ Api.__set__('require', apiRequire);
+ });
+ });
+});
+
+describe('Api prototype methods', () => {
describe('updatePlatform method', () => {
it('should return a resolved promise.', () => {
Api.updatePlatform().then(
- (result) => {
- // Currently updatePlatform only resolves with nothing.
+ result => {
expect(result).toBeUndefined();
}
);
@@ -509,99 +438,22 @@
* @todo improve createPlatform to test actual created platforms.
*/
it('should export static createPlatform function', () => {
+ spyOn(events, 'emit');
+
return Api.createPlatform(tmpDir)
.then((results) => {
- expect(results.constructor.name).toBe(api.constructor.name);
+ expect(events.emit).toHaveBeenCalledWith(
+ 'log',
+ jasmine.stringMatching(/Creating Cordova project/)
+ );
+
+ expect(results.constructor.name).toBe('Api');
});
});
it('should emit createPlatform not callable when error occurs.', () => {
- Api.__set__('require', () => ({
- createProject: () => { throw new Error('Some Random Error'); }
- }));
-
- expect(() => Api.createPlatform(tmpDir)).toThrowError(/createPlatform is not callable from the electron project API/);
-
- Api.__set__('require', apiRequire);
- });
- });
-
- describe('build method', () => {
- const runSpy = jasmine.createSpy('run');
- beforeEach(() => {
- // Mocking require that is called to get version.
- Api.__set__('require', () => ({
- run: { call: runSpy }
- }));
- });
-
- afterEach(() => {
- Api.__set__('require', apiRequire);
- });
-
- it('should execute build', () => {
- const mockBuildOptions = { foo: 'bar' };
- api.build(mockBuildOptions);
- expect(runSpy).toHaveBeenCalledWith(api, mockBuildOptions, api);
- });
- });
-
- describe('run method', () => {
- const runSpy = jasmine.createSpy('run');
- beforeEach(() => {
- // Mocking require that is called to get version.
- Api.__set__('require', () => ({
- run: runSpy
- }));
- });
-
- afterEach(() => {
- Api.__set__('require', apiRequire);
- });
-
- it('should execute run', () => {
- const mockRunOptions = { foo: 'bar' };
- api.run(mockRunOptions);
- expect(runSpy).toHaveBeenCalledWith(mockRunOptions);
- });
- });
-
- describe('clean method', () => {
- const cleanSpy = jasmine.createSpy('clean');
- beforeEach(() => {
- // Mocking require that is called to get version.
- Api.__set__('require', () => ({
- run: cleanSpy
- }));
- });
-
- afterEach(() => {
- Api.__set__('require', apiRequire);
- });
-
- it('should execute clean', () => {
- const mockCleanOptions = { foo: 'bar' };
- api.clean(mockCleanOptions);
- expect(cleanSpy).toHaveBeenCalledWith(mockCleanOptions);
- });
- });
-
- describe('requirements method', () => {
- const requirementsSpy = jasmine.createSpy('requirements');
- beforeEach(() => {
- // Mocking require that is called to get version.
- Api.__set__('require', () => ({
- run: requirementsSpy
- }));
- });
-
- afterEach(() => {
- Api.__set__('require', apiRequire);
- });
-
- it('should execute requirements', () => {
- api.requirements();
- expect(requirementsSpy).toHaveBeenCalled();
+ spyOn(create, 'createProject').and.returnValue(new Error('Some Random Error'));
+ expect(() => Api.createPlatform(tmpDir)).toThrowError();
});
});
});
diff --git a/tests/spec/unit/create.spec.js b/tests/spec/unit/create.spec.js
index 36d58a9..ac40ecc 100644
--- a/tests/spec/unit/create.spec.js
+++ b/tests/spec/unit/create.spec.js
@@ -49,7 +49,7 @@
fs.removeSync(tmpDir);
}
-function createAndValidateProjectDirName (projectname, projectid) {
+function createAndValidateProjectDirName (projectname, projectid, { copyNodeModules = false } = {}) {
// remove existing folder
fs.removeSync(tmpDir);
fs.ensureDirSync(tmpDir);
@@ -59,7 +59,8 @@
const _fs = create.__get__('fs');
create.__set__('fs', {
ensureDirSync: _fs.ensureDirSync,
- existsSync: path => !(path === projectPath),
+ existsSync: path => path !== projectPath &&
+ !(path.includes('node_modules') && copyNodeModules),
copySync: () => true
});
@@ -127,6 +128,13 @@
return createAndValidateProjectDirName(projectname, projectid);
});
+ it('copy node_modules folder if it exists', () => {
+ const projectname = 'withnodemodules';
+ const projectid = 'com.test.withnodemodules';
+
+ return createAndValidateProjectDirName(projectname, projectid, { copyNodeModules: true });
+ });
+
it('should stop creating project when project destination already exists', () => {
const _fs = create.__get__('fs');
create.__set__('fs', {
diff --git a/tests/spec/unit/handler.spec.js b/tests/spec/unit/handler.spec.js
index 7686bc3..60bc511 100644
--- a/tests/spec/unit/handler.spec.js
+++ b/tests/spec/unit/handler.spec.js
@@ -17,320 +17,122 @@
under the License.
*/
+const path = require('path');
+const fs = require('fs-extra');
+const { events } = require('cordova-common');
const rewire = require('rewire');
const handler = rewire('../../../bin/templates/cordova/handler');
-const path = require('path');
describe('Handler export', () => {
describe('www_dir method', () => {
- it('should return the project\'s www dir.', () => {
- const projectDir = 'random-project-dir';
- const actual = handler.www_dir(projectDir);
- const expected = path.join(projectDir, 'www');
- expect(actual).toBe(expected);
+ it(`should return the project's www dir.`, () => {
+ const projectDir = 'mocked-project-dir-path';
+ expect(
+ handler.www_dir(projectDir)
+ ).toBe(path.join(projectDir, 'www'));
});
});
describe('package_name method', () => {
- it('should return default package name when config.xml is missing.', () => {
- const projectDir = 'random-project-dir';
-
- const existsSyncSpy = jasmine.createSpy('existsSync').and.returnValue(false);
- handler.__set__('fs', {
- existsSync: existsSyncSpy
- });
-
- const actual = handler.package_name(projectDir);
- const expected = 'io.cordova.hellocordova';
- expect(actual).toBe(expected);
+ it('should return default package name when config.xml file is missing', () => {
+ spyOn(fs, 'existsSync').and.returnValue(false);
+ expect(
+ handler.package_name('mocked-project-dir-path')
+ ).toBe('io.cordova.hellocordova');
});
- it('should return default package name when config.xml is missing.', () => {
- const projectDir = 'random-project-dir';
+ it('should return default package name when config.xml file does not contain the widget id', () => {
+ spyOn(fs, 'existsSync').and.returnValue(true);
+ spyOn(fs, 'readFileSync').and.returnValue(''); // blank config.file
+ expect(
+ handler.package_name('mocked-project-dir-path')
+ ).toBe('io.cordova.hellocordova');
+ });
- const existsSyncSpy = jasmine.createSpy('existsSync').and.returnValue(true);
- const readFileSyncSpy = jasmine.createSpy('readFileSync').and.returnValue(`
-<?xml version='1.0' encoding='utf-8'?>
-<widget id="com.foobar.random" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
-</widget>
+ it('should return package name defined on the widget element id attribute in config.xml file', () => {
+ spyOn(fs, 'existsSync').and.returnValue(true);
+ spyOn(fs, 'readFileSync').and.returnValue(`
+ <?xml version='1.0' encoding='utf-8'?>
+ <widget id="com.foobar.random" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
+ </widget>
`);
- handler.__set__('fs', {
- existsSync: existsSyncSpy,
- readFileSync: readFileSyncSpy
- });
-
- const actual = handler.package_name(projectDir);
- const expected = 'com.foobar.random';
- expect(actual).toBe(expected);
+ expect(
+ handler.package_name('mocked-project-dir-path')
+ ).toBe('com.foobar.random');
});
});
- describe('JSModule', () => {
- describe('Install', () => {
- it('should write module but does not contain json export.', () => {
- const jsModule = {
- src: 'src',
- name: 'dummy-module'
- };
- const plugin_id = 'com.foo.dummy-plugin';
+ describe('js-module method', () => {
+ describe('js-module.install', () => {
+ const moduleExportTestCase = jsModule => {
const plugin_dir = 'mock';
+ const plugin_id = 'com.foo.dummy-plugin';
const www_dir = 'www';
+ const moduleName = `${plugin_id}.${jsModule.name || path.basename(jsModule.src, path.extname(jsModule.src))}`;
// spies
- const ensureDirSyncSpy = jasmine.createSpy('ensureDirSync').and.returnValue(true);
- const readFileSyncSpy = jasmine.createSpy('readFileSync').and.returnValue('module-content');
- const writeFileSyncSpy = jasmine.createSpy('writeFileSync');
- handler.__set__('fs', {
- ensureDirSync: ensureDirSyncSpy,
- readFileSync: readFileSyncSpy,
- writeFileSync: writeFileSyncSpy
- });
+ spyOn(fs, 'readFileSync').and.returnValue(''); // fake scriptContent
+ spyOn(fs, 'ensureDirSync').and.returnValue(true);
+ spyOn(fs, 'writeFileSync');
handler['js-module'].install(jsModule, plugin_dir, plugin_id, www_dir);
- expect(readFileSyncSpy).toHaveBeenCalled();
- expect(ensureDirSyncSpy).toHaveBeenCalled();
- expect(writeFileSyncSpy).toHaveBeenCalled();
+ const moduleDetination = path.dirname(path.resolve(www_dir, 'plugins', plugin_id, jsModule.src));
+ const writeFileSyncContent = fs.writeFileSync.calls.argsFor(0)[1];
- const actual = writeFileSyncSpy.calls.argsFor(0)[1];
+ expect(fs.readFileSync).toHaveBeenCalledWith(path.resolve(plugin_dir, jsModule.src), 'utf-8');
+ expect(fs.ensureDirSync).toHaveBeenCalledWith(moduleDetination);
+ expect(writeFileSyncContent).toContain(`cordova.define('${moduleName}'`);
- expect(actual).toContain('com.foo.dummy-plugin.dummy-module');
- expect(actual).toContain('module-content');
+ return writeFileSyncContent;
+ };
+
+ it('should write cordova.define for module "com.foo.dummy-plugin.dummy-module" (from source name) and not module.exports as module source is not JSON.', () => {
+ const jsModule = { src: 'src/dummy-module', name: 'dummy-module' };
+ const writeFileSyncContent = moduleExportTestCase(jsModule);
+ expect(writeFileSyncContent).not.toContain(`module.exports`);
});
- it('should write module but does not contain json export.', () => {
- const jsModule = {
- src: 'src.json',
- name: 'dummy-module'
- };
- const plugin_id = 'com.foo.dummy-plugin';
- const plugin_dir = 'mock';
- const www_dir = 'www';
+ it('should write cordova.define for module "com.foo.dummy-plugin.dummy-module" (from source filepath) and not module.exports as module source is not JSON.', () => {
+ const jsModule = { src: 'src/dummy-module' };
+ const writeFileSyncContent = moduleExportTestCase(jsModule);
+ expect(writeFileSyncContent).not.toContain(`module.exports`);
+ });
- // spies
- const ensureDirSyncSpy = jasmine.createSpy('ensureDirSync').and.returnValue(true);
- const readFileSyncSpy = jasmine.createSpy('readFileSync').and.returnValue('module-content');
- const writeFileSyncSpy = jasmine.createSpy('writeFileSync');
- handler.__set__('fs', {
- ensureDirSync: ensureDirSyncSpy,
- readFileSync: readFileSyncSpy,
- writeFileSync: writeFileSyncSpy
- });
-
- handler['js-module'].install(jsModule, plugin_dir, plugin_id, www_dir);
-
- expect(readFileSyncSpy).toHaveBeenCalled();
- expect(ensureDirSyncSpy).toHaveBeenCalled();
- expect(writeFileSyncSpy).toHaveBeenCalled();
-
- const actual = writeFileSyncSpy.calls.argsFor(0)[1];
-
- expect(actual).toContain('com.foo.dummy-plugin.dummy-module');
- expect(actual).toContain(`module.exports = + module-content`);
+ it('should write cordova.define for module "com.foo.dummy-plugin.dummy-module" (from source filepath) and not module.exports as module source is not JSON.', () => {
+ const jsModule = { src: 'src/dummy-module/something.json' };
+ const writeFileSyncContent = moduleExportTestCase(jsModule);
+ expect(writeFileSyncContent).toContain(`module.exports`);
});
});
- describe('Uninstall', () => {
- let emitSpy;
- beforeEach(() => {
- emitSpy = jasmine.createSpy('emit');
- handler.__set__('events', {
- emit: emitSpy
- });
- });
-
+ describe('js-module.uninstall', () => {
it('should emit that js-module uninstall was called.', () => {
- const jsModule = {
- src: 'src.json',
- name: 'dummy-module'
- };
- const plugin_id = 'com.foo.dummy-plugin';
+ const jsModule = { src: 'src/dummy-module', name: 'dummy-module' };
const www_dir = 'www';
- const pluginRelativePath = path.join('plugins', plugin_id, jsModule.src);
+ const plugin_id = 'com.foo.dummy-plugin';
- const removeSyncSpy = jasmine.createSpy('writeFileSync');
- handler.__set__('fs', {
- removeSync: removeSyncSpy
- });
+ // spies
+ spyOn(fs, 'removeSync').and.returnValue(true);
+ spyOn(events, 'emit');
handler['js-module'].uninstall(jsModule, www_dir, plugin_id);
- expect(removeSyncSpy).toHaveBeenCalled();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = `js-module uninstall called : ${pluginRelativePath}`;
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
+ expect(fs.removeSync).toHaveBeenCalledWith(path.join(www_dir, 'plugins', plugin_id));
+ expect(events.emit).toHaveBeenCalledWith(
+ 'verbose',
+ `js-module uninstall called : ${path.join('plugins', plugin_id, jsModule.src)}`
+ );
});
});
});
- describe('SourceFile', () => {
- let emitSpy;
- beforeEach(() => {
- emitSpy = jasmine.createSpy('emit');
- handler.__set__('events', {
- emit: emitSpy
- });
- });
-
- describe('Install', () => {
- it('should emit that source-file install is not supported.', () => {
- handler['source-file'].install();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = 'source-file.install is currently not supported for electron';
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
- });
- });
-
- describe('Uninstall', () => {
- it('should emit that source-file uninstall is not supported.', () => {
- handler['source-file'].uninstall();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = 'source-file.uninstall is currently not supported for electron';
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
- });
- });
- });
-
- describe('HeaderFile', () => {
- let emitSpy;
- beforeEach(() => {
- emitSpy = jasmine.createSpy('emit');
- handler.__set__('events', {
- emit: emitSpy
- });
- });
-
- describe('Install', () => {
- it('should emit that header-file install is not supported.', () => {
- handler['header-file'].install();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = 'header-file.install is not supported for electron';
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
- });
- });
-
- describe('Uninstall', () => {
- it('should emit that header-file uninstall is not supported.', () => {
- handler['header-file'].uninstall();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = 'header-file.uninstall is not supported for electron';
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
- });
- });
- });
-
- describe('ResourceFile', () => {
- let emitSpy;
- beforeEach(() => {
- emitSpy = jasmine.createSpy('emit');
- handler.__set__('events', {
- emit: emitSpy
- });
- });
-
- describe('Install', () => {
- it('should emit that resource-file install is not supported.', () => {
- handler['resource-file'].install();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = 'resource-file.install is not supported for electron';
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
- });
- });
-
- describe('Uninstall', () => {
- it('should emit that resource-file uninstall is not supported.', () => {
- handler['resource-file'].uninstall();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = 'resource-file.uninstall is not supported for electron';
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
- });
- });
- });
-
- describe('Framework', () => {
- let emitSpy;
- beforeEach(() => {
- emitSpy = jasmine.createSpy('emit');
- handler.__set__('events', {
- emit: emitSpy
- });
- });
-
- describe('Install', () => {
- it('should emit that framework install is not supported.', () => {
- handler['framework'].install();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = 'framework.install is not supported for electron';
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
- });
- });
-
- describe('Uninstall', () => {
- it('should emit that framework uninstall is not supported.', () => {
- handler['framework'].uninstall();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = 'framework.uninstall is not supported for electron';
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
- });
- });
- });
-
- describe('LibFile', () => {
- let emitSpy;
- beforeEach(() => {
- emitSpy = jasmine.createSpy('emit');
- handler.__set__('events', {
- emit: emitSpy
- });
- });
-
- describe('Install', () => {
- it('should emit that lib-file install is not supported.', () => {
- handler['lib-file'].install();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = 'lib-file.install is not supported for electron';
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
- });
- });
-
- describe('Uninstall', () => {
- it('should emit that lib-file uninstall is not supported.', () => {
- handler['lib-file'].uninstall();
-
- const actual = emitSpy.calls.argsFor(0)[1];
- const expected = 'lib-file.uninstall is not supported for electron';
- expect(emitSpy).toHaveBeenCalled();
- expect(actual).toBe(expected);
- });
- });
- });
-
- describe('Assets', () => {
+ describe('asset method', () => {
const plugin_dir = 'pluginDir';
const wwwDest = 'dest';
- describe('Install', () => {
- it('should copySync with a directory path.', () => {
+ describe('asset.install', () => {
+ it('should copySync assets to destination.', () => {
const asset = {
itemType: 'asset',
src: 'someSrc/ServiceWorker.js',
@@ -338,57 +140,53 @@
};
// Spies
- const copySyncSpy = jasmine.createSpy('copySync');
- const ensureDirSyncSpy = jasmine.createSpy('ensureDirSync').and.returnValue(true);
-
- handler.__set__('fs', {
- copySync: copySyncSpy,
- ensureDirSync: ensureDirSyncSpy
- });
+ spyOn(fs, 'copySync');
+ spyOn(fs, 'ensureDirSync').and.returnValue(true);
handler.asset.install(asset, plugin_dir, wwwDest);
- expect(ensureDirSyncSpy).toHaveBeenCalled();
- expect(copySyncSpy).toHaveBeenCalledWith(jasmine.any(String), path.join('dest', asset.target));
- });
- it('should call copySync with a file path.', () => {
- const asset = {
- itemType: 'asset',
- src: 'someSrc/ServiceWorker.js',
- target: 'ServiceWorker.js'
- };
-
- // Spies
- const copySyncSpy = jasmine.createSpy('copySync');
- const ensureDirSyncSpy = jasmine.createSpy('ensureDirSync');
-
- handler.__set__('fs', {
- copySync: copySyncSpy,
- ensureDirSync: ensureDirSyncSpy
- });
-
- handler.asset.install(asset, plugin_dir, wwwDest);
- expect(ensureDirSyncSpy).toHaveBeenCalled();
- expect(copySyncSpy).toHaveBeenCalledWith(jasmine.any(String), path.join('dest', asset.target));
+ expect(fs.ensureDirSync).toHaveBeenCalled();
+ expect(fs.copySync).toHaveBeenCalledWith(jasmine.any(String), path.join('dest', asset.target));
});
});
- describe('Uninstall', () => {
+ describe('asset.uninstall', () => {
it('should remove assets', () => {
const asset = { itemType: 'asset', src: 'someSrc', target: 'ServiceWorker.js' };
const mockPluginId = 'com.foobar.random-plugin-id';
// Spies
- const fsRemoveSyncSpy = jasmine.createSpy('removeSync');
- handler.__set__('fs', {
- removeSync: fsRemoveSyncSpy
- });
+ spyOn(fs, 'removeSync').and.returnValue(true);
handler.asset.uninstall(asset, wwwDest, mockPluginId);
- expect(fsRemoveSyncSpy).toHaveBeenCalled();
- expect(fsRemoveSyncSpy.calls.argsFor(0)[0]).toBe(path.join(wwwDest, asset.target));
- expect(fsRemoveSyncSpy.calls.argsFor(1)[0]).toBe(path.join(wwwDest, 'plugins', mockPluginId));
+ expect(fs.removeSync).toHaveBeenCalled();
+ expect(fs.removeSync.calls.argsFor(0)[0]).toBe(path.join(wwwDest, asset.target));
+ expect(fs.removeSync.calls.argsFor(1)[0]).toBe(path.join(wwwDest, 'plugins', mockPluginId));
+ });
+ });
+ });
+
+ describe('Unsupported Handlers', () => {
+ it('should emit that the install and uninstall methods are not supported for X types.', () => {
+ spyOn(events, 'emit');
+
+ // loop unsupported types
+ [
+ 'source-file',
+ 'header-file',
+ 'resource-file',
+ 'framework',
+ 'lib-file'
+ ].forEach(type => {
+ for (const method of ['install', 'uninstall']) {
+ handler[type][method]();
+ expect(events.emit).toHaveBeenCalledWith(
+ 'verbose',
+ `${type}.${method} is not supported for electron`
+ );
+ events.emit.calls.reset();
+ }
});
});
});
diff --git a/tests/spec/unit/lib/update.spec.js b/tests/spec/unit/lib/update.spec.js
index 2849bcb..41be855 100644
--- a/tests/spec/unit/lib/update.spec.js
+++ b/tests/spec/unit/lib/update.spec.js
@@ -25,7 +25,7 @@
it('should reject with an errror that update is not supported.', () => {
update.run().then(
() => {},
- (error) => {
+ error => {
expect(error).toEqual(new Error('Update not supported'));
}
);
@@ -34,14 +34,9 @@
describe('help export method', () => {
it('should warn that updating is not support for Electron.', () => {
- const logSpy = jasmine.createSpy('log');
- update.__set__('console', {
- log: logSpy
- });
-
+ spyOn(console, 'log');
update.help();
-
- expect(logSpy.calls.argsFor(0)[0]).toContain('WARNING : Electron does not support updating. Remove and then re-Add the platform to get the latest.');
+ expect(console.log).toHaveBeenCalledWith('WARNING : Electron does not support updating. Remove and then re-Add the platform to get the latest.');
});
});
});
diff --git a/tests/spec/unit/templates/cordova/lib/ManifestJsonParser.spec.js b/tests/spec/unit/templates/cordova/lib/ManifestJsonParser.spec.js
index 4856a81..4ee70ee 100644
--- a/tests/spec/unit/templates/cordova/lib/ManifestJsonParser.spec.js
+++ b/tests/spec/unit/templates/cordova/lib/ManifestJsonParser.spec.js
@@ -19,7 +19,9 @@
const rewire = require('rewire');
const path = require('path');
-const ConfigParser = require('cordova-common').ConfigParser;
+const fs = require('fs-extra');
+const { ConfigParser } = require('cordova-common');
+const ManifestJsonParser = rewire('../../../../../../bin/templates/cordova/lib/ManifestJsonParser');
const FIXTURES = path.join(__dirname, '..', '..', '..', '..', 'fixtures');
@@ -28,211 +30,148 @@
const cfg2 = new ConfigParser(path.join(FIXTURES, 'test-config-2.xml'));
const cfgEmpty = new ConfigParser(path.join(FIXTURES, 'test-config-empty.xml'));
-describe('Testing ManifestJsonParser.js:', () => {
- let ManifestJsonParser;
- let locations;
+const locations = {
+ buildRes: path.join('mock', 'build-res'),
+ www: path.join('mock', 'www'),
+ configXml: path.join('mock', 'config.xml')
+};
+
+const defaultInitManifest = {
+ background_color: '#FFF',
+ display: 'standalone',
+ orientation: 'any',
+ start_url: 'index.html'
+};
+
+describe('ManifestJson class', () => {
+ let manifestJsonParser;
beforeEach(() => {
- ManifestJsonParser = rewire('../../../../../../bin/templates/cordova/lib/ManifestJsonParser');
-
- locations = {
- buildRes: path.join('mock', 'build-res'),
- www: path.join('mock', 'www'),
- configXml: path.join('mock', 'config.xml')
- };
+ manifestJsonParser = new ManifestJsonParser(locations.www);
});
- describe('ManifestJson class', () => {
- let manifestJsonParser;
+ it('should have been constructed with initial values.', () => {
+ expect(manifestJsonParser).toBeDefined();
+ expect(manifestJsonParser.path).toEqual(path.join(locations.www, 'manifest.json'));
+ expect(manifestJsonParser.www).toEqual(locations.www);
+ expect(manifestJsonParser.manifest).toEqual(defaultInitManifest);
+ });
- beforeEach(() => {
- manifestJsonParser = ManifestJsonParser.__get__('ManifestJsonParser');
- });
+ it('should return when config xml is not defined.', () => {
+ manifestJsonParser.configure();
+ expect(manifestJsonParser.manifest).toEqual(defaultInitManifest);
+ });
- it('should should be defined.', () => {
- expect(manifestJsonParser).toBeDefined();
- });
+ it('should set manifest json object values to default, when config xml is empty.', () => {
+ manifestJsonParser.configure(cfgEmpty);
+ expect(manifestJsonParser.manifest).toEqual(jasmine.objectContaining({
+ start_url: undefined
+ }));
+ });
- it('should set initial value correctly.', () => {
- manifestJsonParser = new ManifestJsonParser(locations.www);
+ it('should read and set manifest json object values from the first config xml.', () => {
+ manifestJsonParser.configure(cfg1);
+ expect(manifestJsonParser.manifest).toEqual(jasmine.objectContaining({
+ orientation: 'portrait',
+ name: 'HelloWorld',
+ short_name: 'HelloWorld',
+ version: 'whatever',
+ description: 'A sample Apache Cordova application.',
+ author: 'Cordova Team',
+ icons: [{ src: 'res/electron/cordova.png', type: 'image/png', sizes: '16x16' }]
+ }));
+ });
- // mock manifest JSON Object
- const manifestJsonObj = {
- background_color: '#FFF',
- display: 'standalone',
- orientation: 'any',
- start_url: 'index.html'
- };
+ it('should read and set manifest json object values from second config xml.', () => {
+ manifestJsonParser.configure(cfg2);
+ expect(manifestJsonParser.manifest).toEqual(jasmine.objectContaining({
+ orientation: 'landscape',
+ name: 'HelloWorld',
+ short_name: 'Hello',
+ theme_color: '0xff0000ff',
+ version: 'whatever',
+ description: 'A sample Apache Cordova application.',
+ author: 'Cordova Team'
+ }));
+ });
- expect(manifestJsonParser.path).toEqual(path.join('mock', 'www', 'manifest.json'));
- expect(manifestJsonParser.www).toEqual(locations.www);
- expect(manifestJsonParser.manifest).toEqual(manifestJsonObj);
- });
+ it('should update theme color if start_url exists in path and contains meta theme-color.', () => {
+ spyOn(fs, 'existsSync').and.returnValue(true);
+ spyOn(fs, 'readFileSync').and.returnValue('<meta name="theme-color" content="#33363b">');
- it('should return when config xml is not defined.', () => {
- manifestJsonParser = new ManifestJsonParser(locations.www).configure(undefined);
+ manifestJsonParser.configureThemeColor(cfg1);
+ expect(manifestJsonParser.manifest.theme_color).toEqual('#33363b');
+ });
- // mock manifest JSON Object
- const manifestJsonObj = {
- background_color: '#FFF',
- display: 'standalone',
- orientation: 'any',
- start_url: 'index.html'
- };
+ it('should update theme color with StatusBarBackgroundColor if start_url file does not contain meta theme-color.', () => {
+ spyOn(fs, 'existsSync').and.returnValue(true);
+ spyOn(fs, 'readFileSync').and.returnValue('');
- expect(manifestJsonParser.manifest).toEqual(manifestJsonObj);
- });
+ manifestJsonParser.configureThemeColor(cfg2);
+ expect(manifestJsonParser.manifest.theme_color).toEqual('0xff0000ff');
+ });
- it('should set manifest json object values to default, when config xml is empty.', () => {
- manifestJsonParser = new ManifestJsonParser(locations.www).configure(cfgEmpty);
+ it('should update theme color with no value when StatusBarBackgroundColor is missing and start_url file does not contain meta theme-color.', () => {
+ spyOn(fs, 'existsSync').and.returnValue(true);
+ spyOn(fs, 'readFileSync').and.returnValue('');
- // mock manifest JSON Object
- const manifestJsonObj = {
- background_color: '#FFF',
- display: 'standalone',
- orientation: 'any',
- start_url: undefined,
- icons: []
- };
+ manifestJsonParser.configureThemeColor(cfgEmpty);
+ expect(manifestJsonParser.manifest.theme_color).toEqual(undefined);
+ });
- expect(manifestJsonParser.manifest).toEqual(manifestJsonObj);
- });
+ it('should write something.', () => {
+ spyOn(fs, 'writeFileSync').and.returnValue(true);
- it('should read and set manifest json object values from the first config xml.', () => {
- manifestJsonParser = new ManifestJsonParser(locations.www).configure(cfg1);
+ manifestJsonParser.write();
+ expect(fs.writeFileSync).toHaveBeenCalledWith(
+ jasmine.any(String),
+ JSON.stringify(defaultInitManifest, null, 2),
+ 'utf8'
+ );
+ });
- // mock manifest JSON Object
- const manifestJsonObj = {
- background_color: '#FFF',
- display: 'standalone',
- orientation: 'portrait',
- start_url: 'index.html',
- name: 'HelloWorld',
- short_name: 'HelloWorld',
- version: 'whatever',
- description: 'A sample Apache Cordova application.',
- author: 'Cordova Team',
- icons: [{ src: 'res/electron/cordova.png', type: 'image/png', sizes: '16x16' }]
- };
- expect(manifestJsonParser.manifest).toEqual(manifestJsonObj);
- });
+ it('should write defaults with empty config.xml.', () => {
+ spyOn(fs, 'writeFileSync').and.returnValue(true);
- it('should read and set manifest json object values from second config xml.', () => {
- manifestJsonParser = new ManifestJsonParser(locations.www).configure(cfg2);
+ manifestJsonParser.configure(cfgEmpty)
+ .write();
- // mock manifest JSON Object
- const manifestJsonObj = {
- background_color: '#FFF',
- display: 'standalone',
- orientation: 'landscape',
- start_url: 'index.html',
- name: 'HelloWorld',
- short_name: 'Hello',
- theme_color: '0xff0000ff',
- version: 'whatever',
- description: 'A sample Apache Cordova application.',
- author: 'Cordova Team',
- icons: []
- };
- expect(manifestJsonParser.manifest).toEqual(manifestJsonObj);
- });
+ const expectedManifest = {
+ background_color: '#FFF',
+ display: 'standalone',
+ orientation: 'any'
+ };
- it('should be called if start_url is defined in config xml.', () => {
- const existsSyncSpy = jasmine.createSpy('existsSync').and.returnValue(true);
- const readFileSyncSpy = jasmine.createSpy('readFileSync').and.returnValue('<meta name="theme-color" content="#33363b">');
- manifestJsonParser.__set__('fs', { readFileSync: readFileSyncSpy, existsSync: existsSyncSpy });
+ expect(fs.writeFileSync).toHaveBeenCalledWith(
+ jasmine.any(String),
+ JSON.stringify(expectedManifest, null, 2),
+ 'utf8'
+ );
+ });
- manifestJsonParser = new ManifestJsonParser(locations.www).configureThemeColor(cfg1);
+ it('should write with user defined values from config.xml.', () => {
+ spyOn(fs, 'writeFileSync').and.returnValue(true);
- expect(existsSyncSpy).toHaveBeenCalled();
- expect(readFileSyncSpy).toHaveBeenCalled();
- });
+ manifestJsonParser.configure(cfg1)
+ .write();
- it('should not be called if start_url is not defined in config xml.', () => {
- const existsSyncSpy = jasmine.createSpy('existsSync').and.returnValue(true);
- const readFileSyncSpy = jasmine.createSpy('readFileSync');
- manifestJsonParser.__set__('fs', { readFileSync: readFileSyncSpy, existsSync: existsSyncSpy });
+ const expectedManifest = {
+ background_color: '#FFF',
+ display: 'standalone',
+ orientation: 'portrait',
+ start_url: 'index.html',
+ name: 'HelloWorld',
+ short_name: 'HelloWorld',
+ version: 'whatever',
+ description: 'A sample Apache Cordova application.',
+ author: 'Cordova Team',
+ icons: [{ src: 'res/electron/cordova.png', type: 'image/png', sizes: '16x16' }]
+ };
- manifestJsonParser = new ManifestJsonParser(locations.www).configureThemeColor(cfgEmpty);
-
- expect(existsSyncSpy).toHaveBeenCalled();
- expect(readFileSyncSpy).toHaveBeenCalled();
- });
-
- it('should write provided data when config xml is empty.', () => {
- const existsSyncSpy = jasmine.createSpy('existsSync').and.returnValue(true);
- const readFileSyncSpy = jasmine.createSpy('readFileSync');
- const writeFileSyncSpy = jasmine.createSpy('writeFileSync');
- manifestJsonParser.__set__('fs', { readFileSync: readFileSyncSpy, existsSync: existsSyncSpy, writeFileSync: writeFileSyncSpy });
-
- manifestJsonParser = new ManifestJsonParser(locations.www).configure(cfgEmpty).write();
-
- expect(existsSyncSpy).not.toHaveBeenCalled();
- expect(readFileSyncSpy).not.toHaveBeenCalled();
- expect(writeFileSyncSpy).toHaveBeenCalled();
-
- // mock manifest JSON Object
- let manifestJsonObj = {
- background_color: '#FFF',
- display: 'standalone',
- orientation: 'any',
- icons: []
- };
-
- const manifestPath = writeFileSyncSpy.calls.argsFor(0)[0];
- expect(manifestPath).toEqual(path.join('mock', 'www', 'manifest.json'));
-
- // get manifest json file content and remove white spaces
- let manifestFile = writeFileSyncSpy.calls.argsFor(0)[1];
-
- // convert to remove white space
- manifestFile = manifestFile.replace(/\s+/g, '');
- manifestJsonObj = JSON.stringify(manifestJsonObj).replace(/\s/g, '');
- expect(manifestFile).toEqual(manifestJsonObj);
-
- const manifestFormat = writeFileSyncSpy.calls.argsFor(0)[2];
- expect(manifestFormat).toEqual('utf8');
- });
-
- it('should write manifest json object values from config xml.', () => {
- const existsSyncSpy = jasmine.createSpy('existsSync').and.returnValue(true);
- const readFileSyncSpy = jasmine.createSpy('readFileSync');
- const writeFileSyncSpy = jasmine.createSpy('writeFileSync');
- manifestJsonParser.__set__('fs', { readFileSync: readFileSyncSpy, existsSync: existsSyncSpy, writeFileSync: writeFileSyncSpy });
-
- manifestJsonParser = new ManifestJsonParser(locations.www).configure(cfg1).write();
-
- expect(existsSyncSpy).toHaveBeenCalled();
- expect(readFileSyncSpy).toHaveBeenCalled();
- expect(writeFileSyncSpy).toHaveBeenCalled();
-
- // mock manifest JSON Object
- let manifestJsonObj = {
- background_color: '#FFF',
- display: 'standalone',
- orientation: 'portrait',
- start_url: 'index.html',
- name: 'HelloWorld',
- short_name: 'HelloWorld',
- version: 'whatever',
- description: 'A sample Apache Cordova application.',
- author: 'Cordova Team',
- icons: [{ src: 'res/electron/cordova.png', type: 'image/png', sizes: '16x16' }]
- };
-
- const manifestPath = writeFileSyncSpy.calls.argsFor(0)[0];
- expect(manifestPath).toEqual(path.join('mock', 'www', 'manifest.json'));
-
- // get manifest json file content and remove white spaces
- let manifestFile = writeFileSyncSpy.calls.argsFor(0)[1];
-
- // convert to remove white space
- manifestFile = manifestFile.replace(/\s+/g, '');
- manifestJsonObj = JSON.stringify(manifestJsonObj).replace(/\s/g, '');
- expect(manifestFile).toEqual(manifestJsonObj);
-
- const manifestFormat = writeFileSyncSpy.calls.argsFor(0)[2];
- expect(manifestFormat).toEqual('utf8');
- });
+ expect(fs.writeFileSync).toHaveBeenCalledWith(
+ jasmine.any(String),
+ JSON.stringify(expectedManifest, null, 2),
+ 'utf8'
+ );
});
});
diff --git a/tests/spec/unit/templates/cordova/lib/PackageJsonParser.spec.js b/tests/spec/unit/templates/cordova/lib/PackageJsonParser.spec.js
index f85360f..c3975c1 100644
--- a/tests/spec/unit/templates/cordova/lib/PackageJsonParser.spec.js
+++ b/tests/spec/unit/templates/cordova/lib/PackageJsonParser.spec.js
@@ -22,13 +22,14 @@
const rewire = require('rewire');
const PackageJsonParser = rewire('../../../../../../bin/templates/cordova/lib/PackageJsonParser');
-const ConfigParser = require('cordova-common').ConfigParser;
+const { ConfigParser, events } = require('cordova-common');
const FIXTURES = path.join(__dirname, '..', '..', '..', '..', 'fixtures');
// Create a real config object before mocking out everything.
const cfg = new ConfigParser(path.join(FIXTURES, 'test-config-1.xml'));
const cfgEmpty = new ConfigParser(path.join(FIXTURES, 'test-config-empty.xml'));
+const cfgNoAuthorCustomEmail = new ConfigParser(path.join(FIXTURES, 'test-config-no-author-custom-email.xml'));
const defaultMockProjectPackageJson = {
name: 'io.cordova.electronTest',
@@ -37,7 +38,10 @@
description: 'A Sample Apache Cordova Electron Application.',
author: 'Apache Cordova Team',
license: 'Apache-2.0',
- dependencies: { 'cordova-electron': '^1.0.2' },
+ dependencies: {
+ 'cordova-electron': '^1.0.0',
+ 'cordova-plugin-camera': '^1.0.0'
+ },
devDependencies: {},
cordova: {
plugins: {},
@@ -51,133 +55,130 @@
configXml: path.join('mock', 'config.xml')
};
+const defaultInitPackageObj = { main: 'cdv-electron-main.js' };
+
describe('PackageJsonParser class', () => {
let packageJsonParser;
- let emitSpy;
beforeEach(() => {
- packageJsonParser = PackageJsonParser.__get__('PackageJsonParser');
-
- emitSpy = jasmine.createSpy('emit');
- packageJsonParser.__set__('events', { emit: emitSpy });
- });
-
- it('should should be defined.', () => {
- expect(packageJsonParser).toBeDefined();
- });
-
- it('should set initial value correctly.', () => {
packageJsonParser = new PackageJsonParser(locations.www, '/root/project');
+ spyOn(events, 'emit');
+ });
- // mock package JSON Object
- const packageJsonObj = { main: 'cdv-electron-main.js' };
-
- expect(packageJsonParser.path).toEqual(path.join('mock', 'www', 'package.json'));
+ it('should have been constructed with initial values.', () => {
+ expect(packageJsonParser).toBeDefined();
+ expect(packageJsonParser.path).toEqual(path.join(locations.www, 'package.json'));
expect(packageJsonParser.www).toEqual(locations.www);
- expect(packageJsonParser.package).toEqual(packageJsonObj);
+ expect(packageJsonParser.package).toEqual(defaultInitPackageObj);
});
- it('should return when config xml is not defined.', () => {
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project')
- .configure(undefined);
+ it('should not modify the package object when config is not provided.', () => {
+ packageJsonParser.configure();
+ // the package object should be the same as it was initialized
+ expect(packageJsonParser.package).toEqual(defaultInitPackageObj);
+ });
- // mock package JSON Object
- const packageJsonObj = { main: 'cdv-electron-main.js' };
+ it('should update the package object with default values, when config.xml is empty.', () => {
+ packageJsonParser.configure(cfgEmpty, defaultMockProjectPackageJson);
+
+ // Expected Mock Package Object
+ const packageJsonObj = Object.assign({}, defaultInitPackageObj, {
+ name: 'io.cordova.hellocordova',
+ displayName: 'HelloCordova',
+ version: '1.0.0',
+ description: 'A sample Apache Cordova application that responds to the deviceready event.',
+ dependencies: {
+ 'cordova-electron': '^1.0.0',
+ 'cordova-plugin-camera': '^1.0.0'
+ },
+ homepage: 'https://cordova.io',
+ license: 'Apache-2.0',
+ author: 'Apache Cordova Team'
+ });
expect(packageJsonParser.package).toEqual(packageJsonObj);
});
- it('should set package json object values to default, when config xml is empty.', () => {
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project')
- .configure(cfgEmpty, defaultMockProjectPackageJson);
+ it('should update package object with values from config.xml.', () => {
+ packageJsonParser.configure(cfg, defaultMockProjectPackageJson);
- // mock package JSON Object
- const packageJsonObj = {
- package:
- {
- main: 'cdv-electron-main.js',
- name: 'io.cordova.hellocordova',
- displayName: 'HelloCordova',
- version: '1.0.0',
- description: 'A sample Apache Cordova application that responds to the deviceready event.',
- dependencies: { 'cordova-electron': '^1.0.2' },
- homepage: 'https://cordova.io',
- license: 'Apache-2.0',
- author: 'Apache Cordova Team'
- }
- };
+ // Expected Mock Package Object
+ const packageJsonObj = Object.assign({}, defaultInitPackageObj, {
+ name: 'whatever',
+ displayName: 'HelloWorld',
+ version: '1.1.1',
+ description: 'A sample Apache Cordova application.',
+ dependencies: {
+ 'cordova-electron': '^1.0.0',
+ 'cordova-plugin-camera': '^1.0.0'
+ },
+ homepage: 'http://cordova.io',
+ license: 'Apache 2.0 License',
+ author: { name: 'Cordova Team', email: 'dev@cordova.com' }
+ });
- expect(packageJsonParser.package).toEqual(packageJsonObj.package);
+ expect(packageJsonParser.package).toEqual(packageJsonObj);
});
- it('should read and set package json object values from config xml.', () => {
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project')
- .configure(cfg, defaultMockProjectPackageJson);
+ it('should warn when any of the dependencies contain cordova-* is defined but not for cordova-plugin-*.', () => {
+ packageJsonParser.configure(cfg, defaultMockProjectPackageJson);
- // mock package JSON Object
- const packageJsonObj = {
- package:
- {
- main: 'cdv-electron-main.js',
- name: 'whatever',
- displayName: 'HelloWorld',
- version: '1.1.1',
- description: 'A sample Apache Cordova application.',
- dependencies: { 'cordova-electron': '^1.0.2' },
- homepage: 'http://cordova.io',
- license: 'Apache 2.0 License',
- author: { name: 'Cordova Team', email: 'dev@cordova.com' }
- }
- };
+ expect(events.emit).toHaveBeenCalledWith(
+ 'warn',
+ jasmine.stringMatching(/^\[Cordova Electron\] The built package size/)
+ );
- expect(packageJsonParser.package).toEqual(packageJsonObj.package);
+ expect(events.emit).toHaveBeenCalledWith(
+ 'verbose',
+ jasmine.stringMatching(/The following Cordova package\(s\) were detected/)
+ );
+
+ expect(events.emit).toHaveBeenCalledWith(
+ 'verbose',
+ jasmine.stringMatching(/cordova-electron/)
+ );
+
+ expect(events.emit).not.toHaveBeenCalledWith(
+ 'verbose',
+ jasmine.stringMatching(/cordova-plugin-camera/)
+ );
});
- it('should warn when "cordova-*" prefixed dependency is defined in package.json dependencies.', () => {
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project')
- .configure(cfg, defaultMockProjectPackageJson);
-
- expect(emitSpy).toHaveBeenCalled();
-
- let actual = emitSpy.calls.argsFor(0)[1];
- let expectedPartial = '[Cordova Electron] The built package size may be larger than necessary.';
- expect(actual).toContain(expectedPartial);
-
- actual = emitSpy.calls.argsFor(1)[1];
- expectedPartial = '[Cordova Electron] The following Cordova package(s) were detected as "dependencies" in the projects "package.json" file.';
- expect(actual).toContain(expectedPartial);
- expect(actual).toContain('cordova-electron');
+ it('should set default author when missing but author email is defined.', () => {
+ packageJsonParser.configure(cfgNoAuthorCustomEmail, defaultMockProjectPackageJson);
+ expect(packageJsonParser.package.author).toEqual({
+ name: 'Apache Cordova Team',
+ email: 'dev@cordova.com'
+ });
});
- it('should not warn when "cordova-*" prefixed dependency is not defined in package.json dependencies.', () => {
+ it('should not warn when any cordova-* packages are defined as devDependency.', () => {
+ // Fix defaultMockProjectPackageJson where cordova-* is devDependency
const mockProjectPackageJson = Object.assign({}, defaultMockProjectPackageJson);
mockProjectPackageJson.devDependencies = Object.assign({}, defaultMockProjectPackageJson.dependencies);
mockProjectPackageJson.dependencies = { foobar: '1.0.0' }; // setting a non "cordova-" dependency
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project')
- .configure(cfg, mockProjectPackageJson);
+ packageJsonParser.configure(cfg, mockProjectPackageJson);
- expect(emitSpy).not.toHaveBeenCalled();
+ expect(events.emit).not.toHaveBeenCalled();
});
it('should skip configuring the Electron app\'s dependencies when the Cordova project\'s package.json dependencies are not set.', () => {
const mockProjectPackageJson = Object.assign({}, defaultMockProjectPackageJson);
mockProjectPackageJson.dependencies = {};
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project')
- .configure(cfg, mockProjectPackageJson);
+ packageJsonParser.configure(cfg, mockProjectPackageJson);
- expect(emitSpy).not.toHaveBeenCalled();
+ expect(events.emit).not.toHaveBeenCalled();
});
it('should skip preparing npm packages that already contain absolute paths.', () => {
const mockProjectPackageJson = Object.assign({}, defaultMockProjectPackageJson);
mockProjectPackageJson.dependencies = { foobar: 'file:/tmp/foobar.tar.gz' };
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project')
- .configure(cfg, mockProjectPackageJson);
+ packageJsonParser.configure(cfg, mockProjectPackageJson);
- expect(emitSpy).not.toHaveBeenCalled();
+ expect(events.emit).not.toHaveBeenCalled();
});
it('should convert npm packages that contain relative path to be absolute paths.', () => {
@@ -186,10 +187,9 @@
spyOn(fs, 'pathExistsSync').and.returnValue(true);
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project', '/root/project')
- .configure(cfg, mockProjectPackageJson);
+ packageJsonParser.configure(cfg, mockProjectPackageJson);
- expect(emitSpy).not.toHaveBeenCalled();
+ expect(events.emit).not.toHaveBeenCalled();
});
it('should warn that an npm packages will be dropped when the absolute path could not be found.', () => {
@@ -198,13 +198,17 @@
spyOn(fs, 'pathExistsSync').and.returnValue(false);
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project', '/root/project')
- .configure(cfg, mockProjectPackageJson);
+ packageJsonParser.configure(cfg, mockProjectPackageJson);
- const actual = emitSpy.calls.argsFor(0)[1];
- const expectedPartial = '[Cordova Electron] The following local npm dependencies could not be located and will not be deployed to the Electron app:';
- expect(actual).toContain(expectedPartial);
- expect(actual).toContain('foobar');
+ expect(events.emit).toHaveBeenCalledWith(
+ 'warn',
+ jasmine.stringMatching(/^\[Cordova Electron\] The following local npm dependencies could not be located and will not be deployed/)
+ );
+
+ expect(events.emit).toHaveBeenCalledWith(
+ 'warn',
+ jasmine.stringMatching(/foobar/)
+ );
});
it('should not set package dependencies when project dependencies is missing.', () => {
@@ -212,92 +216,32 @@
mockProjectPackageJson.devDependencies = Object.assign({}, defaultMockProjectPackageJson.dependencies);
delete mockProjectPackageJson.dependencies;
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project')
- .configure(cfg, mockProjectPackageJson);
+ packageJsonParser.configure(cfg, mockProjectPackageJson);
- expect(emitSpy).not.toHaveBeenCalled();
+ expect(events.emit).not.toHaveBeenCalled();
expect(packageJsonParser.package.dependencies).not.toBeDefined();
});
- it('should write provided data when config xml is empty.', () => {
- const writeFileSyncSpy = jasmine.createSpy('writeFileSync');
- packageJsonParser.__set__('fs', { writeFileSync: writeFileSyncSpy });
+ it('should write something.', () => {
+ spyOn(fs, 'writeFileSync').and.returnValue(true);
+ packageJsonParser.write();
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project')
- .configure(cfgEmpty, defaultMockProjectPackageJson)
- .write();
-
- expect(writeFileSyncSpy).toHaveBeenCalled();
-
- // mock package JSON Object
- let packageJsonObj = {
- package:
- {
- main: 'cdv-electron-main.js',
- name: 'io.cordova.hellocordova',
- displayName: 'HelloCordova',
- version: '1.0.0',
- description: 'A sample Apache Cordova application that responds to the deviceready event.',
- dependencies: { 'cordova-electron': '^1.0.2' },
- homepage: 'https://cordova.io',
- license: 'Apache-2.0',
- author: 'Apache Cordova Team'
- }
- };
-
- const packagePath = writeFileSyncSpy.calls.argsFor(0)[0];
- expect(packagePath).toEqual(path.join('mock', 'www', 'package.json'));
-
- // get package json file content and remove white spaces
- let packageFile = writeFileSyncSpy.calls.argsFor(0)[1];
-
- // convert to remove white space
- packageFile = packageFile.replace(/\s+/g, '');
- packageJsonObj = JSON.stringify(packageJsonObj.package).replace(/\s/g, '');
- expect(packageFile).toEqual(packageJsonObj);
-
- const packageFormat = writeFileSyncSpy.calls.argsFor(0)[2];
- expect(packageFormat).toEqual('utf8');
+ expect(fs.writeFileSync).toHaveBeenCalledWith(
+ jasmine.any(String),
+ JSON.stringify(defaultInitPackageObj, null, 2),
+ 'utf8'
+ );
});
- it('should write package json object values from config xml.', () => {
- const writeFileSyncSpy = jasmine.createSpy('writeFileSync');
- packageJsonParser.__set__('fs', { writeFileSync: writeFileSyncSpy });
-
- packageJsonParser = new PackageJsonParser(locations.www, '/root/project')
- .configure(cfg, defaultMockProjectPackageJson)
+ it('should write package object out with user custom defined values.', () => {
+ spyOn(fs, 'writeFileSync').and.returnValue(true);
+ packageJsonParser.configure(cfg, defaultMockProjectPackageJson)
.write();
- expect(writeFileSyncSpy).toHaveBeenCalled();
-
- // mock package JSON Object
- let packageJsonObj = {
- package:
- {
- main: 'cdv-electron-main.js',
- name: 'whatever',
- displayName: 'HelloWorld',
- version: '1.1.1',
- description: 'A sample Apache Cordova application.',
- dependencies: { 'cordova-electron': '^1.0.2' },
- homepage: 'http://cordova.io',
- license: 'Apache 2.0 License',
- author: { name: 'Cordova Team', email: 'dev@cordova.com' }
- }
- };
-
- const packagePath = writeFileSyncSpy.calls.argsFor(0)[0];
- expect(packagePath).toEqual(path.join('mock', 'www', 'package.json'));
-
- // get package json file content and remove white spaces
- let packageFile = writeFileSyncSpy.calls.argsFor(0)[1];
-
- // convert to remove white space
- packageFile = packageFile.replace(/\s+/g, '');
- packageJsonObj = JSON.stringify(packageJsonObj.package).replace(/\s/g, '');
- expect(packageFile).toEqual(packageJsonObj);
-
- const packageFormat = writeFileSyncSpy.calls.argsFor(0)[2];
- expect(packageFormat).toEqual('utf8');
+ expect(fs.writeFileSync).toHaveBeenCalledWith(
+ jasmine.any(String),
+ jasmine.stringMatching(/whatever/),
+ 'utf8'
+ );
});
});
diff --git a/tests/spec/unit/templates/parser.spec.js b/tests/spec/unit/templates/parser.spec.js
index 0062cc0..4c4fadc 100644
--- a/tests/spec/unit/templates/parser.spec.js
+++ b/tests/spec/unit/templates/parser.spec.js
@@ -17,15 +17,16 @@
under the License.
*/
-const rewire = require('rewire');
const path = require('path');
-const CordovaError = require('cordova-common').CordovaError;
+const fs = require('fs-extra');
+const rewire = require('rewire');
+const { CordovaError, events } = require('cordova-common');
const Parser = rewire('../../../../bin/templates/cordova/parser');
+const mockProjectPath = 'mock_project_path';
+
describe('Parser class', () => {
describe('Constructing parser instanse', () => {
- const mockProjectPath = 'mock_project_path';
-
it('should not have valid electron project', () => {
Parser.__set__('dirExists', jasmine.createSpy('dirExists').and.returnValue(false));
@@ -36,63 +37,35 @@
it('should have valid electron project and set path', () => {
Parser.__set__('dirExists', jasmine.createSpy('dirExists').and.returnValue(true));
-
const parser = new Parser(mockProjectPath);
-
expect(parser.path).toBe(mockProjectPath);
});
});
- describe('update_from_config method', () => {
- const mockProjectPath = 'mock_project_path';
+ describe('Class Methods', () => {
+ let parser;
- it('should return a resolved promise.', () => {
+ beforeEach(() => {
Parser.__set__('dirExists', jasmine.createSpy('dirExists').and.returnValue(true));
-
- const parser = new Parser(mockProjectPath);
- const actual = parser.update_from_config();
-
- expect(typeof actual).toBe(typeof Promise.resolve());
+ parser = new Parser(mockProjectPath);
});
- });
- describe('www_dir method', () => {
- const mockProjectPath = 'mock_project_path';
-
- it('should return the projects www dir path.', () => {
- Parser.__set__('dirExists', jasmine.createSpy('dirExists').and.returnValue(true));
-
- const parser = new Parser(mockProjectPath);
- const actual = parser.www_dir();
-
- expect(actual).toBe(path.join(mockProjectPath, 'www'));
+ describe('update_from_config method', () => {
+ it('should return a resolved promise.', () => {
+ const actual = parser.update_from_config();
+ expect(typeof actual).toBe(typeof Promise.resolve());
+ });
});
- });
- describe('update_www method', () => {
- const mockProjectPath = 'mock_project_path';
-
- it('should detect merges/electron file path and merge/update user source files into the platform staging dir', () => {
- Parser.__set__('dirExists', jasmine.createSpy('dirExists').and.returnValue(true));
-
- const fsExistsSyncSpy = jasmine.createSpy('existsSync').and.returnValue(true);
- Parser.__set__('fs', {
- existsSync: fsExistsSyncSpy
+ describe('www_dir method', () => {
+ it('should return the projects www dir path.', () => {
+ const actual = parser.www_dir();
+ expect(actual).toBe(path.join(mockProjectPath, 'www'));
});
+ });
- const emitSpy = jasmine.createSpy('emit');
- Parser.__set__('events', {
- emit: emitSpy
- });
-
- const mergeAndUpdateDirSpy = jasmine.createSpy('mergeAndUpdateDir');
- Parser.__set__('FileUpdater', {
- mergeAndUpdateDir: mergeAndUpdateDirSpy
- });
-
- const parser = new Parser(mockProjectPath);
-
- const cordovaProject = {
+ describe('update_www method', () => {
+ const mockConfigParser = {
root: 'mock',
projectConfig: {
path: path.join('mock', 'config.xml'),
@@ -103,134 +76,102 @@
}
};
- parser.update_www(cordovaProject);
+ it('should detect merges/electron file path and merge/update user source files into the platform staging dir', () => {
+ spyOn(fs, 'existsSync').and.returnValue(true);
+ spyOn(events, 'emit');
- expect(fsExistsSyncSpy).toHaveBeenCalled();
- expect(emitSpy).toHaveBeenCalled();
+ const mergeAndUpdateDirSpy = jasmine.createSpy('mergeAndUpdateDir');
+ Parser.__set__('FileUpdater', {
+ mergeAndUpdateDir: mergeAndUpdateDirSpy
+ });
- // The emit message was.
- let actualEmit = emitSpy.calls.argsFor(0)[1];
- let expectedEmit = 'Found "merges/electron" folder. Copying its contents into the electron project.';
- expect(actualEmit).toBe(expectedEmit);
+ parser.update_www(mockConfigParser);
- const expectedSourceDirs = [
- 'www',
- path.join('..', mockProjectPath, 'platform_www'),
- path.join('merges', 'electron')
- ];
- const expectedTargetDir = path.join('..', mockProjectPath, 'www');
- actualEmit = emitSpy.calls.argsFor(1)[1];
- expectedEmit = `Merging and updating files from [${expectedSourceDirs.join(', ')}] to ${expectedTargetDir}`;
- expect(actualEmit).toBe(expectedEmit);
+ expect(events.emit).toHaveBeenCalledWith(
+ 'verbose',
+ 'Found "merges/electron" folder. Copying its contents into the electron project.'
+ );
- expect(mergeAndUpdateDirSpy).toHaveBeenCalled();
+ const expectedSourceDirs = [
+ 'www',
+ path.join('..', mockProjectPath, 'platform_www'),
+ path.join('merges', 'electron')
+ ];
+ const expectedTargetDir = path.join('..', mockProjectPath, 'www');
+
+ expect(events.emit).toHaveBeenCalledWith(
+ 'verbose',
+ `Merging and updating files from [${expectedSourceDirs.join(', ')}] to ${expectedTargetDir}`
+ );
+
+ expect(mergeAndUpdateDirSpy).toHaveBeenCalled();
+ });
+
+ it('should detect merges/electron file path and merge/update user source files into the platform staging dir', () => {
+ spyOn(fs, 'existsSync').and.returnValue(false);
+ spyOn(events, 'emit');
+
+ const mergeAndUpdateDirSpy = jasmine.createSpy('mergeAndUpdateDir');
+ Parser.__set__('FileUpdater', {
+ mergeAndUpdateDir: mergeAndUpdateDirSpy
+ });
+
+ parser.update_www(mockConfigParser);
+
+ expect(fs.existsSync).toHaveBeenCalled();
+ expect(events.emit).toHaveBeenCalled();
+
+ // The emit message was.
+ let actualEmit = events.emit.calls.argsFor(0)[1];
+ let expectedEmit = 'Found "merges/electron" folder. Copying its contents into the electron project.';
+ expect(actualEmit).not.toBe(expectedEmit);
+
+ const expectedSourceDirs = [
+ 'www',
+ path.join('..', mockProjectPath, 'platform_www')
+ ];
+ const expectedTargetDir = path.join('..', mockProjectPath, 'www');
+ actualEmit = events.emit.calls.argsFor(0)[1];
+ expectedEmit = `Merging and updating files from [${expectedSourceDirs.join(', ')}] to ${expectedTargetDir}`;
+ expect(actualEmit).toBe(expectedEmit);
+ expect(mergeAndUpdateDirSpy).toHaveBeenCalled();
+ });
});
- it('should detect merges/electron file path and merge/update user source files into the platform staging dir', () => {
- Parser.__set__('dirExists', jasmine.createSpy('dirExists').and.returnValue(true));
-
- const fsExistsSyncSpy = jasmine.createSpy('existsSync').and.returnValue(false);
- Parser.__set__('fs', {
- existsSync: fsExistsSyncSpy
+ describe('config_xml method', () => {
+ it('should return the projects config.xml file path.', () => {
+ expect(parser.config_xml()).toBe(path.join(mockProjectPath, 'config.xml'));
});
-
- const emitSpy = jasmine.createSpy('emit');
- Parser.__set__('events', {
- emit: emitSpy
- });
-
- const mergeAndUpdateDirSpy = jasmine.createSpy('mergeAndUpdateDir');
- Parser.__set__('FileUpdater', {
- mergeAndUpdateDir: mergeAndUpdateDirSpy
- });
-
- const parser = new Parser(mockProjectPath);
-
- const cordovaProject = {
- root: 'mock',
- projectConfig: {
- path: path.join('mock', 'config.xml'),
- cdvNamespacePrefix: 'cdv'
- },
- locations: {
- www: path.join('mock', 'www')
- }
- };
-
- parser.update_www(cordovaProject);
-
- expect(fsExistsSyncSpy).toHaveBeenCalled();
- expect(emitSpy).toHaveBeenCalled();
-
- // The emit message was.
- let actualEmit = emitSpy.calls.argsFor(0)[1];
- let expectedEmit = 'Found "merges/electron" folder. Copying its contents into the electron project.';
- expect(actualEmit).not.toBe(expectedEmit);
-
- const expectedSourceDirs = [
- 'www',
- path.join('..', mockProjectPath, 'platform_www')
- ];
- const expectedTargetDir = path.join('..', mockProjectPath, 'www');
- actualEmit = emitSpy.calls.argsFor(0)[1];
- expectedEmit = `Merging and updating files from [${expectedSourceDirs.join(', ')}] to ${expectedTargetDir}`;
- expect(actualEmit).toBe(expectedEmit);
-
- expect(mergeAndUpdateDirSpy).toHaveBeenCalled();
});
- });
- describe('config_xml method', () => {
- const mockProjectPath = 'mock_project_path';
+ describe('update_project method', () => {
+ it('should copy munged config.xml to platform www dir.', () => {
+ const fsCopySyncSpy = jasmine.createSpy('copySync');
+ Parser.__set__('fs', { copySync: fsCopySyncSpy });
- it('should return the projects config.xml file path.', () => {
- Parser.__set__('dirExists', jasmine.createSpy('dirExists').and.returnValue(true));
+ parser.update_project().then(() => {
+ const actualSrc = fsCopySyncSpy.calls.argsFor(0)[0];
+ const actualDest = fsCopySyncSpy.calls.argsFor(0)[1];
- const parser = new Parser(mockProjectPath);
- const actual = parser.config_xml();
-
- expect(actual).toBe(path.join(mockProjectPath, 'config.xml'));
- });
- });
-
- describe('update_project method', () => {
- const mockProjectPath = 'mock_project_path';
-
- it('should copy munged config.xml to platform www dir.', () => {
- const fsCopySyncSpy = jasmine.createSpy('copySync');
- Parser.__set__('fs', {
- copySync: fsCopySyncSpy
- });
-
- Parser.__set__('dirExists', jasmine.createSpy('dirExists').and.returnValue(true));
-
- const parser = new Parser(mockProjectPath);
-
- parser.update_project().then(() => {
- expect(fsCopySyncSpy).toHaveBeenCalled();
-
- const actualSrc = fsCopySyncSpy.calls.argsFor(0)[0];
- const actualDest = fsCopySyncSpy.calls.argsFor(0)[1];
- expect(actualSrc).toBe(path.join(mockProjectPath, 'config.xml'));
- expect(actualDest).toBe(path.join(mockProjectPath, 'www', 'config.xml'));
+ expect(fsCopySyncSpy).toHaveBeenCalled();
+ expect(actualSrc).toBe(path.join(mockProjectPath, 'config.xml'));
+ expect(actualDest).toBe(path.join(mockProjectPath, 'www', 'config.xml'));
+ });
});
});
});
describe('logFileOp method', () => {
it('should emit passed in message.', () => {
- const emitSpy = jasmine.createSpy('emit');
- Parser.__set__('events', {
- emit: emitSpy
- });
+ spyOn(events, 'emit');
const msg = 'random message';
const logFileOp = Parser.__get__('logFileOp');
logFileOp(msg);
// The emit message was.
- const actualEmit = emitSpy.calls.argsFor(0)[1];
- expect(emitSpy).toHaveBeenCalled();
+ const actualEmit = events.emit.calls.argsFor(0)[1];
+ expect(events.emit).toHaveBeenCalled();
expect(actualEmit).toBe(` ${msg}`);
});
});