This is an automated email from the ASF dual-hosted git repository.

erisu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-electron.git


The following commit(s) were added to refs/heads/master by this push:
     new 31f6619  Implement Electron Custom App Icons Functionality (#13)
31f6619 is described below

commit 31f6619f8bdc060ece266a13336997a66f436372
Author: Gedas Gardauskas <[email protected]>
AuthorDate: Fri Feb 15 11:39:51 2019 +0900

    Implement Electron Custom App Icons Functionality (#13)
---
 DOCUMENTATION.md                                   |  45 +-
 bin/lib/create.js                                  |   3 +
 bin/templates/build-res/installer.png              | Bin 0 -> 39830 bytes
 bin/templates/cordova/Api.js                       |   1 +
 bin/templates/cordova/lib/build.js                 |   4 +-
 bin/templates/cordova/lib/build/base.json          |   4 +-
 bin/templates/cordova/lib/build/darwin.json        |   1 +
 bin/templates/cordova/lib/build/linux.json         |   1 +
 bin/templates/cordova/lib/build/win32.json         |   1 +
 bin/templates/cordova/lib/prepare.js               | 216 ++++-
 bin/templates/project/main.js                      |  23 +-
 bin/templates/project/www/icons/icon.png           | Bin 0 -> 39830 bytes
 package.json                                       |   1 +
 .../unit/templates/cordova/lib/prepare.spec.js     | 893 +++++++++++++++++++++
 14 files changed, 1174 insertions(+), 19 deletions(-)

diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md
index f6c41b2..28dafd6 100644
--- a/DOCUMENTATION.md
+++ b/DOCUMENTATION.md
@@ -30,6 +30,7 @@ Electron is a framework that uses web technologies (HTML, 
CSS, and JS) to build
     - [Create a Project](#create-a-project)
     - [Preview a Project](#preview-a-project)
     - [Build a Project](#build-a-project)
+  - [Customizing the Application's Icon](#customizing-the-applications-icon)
   - [Customizing the Application's Main 
Process](#customizing-the-applications-main-process)
     - [Window Appearance (BrowserWindow)](#window-appearance-browserwindow)
       - [How to set the window default 
size?](#how-to-set-the-window-default-size)
@@ -107,18 +108,48 @@ $ cordova build electron --debug
 $ cordova build electron --release
 ```
 
-<!-- @todo Update prepare.
-Customizing the Application's Icon
+## Customizing the Application's Icon
 
-In the `config.xml` file, there should be an Electron platform node with the 
icons defined. The example is seen as below:
+Customized icon(s) can be declared with the `<icon>` element(s) in the 
`config.xml` file. There are two types of icons that can be defined, the 
application icon and the package installer icon. These icons should be defined 
in the Electron's platform node `<platform name="electron">`.
+
+One icon can be used for the application and installer, but this icon should 
be at least **512x512** pixels to work across all operating systems.
+
+_Notice: If a customized icon is not provided, the Apache Cordova default 
icons are used._
+
+_Notice: macOS does not display custom icons when using `cordova run`. It 
defaults to the Electron's icon._
+
+```xml
+<platform name="electron">
+  <icon src="res/electron/icon.png" />
+</platform>
 ```
+
+You can supply unique icons for the application and installer by setting the 
`target` attribute. As mentioned above, the installer image should be 
**512x512** pixels to work across all platforms.
+
+```xml
 <platform name="electron">
-  <icon src="res/electron/icon.ico" />
-  <icon src="res/electron/icon.icns" />
-  <icon src="res/electron/32x32.png" />
+  <icon src="res/electron/app.png" target="app" />
+  <icon src="res/electron/installer.png" target="installer" />
+</platform>
+```
+
+For devices that support high-DPI resolutions, such as Apple's Retina display, 
you can create a set of images with the same base filename but suffix with its 
multiplier.
+
+For example, if the base image's filename `icon.png` and is the standard 
resolution, then `[email protected]` will be treated as a high-resolution image that 
with a DPI doubled from the base.
+
+* icon.png (256px x 256px)
+* [email protected] (512px x 512px)
+
+If you want to support displays with different DPI densities at the same time, 
you can put images with different sizes in the same folder and use the filename 
without DPI suffixes. For example:
+
+```xml
+<platform name="electron">
+  <icon src="res/electron/icon.png" />
+  <icon src="res/electron/[email protected]" />
+  <icon src="res/electron/[email protected]" />
+  <icon src="res/electron/[email protected]" target="installer" />
 </platform>
 ```
--->
 
 ## Customizing the Application's Main Process
 
diff --git a/bin/lib/create.js b/bin/lib/create.js
index 0122f6d..b028647 100644
--- a/bin/lib/create.js
+++ b/bin/lib/create.js
@@ -53,6 +53,9 @@ module.exports.createProject = (project_path, package_name, 
project_name, option
     // Make sure that the platform directory is created if missing.
     fs.ensureDirSync(project_path);
 
+    // copy templates/build-res directory ( recursive )
+    fs.copySync(path.join(ROOT, 'bin/templates/build-res'), 
path.join(project_path, 'build-res'), { overwrite: false });
+
     // copy templates/cordova directory ( recursive )
     fs.copySync(path.join(ROOT, 'bin/templates/cordova'), 
path.join(project_path, 'cordova'), { overwrite: false });
 
diff --git a/bin/templates/build-res/installer.png 
b/bin/templates/build-res/installer.png
new file mode 100644
index 0000000..c9465f3
Binary files /dev/null and b/bin/templates/build-res/installer.png differ
diff --git a/bin/templates/cordova/Api.js b/bin/templates/cordova/Api.js
index d16d9eb..3260259 100644
--- a/bin/templates/cordova/Api.js
+++ b/bin/templates/cordova/Api.js
@@ -68,6 +68,7 @@ class Api {
             configXml: path.join(this.root, 'config.xml'),
             defaultConfigXml: path.join(this.root, 'cordova/defaults.xml'),
             build: path.join(this.root, 'build'),
+            buildRes: path.join(this.root, 'build-res'),
             cache: path.join(this.root, 'cache'),
             // NOTE: Due to platformApi spec we need to return relative paths 
here
             cordovaJs: 'bin/templates/project/assets/www/cordova.js',
diff --git a/bin/templates/cordova/lib/build.js 
b/bin/templates/cordova/lib/build.js
index 190c3e0..f005859 100644
--- a/bin/templates/cordova/lib/build.js
+++ b/bin/templates/cordova/lib/build.js
@@ -249,8 +249,10 @@ class ElectronBuilder {
             APP_AUTHOR: packageJson.author,
             APP_ID: packageJson.name,
             APP_TITLE: packageJson.displayName,
-            APP_WWW_DIR: this.api.locations.www,
+            APP_INSTALLER_ICON: 'installer.png',
             APP_BUILD_DIR: this.api.locations.build,
+            APP_BUILD_RES_DIR: this.api.locations.buildRes,
+            APP_WWW_DIR: this.api.locations.www,
             BUILD_TYPE: this.isDevelopment ? 'development' : 'distribution'
         };
 
diff --git a/bin/templates/cordova/lib/build/base.json 
b/bin/templates/cordova/lib/build/base.json
index 27b671b..de00a29 100644
--- a/bin/templates/cordova/lib/build/base.json
+++ b/bin/templates/cordova/lib/build/base.json
@@ -5,13 +5,13 @@
 
     "directories": {
       "app": "${APP_WWW_DIR}",
+      "buildResources": "${APP_BUILD_RES_DIR}",
       "output": "${APP_BUILD_DIR}"
     },
-
     "electronVersion": "4.0.1",
 
     "electronDownload": {
       "version": "4.0.1"
     }
   }
-}
+}
\ No newline at end of file
diff --git a/bin/templates/cordova/lib/build/darwin.json 
b/bin/templates/cordova/lib/build/darwin.json
index bd608f8..31b85e5 100644
--- a/bin/templates/cordova/lib/build/darwin.json
+++ b/bin/templates/cordova/lib/build/darwin.json
@@ -3,6 +3,7 @@
   "config": {
     "mac": {
       "type": "${BUILD_TYPE}",
+      "icon": "${APP_INSTALLER_ICON}",
       "target": [
         {
           "target": "dmg",
diff --git a/bin/templates/cordova/lib/build/linux.json 
b/bin/templates/cordova/lib/build/linux.json
index 0bdeb9e..9154c99 100644
--- a/bin/templates/cordova/lib/build/linux.json
+++ b/bin/templates/cordova/lib/build/linux.json
@@ -3,6 +3,7 @@
   "config": {
     "linux": {
       "maintainer": "${APP_AUTHOR}",
+      "icon": "${APP_INSTALLER_ICON}",
       "target": [
         {
           "target": "tar.gz",
diff --git a/bin/templates/cordova/lib/build/win32.json 
b/bin/templates/cordova/lib/build/win32.json
index 05326f9..956c9a8 100644
--- a/bin/templates/cordova/lib/build/win32.json
+++ b/bin/templates/cordova/lib/build/win32.json
@@ -2,6 +2,7 @@
   "win": [],
   "config": {
     "win": {
+      "icon": "${APP_INSTALLER_ICON}",
       "target": [
         {
           "target": "nsis",
diff --git a/bin/templates/cordova/lib/prepare.js 
b/bin/templates/cordova/lib/prepare.js
index b6b78bd..f64bd64 100644
--- a/bin/templates/cordova/lib/prepare.js
+++ b/bin/templates/cordova/lib/prepare.js
@@ -17,9 +17,10 @@
     under the License.
 */
 
-const path = require('path');
 const fs = require('fs-extra');
-const { ConfigParser, xmlHelpers } = require('cordova-common');
+const path = require('path');
+const shell = require('shelljs');
+const { ConfigParser, xmlHelpers, events, CordovaError } = 
require('cordova-common');
 
 module.exports.prepare = function (cordovaProject, options) {
     // First cleanup current config and merge project's one into own
@@ -47,7 +48,9 @@ module.exports.prepare = function (cordovaProject, options) {
     this.config.write();
 
     // Update own www dir with project's www assets and plugins' assets and 
js-files
-    this.parser.update_www(cordovaProject, options);
+    this.parser.update_www(cordovaProject, this.locations);
+    // Update icons
+    updateIcons(cordovaProject, this.locations);
 
     // Copy or Create manifest.json
     const srcManifestPath = path.join(cordovaProject.locations.www, 
'manifest.json');
@@ -243,3 +246,210 @@ class ManifestJson {
         fs.writeFileSync(this.path, JSON.stringify(this.manifest, null, 2), 
'utf8');
     }
 }
+
+/**
+ * Update Electron App and Installer icons.
+ */
+function updateIcons (cordovaProject, locations) {
+    const icons = cordovaProject.projectConfig.getIcons('electron');
+
+    // Skip if there are no app defined icons in config.xml
+    if (icons.length === 0) {
+        events.emit('verbose', 'This app does not have icons defined');
+        return;
+    }
+
+    checkIconsAttributes(icons);
+
+    const choosenIcons = prepareIcons(icons);
+    const resourceMap = createResourceMap(cordovaProject, locations, 
choosenIcons);
+
+    events.emit('verbose', 'Updating icons');
+    copyIcons(cordovaProject.root, resourceMap);
+}
+
+/**
+ * Check if all required attributes are set.
+ */
+function checkIconsAttributes (icons) {
+    let errorMissingAttributes = [];
+    let errorWrongSize = [];
+    let errorMessage = [];
+    icons.forEach(icon => {
+        if (!icon.src) {
+            errorMissingAttributes.push(icon.target ? icon.target : 'size=' + 
(icon.height || icon.width));
+        }
+        if ((icon.height && icon.width) < 512 && (icon.height && icon.width) 
!== undefined) {
+            errorWrongSize.push(icon.target === 'installer' ? `for target: 
${icon.target}` : `given: width=${icon.width} height=${icon.height}`);
+        }
+    });
+    if (errorMissingAttributes.length > 0) {
+        errorMessage.push('One of the following attributes are set but missing 
the other for the target: ' + errorMissingAttributes.join(', ') + '. Please 
ensure that all required attributes are defined.');
+    }
+    if (errorWrongSize.length > 0) {
+        errorMessage.push('Size of icon does not match required size ' + 
errorWrongSize.join(', ') + '. Please ensure that .png icon for is at least 
512x512.');
+    }
+    if (errorMessage.length > 0) {
+        throw new CordovaError(errorMessage.join(' '));
+    }
+}
+
+/**
+ *  Find and select icons for the app and installer.
+ *  Also, set high resolution icons, if provided by a user.
+ */
+function prepareIcons (icons) {
+    let customIcon;
+    let appIcon;
+    let installerIcon;
+
+    // choose one icon for a target
+    const chooseOne = (defaultIcon, icon) => {
+        events.emit('verbose', `Found extra icon for target ${icon.target}: 
${defaultIcon.src} and ignoring in favor of ${icon.src}.`);
+
+        defaultIcon = icon;
+
+        return defaultIcon;
+    };
+
+    // find if there is high resolution images that has DPI suffix
+    const highResAndRemainingIcons = findHighResIcons(icons);
+
+    const highResIcons = highResAndRemainingIcons.highResIcons;
+    const remainingIcons = highResAndRemainingIcons.remainingIcons;
+
+    // iterate over remaining icon elements to find the icons for the app and 
installer
+    for (let i = 0; i < remainingIcons.length; i++) {
+        // if (fs.existsSync(icons[i].src)) {
+        let icon = remainingIcons[i];
+        const size = icon.width || icon.height;
+        icon.extension = path.extname(icon.src);
+
+        switch (icon.target) {
+        case 'app':
+            appIcon = appIcon ? chooseOne(appIcon, icon) : icon;
+            break;
+        case 'installer':
+            installerIcon = installerIcon ? chooseOne(installerIcon, icon) : 
icon;
+            break;
+        case undefined:
+            if ((size <= 512 || size === undefined) && 
!Object.keys(highResIcons).length) {
+                customIcon = customIcon ? chooseOne(customIcon, icon) : icon;
+            }
+            break;
+        }
+    }
+
+    return { customIcon, appIcon, installerIcon, highResIcons };
+}
+
+/**
+ *  Find and high resolution icons and return remaining icons,
+ *  unless an icon has a specified target.
+ */
+function findHighResIcons (icons) {
+    // find icons that are not in the highResIcons, unless they have a target 
set
+    const findRemainingIcons = (icons, highResIcons) => icons.filter(
+        (icon) => (icon.target || (!icon.target && 
!highResIcons.includes(icon)))
+            ? Object.assign(icon)
+            : false
+    );
+
+    let highResIcons = icons.filter(icon => {
+        if (icon.src.includes('@')) {
+            const extension = path.extname(icon.src);
+            const suffix = icon.src.split('@').pop().slice(0, 
-extension.length);
+
+            return Object.assign(icon, { suffix, extension });
+        }
+    });
+
+    let remainingIcons = findRemainingIcons(icons, highResIcons);
+    // set normal image that has standard resolution
+    const has1x = highResIcons.find(obj => obj.suffix === '1x');
+    if (!has1x && Object.keys(highResIcons).length) {
+        const highResIcon = highResIcons[Object.keys(highResIcons)[0]];
+        let baseIcon = remainingIcons.find(obj => obj.src === 
highResIcon.src.split('@')[0] + highResIcon.extension);
+
+        if (!baseIcon) {
+            throw new CordovaError('Base icon for high resolution images was 
not found.');
+        }
+
+        const extension = path.extname(baseIcon.src);
+        const suffix = '1x';
+
+        baseIcon = Object.assign(baseIcon, { suffix, extension });
+
+        highResIcons.push(baseIcon);
+
+        remainingIcons = findRemainingIcons(icons, highResIcons);
+    }
+
+    return { highResIcons, remainingIcons };
+}
+
+/**
+ * Map selected icons to the approporiate target directory and name.
+ */
+function createResourceMap (cordovaProject, locations, icons) {
+    let resourceMap = [];
+
+    for (const key in icons) {
+        const icon = icons[key];
+
+        if (!icon) {
+            continue;
+        }
+
+        let targetPath;
+        switch (key) {
+        case 'customIcon':
+            // Copy icon for the App
+            targetPath = path.join(locations.www, 'img', 
`app${icon.extension}`);
+            resourceMap.push(mapIconResources(cordovaProject.root, icon.src, 
targetPath));
+            // Copy icon for the Installer
+            targetPath = path.join(locations.buildRes, 
`installer${icon.extension}`);
+            resourceMap.push(mapIconResources(cordovaProject.root, icon.src, 
targetPath));
+            break;
+        case 'appIcon':
+            targetPath = path.join(locations.www, 'img', 
`app${icon.extension}`);
+            resourceMap.push(mapIconResources(cordovaProject.root, icon.src, 
targetPath));
+            break;
+        case 'installerIcon':
+            targetPath = path.join(locations.buildRes, 
`installer${icon.extension}`);
+            resourceMap.push(mapIconResources(cordovaProject.root, icon.src, 
targetPath));
+            break;
+        case 'highResIcons':
+            for (const key in icon) {
+                const highResIcon = icon[key];
+                targetPath = path.join(locations.www, 'img', 'icon');
+                targetPath += highResIcon.suffix === '1x' ? 
highResIcon.extension : `@${highResIcon.suffix}${highResIcon.extension}`;
+                resourceMap.push(mapIconResources(cordovaProject.root, 
highResIcon.src, targetPath));
+            }
+            break;
+        }
+    }
+    return resourceMap;
+}
+
+/**
+ * Get a map containing resources of a specified name (or directory) to the 
target directory.
+ */
+function mapIconResources (rootDir, sourcePath, targetPath) {
+    let pathMap = {};
+    shell.ls(path.join(rootDir, sourcePath)).forEach(() => {
+        pathMap[sourcePath] = targetPath;
+    });
+    return pathMap;
+}
+
+/**
+ * Copy icons to the target destination according to the resource map.
+ */
+function copyIcons (rootDir, resourceMap) {
+    resourceMap.forEach(element => {
+        if (Object.keys(element).length) {
+            fs.copySync(path.join(rootDir, Object.keys(element)[0]), 
Object.values(element)[0]);
+        }
+    });
+}
diff --git a/bin/templates/project/main.js b/bin/templates/project/main.js
index d3f8b36..9312ece 100644
--- a/bin/templates/project/main.js
+++ b/bin/templates/project/main.js
@@ -17,11 +17,9 @@
     under the License.
 */
 
-const electron = require('electron');
-// Module to control application life.
-const app = electron.app;
-// Module to create native browser window.
-const BrowserWindow = electron.BrowserWindow;
+const fs = require('fs');
+// Module to control application life, browser window and tray.
+const { app, BrowserWindow } = require('electron');
 // Electron settings from .json file.
 const cdvElectronSettings = require('./cdv-electron-settings.json');
 
@@ -31,7 +29,20 @@ let mainWindow;
 
 function createWindow () {
     // Create the browser window.
-    mainWindow = new BrowserWindow({ width: 800, height: 600 });
+    let appIcon;
+    if (fs.existsSync(`${__dirname}/img/app.png`)) {
+        appIcon = `${__dirname}/img/app.png`;
+    } else if (fs.existsSync(`${__dirname}/img/icon.png`)) {
+        appIcon = `${__dirname}/img/icon.png`;
+    } else {
+        appIcon = `${__dirname}/img/logo.png`;
+    }
+
+    mainWindow = new BrowserWindow({
+        width: 800,
+        height: 600,
+        icon: appIcon
+    });
 
     // and load the index.html of the app.
     // TODO: possibly get this data from config.xml
diff --git a/bin/templates/project/www/icons/icon.png 
b/bin/templates/project/www/icons/icon.png
new file mode 100644
index 0000000..c9465f3
Binary files /dev/null and b/bin/templates/project/www/icons/icon.png differ
diff --git a/package.json b/package.json
index b194125..61c6e3d 100644
--- a/package.json
+++ b/package.json
@@ -40,6 +40,7 @@
     "eslint-plugin-standard": "^4.0.0",
     "jasmine": "^3.3.1",
     "nyc": "^13.1.0",
+    "rewire": "^4.0.1",
     "tmp": "^0.0.33"
   },
   "author": "Apache Software Foundation",
diff --git a/tests/spec/unit/templates/cordova/lib/prepare.spec.js 
b/tests/spec/unit/templates/cordova/lib/prepare.spec.js
new file mode 100644
index 0000000..0d8541e
--- /dev/null
+++ b/tests/spec/unit/templates/cordova/lib/prepare.spec.js
@@ -0,0 +1,893 @@
+/*
+    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.
+*/
+
+const rewire = require('rewire');
+const CordovaError = require('cordova-common').CordovaError;
+
+/**
+ * Create a mock item from the getIcon collection with the supplied updated 
data.
+ *
+ * @param {Object} data Changes to apply to the mock getIcon item
+ */
+function mockGetIconItem (data) {
+    return Object.assign({}, {
+        src: undefined,
+        target: undefined,
+        density: undefined,
+        platform: 'electron',
+        width: undefined,
+        height: undefined,
+        background: undefined,
+        foreground: undefined
+    }, data);
+}
+
+describe('Testing prepare.js:', () => {
+    let prepare;
+
+    // Spies
+    let emitSpy;
+    let updatePathsSpy;
+
+    let cordovaProject;
+    let locations;
+
+    beforeEach(() => {
+        prepare = 
rewire('../../../../../../bin/templates/cordova/lib/prepare');
+
+        cordovaProject = {
+            root: '/mock',
+            projectConfig: {
+                path: '/mock/config.xml',
+                cdvNamespacePrefix: 'cdv'
+            }
+        };
+
+        locations = {
+            buildRes: '/mock/build-res',
+            www: '/mock/www'
+        };
+
+        emitSpy = jasmine.createSpy('emit');
+        prepare.__set__('events', {
+            emit: emitSpy
+        });
+
+        updatePathsSpy = jasmine.createSpy('updatePaths');
+        prepare.__set__('FileUpdater', {
+            updatePaths: updatePathsSpy
+        });
+    });
+
+    describe('updateIcons method', () => {
+
+        it('should detect no defined icons.', () => {
+            const updateIcons = prepare.__get__('updateIcons');
+
+            cordovaProject.projectConfig.getIcons = () => {
+                return [];
+            };
+
+            updateIcons(cordovaProject, locations);
+
+            // The emit was called
+            expect(emitSpy).toHaveBeenCalled();
+
+            // The emit message was.
+            const actual = emitSpy.calls.argsFor(0)[1];
+            const expected = 'This app does not have icons defined';
+            expect(actual).toEqual(expected);
+        });
+
+        it('should update icons.', () => {
+            const updateIcons = prepare.__get__('updateIcons');
+
+            // create spies
+            const checkIconsAttributesSpy = 
jasmine.createSpy('checkIconsAttributes');
+            prepare.__set__('checkIconsAttributes', checkIconsAttributesSpy);
+            const prepareIconsSpy = jasmine.createSpy('prepareIcons');
+            prepare.__set__('prepareIcons', prepareIconsSpy);
+            const createResourceMapSpy = 
jasmine.createSpy('createResourceMap');
+            prepare.__set__('createResourceMap', createResourceMapSpy);
+            const copyIconsSpy = jasmine.createSpy('copyIcons');
+            prepare.__set__('copyIcons', copyIconsSpy);
+
+            cordovaProject.projectConfig.getIcons = () => {
+                const icon = mockGetIconItem({});
+                return [icon];
+            };
+
+            updateIcons(cordovaProject, locations);
+
+            // The emit was called
+            expect(emitSpy).toHaveBeenCalled();
+            expect(checkIconsAttributesSpy).toHaveBeenCalled();
+            expect(prepareIconsSpy).toHaveBeenCalled();
+            expect(createResourceMapSpy).toHaveBeenCalled();
+            expect(copyIconsSpy).toHaveBeenCalled();
+
+            // The emit message was.
+            const actual = emitSpy.calls.argsFor(0)[1];
+            const expected = 'Updating icons';
+            expect(actual).toEqual(expected);
+        });
+    });
+
+    describe('checkIconsAttributes method', () => {
+        let checkIconsAttributes;
+
+        beforeEach(() => {
+            checkIconsAttributes = prepare.__get__('checkIconsAttributes');
+        });
+
+        it('should detect icons with missing src and throw an error with 
size=undefined in message.', () => {
+            const icons = [
+                mockGetIconItem({
+                    src: ''
+                })
+            ];
+
+            expect(() => {
+                checkIconsAttributes(icons);
+            }).toThrow(
+                new CordovaError('One of the following attributes are set but 
missing the other for the target: size=undefined. Please ensure that all 
required attributes are defined.')
+            );
+        });
+
+        it('should detect icons with missing src, but defined size and throw 
an error with size in message.', () => {
+            const icons = [
+                mockGetIconItem({
+                    src: '',
+                    width: 512,
+                    height: 512
+                })
+            ];
+
+            expect(() => {
+                checkIconsAttributes(icons);
+            }).toThrow(
+                new CordovaError('One of the following attributes are set but 
missing the other for the target: size=512. Please ensure that all required 
attributes are defined.')
+            );
+        });
+
+        it('should detect icons with target set, but missing src and throw an 
error with target in message.', () => {
+            const icons = [
+                mockGetIconItem({
+                    src: '',
+                    target: 'installer'
+                })
+            ];
+
+            expect(() => {
+                checkIconsAttributes(icons);
+            }).toThrow(
+                new CordovaError('One of the following attributes are set but 
missing the other for the target: installer. Please ensure that all required 
attributes are defined.')
+            );
+        });
+
+        it('should detect icons with wrong size defined and throw an error 
with and sizes in message.', () => {
+            const icons = [
+                mockGetIconItem({
+                    src: 'res/electron/cordova_512.png',
+                    height: 512,
+                    width: 256
+                })
+            ];
+
+            expect(() => {
+                checkIconsAttributes(icons);
+            }).toThrow(
+                new CordovaError('Size of icon does not match required size 
given: width=256 height=512. Please ensure that .png icon for is at least 
512x512.')
+            );
+        });
+
+        it('should detect icons with wrong size defined for the installer and 
throw an error with target and sizes in message.', () => {
+            const icons = [
+                mockGetIconItem({
+                    src: 'res/electron/cordova_512.png',
+                    target: 'installer',
+                    height: 256,
+                    width: 256
+                })
+            ];
+
+            expect(() => {
+                checkIconsAttributes(icons);
+            }).toThrow(
+                new CordovaError('Size of icon does not match required size 
for target: installer. Please ensure that .png icon for is at least 512x512.')
+            );
+        });
+    });
+
+    describe('prepareIcons method', () => {
+        let prepareIcons;
+
+        beforeEach(() => {
+            prepareIcons = prepare.__get__('prepareIcons');
+        });
+
+        it('should return array of objects with custom icon, when there is 
only one icon in res folder.', () => {
+            const icons = mockGetIconItem({
+                src: 'res/logo.png',
+                platform: undefined
+            });
+
+            const actual = prepareIcons([icons]);
+            const expected = {
+                customIcon: Object.assign(icons, { extension: '.png' }),
+                appIcon: undefined,
+                installerIcon: undefined,
+                highResIcons: []
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with custom icon, when there is 
only one icon in res/electron folder.', () => {
+            const icons = mockGetIconItem({
+                src: 'res/electron/logo.png'
+            });
+
+            const actual = prepareIcons([icons]);
+            const expected = {
+                customIcon: Object.assign(icons, { extension: '.png' }),
+                appIcon: undefined,
+                installerIcon: undefined,
+                highResIcons: []
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with custom icons, when there is 
only one icon with correct width and height set.', () => {
+            const icons = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                width: 512,
+                height: 512
+            });
+
+            const actual = prepareIcons([icons]);
+            const expected = {
+                customIcon: Object.assign(icons, { extension: '.png' }),
+                appIcon: undefined,
+                installerIcon: undefined,
+                highResIcons: []
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with installer icon, when icon is 
defined for target=installer', () => {
+            const icons = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512
+            });
+
+            const actual = prepareIcons([icons]);
+            const expected = {
+                customIcon: undefined,
+                appIcon: undefined,
+                installerIcon: Object.assign(icons, { extension: '.png' }),
+                highResIcons: []
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with app and installer icon, when 
there is one icon with target=app and one with target=installer', () => {
+            const app = mockGetIconItem({
+                src: 'res/electron/cordova.png',
+                target: 'app',
+                width: 512,
+                height: 512
+            });
+            const installer = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512,
+                height: 512
+            });
+            const icons = [ app, installer ];
+
+            const actual = prepareIcons(icons);
+            const expected = {
+                customIcon: undefined,
+                appIcon: Object.assign(app, { extension: '.png' }),
+                installerIcon: Object.assign(installer, { extension: '.png' }),
+                highResIcons: []
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with app and installer icon, when 
there more one icon with target=app and more than one with target=installer', 
() => {
+            const app = mockGetIconItem({
+                src: 'res/electron/cordova.png',
+                target: 'app',
+                width: 512,
+                height: 512
+            });
+            const installer = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512,
+                height: 512
+            });
+            const installer2 = mockGetIconItem({
+                src: 'res/electron/cordova_512_extra.png',
+                target: 'installer',
+                width: 512,
+                height: 512
+            });
+            const icons = [ app, installer, installer2 ];
+
+            let actual = prepareIcons(icons);
+            let expected = {
+                customIcon: undefined,
+                appIcon: Object.assign(app, { extension: '.png' }),
+                installerIcon: Object.assign(installer2, { extension: '.png' 
}),
+                highResIcons: []
+            };
+
+            expect(expected).toEqual(actual);
+
+            // The emit was called
+            expect(emitSpy).toHaveBeenCalled();
+
+            // The emit message was.
+            actual = emitSpy.calls.argsFor(0)[1];
+            expected = 'Found extra icon for target installer: 
res/electron/cordova_512.png and ignoring in favor of 
res/electron/cordova_512_extra.png.';
+            expect(actual).toEqual(expected);
+        });
+
+        it('should return array of objects with high resolution icons, if they 
are defined', () => {
+            const highRes10 = mockGetIconItem({ src: 
'res/electron/cordova.png' });
+            const highRes15 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes20 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes40 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes80 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+
+            const icons = [ highRes10, highRes15, highRes20, highRes40, 
highRes80 ];
+
+            const actual = prepareIcons(icons);
+            const expected = {
+                customIcon: undefined,
+                appIcon: undefined,
+                installerIcon: undefined,
+                highResIcons: [
+                    Object.assign(highRes15, { suffix: '1.5x', extension: 
'.png' }),
+                    Object.assign(highRes20, { suffix: '2x', extension: '.png' 
}),
+                    Object.assign(highRes40, { suffix: '4x', extension: '.png' 
}),
+                    Object.assign(highRes80, { suffix: '8x', extension: '.png' 
}),
+                    Object.assign(highRes10, { suffix: '1x', extension: '.png' 
})
+                ]
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with high resolution icons, if they 
are defined and an extra icon with target=installer', () => {
+            const installer = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512,
+                height: 512
+            });
+            const highRes10 = mockGetIconItem({ src: 
'res/electron/cordova.png' });
+            const highRes15 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes20 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes40 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes80 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+
+            const icons = [ installer, highRes10, highRes15, highRes20, 
highRes40, highRes80 ];
+
+            const actual = prepareIcons(icons);
+            const expected = {
+                customIcon: undefined,
+                appIcon: undefined,
+                installerIcon: Object.assign(installer, { extension: '.png' }),
+                highResIcons: [
+                    Object.assign(highRes15, { suffix: '1.5x', extension: 
'.png' }),
+                    Object.assign(highRes20, { suffix: '2x', extension: '.png' 
}),
+                    Object.assign(highRes40, { suffix: '4x', extension: '.png' 
}),
+                    Object.assign(highRes80, { suffix: '8x', extension: '.png' 
}),
+                    Object.assign(highRes10, { suffix: '1x', extension: '.png' 
})
+                ]
+            };
+
+            expect(expected).toEqual(actual);
+        });
+    });
+
+    describe('findHighResIcons', () => {
+        let findHighResIcons;
+
+        beforeEach(() => {
+            findHighResIcons = prepare.__get__('findHighResIcons');
+        });
+
+        it('should return array of objects with remaining icons, when there is 
only one icon in res folder.', () => {
+            const icons = mockGetIconItem({
+                src: 'res/logo.png',
+                platform: undefined
+            });
+
+            const actual = findHighResIcons([icons]);
+            const expected = {
+                highResIcons: [],
+                remainingIcons: [icons]
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with remaining icons, when there is 
only one icon in res/electron folder.', () => {
+            const icons = mockGetIconItem({
+                src: 'res/electron/logo.png'
+            });
+
+            const actual = findHighResIcons([icons]);
+            const expected = {
+                highResIcons: [],
+                remainingIcons: [icons]
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with remaining icon, when there is 
only one icon with correct width and height set.', () => {
+            const icons = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                width: 512,
+                height: 512
+            });
+
+            const actual = findHighResIcons([icons]);
+            const expected = {
+                highResIcons: [],
+                remainingIcons: [icons]
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with remaining icon, when icon is 
defined for target=installer', () => {
+            const icons = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512
+            });
+
+            const actual = findHighResIcons([icons]);
+            const expected = {
+                highResIcons: [],
+                remainingIcons: [icons]
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with app and installer icon, when 
there is one icon with target=app and one with target=installer', () => {
+            const app = mockGetIconItem({
+                src: 'res/electron/cordova.png',
+                target: 'app',
+                width: 512,
+                height: 512
+            });
+            const installer = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512,
+                height: 512
+            });
+            const icons = [ app, installer ];
+
+            const actual = findHighResIcons(icons);
+            const expected = {
+                highResIcons: [],
+                remainingIcons: icons
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return remainingIcons array of objects with app and 
installer icon, when there more one icon with target=app and more than one with 
target=installer', () => {
+            const app = mockGetIconItem({
+                src: 'res/electron/cordova.png',
+                target: 'app',
+                width: 512,
+                height: 512
+            });
+            const installer = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512,
+                height: 512
+            });
+            const installer2 = mockGetIconItem({
+                src: 'res/electron/cordova_512_extra.png',
+                target: 'installer',
+                width: 512,
+                height: 512
+            });
+            const icons = [ app, installer, installer2 ];
+
+            const actual = findHighResIcons(icons);
+            const expected = {
+                highResIcons: [],
+                remainingIcons: icons
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should throw Cordova Error when there is no base icon', () => {
+            const highRes15 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes20 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes40 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes80 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+
+            const icons = [ highRes15, highRes20, highRes40, highRes80 ];
+
+            expect(() => {
+                findHighResIcons(icons);
+            }).toThrow(
+                new CordovaError('Base icon for high resolution images was not 
found.')
+            );
+        });
+
+        it('should return array of objects with high resolution icons, if they 
are defined', () => {
+            const highRes10 = mockGetIconItem({ src: 
'res/electron/cordova.png' });
+            const highRes15 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes20 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes40 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes80 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+
+            const icons = [ highRes10, highRes15, highRes20, highRes40, 
highRes80 ];
+
+            const actual = findHighResIcons(icons);
+            const expected = {
+                highResIcons: [
+                    Object.assign(highRes15, { suffix: '1.5x', extension: 
'.png' }),
+                    Object.assign(highRes20, { suffix: '2x', extension: '.png' 
}),
+                    Object.assign(highRes40, { suffix: '4x', extension: '.png' 
}),
+                    Object.assign(highRes80, { suffix: '8x', extension: '.png' 
}),
+                    Object.assign(highRes10, { suffix: '1x', extension: '.png' 
})
+                ],
+                remainingIcons: []
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with high resolution icons, if they 
are defined and an extra icon with target=installer', () => {
+            const installer = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512,
+                height: 512
+            });
+            const highRes10 = mockGetIconItem({ src: 
'res/electron/cordova.png' });
+            const highRes15 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes20 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes40 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes80 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+
+            const icons = [ installer, highRes10, highRes15, highRes20, 
highRes40, highRes80 ];
+
+            const actual = findHighResIcons(icons);
+            const expected = {
+                highResIcons: [
+                    Object.assign(highRes15, { suffix: '1.5x', extension: 
'.png' }),
+                    Object.assign(highRes20, { suffix: '2x', extension: '.png' 
}),
+                    Object.assign(highRes40, { suffix: '4x', extension: '.png' 
}),
+                    Object.assign(highRes80, { suffix: '8x', extension: '.png' 
}),
+                    Object.assign(highRes10, { suffix: '1x', extension: '.png' 
})
+                ],
+                remainingIcons: [installer]
+            };
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should return array of objects with high resolution icons, if they 
are defined and remaining icon with target=installer', () => {
+            const highRes10 = mockGetIconItem({ src: 
'res/electron/cordova.png' });
+            const highRes15 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes20 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes40 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes80 = mockGetIconItem({ src: 
'res/electron/[email protected]', target: 'installer' });
+
+            const icons = [ highRes10, highRes15, highRes20, highRes40, 
highRes80 ];
+
+            const actual = findHighResIcons(icons);
+            const expected = {
+                highResIcons: [
+                    Object.assign(highRes15, { suffix: '1.5x', extension: 
'.png' }),
+                    Object.assign(highRes20, { suffix: '2x', extension: '.png' 
}),
+                    Object.assign(highRes40, { suffix: '4x', extension: '.png' 
}),
+                    Object.assign(highRes80, { suffix: '8x', extension: '.png' 
}),
+                    Object.assign(highRes10, { suffix: '1x', extension: '.png' 
})
+                ],
+                remainingIcons: [Object.assign(highRes80, { suffix: '8x', 
extension: '.png' })]
+            };
+
+            expect(expected).toEqual(actual);
+        });
+    });
+
+    describe('createResourceMap method', () => {
+        let createResourceMap;
+        let shellLsSpy;
+
+        beforeEach(() => {
+            createResourceMap = prepare.__get__('createResourceMap');
+            shellLsSpy = prepare.__get__('mapIconResources');
+
+            shellLsSpy = jasmine.createSpy('ls').and.returnValue([true]);
+            prepare.__set__('shell', { ls: shellLsSpy });
+        });
+
+        it('should map custom icon to installer and app icon locations', () => 
{
+
+            const icon = mockGetIconItem({
+                src: 'res/logo.png',
+                platform: undefined
+            });
+            let data = {
+                customIcon: Object.assign(icon, { extension: '.png' }),
+                appIcon: undefined,
+                installerIcon: undefined,
+                highResIcons: []
+            };
+
+            const actual = createResourceMap(cordovaProject, locations, data);
+
+            expect(shellLsSpy).toHaveBeenCalled();
+
+            const expected = [
+                { 'res/logo.png': '/mock/www/img/app.png' },
+                { 'res/logo.png': '/mock/build-res/installer.png' }
+            ];
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should map installer icon to appoporiate location', () => {
+            const icons = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512
+            });
+            const data = {
+                customIcon: undefined,
+                appIcon: undefined,
+                installerIcon: Object.assign(icons, { extension: '.png' }),
+                highResIcons: []
+            };
+
+            const actual = createResourceMap(cordovaProject, locations, data);
+
+            expect(shellLsSpy).toHaveBeenCalled();
+
+            const expected = [
+                { 'res/electron/cordova_512.png': 
'/mock/build-res/installer.png' }
+            ];
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should map installer and app icon to appoporiate location', () => {
+            const app = mockGetIconItem({
+                src: 'res/electron/cordova.png',
+                target: 'app',
+                width: 512,
+                height: 512
+            });
+            const installer = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512,
+                height: 512
+            });
+            const data = {
+                customIcon: undefined,
+                appIcon: Object.assign(app, { extension: '.png' }),
+                installerIcon: Object.assign(installer, { extension: '.png' }),
+                highResIcons: []
+            };
+
+            const actual = createResourceMap(cordovaProject, locations, data);
+
+            expect(shellLsSpy).toHaveBeenCalled();
+
+            const expected = [
+                { 'res/electron/cordova.png': '/mock/www/img/app.png' },
+                { 'res/electron/cordova_512.png': 
'/mock/build-res/installer.png' }
+            ];
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should map high resolution icons to appoporiate location', () => {
+            const highRes10 = mockGetIconItem({ src: 
'res/electron/cordova.png' });
+            const highRes15 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes20 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes40 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes80 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+
+            const data = {
+                customIcon: undefined,
+                appIcon: undefined,
+                installerIcon: undefined,
+                highResIcons: [
+                    Object.assign(highRes15, { suffix: '1.5x', extension: 
'.png' }),
+                    Object.assign(highRes20, { suffix: '2x', extension: '.png' 
}),
+                    Object.assign(highRes40, { suffix: '4x', extension: '.png' 
}),
+                    Object.assign(highRes80, { suffix: '8x', extension: '.png' 
}),
+                    Object.assign(highRes10, { suffix: '1x', extension: '.png' 
})
+                ]
+            };
+
+            const actual = createResourceMap(cordovaProject, locations, data);
+
+            expect(shellLsSpy).toHaveBeenCalled();
+
+            const expected = [
+                { 'res/electron/[email protected]': 
'/mock/www/img/[email protected]' },
+                { 'res/electron/[email protected]': '/mock/www/img/[email protected]' },
+                { 'res/electron/[email protected]': '/mock/www/img/[email protected]' },
+                { 'res/electron/[email protected]': '/mock/www/img/[email protected]' },
+                { 'res/electron/cordova.png': '/mock/www/img/icon.png' }
+            ];
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should map high resolution icons and installer icon to appoporiate 
location', () => {
+            const installer = mockGetIconItem({
+                src: 'res/electron/cordova_512.png',
+                target: 'installer',
+                width: 512,
+                height: 512
+            });
+            const highRes10 = mockGetIconItem({ src: 
'res/electron/cordova.png' });
+            const highRes15 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes20 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes40 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+            const highRes80 = mockGetIconItem({ src: 
'res/electron/[email protected]' });
+
+            const data = {
+                customIcon: undefined,
+                appIcon: undefined,
+                installerIcon: Object.assign(installer, { extension: '.png' }),
+                highResIcons: [
+                    Object.assign(highRes15, { suffix: '1.5x', extension: 
'.png' }),
+                    Object.assign(highRes20, { suffix: '2x', extension: '.png' 
}),
+                    Object.assign(highRes40, { suffix: '4x', extension: '.png' 
}),
+                    Object.assign(highRes80, { suffix: '8x', extension: '.png' 
}),
+                    Object.assign(highRes10, { suffix: '1x', extension: '.png' 
})
+                ]
+            };
+
+            const actual = createResourceMap(cordovaProject, locations, data);
+
+            expect(shellLsSpy).toHaveBeenCalled();
+
+            const expected = [
+                { 'res/electron/cordova_512.png': 
'/mock/build-res/installer.png' },
+                { 'res/electron/[email protected]': 
'/mock/www/img/[email protected]' },
+                { 'res/electron/[email protected]': '/mock/www/img/[email protected]' },
+                { 'res/electron/[email protected]': '/mock/www/img/[email protected]' },
+                { 'res/electron/[email protected]': '/mock/www/img/[email protected]' },
+                { 'res/electron/cordova.png': '/mock/www/img/icon.png' }
+            ];
+
+            expect(expected).toEqual(actual);
+        });
+
+    });
+
+    describe('mapIconResources method', () => {
+        let mapIconResources;
+        let shellLsSpy;
+
+        beforeEach(() => {
+            mapIconResources = prepare.__get__('mapIconResources');
+            shellLsSpy = prepare.__get__('mapIconResources');
+
+            shellLsSpy = jasmine.createSpy('ls').and.returnValue([true]);
+            prepare.__set__('shell', { ls: shellLsSpy });
+        });
+
+        it('should not be called if resource does not exist.', () => {
+            mapIconResources(cordovaProject.root, '', '');
+
+            shellLsSpy = jasmine.createSpy('ls').and.returnValue([false]);
+            prepare.__set__('shell', { ls: shellLsSpy });
+
+            expect(shellLsSpy).not.toHaveBeenCalled();
+        });
+
+        it('should map to file to file', () => {
+            const sourcePath = 
`${cordovaProject.root}/res/electron/cordova_512.png`;
+            const targetPath = `${cordovaProject.root}/www/img/icon.png`;
+
+            const expected = {};
+            expected[sourcePath] = targetPath;
+
+            const actual = mapIconResources(cordovaProject.root, sourcePath, 
targetPath);
+
+            expect(shellLsSpy).toHaveBeenCalled();
+
+            expect(expected).toEqual(actual);
+        });
+
+        it('should map to folder to folder', () => {
+            const sourcePath = `${cordovaProject.root}/res/electron/`;
+            const targetPath = `${cordovaProject.root}/www/img/`;
+
+            const expected = {};
+            expected[sourcePath] = targetPath;
+
+            const actual = mapIconResources(cordovaProject.root, sourcePath, 
targetPath);
+
+            expect(shellLsSpy).toHaveBeenCalled();
+
+            expect(expected).toEqual(actual);
+        });
+
+    });
+
+    describe('copyIcons method', () => {
+        let copyIcons;
+        let fsCopySyncSpy;
+
+        beforeEach(() => {
+            copyIcons = prepare.__get__('copyIcons');
+
+            fsCopySyncSpy = jasmine.createSpy('copySync');
+            prepare.__set__('fs', { copySync: fsCopySyncSpy });
+        });
+
+        it('should not copy as no resources provided.', () => {
+            copyIcons(cordovaProject.root, []);
+            expect(fsCopySyncSpy).not.toHaveBeenCalled();
+        });
+
+        it('should copy provided resources.', () => {
+            copyIcons(cordovaProject.root, [
+                { 'res/electron/cordova_512.png': 
`${cordovaProject.root}/build-res/installer.png` },
+                { 'res/electron/cordova.png': 
`${cordovaProject.root}/www/img/icon.png` }
+            ]);
+
+            expect(fsCopySyncSpy).toHaveBeenCalled();
+
+            const installerIconSrcPathTest = fsCopySyncSpy.calls.argsFor(0)[0];
+            const installerIconDestPathTest = 
fsCopySyncSpy.calls.argsFor(0)[1];
+            
expect(installerIconSrcPathTest).toBe(`${cordovaProject.root}/res/electron/cordova_512.png`);
+            
expect(installerIconDestPathTest).toBe(`${cordovaProject.root}/build-res/installer.png`);
+
+            const appIconSrcPathTest = fsCopySyncSpy.calls.argsFor(1)[0];
+            const appIconDestPathTest = fsCopySyncSpy.calls.argsFor(1)[1];
+            
expect(appIconSrcPathTest).toBe(`${cordovaProject.root}/res/electron/cordova.png`);
+            
expect(appIconDestPathTest).toBe(`${cordovaProject.root}/www/img/icon.png`);
+        });
+    });
+});


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to