1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/test/test-clipboard.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,222 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +"use strict"; 1.8 + 1.9 +require("sdk/clipboard"); 1.10 + 1.11 +const { Cc, Ci } = require("chrome"); 1.12 + 1.13 +const imageTools = Cc["@mozilla.org/image/tools;1"]. 1.14 + getService(Ci.imgITools); 1.15 + 1.16 +const io = Cc["@mozilla.org/network/io-service;1"]. 1.17 + getService(Ci.nsIIOService); 1.18 + 1.19 +const base64png = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYA" + 1.20 + "AABzenr0AAAASUlEQVRYhe3O0QkAIAwD0eyqe3Q993AQ3cBSUKpygfsNTy" + 1.21 + "N5ugbQpK0BAADgP0BRDWXWlwEAAAAAgPsA3rzDaAAAAHgPcGrpgAnzQ2FG" + 1.22 + "bWRR9AAAAABJRU5ErkJggg%3D%3D"; 1.23 + 1.24 +const base64jpeg = "data:image/jpeg;base64,%2F9j%2F4AAQSkZJRgABAQAAAQABAAD%2F" + 1.25 + "2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCg" + 1.26 + "sOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD%2F2wBDAQMDAwQDBAgEBAgQCw" + 1.27 + "kLEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ" + 1.28 + "EBAQEBAQEBD%2FwAARCAAgACADAREAAhEBAxEB%2F8QAHwAAAQUBAQEBAQ" + 1.29 + "EAAAAAAAAAAAECAwQFBgcICQoL%2F8QAtRAAAgEDAwIEAwUFBAQAAAF9AQ" + 1.30 + "IDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRol" + 1.31 + "JicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eX" + 1.32 + "qDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJ" + 1.33 + "ytLT1NXW19jZ2uHi4%2BTl5ufo6erx8vP09fb3%2BPn6%2F8QAHwEAAwEB" + 1.34 + "AQEBAQEBAQAAAAAAAAECAwQFBgcICQoL%2F8QAtREAAgECBAQDBAcFBAQA" + 1.35 + "AQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNO" + 1.36 + "El8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0" + 1.37 + "dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6ws" + 1.38 + "PExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3%2BPn6%2F9oADAMB" + 1.39 + "AAIRAxEAPwD5Kr8kP9CwoA5f4m%2F8iRqX%2FbH%2FANHJXr5F%2FwAjCn" + 1.40 + "8%2F%2FSWfnnir%2FwAkji%2F%2B4f8A6dgeD1%2BiH8bn1BX5If6FmFqW" + 1.41 + "pXtveyQwzbUXGBtB7D2r9l4U4UyjMsoo4rFUeacua75pLaUktFJLZH5NxN" + 1.42 + "xNmmX5pVw2Gq8sI8tlyxe8U3q03uzD8S3dxqOi3NneSeZDJs3LgDOHBHI5" + 1.43 + "6gV%2BkcG%2BH%2FDmJzuhSq4e8XzfbqfyS%2FvH5rx1xTm2MyDEUa1W8X" + 1.44 + "yXXLFbTi%2BkThv7B0r%2FAJ9f%2FH2%2Fxr90%2FwCIVcI%2F9An%2FAJ" + 1.45 + "Uq%2FwDyZ%2FO%2F16v%2FADfgv8j0r%2FhZvgj%2FAKDf%2FktN%2FwDE" + 1.46 + "V%2Fnr%2FYWYf8%2B%2Fxj%2Fmf3R%2FxFXhH%2FoL%2FwDKdX%2F5Azrv" + 1.47 + "xLouo3D3lne%2BZDJja3luM4GDwRnqDX9LeH%2FBud4nhzD1aVC8Xz%2Fa" + 1.48 + "h%2Fz8l%2FePx%2FinjrIMZm1WtRxF4vls%2BSa2jFdYlDUdRsp7OSKKbc" + 1.49 + "7YwNpHce1fqfCvCub5bm9HFYqjywjzXfNF7xklopN7s%2BC4l4lyvMMrq4" + 1.50 + "fD1bzfLZcsltJPqktkYlfsZ%2BUnBV%2FnufVnXaD%2FAMgqD%2FgX%2Fo" + 1.51 + "Rr%2BxvCr%2FkkcJ%2F3E%2F8ATsz5%2FHfx5fL8kX6%2FQjkCgD%2F%2F" + 1.52 + "2Q%3D%3D"; 1.53 + 1.54 +const canvasHTML = "data:text/html," + encodeURIComponent( 1.55 + "<html>\ 1.56 + <body>\ 1.57 + <canvas width='32' height='32'></canvas>\ 1.58 + </body>\ 1.59 + </html>" 1.60 +); 1.61 + 1.62 +function comparePixelImages(imageA, imageB, callback) { 1.63 + let tabs = require("sdk/tabs"); 1.64 + 1.65 + tabs.open({ 1.66 + url: canvasHTML, 1.67 + 1.68 + onReady: function onReady(tab) { 1.69 + let worker = tab.attach({ 1.70 + contentScript: "new " + function() { 1.71 + let canvas = document.querySelector("canvas"); 1.72 + let context = canvas.getContext("2d"); 1.73 + 1.74 + self.port.on("draw-image", function(imageURI) { 1.75 + let img = new Image(); 1.76 + 1.77 + img.onload = function() { 1.78 + context.drawImage(this, 0, 0); 1.79 + 1.80 + let pixels = Array.join(context.getImageData(0, 0, 32, 32).data); 1.81 + self.port.emit("image-pixels", pixels); 1.82 + } 1.83 + 1.84 + img.src = imageURI; 1.85 + }); 1.86 + } 1.87 + }); 1.88 + 1.89 + let compared = ""; 1.90 + 1.91 + worker.port.on("image-pixels", function (pixels) { 1.92 + if (!compared) { 1.93 + compared = pixels; 1.94 + this.emit("draw-image", imageB); 1.95 + } else { 1.96 + callback(compared === pixels); 1.97 + tab.close() 1.98 + } 1.99 + }); 1.100 + 1.101 + worker.port.emit("draw-image", imageA); 1.102 + } 1.103 + }); 1.104 +} 1.105 + 1.106 + 1.107 +// Test the typical use case, setting & getting with no flavors specified 1.108 +exports["test With No Flavor"] = function(assert) { 1.109 + var contents = "hello there"; 1.110 + var flavor = "text"; 1.111 + var fullFlavor = "text/unicode"; 1.112 + var clip = require("sdk/clipboard"); 1.113 + 1.114 + // Confirm we set the clipboard 1.115 + assert.ok(clip.set(contents)); 1.116 + 1.117 + // Confirm flavor is set 1.118 + assert.equal(clip.currentFlavors[0], flavor); 1.119 + 1.120 + // Confirm we set the clipboard 1.121 + assert.equal(clip.get(), contents); 1.122 + 1.123 + // Confirm we can get the clipboard using the flavor 1.124 + assert.equal(clip.get(flavor), contents); 1.125 + 1.126 + // Confirm we can still get the clipboard using the full flavor 1.127 + assert.equal(clip.get(fullFlavor), contents); 1.128 +}; 1.129 + 1.130 +// Test the slightly less common case where we specify the flavor 1.131 +exports["test With Flavor"] = function(assert) { 1.132 + var contents = "<b>hello there</b>"; 1.133 + var contentsText = "hello there"; 1.134 + var flavor = "html"; 1.135 + var fullFlavor = "text/html"; 1.136 + var unicodeFlavor = "text"; 1.137 + var unicodeFullFlavor = "text/unicode"; 1.138 + var clip = require("sdk/clipboard"); 1.139 + 1.140 + assert.ok(clip.set(contents, flavor)); 1.141 + 1.142 + assert.equal(clip.currentFlavors[0], unicodeFlavor); 1.143 + assert.equal(clip.currentFlavors[1], flavor); 1.144 + assert.equal(clip.get(), contentsText); 1.145 + assert.equal(clip.get(flavor), contents); 1.146 + assert.equal(clip.get(fullFlavor), contents); 1.147 + assert.equal(clip.get(unicodeFlavor), contentsText); 1.148 + assert.equal(clip.get(unicodeFullFlavor), contentsText); 1.149 +}; 1.150 + 1.151 +// Test that the typical case still works when we specify the flavor to set 1.152 +exports["test With Redundant Flavor"] = function(assert) { 1.153 + var contents = "<b>hello there</b>"; 1.154 + var flavor = "text"; 1.155 + var fullFlavor = "text/unicode"; 1.156 + var clip = require("sdk/clipboard"); 1.157 + 1.158 + assert.ok(clip.set(contents, flavor)); 1.159 + assert.equal(clip.currentFlavors[0], flavor); 1.160 + assert.equal(clip.get(), contents); 1.161 + assert.equal(clip.get(flavor), contents); 1.162 + assert.equal(clip.get(fullFlavor), contents); 1.163 +}; 1.164 + 1.165 +exports["test Not In Flavor"] = function(assert) { 1.166 + var contents = "hello there"; 1.167 + var flavor = "html"; 1.168 + var clip = require("sdk/clipboard"); 1.169 + 1.170 + assert.ok(clip.set(contents)); 1.171 + // If there's nothing on the clipboard with this flavor, should return null 1.172 + assert.equal(clip.get(flavor), null); 1.173 +}; 1.174 + 1.175 +exports["test Set Image"] = function(assert) { 1.176 + var clip = require("sdk/clipboard"); 1.177 + var flavor = "image"; 1.178 + var fullFlavor = "image/png"; 1.179 + 1.180 + assert.ok(clip.set(base64png, flavor), "clipboard set"); 1.181 + assert.equal(clip.currentFlavors[0], flavor, "flavor is set"); 1.182 +}; 1.183 + 1.184 +exports["test Get Image"] = function(assert, done) { 1.185 + var clip = require("sdk/clipboard"); 1.186 + 1.187 + clip.set(base64png, "image"); 1.188 + 1.189 + var contents = clip.get(); 1.190 + 1.191 + comparePixelImages(base64png, contents, function (areEquals) { 1.192 + assert.ok(areEquals, 1.193 + "Image gets from clipboard equals to image sets to the clipboard"); 1.194 + 1.195 + done(); 1.196 + }); 1.197 +} 1.198 + 1.199 +exports["test Set Image Type Not Supported"] = function(assert) { 1.200 + var clip = require("sdk/clipboard"); 1.201 + var flavor = "image"; 1.202 + 1.203 + assert.throws(function () { 1.204 + clip.set(base64jpeg, flavor); 1.205 + }, "Invalid flavor for image/jpeg"); 1.206 + 1.207 +}; 1.208 + 1.209 +// Notice that `imageTools.decodeImageData`, used by `clipboard.set` method for 1.210 +// images, write directly to the javascript console the error in case the image 1.211 +// is corrupt, even if the error is catched. 1.212 +// 1.213 +// See: http://mxr.mozilla.org/mozilla-central/source/image/src/Decoder.cpp#136 1.214 +exports["test Set Image Type Wrong Data"] = function(assert) { 1.215 + var clip = require("sdk/clipboard"); 1.216 + var flavor = "image"; 1.217 + 1.218 + var wrongPNG = "data:image/png" + base64jpeg.substr(15); 1.219 + 1.220 + assert.throws(function () { 1.221 + clip.set(wrongPNG, flavor); 1.222 + }, "Unable to decode data given in a valid image."); 1.223 +}; 1.224 + 1.225 +require("test").run(exports)