image/test/unit/async_load_tests.js

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

michael@0 1 /*
michael@0 2 * Test to ensure that image loading/decoding notifications are always
michael@0 3 * delivered async, and in the order we expect.
michael@0 4 *
michael@0 5 * Must be included from a file that has a uri of the image to test defined in
michael@0 6 * var uri.
michael@0 7 */
michael@0 8
michael@0 9 const Cc = Components.classes;
michael@0 10 const Ci = Components.interfaces;
michael@0 11 const Cu = Components.utils;
michael@0 12 const Cr = Components.results;
michael@0 13
michael@0 14 Cu.import("resource://testing-common/httpd.js");
michael@0 15
michael@0 16 var server = new HttpServer();
michael@0 17 server.registerDirectory("/", do_get_file(''));
michael@0 18 server.registerContentType("sjs", "sjs");
michael@0 19 server.start(-1);
michael@0 20
michael@0 21
michael@0 22 load('image_load_helpers.js');
michael@0 23
michael@0 24 var requests = [];
michael@0 25
michael@0 26 // Return a closure that holds on to the listener from the original
michael@0 27 // imgIRequest, and compares its results to the cloned one.
michael@0 28 function getCloneStopCallback(original_listener)
michael@0 29 {
michael@0 30 return function cloneStop(listener) {
michael@0 31 do_check_eq(original_listener.state, listener.state);
michael@0 32
michael@0 33 // Sanity check to make sure we didn't accidentally use the same listener
michael@0 34 // twice.
michael@0 35 do_check_neq(original_listener, listener);
michael@0 36 do_test_finished();
michael@0 37 }
michael@0 38 }
michael@0 39
michael@0 40 // Make sure that cloned requests get all the same callbacks as the original,
michael@0 41 // but they aren't synchronous right now.
michael@0 42 function checkClone(other_listener, aRequest)
michael@0 43 {
michael@0 44 do_test_pending();
michael@0 45
michael@0 46 // For as long as clone notification is synchronous, we can't test the clone state reliably.
michael@0 47 var listener = new ImageListener(null, function(foo, bar) { do_test_finished(); } /*getCloneStopCallback(other_listener)*/);
michael@0 48 listener.synchronous = false;
michael@0 49 var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
michael@0 50 .createScriptedObserver(listener);
michael@0 51 var clone = aRequest.clone(outer);
michael@0 52 requests.push(clone);
michael@0 53 }
michael@0 54
michael@0 55 // Ensure that all the callbacks were called on aRequest.
michael@0 56 function checkSizeAndLoad(listener, aRequest)
michael@0 57 {
michael@0 58 do_check_neq(listener.state & SIZE_AVAILABLE, 0);
michael@0 59 do_check_neq(listener.state & LOAD_COMPLETE, 0);
michael@0 60
michael@0 61 do_test_finished();
michael@0 62 }
michael@0 63
michael@0 64 function secondLoadDone(oldlistener, aRequest)
michael@0 65 {
michael@0 66 do_test_pending();
michael@0 67
michael@0 68 try {
michael@0 69 var staticrequest = aRequest.getStaticRequest();
michael@0 70
michael@0 71 // For as long as clone notification is synchronous, we can't test the
michael@0 72 // clone state reliably.
michael@0 73 var listener = new ImageListener(null, checkSizeAndLoad);
michael@0 74 listener.synchronous = false;
michael@0 75 var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
michael@0 76 .createScriptedObserver(listener);
michael@0 77 var staticrequestclone = staticrequest.clone(outer);
michael@0 78 requests.push(staticrequestclone);
michael@0 79 } catch(e) {
michael@0 80 // We can't create a static request. Most likely the request we started
michael@0 81 // with didn't load successfully.
michael@0 82 do_test_finished();
michael@0 83 }
michael@0 84
michael@0 85 run_loadImageWithChannel_tests();
michael@0 86
michael@0 87 do_test_finished();
michael@0 88 }
michael@0 89
michael@0 90 // Load the request a second time. This should come from the image cache, and
michael@0 91 // therefore would be at most risk of being served synchronously.
michael@0 92 function checkSecondLoad()
michael@0 93 {
michael@0 94 do_test_pending();
michael@0 95
michael@0 96 var listener = new ImageListener(checkClone, secondLoadDone);
michael@0 97 var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
michael@0 98 .createScriptedObserver(listener);
michael@0 99 requests.push(gCurrentLoader.loadImageXPCOM(uri, null, null, null, null, outer, null, 0, null, null));
michael@0 100 listener.synchronous = false;
michael@0 101 }
michael@0 102
michael@0 103 function firstLoadDone(oldlistener, aRequest)
michael@0 104 {
michael@0 105 checkSecondLoad(uri);
michael@0 106
michael@0 107 do_test_finished();
michael@0 108 }
michael@0 109
michael@0 110 // Return a closure that allows us to check the stream listener's status when the
michael@0 111 // image starts loading.
michael@0 112 function getChannelLoadImageStartCallback(streamlistener)
michael@0 113 {
michael@0 114 return function channelLoadStart(imglistener, aRequest) {
michael@0 115 // We must not have received all status before we get this start callback.
michael@0 116 // If we have, we've broken people's expectations by delaying events from a
michael@0 117 // channel we were given.
michael@0 118 do_check_eq(streamlistener.requestStatus & STOP_REQUEST, 0);
michael@0 119
michael@0 120 checkClone(imglistener, aRequest);
michael@0 121 }
michael@0 122 }
michael@0 123
michael@0 124 // Return a closure that allows us to check the stream listener's status when the
michael@0 125 // image finishes loading.
michael@0 126 function getChannelLoadImageStopCallback(streamlistener, next)
michael@0 127 {
michael@0 128 return function channelLoadStop(imglistener, aRequest) {
michael@0 129
michael@0 130 next();
michael@0 131
michael@0 132 do_test_finished();
michael@0 133 }
michael@0 134 }
michael@0 135
michael@0 136 // Load the request a second time. This should come from the image cache, and
michael@0 137 // therefore would be at most risk of being served synchronously.
michael@0 138 function checkSecondChannelLoad()
michael@0 139 {
michael@0 140 do_test_pending();
michael@0 141
michael@0 142 var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
michael@0 143 var channel = ioService.newChannelFromURI(uri);
michael@0 144 var channellistener = new ChannelListener();
michael@0 145 channel.asyncOpen(channellistener, null);
michael@0 146
michael@0 147 var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
michael@0 148 getChannelLoadImageStopCallback(channellistener,
michael@0 149 all_done_callback));
michael@0 150 var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
michael@0 151 .createScriptedObserver(listener);
michael@0 152 var outlistener = {};
michael@0 153 requests.push(gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener));
michael@0 154 channellistener.outputListener = outlistener.value;
michael@0 155
michael@0 156 listener.synchronous = false;
michael@0 157 }
michael@0 158
michael@0 159 function run_loadImageWithChannel_tests()
michael@0 160 {
michael@0 161 // To ensure we're testing what we expect to, create a new loader and cache.
michael@0 162 gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader);
michael@0 163
michael@0 164 do_test_pending();
michael@0 165
michael@0 166 var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
michael@0 167 var channel = ioService.newChannelFromURI(uri);
michael@0 168 var channellistener = new ChannelListener();
michael@0 169 channel.asyncOpen(channellistener, null);
michael@0 170
michael@0 171 var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
michael@0 172 getChannelLoadImageStopCallback(channellistener,
michael@0 173 checkSecondChannelLoad));
michael@0 174 var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
michael@0 175 .createScriptedObserver(listener);
michael@0 176 var outlistener = {};
michael@0 177 requests.push(gCurrentLoader.loadImageWithChannelXPCOM(channel, outer, null, outlistener));
michael@0 178 channellistener.outputListener = outlistener.value;
michael@0 179
michael@0 180 listener.synchronous = false;
michael@0 181 }
michael@0 182
michael@0 183 function all_done_callback()
michael@0 184 {
michael@0 185 server.stop(function() { do_test_finished(); });
michael@0 186 }
michael@0 187
michael@0 188 function startImageCallback(otherCb)
michael@0 189 {
michael@0 190 return function(listener, request)
michael@0 191 {
michael@0 192 // Make sure we can load the same image immediately out of the cache.
michael@0 193 do_test_pending();
michael@0 194 var listener2 = new ImageListener(null, function(foo, bar) { do_test_finished(); });
michael@0 195 var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
michael@0 196 .createScriptedObserver(listener2);
michael@0 197 requests.push(gCurrentLoader.loadImageXPCOM(uri, null, null, null, null, outer, null, 0, null, null));
michael@0 198 listener2.synchronous = false;
michael@0 199
michael@0 200 // Now that we've started another load, chain to the callback.
michael@0 201 otherCb(listener, request);
michael@0 202 }
michael@0 203 }
michael@0 204
michael@0 205 var gCurrentLoader;
michael@0 206
michael@0 207 function cleanup()
michael@0 208 {
michael@0 209 for (var i = 0; i < requests.length; ++i) {
michael@0 210 requests[i].cancelAndForgetObserver(0);
michael@0 211 }
michael@0 212 }
michael@0 213
michael@0 214 function run_test()
michael@0 215 {
michael@0 216 do_register_cleanup(cleanup);
michael@0 217
michael@0 218 gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader);
michael@0 219
michael@0 220 do_test_pending();
michael@0 221 var listener = new ImageListener(startImageCallback(checkClone), firstLoadDone);
michael@0 222 var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
michael@0 223 .createScriptedObserver(listener);
michael@0 224 var req = gCurrentLoader.loadImageXPCOM(uri, null, null, null, null, outer, null, 0, null, null);
michael@0 225 requests.push(req);
michael@0 226
michael@0 227 // Ensure that we don't cause any mayhem when we lock an image.
michael@0 228 req.lockImage();
michael@0 229
michael@0 230 listener.synchronous = false;
michael@0 231 }

mercurial