summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/promise/debugger-reaction-does-not-resolve.js
blob: 48aec08e26b6d95c73a5d1f12b14e66779bc9d65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
// Promise.race(...) may add a dummy PromiseReaction which is only used for the
// debugger. Ensure that this dummy reaction can't influence the normal Promise
// resolution behaviour.
//
// See BlockOnPromise when called from PerformPromiseRace for when this dummy
// reaction is created.

function newPromiseCapability() {
    var resolve, reject, promise = new Promise(function(r1, r2) {
        resolve = r1;
        reject = r2;
    });
    return {promise, resolve, reject};
}

function neverCalled() {
    // Quit with non-zero exit code to ensure a test suite error is shown,
    // even when this function is called within promise handlers which normally
    // swallow any exceptions.
    quit(1);
}

var c = 0;
var g_resolve;

var resolvedValues = [];

function resolveCapability(v) {
   resolvedValues.push(v);
}

class P extends Promise {
    constructor(executor) {
        // Only the very first object created through this constructor gets
        // special treatment, all other invocations create built-in Promise
        // objects.
        if (c++ > 1) {
            return new Promise(executor);
        }

        executor(resolveCapability, neverCalled);

        var {promise, resolve} = newPromiseCapability();
        g_resolve = resolve;

        // Use an async function to create a Promise without resolving functions.
        var p = async function(){ await promise; return 456; }();

        // Ensure the species constructor is not the built-in Promise constructor
        // to avoid falling into the fast path.
        p.constructor = {
            [Symbol.species]: P
        };

        return p;
    }
}

var {promise: alwaysPending} = newPromiseCapability();

// The promise returned from race() should never be resolved.
P.race([alwaysPending]).then(neverCalled, neverCalled);

g_resolve(123);

drainJobQueue();

// Check |resolvedValues| to ensure resolving functions were properly called.
assertEq(resolvedValues.length, 2);
assertEq(resolvedValues[0], alwaysPending);
assertEq(resolvedValues[1], 456);