Repository: cordova-windows
Updated Branches:
  refs/heads/master a4c673e30 -> 10594681c


CB-10622 Support any MRT qualifiers for Windows icons

This closes #159, closes #162, closes #149


Project: http://git-wip-us.apache.org/repos/asf/cordova-windows/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-windows/commit/10594681
Tree: http://git-wip-us.apache.org/repos/asf/cordova-windows/tree/10594681
Diff: http://git-wip-us.apache.org/repos/asf/cordova-windows/diff/10594681

Branch: refs/heads/master
Commit: 10594681c9331f2be9bfd30d54a0c170e36a84f3
Parents: a4c673e
Author: Vladimir Kotikov <kotikov.vladi...@gmail.com>
Authored: Mon Mar 14 15:24:15 2016 +0300
Committer: Vladimir Kotikov <kotikov.vladi...@gmail.com>
Committed: Tue Mar 29 09:54:44 2016 +0300

----------------------------------------------------------------------
 spec/unit/MRTImage.spec.js       | 70 ++++++++++++++++++++++++++++++
 spec/unit/Prepare.Win10.spec.js  | 80 ++++++++++++++++++++++++++++++++++-
 template/cordova/lib/MRTImage.js | 65 ++++++++++++++++++++++++++++
 template/cordova/lib/prepare.js  | 37 +++++++---------
 4 files changed, 229 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/10594681/spec/unit/MRTImage.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/MRTImage.spec.js b/spec/unit/MRTImage.spec.js
new file mode 100644
index 0000000..4f27df0
--- /dev/null
+++ b/spec/unit/MRTImage.spec.js
@@ -0,0 +1,70 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var MRTImage = require('../../template/cordova/lib/MRTImage');
+
+describe('MRTImage class', function () {
+
+    it('should be constructable', function () {
+        expect(new MRTImage('some/path/Image.scale-240.png')).toBeDefined();
+    });
+
+    it('should detect base name and qualifiers properly', function () {
+        expect(new 
MRTImage('some/path/Image.scale-240.png').basename).toBe('Image');
+        expect(new 
MRTImage('some/path/Basename.with.dots.scale-240.png').basename).toBe('Basename.with.dots');
+        expect(new 
MRTImage('some/path/Basename.with.dots.png').basename).toBe('Basename.with');
+
+        expect(new 
MRTImage('some/path/Image.png').qualifiers).toBe('scale-100');
+        expect(new 
MRTImage('some/path/Image.scale-240.png').qualifiers).toBe('scale-240');
+        expect(new 
MRTImage('some/path/Image.targetsize-20_altform-unplated.png').qualifiers).toBe('targetsize-20_altform-unplated');
+    });
+
+    describe('matchesTo method', function () {
+        it('should compare MRTImage instances properly', function () {
+            var testImage = new MRTImage('some/path/Basename.scale-240.png');
+
+            expect(new 
MRTImage('some/path/Basename.png').matchesTo(testImage)).toBe(true);
+            expect(new 
MRTImage('some/path/Basename.scale-240.png').matchesTo(testImage)).toBe(true);
+            expect(new 
MRTImage('some/path/Basename.targetsize-20_scale-240.png').matchesTo(testImage)).toBe(true);
+
+            expect(new MRTImage(testImage).matchesTo('')).toBe(false);
+            expect(new MRTImage(testImage).matchesTo({})).toBe(false);
+            expect(new MRTImage(testImage).matchesTo(undefined)).toBe(false);
+
+            expect(new 
MRTImage('some/path/Basename.jpg').matchesTo(testImage)).toBe(false);
+            expect(new 
MRTImage('some/path/Basename.with.dots.scale-240.png').matchesTo(testImage)).toBe(false);
+        });
+    });
+
+    describe('generateFilenameFrom method', function () {
+        it('should use baseName argument to construct new filename', function 
() {
+            var testImage = new MRTImage('some/path/Basename.scale-240.png');
+
+            
expect(testImage.generateFilenameFrom('NewName')).toMatch(/^NewName(.*)\.png/);
+            
expect(testImage.generateFilenameFrom('NewName')).not.toMatch(/Basename/);
+        });
+
+        it('should leave qualifiers unchanged', function () {
+            var testImage = new MRTImage('some/path/Basename.scale-240.png');
+
+            
expect(testImage.generateFilenameFrom('NewName')).toMatch(/\.scale-240\.png$/);
+            
expect(testImage.generateFilenameFrom('NewName.with.dots-and-dashes')).toMatch(/\.scale-240\.png$/);
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/10594681/spec/unit/Prepare.Win10.spec.js
----------------------------------------------------------------------
diff --git a/spec/unit/Prepare.Win10.spec.js b/spec/unit/Prepare.Win10.spec.js
index b0d671d..074c3a5 100644
--- a/spec/unit/Prepare.Win10.spec.js
+++ b/spec/unit/Prepare.Win10.spec.js
@@ -17,6 +17,9 @@
     under the License.
 */
 
+var path = require('path');
+var shell = require('shelljs');
+
 var rewire  = require('rewire'),
     prepare = rewire('../../template/cordova/lib/prepare'),
     AppxManifest = require('../../template/cordova/lib/AppxManifest'),
@@ -382,7 +385,6 @@ describe('A Windows 10 project should apply the uap: 
namespace prefix to certain
     });
 });
 
-
 function createMockConfigAndManifestForDescription(description) {
     var config = {
         version: function() { return '1.0.0.0'; },
@@ -453,3 +455,79 @@ describe('Package description', function () {
         expect(desc.attrib.Description).not.toMatch(/\n|\t/);
     });
 });
+
+describe('copyIcons method', function () {
+    var copyImages = prepare.__get__('copyImages');
+
+    var PROJECT = '/some/path';
+
+    function createMockConfig(images) {
+        var result = jasmine.createSpyObj('config', ['getIcons', 
'getSplashScreens']);
+        result.getIcons.andReturn(images);
+        result.getSplashScreens.andReturn([]);
+
+        return result;
+    }
+
+    beforeEach(function () {
+        spyOn(shell, 'cp');
+    });
+
+    it('should guess target filename based on icon size', function () {
+        var images = [
+            {src: 'res/Windows/Square44x44Logo_100.png', width: '44', height: 
'44' },
+            {src: 'res/Windows/Square44x44Logo_240.png', width: '106', height: 
'106' }
+        ];
+
+        var config = createMockConfig(images);
+
+        copyImages(config, PROJECT);
+
+        expect(shell.cp).toHaveBeenCalledWith('-f', 
path.normalize('res/Windows/Square44x44Logo_100.png'), path.join(PROJECT, 
'images/Square44x44Logo.scale-100.png'));
+        expect(shell.cp).toHaveBeenCalledWith('-f', 
path.normalize('res/Windows/Square44x44Logo_240.png'), path.join(PROJECT, 
'images/Square44x44Logo.scale-240.png'));
+    });
+
+    it('should ignore unknown icon sizes and emit a warning', function () {
+        var config = createMockConfig([
+            {src: 'res/Windows/UnknownImage.png', width: '999', height: '999' 
},
+        ]);
+
+        var warnSpy = jasmine.createSpy('warn');
+        events.on('warn', warnSpy);
+        copyImages(config, PROJECT);
+        expect(shell.cp).not.toHaveBeenCalled();
+        expect(warnSpy.calls[0].args[0]).toMatch('image is skipped');
+    });
+
+    describe('when "target" attribute is specified for the image', function () 
{
+        it('should copy all images with the same base name and extension to 
destination dir', function () {
+            var matchingFiles = [
+                'res/Windows/Square44x44.scale-100.png',
+                'res/Windows/Square44x44.targetsize-16.png',
+                'res/Windows/Square44x44.scale-150_targetsize-16.png',
+                'res/Windows/Square44x44.targetsize-16_scale-200.png',
+                
'res/Windows/Square44x44.targetsize-16_altform-unplated_scale-200.png'
+            ];
+
+            var nonMatchingFiles = [
+                'res/Windows/Square55x55.scale-100.png',
+                'res/Windows/Square44x44.targetsize-16.jpg'
+            ];
+
+            spyOn(fs, 
'readdirSync').andReturn(matchingFiles.concat(nonMatchingFiles));
+
+            var images = [{src: 'res/Windows/Square44x44.png', target: 
'SmallIcon' }];
+            var config = createMockConfig(images);
+
+            copyImages(config, PROJECT);
+
+            expect(shell.cp.calls.length).toBe(5);
+            matchingFiles.forEach(function (filename) {
+                expect(shell.cp).toHaveBeenCalledWith('-f', 
path.normalize(filename), jasmine.any(String));
+            });
+            shell.cp.calls.forEach(function (call) {
+                
expect(path.basename(call.args[2])).toMatch(/^SmallIcon.*\.png$/);
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/10594681/template/cordova/lib/MRTImage.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/MRTImage.js b/template/cordova/lib/MRTImage.js
new file mode 100644
index 0000000..822ece9
--- /dev/null
+++ b/template/cordova/lib/MRTImage.js
@@ -0,0 +1,65 @@
+/**
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+*/
+
+var path = require('path');
+
+function MRTImage(filePath) {
+    this.path = filePath;
+    this.location = path.dirname(filePath);
+    this.extension = path.extname(filePath);
+    this.basename = path.basename(filePath, this.extension);
+    // 'scale-100' is the default qualifier
+    this.qualifiers = 'scale-100';
+
+    var nameParts = this.basename.split('.');
+    if (nameParts.length > 1) {
+        // Qualifiers is the dotted segment in the file just before the file 
extension
+        // If no such segment in filename, then qualifiers is empty string
+        this.qualifiers = nameParts[nameParts.length - 1];
+        // Basename it everything before that segment
+        this.basename = nameParts.slice(0, -1).join('.');
+    }
+}
+
+/**
+ * Indicates whether the current instance is matches to another one
+ *     (base names and extensions are equal)
+ *
+ * @param {MRTImage} anotherImage Another instance of MRTImage class.
+ * @returns {Boolean} True if the current instance is matches to another one
+ */
+MRTImage.prototype.matchesTo = function (anotherImage) {
+    return anotherImage instanceof MRTImage &&
+        anotherImage.basename === this.basename &&
+        anotherImage.extension === this.extension;
+};
+
+/**
+ * Generates a new filename based on new base name for the file. for example
+ *     new 
MRTImage('myFileName.scale-400.png').replaceBaseName('otherFileName')
+ *            -> 'otherFileName.scale-400.png'
+ *
+ * @param {String} baseName A new base name to use
+ * @returns {String} A new filename
+ */
+MRTImage.prototype.generateFilenameFrom = function (baseName) {
+    return [baseName, this.qualifiers].join('.') + this.extension;
+};
+
+module.exports = MRTImage;

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/10594681/template/cordova/lib/prepare.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/prepare.js b/template/cordova/lib/prepare.js
index e8e04fc..f2d560c 100644
--- a/template/cordova/lib/prepare.js
+++ b/template/cordova/lib/prepare.js
@@ -23,6 +23,7 @@ var path = require('path');
 var shell = require('shelljs');
 var et = require('elementtree');
 var Version = require('./Version');
+var MRTImage = require('./MRTImage');
 var AppxManifest = require('./AppxManifest');
 var MSBuildTools = require('./MSBuildTools');
 var ConfigParser = require('./ConfigParser');
@@ -303,30 +304,22 @@ function copyImages(config, platformRoot) {
     }
 
     function copyMrtImage(src, dest) {
-        var srcDir = path.dirname(src),
-            srcExt = path.extname(src),
-            srcFileName = path.basename(src, srcExt);
+        // Parse source path into new MRTImage
+        var imageToCopy = new MRTImage(src);
 
-        var destExt = path.extname(dest),
-            destFileName = path.basename(dest, destExt);
+        // then get all matching MRT images in source directory
+        var candidates = fs.readdirSync(imageToCopy.location)
+        .map(function (file) { return new MRTImage(file); })
+        .filter(imageToCopy.matchesTo, imageToCopy);
 
-        // all MRT images: logo.png, logo.scale-100.png, logo.scale-200.png, 
etc
-        var images = fs.readdirSync(srcDir).filter(function(e) {
-            return e.match('^'+srcFileName + '(.scale-[0-9]+)?' + srcExt);
-        });
-        // warn if no images found
-        if (images.length === 0) {
-            events.emit('warn', 'No images found for target: ' + destFileName);
-            return;
-        }
-        // copy images with new name but keeping scale suffix
-        images.forEach(function(img) {
-            var scale = path.extname(path.basename(img, srcExt));
-            if (scale === '') {
-                scale = '.scale-100';
-            }
-            copyImage(path.join(srcDir, img), destFileName+scale+destExt);
+        candidates.forEach(function(mrtImage) {
+            // copy images with new base name but keeping qualifier
+            copyImage(mrtImage.path, mrtImage.generateFilenameFrom(dest));
         });
+
+        // Warn user if no images were copied
+        if (candidates.length === 0)
+            events.emit('warn', 'No images found for target: ' + dest);
     }
 
     // Platform default images
@@ -371,7 +364,7 @@ function copyImages(config, platformRoot) {
 
     images.forEach(function (img) {
         if (img.target) {
-            copyMrtImage(img.src, img.target + '.png');
+            copyMrtImage(img.src, img.target);
         } else {
             // find target image by size
             var targetImg = findPlatformImage (img.width, img.height);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cordova.apache.org
For additional commands, e-mail: commits-h...@cordova.apache.org

Reply via email to