-
-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Give a deprecation warning if a suite callback returns a value. #3243
Conversation
@jleedev Awesome! Indeed the |
Thanks. I'm not sure adding more checks around ways in which Mocha can be misused is something we need to be in the business of. Nowhere in the documentation does it state that the return value of a suite's callback is consumed. Similarly, you could pass a |
@Bamieh Given my comments above, do you still think this should be merged? |
My argument here is that "just slap async on the function" is so tempting to integrate with whatever resources are needed, and it's easy to break your entire test suite in a subtle way. I don't think it's at all the same as attemping to pass That being said, it could be beneficial to call out a suggested fix — "You probably want to use |
if the describe block returns anything truthy, throw an error |
I get what you're saying about I like @ORESoftware's suggestion, actually, but that is a breaking change, because it doesn't necessarily cause anybody's tests to fail. For example: describe('something', function () {
it('is my test', function () {
// ...
});
return true;
}); It's pointless, but it currently works, unlike using What would we think of adding a soft deprecation warning if a value is returned from a |
@boneskull add a warning if anything truthy is returned for the next few patches, then maybe next minor release throw an error? |
@ORESoftware well, next major since it's breaking, but yeah, that's the idea. |
yeah I guess that makes sense |
@jleedev are you on-board changing this to a deprecation message? basically:
|
Yes, I like that. Branch updated with this strawman. Robots are running the browser tests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@boneskull IMHO we should not be warning users for mocha misuse, so in most cases we should not be doing this. However i feel that this warning is reasonable to prevent very subtle errors, but again it is restricting our users for no real reason on the library level, a small warning text in the documentation might suffice here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, looks good. I have a couple changes needed to avoid user complaints 😉
lib/utils.js
Outdated
* | ||
* @param {string} msg | ||
*/ | ||
exports.deprecate = process.emitWarning |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to complicate this, but it's a bit more complicated. 😝
- The user should only see this notice once. For each unique
msg
, we need some to keep some flag (probably in an object, as its key, since we have no access toSet
) and do nothing if the flag is already set. For safety, coercemsg
into astring
viamsg = String(msg)
- Internally,
process.emitWarning
emits on the next tick. So,console.warn(msg)
must happen withinprocess.nextTick
as well. This is to avoid bloating or interfering w/ the call stack
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, please rebase onto master
to make the Snyk warning go away
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If process.nextTick
is unavailable (outside of Node), is it preferred to use Promise.resolve().then(…)
or setTimeout(…, 0)
?
(Aha, Snyk wouldn't actually show me anything.)
Did this change and rebased.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this also need to hook into the --no-deprecation
flags?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Looking good.
There's a unit test suite for the utils
module; could you add a quick unit test for exports.deprecate()
? It's throwing off the coverage numbers.
After we have a test (and the other change I mentioned) it'll be good to merge. Great work!
As long as this is not supported, the behavior is confusing (see issue 2975 and others). It can produce a suite that is not properly initialized. Turning this into a hard error will make it clear that this is not supported.
I actually added to the integration tests. Is it possible to verify a call to |
The message itself implies that this was previously supported. 'Returning a value from a Suite was previously undocumented; it is now explicitly verboten and will throw an exception in the next major version of Mocha' |
I disagree; it was not disallowed, not supported. If you pass an extra parameter to any given function in Mocha's API, if it doesn't break, that doesn't imply it's supported.
I agree that we shouldn't generally be in the business of warning users about misusing the API. The only reason I'm entertaining it is because of the potential for causing difficult-to-solve problems. IMO the real problem here is that suites don't support async behavior. Maybe that should change. If we do want that to change (at some point), we shouldn't merge this, and instead add a note to the docs. @mochajs/core would love further thoughts |
@boneskull I agree with you about not merging this if there is a possibility of having async suites. I do not see the value of supporting async suites, as I usually encourage people to write all the fetching logic in the |
I don't understand why the possibility of async suites in the future should prevent merging this right now. Either way, adding async suites will break compatibility to the same degree, and the warning can be removed. No one should be returning a Promise from a suite before they're actually supported. |
4547268
to
7613521
Compare
@boneskull were your concerns addressed? |
churn, mainly. but async suites is probably a ways off. |
@plroebuck I've noted two problems. fine to merge and then fix them after; I don't want to ask @jleedev to do more work. |
I've "approved", but the stuff I noted must be addressed one way or another |
I'll ask. Since this was intended for patch release, plan going forward is to?
|
Description of the Change
As long as this is not supported, the behavior is confusing. It can produce a suite that is not properly initialized. Turning this into a hard error will make it clear that this is not supported.
In short, the test suite below currently does nothing; this change will make it into an error.
Other usage could possibly produce a partially-initialized test suite that fails for unknown reasons; this will make it fail obviously.
Alternate Designs
Original proposal was to throw, but settled for a deprecation warning in the accepted version.
This would need be revisited in future to throw an Error instead.
Why should this be in core?
N/A
Benefits
Reduction in user confusion/expectations attempting to use
describe
function as anything but a namespace.Possible Drawbacks
Users will get deprecation warning for unsupported behavior.
No real downside to knowledge.
Applicable issues
Fixes #2975
semver-patch