forked from mirrors/gecko-dev
		
	 5dec0e0beb
			
		
	
	
		5dec0e0beb
		
	
	
	
	
		
			
			This patch was autogenerated by my decomponents.py
It covers almost every file with the extension js, jsm, html, py,
xhtml, or xul.
It removes blank lines after removed lines, when the removed lines are
preceded by either blank lines or the start of a new block. The "start
of a new block" is defined fairly hackily: either the line starts with
//, ends with */, ends with {, <![CDATA[, """ or '''. The first two
cover comments, the third one covers JS, the fourth covers JS embedded
in XUL, and the final two cover JS embedded in Python. This also
applies if the removed line was the first line of the file.
It covers the pattern matching cases like "var {classes: Cc,
interfaces: Ci, utils: Cu, results: Cr} = Components;". It'll remove
the entire thing if they are all either Ci, Cr, Cc or Cu, or it will
remove the appropriate ones and leave the residue behind. If there's
only one behind, then it will turn it into a normal, non-pattern
matching variable definition. (For instance, "const { classes: Cc,
Constructor: CC, interfaces: Ci, utils: Cu } = Components" becomes
"const CC = Components.Constructor".)
MozReview-Commit-ID: DeSHcClQ7cG
--HG--
extra : rebase_source : d9c41878036c1ef7766ef5e91a7005025bc1d72b
		
	
			
		
			
				
	
	
		
			272 lines
		
	
	
	
		
			8.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			272 lines
		
	
	
	
		
			8.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| ChromeUtils.import("resource://gre/modules/Timer.jsm", this);
 | |
| ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm", this);
 | |
| 
 | |
| // Prevent test failures due to the unhandled rejections in this test file.
 | |
| PromiseTestUtils.disableUncaughtRejectionObserverForSelfTest();
 | |
| 
 | |
| add_task(async function test_globals() {
 | |
|   Assert.equal(Promise.defer || undefined, undefined, "We are testing DOM Promise.");
 | |
|   Assert.notEqual(PromiseDebugging, undefined, "PromiseDebugging is available.");
 | |
| });
 | |
| 
 | |
| add_task(async function test_promiseID() {
 | |
|   let p1 = new Promise(resolve => {});
 | |
|   let p2 = new Promise(resolve => {});
 | |
|   let p3 = p2.catch(null);
 | |
|   let promise = [p1, p2, p3];
 | |
| 
 | |
|   let identifiers = promise.map(PromiseDebugging.getPromiseID);
 | |
|   info("Identifiers: " + JSON.stringify(identifiers));
 | |
|   let idSet = new Set(identifiers);
 | |
|   Assert.equal(idSet.size, identifiers.length,
 | |
|     "PromiseDebugging.getPromiseID returns a distinct id per promise");
 | |
| 
 | |
|   let identifiers2 = promise.map(PromiseDebugging.getPromiseID);
 | |
|   Assert.equal(JSON.stringify(identifiers),
 | |
|                JSON.stringify(identifiers2),
 | |
|                "Successive calls to PromiseDebugging.getPromiseID return the same id for the same promise");
 | |
| });
 | |
| 
 | |
| add_task(async function test_observe_uncaught() {
 | |
|   // The names of Promise instances
 | |
|   let names = new Map();
 | |
| 
 | |
|   // The results for UncaughtPromiseObserver callbacks.
 | |
|   let CallbackResults = function(name) {
 | |
|     this.name = name;
 | |
|     this.expected = new Set();
 | |
|     this.observed = new Set();
 | |
|     this.blocker = new Promise(resolve => this.resolve = resolve);
 | |
|   };
 | |
|   CallbackResults.prototype = {
 | |
|     observe: function(promise) {
 | |
|       info(this.name + " observing Promise " + names.get(promise));
 | |
|       Assert.equal(PromiseDebugging.getState(promise).state, "rejected",
 | |
|                    this.name + " observed a rejected Promise");
 | |
|       if (!this.expected.has(promise)) {
 | |
|         Assert.ok(false,
 | |
|             this.name + " observed a Promise that it expected to observe, " +
 | |
|             names.get(promise) +
 | |
|             " (" + PromiseDebugging.getPromiseID(promise) +
 | |
|             ", " + PromiseDebugging.getAllocationStack(promise) + ")");
 | |
| 
 | |
|       }
 | |
|       Assert.ok(this.expected.delete(promise),
 | |
|                 this.name + " observed a Promise that it expected to observe, " +
 | |
|                 names.get(promise)  + " (" + PromiseDebugging.getPromiseID(promise) + ")");
 | |
|       Assert.ok(!this.observed.has(promise),
 | |
|                 this.name + " observed a Promise that it has not observed yet");
 | |
|       this.observed.add(promise);
 | |
|       if (this.expected.size == 0) {
 | |
|         this.resolve();
 | |
|       } else {
 | |
|         info(this.name + " is still waiting for " + this.expected.size + " observations:");
 | |
|         info(JSON.stringify(Array.from(this.expected.values(), (x) => names.get(x))));
 | |
|       }
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   let onLeftUncaught = new CallbackResults("onLeftUncaught");
 | |
|   let onConsumed = new CallbackResults("onConsumed");
 | |
| 
 | |
|   let observer = {
 | |
|     onLeftUncaught: function(promise, data) {
 | |
|       onLeftUncaught.observe(promise);
 | |
|     },
 | |
|     onConsumed: function(promise) {
 | |
|       onConsumed.observe(promise);
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   let resolveLater = function(delay = 20) {
 | |
|     return new Promise((resolve, reject) => setTimeout(resolve, delay));
 | |
|   };
 | |
|   let rejectLater = function(delay = 20) {
 | |
|     return new Promise((resolve, reject) => setTimeout(reject, delay));
 | |
|   };
 | |
|   let makeSamples = function*() {
 | |
|     yield {
 | |
|       promise: Promise.resolve(0),
 | |
|       name: "Promise.resolve",
 | |
|     };
 | |
|     yield {
 | |
|       promise: Promise.resolve(resolve => resolve(0)),
 | |
|       name: "Resolution callback",
 | |
|     };
 | |
|     yield {
 | |
|       promise: Promise.resolve(0).catch(null),
 | |
|       name: "`catch(null)`"
 | |
|     };
 | |
|     yield {
 | |
|       promise: Promise.reject(0).catch(() => {}),
 | |
|       name: "Reject and catch immediately",
 | |
|     };
 | |
|     yield {
 | |
|       promise: resolveLater(),
 | |
|       name: "Resolve later",
 | |
|     };
 | |
|     yield {
 | |
|       promise: Promise.reject("Simple rejection"),
 | |
|       leftUncaught: true,
 | |
|       consumed: false,
 | |
|       name: "Promise.reject",
 | |
|     };
 | |
| 
 | |
|     // Reject a promise now, consume it later.
 | |
|     let p = Promise.reject("Reject now, consume later");
 | |
|     setTimeout(() => p.catch(() => {
 | |
|       info("Consumed promise");
 | |
|     }), 200);
 | |
|     yield {
 | |
|       promise: p,
 | |
|       leftUncaught: true,
 | |
|       consumed: true,
 | |
|       name: "Reject now, consume later",
 | |
|     };
 | |
| 
 | |
|     yield {
 | |
|       promise: Promise.all([
 | |
|         Promise.resolve("Promise.all"),
 | |
|         rejectLater()
 | |
|       ]),
 | |
|       leftUncaught: true,
 | |
|       name: "Rejecting through Promise.all"
 | |
|     };
 | |
|     yield {
 | |
|       promise: Promise.race([
 | |
|         resolveLater(500),
 | |
|         Promise.reject(),
 | |
|       ]),
 | |
|       leftUncaught: true, // The rejection wins the race.
 | |
|       name: "Rejecting through Promise.race",
 | |
|     };
 | |
|     yield {
 | |
|       promise: Promise.race([
 | |
|         Promise.resolve(),
 | |
|         rejectLater(500)
 | |
|       ]),
 | |
|       leftUncaught: false, // The resolution wins the race.
 | |
|       name: "Resolving through Promise.race",
 | |
|     };
 | |
| 
 | |
|     let boom = new Error("`throw` in the constructor");
 | |
|     yield {
 | |
|       promise: new Promise(() => { throw boom; }),
 | |
|       leftUncaught: true,
 | |
|       name: "Throwing in the constructor",
 | |
|     };
 | |
| 
 | |
|     let rejection = Promise.reject("`reject` during resolution");
 | |
|     yield {
 | |
|       promise: rejection,
 | |
|       leftUncaught: false,
 | |
|       consumed: false, // `rejection` is consumed immediately (see below)
 | |
|       name: "Promise.reject, again",
 | |
|     };
 | |
| 
 | |
|     yield {
 | |
|       promise: new Promise(resolve => resolve(rejection)),
 | |
|       leftUncaught: true,
 | |
|       consumed: false,
 | |
|       name: "Resolving with a rejected promise",
 | |
|     };
 | |
| 
 | |
|     yield {
 | |
|       promise: Promise.resolve(0).then(() => rejection),
 | |
|       leftUncaught: true,
 | |
|       consumed: false,
 | |
|       name: "Returning a rejected promise from success handler",
 | |
|     };
 | |
| 
 | |
|     yield {
 | |
|       promise: Promise.resolve(0).then(() => { throw new Error(); }),
 | |
|       leftUncaught: true,
 | |
|       consumed: false,
 | |
|       name: "Throwing during the call to the success callback",
 | |
|     };
 | |
|   };
 | |
|   let samples = [];
 | |
|   for (let s of makeSamples()) {
 | |
|     samples.push(s);
 | |
|     info("Promise '" + s.name + "' has id " + PromiseDebugging.getPromiseID(s.promise));
 | |
|   }
 | |
| 
 | |
|   PromiseDebugging.addUncaughtRejectionObserver(observer);
 | |
| 
 | |
|   for (let s of samples) {
 | |
|     names.set(s.promise, s.name);
 | |
|     if (s.leftUncaught || false) {
 | |
|       onLeftUncaught.expected.add(s.promise);
 | |
|     }
 | |
|     if (s.consumed || false) {
 | |
|       onConsumed.expected.add(s.promise);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   info("Test setup, waiting for callbacks.");
 | |
|   await onLeftUncaught.blocker;
 | |
| 
 | |
|   info("All calls to onLeftUncaught are complete.");
 | |
|   if (onConsumed.expected.size != 0) {
 | |
|     info("onConsumed is still waiting for the following Promise:");
 | |
|     info(JSON.stringify(Array.from(onConsumed.expected.values(), (x) => names.get(x))));
 | |
|     await onConsumed.blocker;
 | |
|   }
 | |
| 
 | |
|   info("All calls to onConsumed are complete.");
 | |
|   let removed = PromiseDebugging.removeUncaughtRejectionObserver(observer);
 | |
|   Assert.ok(removed, "removeUncaughtRejectionObserver succeeded");
 | |
|   removed = PromiseDebugging.removeUncaughtRejectionObserver(observer);
 | |
|   Assert.ok(!removed, "second call to removeUncaughtRejectionObserver didn't remove anything");
 | |
| });
 | |
| 
 | |
| 
 | |
| add_task(async function test_uninstall_observer() {
 | |
|   let Observer = function() {
 | |
|     this.blocker = new Promise(resolve => this.resolve = resolve);
 | |
|     this.active = true;
 | |
|   };
 | |
|   Observer.prototype = {
 | |
|     set active(x) {
 | |
|       this._active = x;
 | |
|       if (x) {
 | |
|         PromiseDebugging.addUncaughtRejectionObserver(this);
 | |
|       } else {
 | |
|         PromiseDebugging.removeUncaughtRejectionObserver(this);
 | |
|       }
 | |
|     },
 | |
|     onLeftUncaught: function() {
 | |
|       Assert.ok(this._active, "This observer is active.");
 | |
|       this.resolve();
 | |
|     },
 | |
|     onConsumed: function() {
 | |
|       Assert.ok(false, "We should not consume any Promise.");
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   info("Adding an observer.");
 | |
|   let deactivate = new Observer();
 | |
|   Promise.reject("I am an uncaught rejection.");
 | |
|   await deactivate.blocker;
 | |
|   Assert.ok(true, "The observer has observed an uncaught Promise.");
 | |
|   deactivate.active = false;
 | |
|   info("Removing the observer, it should not observe any further uncaught Promise.");
 | |
| 
 | |
|   info("Rejecting a Promise and waiting a little to give a chance to observers.");
 | |
|   let wait = new Observer();
 | |
|   Promise.reject("I am another uncaught rejection.");
 | |
|   await wait.blocker;
 | |
|   await new Promise(resolve => setTimeout(resolve, 100));
 | |
|   // Normally, `deactivate` should not be notified of the uncaught rejection.
 | |
|   wait.active = false;
 | |
| });
 | |
| 
 | |
| function run_test() {
 | |
|   run_next_test();
 | |
| }
 |