-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
chore: migrate jest-environment-node to TypeScript #7985
Conversation
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need the corporate CLA signed. If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks! |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
Ok, got it! That's what you were referring to here #7964 (review) I take? I'll wait for #7987 to be merged and then I'll finish up this PR. |
Yeah! |
@@ -88,7 +84,7 @@ class NodeEnvironment { | |||
} | |||
|
|||
// Disabling rule as return type depends on script's return type. | |||
runScript(script: Script): ?any { | |||
runScript(script: Script): any | null | undefined { |
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.
null | undefined
is redundant since this is already any.
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.
It shouldn't be any
. This is my current best guess at the type: https://github.com/facebook/jest/blob/419661f57ea8e3af26a788bb3db92127c854d13b/packages/jest-environment/src/index.ts#L30-L32
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.
Essentially, the return value this object: https://github.com/facebook/jest/blob/419661f57ea8e3af26a788bb3db92127c854d13b/packages/jest-transform/src/ScriptTransformer.ts#L559-L565
which is called like this: https://github.com/facebook/jest/blob/419661f57ea8e3af26a788bb3db92127c854d13b/packages/jest-runtime/src/index.ts#L689-L711
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.
null | undefined
is redundant since this is already any.
I agree, I was just trying to refactor without changing to much. I'll try to change it into a proper type instead of any
.
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.
@SimenB WRT the any
type here. I've just logged what is returned from runScript() and it looks like this (in a separate app/jest setup):
{ 'Object.<anonymous>': [Function: Object.<anonymous>] }
JSON stringified it is an empty object:
'{}'
I'm not sure what to put as the return type here. I just don't have enough understanding of what is being done in the method. Just keep it as any
? Or an unsealed object {} | undefined | null
? Open to suggestions.
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.
Never mind, I'll follow your diff below.
@lirbank merged |
Codecov Report
@@ Coverage Diff @@
## master #7985 +/- ##
==========================================
+ Coverage 64.54% 64.54% +<.01%
==========================================
Files 257 257
Lines 10074 10076 +2
Branches 1587 1586 -1
==========================================
+ Hits 6502 6504 +2
- Misses 3229 3230 +1
+ Partials 343 342 -1
Continue to review full report at Codecov.
|
Opened up #7988 as well, which is needed here. If I rebase this branch on top of master, I can apply this diff: diff --git i/packages/jest-environment-node/src/index.ts w/packages/jest-environment-node/src/index.ts
index 28473c6c5..3a9b5672e 100644
--- i/packages/jest-environment-node/src/index.ts
+++ w/packages/jest-environment-node/src/index.ts
@@ -9,6 +9,7 @@ import vm, {Script, Context} from 'vm';
import {Global, Config} from '@jest/types';
import {ModuleMocker} from 'jest-mock';
import {installCommonGlobals} from 'jest-util';
+import {JestEnvironment} from '@jest/environment';
import {JestFakeTimers as FakeTimers} from '@jest/fake-timers';
type Timer = {
@@ -17,11 +18,11 @@ type Timer = {
unref: () => Timer;
};
-class NodeEnvironment {
- context?: Context | null;
- fakeTimers?: FakeTimers<Timer> | null;
- global?: Global.Global | null;
- moduleMocker?: ModuleMocker | null;
+class NodeEnvironment implements JestEnvironment {
+ context: Context | null;
+ fakeTimers: FakeTimers<Timer> | null;
+ global: Global.Global;
+ moduleMocker: ModuleMocker | null;
constructor(config: Config.ProjectConfig) {
this.context = vm.createContext();
@@ -70,11 +71,11 @@ class NodeEnvironment {
});
}
- setup(): Promise<void> {
+ setup() {
return Promise.resolve();
}
- teardown(): Promise<void> {
+ teardown() {
if (this.fakeTimers) {
this.fakeTimers.dispose();
}
@@ -83,8 +84,8 @@ class NodeEnvironment {
return Promise.resolve();
}
- // Disabling rule as return type depends on script's return type.
- runScript(script: Script): any | null | undefined {
+ // TS infers the return type to be `any`, since that's what `runInContext` returns.
+ runScript(script: Script): ReturnType<JestEnvironment['runScript']> {
if (this.context) {
return script.runInContext(this.context);
}
@@ -92,4 +93,4 @@ class NodeEnvironment {
}
}
-module.exports = NodeEnvironment;
+export = NodeEnvironment; and everything seems to work 🙂 |
@SimenB do you want |
@@ -60,7 +54,8 @@ class NodeEnvironment { | |||
}, | |||
}); | |||
|
|||
const timerRefToId = (timer: Timer): ?number => (timer && timer.id) || null; | |||
const timerRefToId = (timer: Timer): number | undefined => | |||
(timer && timer.id) || undefined; |
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.
Please note that I've changed the possible return type from null to undefined here. FakeTimers does not like the timerConfig if timerRefToId returns null (but undefined is OK).
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.
That's fine. Happy to get rid of the null
!
Yes 🙂 |
Thanks! Could you update the changelog and mark this PR ready for review (I'm not allowed to merge while it's a draft 🙂)? |
Updated git diff: diff --git a/packages/jest-environment-node/build/index.js b/packages/jest-environment-node/build/index.js
index 1c59cb7b7..25d56a387 100644
--- a/packages/jest-environment-node/build/index.js
+++ b/packages/jest-environment-node/build/index.js
@@ -10,10 +10,10 @@ function _vm() {
return data;
}
-function _fakeTimers() {
- const data = require('@jest/fake-timers');
+function _jestMock() {
+ const data = require('jest-mock');
- _fakeTimers = function _fakeTimers() {
+ _jestMock = function _jestMock() {
return data;
};
@@ -30,10 +30,10 @@ function _jestUtil() {
return data;
}
-function _jestMock() {
- const data = _interopRequireDefault(require('jest-mock'));
+function _fakeTimers() {
+ const data = require('@jest/fake-timers');
- _jestMock = function _jestMock() {
+ _fakeTimers = function _fakeTimers() {
return data;
};
@@ -49,8 +49,6 @@ function _interopRequireDefault(obj) {
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
- *
- *
*/
class NodeEnvironment {
constructor(config) {
@@ -75,7 +73,7 @@ class NodeEnvironment {
}
(0, _jestUtil().installCommonGlobals)(global, config.globals);
- this.moduleMocker = new (_jestMock()).default.ModuleMocker(global);
+ this.moduleMocker = new (_jestMock()).ModuleMocker(global);
const timerIdToRef = id => ({
id,
@@ -89,7 +87,7 @@ class NodeEnvironment {
}
});
- const timerRefToId = timer => (timer && timer.id) || null;
+ const timerRefToId = timer => (timer && timer.id) || undefined;
const timerConfig = {
idToRef: timerIdToRef,
@@ -115,7 +113,8 @@ class NodeEnvironment {
this.context = null;
this.fakeTimers = null;
return Promise.resolve();
- } // Disabling rule as return type depends on script's return type.
+ } // TS infers the return type to be `any`, since that's what `runInContext`
+ // returns.
runScript(script) {
if (this.context) { |
Thanks! |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
@SimenB here is a first migration of
jest-environment-node
.I can't seem to import
FakeTimers
via the default module export. If I do this:I get
Cannot find name 'FakeTimers'.ts(2304)
.However, this works (albeit not ideal):
I think it has to do with the use of NodeJS-style export in
jest-utils
(instead of ES6 styleexport {}
(no equals sign)), but not sure:https://github.com/facebook/jest/blob/51817fd79a3744078a82861f3763dc346ca0cbd6/packages/jest-util/src/index.ts#L30-L52
How should I deal with this you think?