Migrate Sinon.jsm to an ES module
Categories
(Testing :: General, task)
Tracking
(firefox113 fixed)
Tracking | Status | |
---|---|---|
firefox113 | --- | fixed |
People
(Reporter: standard8, Assigned: canadahonk)
References
(Blocks 1 open bug)
Details
(Whiteboard: [esmification-timeline])
Attachments
(1 file)
(deleted),
text/x-phabricator-request
|
Details |
As part of the ongoing migration work, we should migrate Sinon.jsm to be a module file, or possibly change sinon.js to be a module.
One difficult part here is dealing with how sinon.js overrides/uses setTimeout and other functions, and how we currently deal with overriding them.
Attempting to do a simple conversion of the jsm
file to sys.mjs
fails due to:
Unexpected exception ReferenceError: setTimeout is not defined at resource://testing-common/sinon-7.2.7.js:3777
I suspect that's something to do with loadSubScript
being called inside a system module, but I'm not sure.
Comment 1•2 years ago
|
||
sinon-7.2.7.js
expects setTimout
being defined as global variable:
setTimeout: setTimeout,
but it's loaded with an object only with global
property:
const obj = {
global: {
...
},
};
Services.scriptloader.loadSubScript(
"resource://testing-common/sinon-7.2.7.js",
obj
);
so, the lookup for setTimeout
goes to the enclosing scope, and in this case,
the lexical variable in Sinon.jsm
is used:
const {
...
setTimeout,
...
} = ChromeUtils.importESModule("resource://gre/modules/Timer.sys.mjs");
This is the following case, where WithEnvironmentObject
holds the obj
, and the NonSyntacticLexicalEnvironmentObject[this=nsvo]
holds setTimeout
.
* B.2 Subscript loading (Shared-global JSM)
*
* The target object of a subscript load may be in a JSM with a shared global,
* in which case we will also have the NonSyntacticVariablesObject on the
* chain.
* NonSyntacticLexicalEnvironmentObject for target object holds lexical
* variables and WithEnvironmentObject holds qualified variables.
* Unqualified names goes to NonSyntacticVariablesObject.
*
* Target object's global
* |
* GlobalLexicalEnvironmentObject[this=global]
* |
* NonSyntacticVariablesObject (unqualified names)
* |
* NonSyntacticLexicalEnvironmentObject[this=nsvo]
* |
* WithEnvironmentObject wrapping target (qualified 'var's)
* |
* NonSyntacticLexicalEnvironmentObject[this=target] (lexical vars)
NonSyntacticVariablesObject
and NonSyntacticLexicalEnvironmentObject[this=nsvo]
are created because JSM uses non-syntactic scope.
then, if Sinon.jsm
is ESMified, ESM does not use non-syntactic scope, and NonSyntacticLexicalEnvironmentObject[this=nsvo]
is not created for global lexical variable, which means setTimeout
lookup cannot find setTimeout
lexical variable there.
Only global variables defined on the shared global is accessible from the subscript.
* B.1 Subscript loading
*
* Subscripts may be loaded into a target object and it's associated global.
* NonSyntacticLexicalEnvironmentObject holds lexical variables and
* WithEnvironmentObject holds qualified variables. Unqualified names goes
* to the target object's global.
* They have the following env chain:
*
* Target object's global (unqualified names)
* |
* GlobalLexicalEnvironmentObject[this=global]
* |
* WithEnvironmentObject wrapping target (qualified 'var's)
* |
* NonSyntacticLexicalEnvironmentObject[this=target] (lexical vars)
Possible workaround is to pass setTimeout
and other variables sinon-7.2.7.js
expects as obj
's property, in the same way as global
property there.
const obj = {
global: {
...
},
clearInterval,
clearTimeout,
setInterval,
setIntervalWithTarget,
setTimeout,
setTimeoutWithTarget,
// and maybe some more?
};
Services.scriptloader.loadSubScript(
"resource://testing-common/sinon-7.2.7.js",
obj
);
Assignee | ||
Comment 2•2 years ago
|
||
Migrated testing/modules/Sinon.sys.mjs
to an ES module.
testing
should now be 100% ESM :tada:
Updated•2 years ago
|
Comment 4•2 years ago
|
||
bugherder |
Description
•