/image/test/unit/async_load_tests.js

http://github.com/zpao/v8monkey · JavaScript · 209 lines · 130 code · 41 blank · 38 comment · 0 complexity · b3b5b02e123a19bfbc4e15399eec0d36 MD5 · raw file

  1. /*
  2. * Test to ensure that image loading/decoding notifications are always
  3. * delivered async, and in the order we expect.
  4. *
  5. * Must be included from a file that has a uri of the image to test defined in
  6. * var uri.
  7. */
  8. do_load_httpd_js();
  9. var server = new nsHttpServer();
  10. server.registerDirectory("/", do_get_file(''));
  11. server.registerContentType("sjs", "sjs");
  12. server.start(8088);
  13. load('image_load_helpers.js');
  14. var requests = [];
  15. // Return a closure that holds on to the listener from the original
  16. // imgIRequest, and compares its results to the cloned one.
  17. function getCloneStopCallback(original_listener)
  18. {
  19. return function cloneStop(listener) {
  20. do_check_eq(original_listener.state, listener.state);
  21. // Sanity check to make sure we didn't accidentally use the same listener
  22. // twice.
  23. do_check_neq(original_listener, listener);
  24. do_test_finished();
  25. }
  26. }
  27. // Make sure that cloned requests get all the same callbacks as the original,
  28. // but they aren't synchronous right now.
  29. function checkClone(other_listener, aRequest)
  30. {
  31. do_test_pending();
  32. // For as long as clone notification is synchronous, we can't test the clone state reliably.
  33. var listener = new ImageListener(null, function(foo, bar) { do_test_finished(); } /*getCloneStopCallback(other_listener)*/);
  34. listener.synchronous = false;
  35. var clone = aRequest.clone(listener);
  36. }
  37. // Ensure that all the callbacks were called on aRequest.
  38. function checkAllCallbacks(listener, aRequest)
  39. {
  40. do_check_eq(listener.state, ALL_BITS);
  41. do_test_finished();
  42. }
  43. function secondLoadDone(oldlistener, aRequest)
  44. {
  45. do_test_pending();
  46. try {
  47. var staticrequest = aRequest.getStaticRequest();
  48. // For as long as clone notification is synchronous, we can't test the
  49. // clone state reliably.
  50. var listener = new ImageListener(null, checkAllCallbacks);
  51. listener.synchronous = false;
  52. var staticrequestclone = staticrequest.clone(listener);
  53. } catch(e) {
  54. // We can't create a static request. Most likely the request we started
  55. // with didn't load successfully.
  56. do_test_finished();
  57. }
  58. run_loadImageWithChannel_tests();
  59. do_test_finished();
  60. }
  61. // Load the request a second time. This should come from the image cache, and
  62. // therefore would be at most risk of being served synchronously.
  63. function checkSecondLoad()
  64. {
  65. do_test_pending();
  66. var loader = Cc["@mozilla.org/image/loader;1"].getService(Ci.imgILoader);
  67. var listener = new ImageListener(checkClone, secondLoadDone);
  68. requests.push(loader.loadImage(uri, null, null, null, null, listener, null, 0, null, null, null));
  69. listener.synchronous = false;
  70. }
  71. function firstLoadDone(oldlistener, aRequest)
  72. {
  73. checkSecondLoad(uri);
  74. do_test_finished();
  75. }
  76. // Return a closure that allows us to check the stream listener's status when the
  77. // image starts loading.
  78. function getChannelLoadImageStartCallback(streamlistener)
  79. {
  80. return function channelLoadStart(imglistener, aRequest) {
  81. // We must not have received any status before we get this start callback.
  82. // If we have, we've broken people's expectations by delaying events from a
  83. // channel we were given.
  84. do_check_eq(streamlistener.requestStatus, 0);
  85. checkClone(imglistener, aRequest);
  86. }
  87. }
  88. // Return a closure that allows us to check the stream listener's status when the
  89. // image finishes loading.
  90. function getChannelLoadImageStopCallback(streamlistener, next)
  91. {
  92. return function channelLoadStop(imglistener, aRequest) {
  93. // We absolutely must not get imgIDecoderObserver::onStopRequest after
  94. // nsIRequestObserver::onStopRequest has fired. If we do that, we've broken
  95. // people's expectations by delaying events from a channel we were given.
  96. do_check_eq(streamlistener.requestStatus & STOP_REQUEST, 0);
  97. next();
  98. do_test_finished();
  99. }
  100. }
  101. // Load the request a second time. This should come from the image cache, and
  102. // therefore would be at most risk of being served synchronously.
  103. function checkSecondChannelLoad()
  104. {
  105. do_test_pending();
  106. var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
  107. var channel = ioService.newChannelFromURI(uri);
  108. var channellistener = new ChannelListener();
  109. channel.asyncOpen(channellistener, null);
  110. var loader = Cc["@mozilla.org/image/loader;1"].getService(Ci.imgILoader);
  111. var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
  112. getChannelLoadImageStopCallback(channellistener,
  113. all_done_callback));
  114. var outlistener = {};
  115. requests.push(loader.loadImageWithChannel(channel, listener, null, outlistener));
  116. channellistener.outputListener = outlistener.value;
  117. listener.synchronous = false;
  118. }
  119. function run_loadImageWithChannel_tests()
  120. {
  121. // To ensure we're testing what we expect to, clear the content image cache
  122. // between test runs.
  123. var loader = Cc["@mozilla.org/image/loader;1"].getService(Ci.imgILoader);
  124. loader.QueryInterface(Ci.imgICache);
  125. loader.clearCache(false);
  126. do_test_pending();
  127. var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
  128. var channel = ioService.newChannelFromURI(uri);
  129. var channellistener = new ChannelListener();
  130. channel.asyncOpen(channellistener, null);
  131. var loader = Cc["@mozilla.org/image/loader;1"].getService(Ci.imgILoader);
  132. var listener = new ImageListener(getChannelLoadImageStartCallback(channellistener),
  133. getChannelLoadImageStopCallback(channellistener,
  134. checkSecondChannelLoad));
  135. var outlistener = {};
  136. requests.push(loader.loadImageWithChannel(channel, listener, null, outlistener));
  137. channellistener.outputListener = outlistener.value;
  138. listener.synchronous = false;
  139. }
  140. function all_done_callback()
  141. {
  142. server.stop(function() { do_test_finished(); });
  143. }
  144. function startImageCallback(otherCb)
  145. {
  146. return function(listener, request)
  147. {
  148. var loader = Cc["@mozilla.org/image/loader;1"].getService(Ci.imgILoader);
  149. // Make sure we can load the same image immediately out of the cache.
  150. do_test_pending();
  151. var listener2 = new ImageListener(null, function(foo, bar) { do_test_finished(); });
  152. requests.push(loader.loadImage(uri, null, null, null, null, listener2, null, 0, null, null, null));
  153. listener2.synchronous = false;
  154. // Now that we've started another load, chain to the callback.
  155. otherCb(listener, request);
  156. }
  157. }
  158. function run_test()
  159. {
  160. var loader = Cc["@mozilla.org/image/loader;1"].getService(Ci.imgILoader);
  161. do_test_pending();
  162. var listener = new ImageListener(startImageCallback(checkClone), firstLoadDone);
  163. var req = loader.loadImage(uri, null, null, null, null, listener, null, 0, null, null, null);
  164. requests.push(req);
  165. // Ensure that we don't cause any mayhem when we lock an image.
  166. req.lockImage();
  167. listener.synchronous = false;
  168. }