Skip to content
This repository has been archived by the owner on Sep 19, 2018. It is now read-only.

Asynchronous step function that does not modify this value #236

Closed
JosephPecoraro opened this issue Jan 30, 2017 · 9 comments
Closed

Asynchronous step function that does not modify this value #236

JosephPecoraro opened this issue Jan 30, 2017 · 9 comments

Comments

@JosephPecoraro
Copy link
Contributor

JosephPecoraro commented Jan 30, 2017

When attempting to write an async test, t.step_func is useful for wrapping a callback function, however it modifies the this value within the callback. I'd like to add a variant that doesn't modify the this value, t.step_func_unmodified_this.


Implementation (simplified)

Test.prototype.step_func_unmodified_this = function(func)
{
    var t = this;
    return function() {
        return t.step.apply(test_this, [func, this].concat(Array.from(arguments));
    };
}

Docs

For asynchronous callbacks where the this value is significant, step_func_unmodified_this can be used. For example:

var observer = new Observer(t.step_func_unmodified_this(function() {
    assert_true(this instanceof Observer, "this value must be Observer");
    t.done();
}));

Currently the above test would need to be written something like:

var finish = t.step_func(function() { t.done(); });
var observer = new Observer(function() {
    var self = this;
    t.step(function() {
        assert_true(self instanceof Observer, "this value must be Observer");
        finish();
    });
});

Which is quite obtuse, and requires using a different name for this even though this is what is being tested.

@gsnedders
Copy link
Contributor

What does step_func have as this when it does call?

@JosephPecoraro
Copy link
Contributor Author

The this value is test object created by async_test:

let x = async_test(function(t) {
    setTimeout(t.step_func(function() {
        console.log(this === x); // true
        console.log(this === t); // true
        t.done();
    }));
}, "Title");

@JosephPecoraro
Copy link
Contributor Author

You could change Test.prototype.step_func to not modify the this value if an explicit this_obj was not provided.

Something like: (untested)

Test.prototype.step_func = function(func, this_obj)
{
    var test_this = this;
    var has_explicit_this_obj = arguments.length > 1;

    return function()
    {
        var func_this = has_explicit_this_obj ? this_obj : this;
        return test_this.step.apply(test_this, [func, func_this].concat(
            Array.prototype.slice.call(arguments)));
    };
};

I wasn't sure if anything relied on this behavior (I only just started using testharness.js today).

@gsnedders
Copy link
Contributor

I wasn't sure if anything relied on this behavior (I only just started using testharness.js today).

I have no idea! I'm wondering if we can get away with that. :)

@JosephPecoraro
Copy link
Contributor Author

Do you have a way of running all (or a large portion of) the tests? I'm afraid if I do it I won't be able to test enough of the tests to guarantee there will be no regressions.

@gsnedders
Copy link
Contributor

I can, though it takes a while. Probably easier when I'm not travelling and using my laptop. :)

@Ms2ger
Copy link
Contributor

Ms2ger commented Jan 31, 2017

I'm a little concerned about changing this; would using .bind(this) be sufficient?

@JosephPecoraro
Copy link
Contributor Author

bind would override the this that we are trying to test. Or were you thinking of using it on something else?

@wpt-issue-mover
Copy link
Collaborator

This issue has been moved to web-platform-tests/wpt#7182; please continue all discussion there.

@w3c w3c locked and limited conversation to collaborators Aug 31, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants