Henrique Barcelos
Henrique Barcelos

Reputation: 7900

Node debug: watch expression yields different result from exec console.log

I'm implementing my own Promise A+ compatible package just for the fun. While testing it, and error came accross and I'm having a bad time to solve it.

I'm trying to test it against the Promise A+ Test Suite. The test cases that are causing the issue are all that test "If/when y is a thenable for a thenable..." (described here).

Here is the description of the first failing test:

Promise Promises/A+ Test 2.3.3: Otherwise, if x is an object or function, 2.3.3.3: If then is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise 2.3.3.3.1: If/when resolvePromise is called with value y, run [[Resolve]](promise, y) y is a thenable for a thenable y is an already-fulfilled promise for a synchronously-fulfilled custom thenable then calls resolvePromise synchronously via return from a fulfilled promise

This is how I wrote my adapter:

var adapter = (function() {
    var res, rej;
    return {
        defered: {
            promise: new Promise(function(resolve, reject){
                res = resolve;
                rej = reject;
            }),
            resolve: res,
            reject: rej,
        }
    }
})();

describe("Promises/A+ Tests", function () {
    require("promises-aplus-tests").mocha(adapter);
});

Here is the gist for the full implementation. The issue is happening on the following part:

Promise.prototype.then = function(onFulfill, onReject) {
    let p = new Promise();

    debugger;
    let pending = {
        fulfill: isFunction(onFulfill) ? onFulfill : v => v,
        reject: isFunction(onReject) ? onReject : e => { throw e },
        promise: p,
    };

    this.queue.push(pending);

    run.call(this);

    return p;
};

Here's when the oddities begin. One of the tests tries to assess that when a promise yields a promise to a promise, it will be fulfilled with the same value.

I'm getting some strange errors, so I tried to debug it all the way.

What is going on: when the debugger reach the breakpoint in the code above, watch is behaving weirdly.

If I run watch('onFulfill'), watchers will give me:

0: onFulfill = undefined

But if I do exec console.log(onFulfill), it will print:

< [Function: onBasePromiseFulfilled]

What is going on here?

Edit:

When stopped in the debugger statement, having created the p variable, if I type:

> p

in the debugger console, It gives me:

< { state: State('pending'), queue: [] }

But if I try to do:

> exec console.log(p)

The program crashes, giving me a termination error.

Upvotes: 3

Views: 268

Answers (1)

ekuusela
ekuusela

Reputation: 5292

I tried to reproduce this but your adapter doesn't look like what they describe in the readme: adapter.deferred should be a function. After modifying your adapter I managed to debug it using node-inspector.

Even after fixing the adapter, I did get some weird behaviour with mocha debug console but it's my first time debugging with node/mocha so I don't know if it's actually weird. No termination errors, but trying to console.log some definitely defined variables came out as undefined.

Also, without modifying the adapter, running the tests failed almost immediately with a clear error message. Se we probably were running the tests differently or something was different with our setups if you didn't get that.

Here's the adapter I used:

var adapter = (function() {
    var res, rej;
    return {
        deferred: function() { 
            return {
                promise: new Promise(function(resolve, reject){
                    res = resolve;
                    rej = reject;
                }),
                resolve: res,
                reject: rej,
            };
        }
    }
})();

Upvotes: 1

Related Questions