-
Notifications
You must be signed in to change notification settings - Fork 23
feat: migrate lib to typescript #40
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
Conversation
ESLint is failing due to missing resolvers from I'll add the missing eslint settings and the required peer dependency |
Ok funny thing: it is failing not due to I'll add the missing |
please use the full |
Node 10 is failing due to unexpected token at class BaseTestRunner {
_globalConfig;
_context;
constructor(globalConfig, context) {
this._globalConfig = globalConfig;
this._context = context;
}
} I'll add the |
6e910e1
to
e51967c
Compare
1ecb9f8
to
a4eb7c4
Compare
I rebased and fix some lint errors. Unfortunately some lint rules have to be disabled:
errorMessage || test.errorMessage
? [(errorMessage || test.errorMessage) as string]
: [] Edit: |
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.
can you remove
create-jest-runner/.eslintignore
Lines 4 to 5 in 3f50f78
# remove after migrating to TS | |
types/ |
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! I just left some nits, but overall this is really solid 👍
lib/createJestRunner.ts
Outdated
readonly _globalConfig: Config.GlobalConfig; | ||
|
||
readonly _context: JestRunner.TestRunnerContext; |
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.
readonly _globalConfig: Config.GlobalConfig; | |
readonly _context: JestRunner.TestRunnerContext; | |
private readonly _globalConfig: Config.GlobalConfig; | |
private readonly _context: JestRunner.TestRunnerContext; |
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.
Making _globalConfig
and _context
private requires removing the corresponding class properties in the declare class TestRunner { /* */ }
otherwise typescript complains about Types have separate declarations of a private property '_globalConfig'.
I can add the private
keyword if you think this is good enough :)
@@ -53,7 +77,7 @@ const createRunner = (runPath, { getExtraOptions } = {}) => { | |||
} | |||
|
|||
return onStart(test).then(() => { | |||
// eslint-disable-next-line import/no-dynamic-require, global-require | |||
// eslint-disable-next-line import/no-dynamic-require, global-require, @typescript-eslint/no-var-requires | |||
const runner = require(runPath); |
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.
I wonder if we should do import(runPath)
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.
It can be done by changing it to:
onStart(test).then(() => import(runPath)).then(runner => { /* */ })
But babel
would emit more code
onStart(test)
.then(() => Promise.resolve(`${runPath}`)
.then(s => _interopRequireWildcard(require(s))))
.then(runner => { /* */ })
Instead of what it currently emits:
onStart(test).then(() => {
const runner = require(runPath);
/* */
})
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.
we should change when we drop node 10
} | ||
|
||
// Copied and adapted from https://github.com/facebook/jest/blob/2dafb09d51584d3785f3280f569784ec4334b5d8/packages/jest-runner/src/index.ts#L48-L285 | ||
export declare abstract class TestRunner { |
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.
is this something we should export from Jest?
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.
Actually it is exported from "jest-runner"
as
declare class JestRunner { /* ... */ }
export = JestRunner
But unfortunately I cannot use this JestRunner
to annotate the return type of createTestRunner
since it contains properties that our BaseTestRunner
does not have, namely:
private readonly eventEmitter: Emittery.Typed<JestTestEvents>
readonly __PRIVATE_UNSTABLE_API_supportsEventEmitters__: boolean
readonly isSerial?: boolean
on: Emittery.Typed<JestTestEvents>
(an alias of eventEmitter but bound tothis.eventEmitter
)
I actually dug into the jest
codebase but it seems that the event emitter api seems to be considered unstable and prone to change in jest
v27 (I suspect it has something to do with the jest-circus
and flux-based architecture thingy), and I'm not sure if it is the right thing to add an additional dependency emittery
to the project.
I couldn't find related docs or changelogs for the eventEmitters which were added since this commit so I decided I would copy and paste the JestRunner
class declaration from jest-runner
package with the fields that BaseTestRunner
does not implement removed.
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.
I tried and I can change TestRunner
in lib/types.ts
to
export declare abstract class TestRunner
implements
Omit<JestRunner, '__PRIVATE_UNSTABLE_API_supportsEventEmitters__' | 'on'> {
constructor(globalConfig: JestConfig.GlobalConfig);
runTests(
tests: Array<JestRunner.Test>,
watcher: JestRunner.TestWatcher,
onStart: JestRunner.OnTestStart,
onResult: JestRunner.OnTestSuccess,
onFailure: JestRunner.OnTestFailure,
options: JestRunner.TestRunnerOptions,
): Promise<void>;
}
But I'm not sure if using the Omit<>
utility type here is good practice. Any suggestions on improvements?
6b619d7
to
99ee3fd
Compare
Hey @SimenB happy new year🙂 any chance that we could continue this in 2021? |
@lokshunhung happy new year! 😅 I've completely dropped the ball on this one... Would you be up for rebasing it? Feel free to squash everything into a single commit for that to avoid horrible conflicts repeatedly. After that I'll take a new look 🙂 (please ping me when you've rebased, GH doesn't always send an email for pushes) |
chore: install @babel/preset-typescript ^7.0.0 chore: enable @babel/preset-typescript in babelrc enable options defaults to be enabled in babel 8 disable babelrc allowNamespaces because namespaces are legacy ts features and probably should not be used chore: add tsconfig.json esModuleInterop is disabled or else https://github.com/facebook/jest/blob/master/scripts/babel-plugin-jest-replace-ts-require-assignment.js might be needed to be copied to this repo Co-authored-by: Simen Bekkhus <[email protected]> enable emitDeclarationOnly in tsconfig.json Co-authored-by: Simen Bekkhus <[email protected]> chore: enable importsNotUsedAsValues, disable isloatedModules in tsconfig.json Co-authored-by: Simen Bekkhus <[email protected]> refactor: migrate toTestResult.js to ts refactor: fix toTestResult.ts types Allowing type checking to pass requires the following changes: - Remove optional result.console: null - Add result.leaks: false - Add result.openHandles: [] - Add result.perfStats.runtime: (end - start) - Add result.perfStats.slow: false - Add result.snapshot.uncheckedKeys: [] - Remove optional result.sourceMaps: {} - Remove optional result.testExecError: null - Add result.testResults[].failureDetails: [] - Change result.testResults[].failureMessage to always return a string - Change result.testResults[].fullName to always return a string refactor: extract & document getPerfStats fn in toTestResult.ts refactor: extract getSnapshot fn from toTestResult.ts refactor: extract getTestResults fn from toTestResult.ts refactor: migrate todo.js to ts refactor: extract common types from todo.ts refactor: migrate skip.js to ts refactor: extract common types from skip.ts refactor: migrate pass.js to ts refactor: extract common types from pass.ts refactor: migrate fail.js to ts fix: add fail.ts errorMessage to toTestResult options.tests refactor: migrate createJestRunner.js to ts refactor: _createParallelTestRun return Promise<void> in createJestRunner.ts The method _createParallelTestRun returns Promise<PollExitRun> implicitly via cleanup By wrapping the cleanup function with an arrow function body, it explicitly returns undefined (void) This allows _createParallelTestRun to remove the type cast in its return refactor: migrate index.js to ts chore: add eslint-plugin-import ts settings merge the settings from eslint-plugin-import/typescript preset with eslint-config-airbnb-base https://github.com/benmosher/eslint-plugin-import/blob/4f1101e584558d9c686144b71222acaaf4f70b72/config/typescript.js https://github.com/airbnb/javascript/blob/c5bee75b1b358a3749f1a6d38ee6fad73de28e29/packages/eslint-config-airbnb-base/rules/imports.js chore: use eslint plugin:import/typescript less boilerplate settings seems better than adding a bunch of settings chore: disable no-console lint warning in fixtures chore: disable import/no-unresolved lint for build artifacts fix: add --extensions '.ts' flag so babel compiles ts chore: update script to build types chore: add @babel/plugin-proposal-class-properties this fixes node 10 tests failing due to class properties declaration not being tranformed build: add yarn build-types to ci chore: disable no-useless-constructor lint this rule throws an error of `Cannot read property 'body' of null` when encountering ts ambient class declarations chore: update import/extensions lint options eslint-config-airbnb-base does not include .ts extension in this rule https://github.com/airbnb/javascript/blob/c5bee75b1b358a3749f1a6d38ee6fad73de28e29/packages/eslint-config-airbnb-base/rules/imports.js#L139-L143 chore: disable import/export lint this rule does not understand ts function overloading chore: remove tsc noEmit flag in package.json setting emitDeclarationOnly flag is sufficient for tsc to not emit js files Co-authored-by: Simen Bekkhus <[email protected]> chore: update watch script in package.json Co-authored-by: Simen Bekkhus <[email protected]> chore: remote duplicate eslint override for fixtures refactor: extract error message handling logic in toTestResult.ts chore: update lint rule overrides for js files refactor: fix explicit-module-boundary-types lint warnings chore: remove unused eslintignore glob chore: remove "types/" from files in package.json refactor: extract CreateRunnerOptions in createJestRunner.ts chore: remove unused 'typecheck' npm script it's basically the same as 'build-types' since the '--noEmit' flag was removed chore: remove unnecessary onlyRemoveTypeImports in .babelrc refactor: reuse jest types in types.ts Co-authored-by: Simen Bekkhus <[email protected]> chore: fix lint errors
99ee3fd
to
b0b8d11
Compare
I squashed everything and rebased. Here are the list of changes I made in order to rebase:
I appreciate if you could take a look @SimenB 😄 |
it is shipped by default by preset-env
Thanks for working on this @lokshunhung! |
This pr addresses the following goals in #39
Bump babel & related dependencies to latest, add @babel/preset-typescript
@babel/*
dependencies are updated to the latest 7.12.xAdd tsconfig.json with strict type-checking enabled
tsconfig.json
is initialized withtsc --init
with a few more options enabledAdd typecheck script to package.json#scripts
Type checking of the
lib
directory can be execute withyarn run typecheck
Migrate files in lib one-by-one to typescript & make necessary changes for type-checking to pass
All files in
lib
are migrated to typescript with the following changes that might be potentially breaking for downstream packages:toTestResult.ts
return type has some properties changed fromnull
toundefined
, and some more properties are addedfail.ts
additional error message handling (I'm not sure if the original behaviour of selectively passing onlyoptions.errorMessage
but notoptions.test.errorMessage
to the argument oftoTestResult
call is intentional, but it would be great to have it clarified / deprecate one of the options of passing error message in a future PR)