You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is an impedance mismatch in the current 1.x series API for td.replace that is causing enough confusion and edge case pain that I think we should unwind it.
In the above case, button is essentially set to {press: td.func('Button#press')}.
However, in the './gamepad' module, a constructor for Button will be provided when it's imported/required, so that the line new Button().press('A') will behave the same way in production as it does when under test.
This was done because a unit test typically just wants to get at the "instance" methods on the type that's being replaced and to have to reach into the prototype by doing: td.verify(button.prototype.press('A')) was initially seen as unnecessarily awkward.
The case for changing this
A few reasons we want to change this:
This is surprising behavior to everyone but @searls
Returning the same thing to the test and the subject will be more obvious/honest/symmetrical for users
This will allow us to refactor one of the ugliest parts of td.js's codebase
"static" methods, or properties on the constructor function (as opposed to the prototype) are neither faked nor returned to the test
This may enable "instanceof" if we set up prototypal inheritance between our fake constructors and the constructor being doubled.
This may enable us to allow users to ensure replaced dependencies are instantiated as expected, which couldn't be done before because the constructor function itself wasn't faked and returned
Requirements
Figure out how to stub/verify the constructor itself to be sure the subject instantiates the dependency with the expected params. I have no idea how we'll do this, but this is probably our only chance of figuring that out. I'd like to see a few examples of this that accomplish what a reasonable user would want before we decide on a final API
Ensure the final API works will pass instanceof checks in subject code (e.g. if I td.replacePantsError then error instanceof PantsError should return true for the fake (and not for other arbitrary faked constructors)
Ensure the final API works with ES6 "static" methods
Cut a migration release that warns with instructions for how to fix this and, potentially, an intermediary API folks can opt-into and then simply do a grep-replace when they do upgrade to 2.x
This will obviate the need for implementing the following as separate features: #54, #159, #164, #121, #108
The text was updated successfully, but these errors were encountered:
There is an impedance mismatch in the current 1.x series API for td.replace that is causing enough confusion and edge case pain that I think we should unwind it.
First, an example to anyone not familiar:
Example
Suppose we have module
'./gamepad'
:If we're testing
Gamepad
and replacingButton
In the above case,
button
is essentially set to{press: td.func('Button#press')}
.However, in the
'./gamepad'
module, a constructor for Button will be provided when it's imported/required, so that the linenew Button().press('A')
will behave the same way in production as it does when under test.This was done because a unit test typically just wants to get at the "instance" methods on the type that's being replaced and to have to reach into the
prototype
by doing:td.verify(button.prototype.press('A'))
was initially seen as unnecessarily awkward.The case for changing this
A few reasons we want to change this:
Requirements
td.replace
PantsError
thenerror instanceof PantsError
should return true for the fake (and not for other arbitrary faked constructors)This will obviate the need for implementing the following as separate features: #54, #159, #164, #121, #108
The text was updated successfully, but these errors were encountered: