canvas-tests.js (6644B)
1 function _valToString(val) 2 { 3 if (val === undefined || val === null) 4 return '[' + typeof(val) + ']'; 5 return val.toString() + '[' + typeof(val) + ']'; 6 } 7 8 function _assert(cond, text) 9 { 10 assert_true(!!cond, text); 11 } 12 13 function _assertSame(a, b, text_a, text_b) 14 { 15 var msg = text_a + ' === ' + text_b + ' (got ' + _valToString(a) + 16 ', expected ' + _valToString(b) + ')'; 17 assert_equals(a, b, msg); 18 } 19 20 function _assertDifferent(a, b, text_a, text_b) 21 { 22 var msg = text_a + ' !== ' + text_b + ' (got ' + _valToString(a) + 23 ', expected not ' + _valToString(b) + ')'; 24 assert_not_equals(a, b, msg); 25 } 26 27 28 function _getPixel(canvas, x,y) 29 { 30 var ctx = canvas.getContext('2d'); 31 var imgdata = ctx.getImageData(x, y, 1, 1); 32 return [ imgdata.data[0], imgdata.data[1], imgdata.data[2], imgdata.data[3] ]; 33 } 34 35 function _assertPixel(canvas, x, y, r, g, b, a) 36 { 37 var c = _getPixel(canvas, x,y); 38 assert_equals(c[0], r, 'Red channel of the pixel at (' + x + ', ' + y + ')'); 39 assert_equals(c[1], g, 'Green channel of the pixel at (' + x + ', ' + y + ')'); 40 assert_equals(c[2], b, 'Blue channel of the pixel at (' + x + ', ' + y + ')'); 41 assert_equals(c[3], a, 'Alpha channel of the pixel at (' + x + ', ' + y + ')'); 42 } 43 44 function _assertPixelApprox(canvas, x, y, r, g, b, a, tolerance) 45 { 46 var c = _getPixel(canvas, x,y); 47 assert_approx_equals(c[0], r, tolerance, 'Red channel of the pixel at (' + x + ', ' + y + ')'); 48 assert_approx_equals(c[1], g, tolerance, 'Green channel of the pixel at (' + x + ', ' + y + ')'); 49 assert_approx_equals(c[2], b, tolerance, 'Blue channel of the pixel at (' + x + ', ' + y + ')'); 50 assert_approx_equals(c[3], a, tolerance, 'Alpha channel of the pixel at (' + x + ', ' + y + ')'); 51 } 52 53 function _assertMatricesApproxEqual(matA, matB) 54 { 55 A = matA.toFloat32Array(); 56 B = matB.toFloat32Array(); 57 assert_equals(A.length, B.length); 58 for (var i = 0; i < A.length; i++) { 59 assert_approx_equals(A[i], B[i], 10e-6); 60 } 61 } 62 63 function rad2deg(angle_in_radians) { 64 return angle_in_radians / Math.PI * 180; 65 } 66 67 function deg2rad(angle_in_degrees) { 68 return angle_in_degrees / 180 * Math.PI; 69 } 70 71 let _deferred = false; 72 73 function deferTest() { 74 _deferred = true; 75 } 76 77 function _addTest(testFn, attributes={}) 78 { 79 on_event(window, "load", function() 80 { 81 t.step(function() { 82 var canvas = document.getElementById('c'); 83 var ctx = canvas.getContext('2d', attributes); 84 t.step(testFn, window, canvas, ctx); 85 }); 86 87 if (!_deferred) { 88 t.done(); 89 } 90 }); 91 } 92 93 function _assertGreen(ctx, canvasWidth, canvasHeight) 94 { 95 var testColor = function(d, idx, expected) { 96 assert_equals(d[idx], expected, "d[" + idx + "]", String(expected)); 97 }; 98 var imagedata = ctx.getImageData(0, 0, canvasWidth, canvasHeight); 99 var w = imagedata.width, h = imagedata.height, d = imagedata.data; 100 for (var i = 0; i < h; ++i) { 101 for (var j = 0; j < w; ++j) { 102 testColor(d, 4 * (w * i + j) + 0, 0); 103 testColor(d, 4 * (w * i + j) + 1, 255); 104 testColor(d, 4 * (w * i + j) + 2, 0); 105 testColor(d, 4 * (w * i + j) + 3, 255); 106 } 107 } 108 } 109 110 function addCrossOriginYellowImage() 111 { 112 var img = new Image(); 113 img.id = "yellow.png"; 114 img.className = "resource"; 115 img.src = get_host_info().HTTP_REMOTE_ORIGIN + "/images/yellow.png"; 116 document.body.appendChild(img); 117 } 118 119 function addCrossOriginRedirectYellowImage() 120 { 121 var img = new Image(); 122 img.id = "yellow.png"; 123 img.className = "resource"; 124 img.src = get_host_info().HTTP_ORIGIN + "/common/redirect.py?location=" + 125 get_host_info().HTTP_REMOTE_ORIGIN + "/images/yellow.png"; 126 document.body.appendChild(img); 127 } 128 129 function forEachCanvasSource(crossOriginUrl, sameOriginUrl, callback) { 130 function makeImage() { 131 return new Promise((resolve, reject) => { 132 const image = new Image(); 133 image.onload = () => resolve(image); 134 image.onerror = reject; 135 image.src = crossOriginUrl + "/images/red.png"; 136 }); 137 } 138 139 const arguments = [ 140 { 141 name: "cross-origin HTMLImageElement", 142 factory: makeImage, 143 }, 144 145 { 146 name: "cross-origin SVGImageElement", 147 factory: () => { 148 return new Promise((resolve, reject) => { 149 const image = document.createElementNS("http://www.w3.org/2000/svg", "image"); 150 image.onload = () => resolve(image); 151 image.onerror = reject; 152 image.setAttribute("externalResourcesRequired", "true"); 153 image.setAttributeNS("http://www.w3.org/1999/xlink", 'xlink:href', crossOriginUrl + "/images/red.png"); 154 document.body.appendChild(image); 155 }); 156 }, 157 }, 158 159 { 160 name: "cross-origin HTMLVideoElement", 161 factory: () => { 162 return new Promise((resolve, reject) => { 163 const video = document.createElement("video"); 164 video.oncanplaythrough = () => resolve(video); 165 video.preload = "auto"; 166 video.onerror = reject; 167 video.src = getVideoURI(crossOriginUrl + "/media/movie_300"); 168 }); 169 }, 170 }, 171 172 { 173 name: "redirected to cross-origin HTMLVideoElement", 174 factory: () => { 175 return new Promise((resolve, reject) => { 176 const video = document.createElement("video"); 177 video.oncanplaythrough = () => resolve(video); 178 video.preload = "auto"; 179 video.onerror = reject; 180 video.src = "/common/redirect.py?location=" + getVideoURI(crossOriginUrl + "/media/movie_300"); 181 }); 182 }, 183 }, 184 185 { 186 name: "redirected to same-origin HTMLVideoElement", 187 factory: () => { 188 return new Promise((resolve, reject) => { 189 const video = document.createElement("video"); 190 video.oncanplaythrough = () => resolve(video); 191 video.preload = "auto"; 192 video.onerror = reject; 193 video.src = crossOriginUrl + "/common/redirect.py?location=" + getVideoURI(sameOriginUrl + "/media/movie_300"); 194 }); 195 }, 196 }, 197 198 { 199 name: "unclean HTMLCanvasElement", 200 factory: () => { 201 return makeImage().then(image => { 202 const canvas = document.createElement("canvas"); 203 const context = canvas.getContext("2d"); 204 context.drawImage(image, 0, 0); 205 return canvas; 206 }); 207 }, 208 }, 209 210 { 211 name: "unclean ImageBitmap", 212 factory: () => { 213 return makeImage().then(createImageBitmap); 214 }, 215 }, 216 ]; 217 218 for (let { name, factory } of arguments) { 219 callback(name, factory); 220 } 221 }