-
-
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
fix: add global leaks detection on watch-run #4059
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -85,10 +85,17 @@ const createRerunner = (mocha, beforeRun) => { | |||||
|
||||||
let rerunScheduled = false; | ||||||
|
||||||
let initialGlobals = null; | ||||||
|
||||||
const run = () => { | ||||||
try { | ||||||
beforeRun(); | ||||||
resetMocha(mocha); | ||||||
|
||||||
if (!initialGlobals) { | ||||||
initialGlobals = Object.keys(global); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Style] Now that Mocha doesn't need to support super old versions of IE & the like, let's switch to a
Suggested change
That way the |
||||||
} | ||||||
|
||||||
runner = mocha.run(() => { | ||||||
runner = null; | ||||||
if (rerunScheduled) { | ||||||
|
@@ -114,6 +121,15 @@ const createRerunner = (mocha, beforeRun) => { | |||||
}; | ||||||
|
||||||
const rerun = () => { | ||||||
if (initialGlobals) { | ||||||
Object.keys(global).forEach(k => { | ||||||
if (initialGlobals.indexOf(k) === -1) { | ||||||
delete global[k]; | ||||||
} | ||||||
}); | ||||||
initialGlobals = null; | ||||||
} | ||||||
|
||||||
rerunScheduled = false; | ||||||
eraseLine(); | ||||||
run(); | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
describe('leak detection', function() { | ||
function testMe() { | ||
x = 123; // leak variable | ||
} | ||
|
||
it('should not leak', function(done) { | ||
testMe(); | ||
done(); // just pass | ||
}); | ||
|
||
before(function() {}); | ||
|
||
after(function() {}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hooks needed here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense, but isn't intuitive from the test. Request: how about a quick comment explaining why these are 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.
@Uzlopak @voxpelli and I talked about this approach: we think it's promising and gets the job done partially, but there are blocking edge cases around side effects. For example, if the first time a test is run, the test imports cached polyfills that add globals, deleting the global after the test would mean subsequent tests would fail.
delete global[k]
isn't something that Mocha can reasonably do.Instead, we think a more workable approach would be to have the runner check for global leaks against the initial state of globals before all tests. I.e. keep the
initialGlobals
idea, but not thedelete global[k]
idea. Doing so would mean that necessary globals that can only be introduced exactly one won't be deleted on--watch
. (does that make sense?)One drawback of this proposed approach is that if a leak exists in a test, then is fixed, it'll still be reported on re-runs. Mocha's messaging when
--check-leaks
and--watch
are enabled will have to note that if the leak is fixed then the user will have to restart Mocha.So, two requests, please:
See also #4954 / #4954 (comment). Part of why we're looking at deprecating the
--check-leaks
feature long-term is that it isn't comprehensive enough to get many common modern use cases. The only reliable way for a test framework to achieve true encapsulation(-ish) and leak detection is with VMs the way Jest & co do. For Mocha, you'd have to build a plugin and/or use linting and/or / type checking and/or"use strict";
and/or proper ESM.