Skip to content
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-runtime to TypeScript #7964

Merged
merged 16 commits into from Feb 25, 2019
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -57,6 +57,7 @@
- `[jest-circus]`: Migrate to TypeScript ([#7916](https://github.com/facebook/jest/pull/7916))
- `[jest-phabricator]`: Migrate to TypeScript ([#7965](https://github.com/facebook/jest/pull/7965))
- `[jest-runner]`: Migrate to TypeScript ([#7968](https://github.com/facebook/jest/pull/7968))
- `[jest-runtime]`: Migrate to TypeScript ([#7964](https://github.com/facebook/jest/pull/7964))

### Performance

Expand Down
1 change: 1 addition & 0 deletions packages/jest-circus/package.json
Expand Up @@ -11,6 +11,7 @@
"types": "build/index.d.ts",
"dependencies": {
"@babel/traverse": "^7.1.0",
"@jest/environment": "^24.1.0",
"@jest/types": "^24.1.0",
"@types/node": "*",
"chalk": "^2.0.1",
Expand Down
Expand Up @@ -6,17 +6,18 @@
*/

import path from 'path';
import {Config, TestResult, Environment} from '@jest/types';
// @ts-ignore TODO Remove ignore when jest-runtime is migrated to ts
import Runtime from 'jest-runtime'; // eslint-disable-line import/no-extraneous-dependencies
import {Config, TestResult} from '@jest/types';
import {JestEnvironment} from '@jest/environment';
// eslint-disable-next-line import/no-extraneous-dependencies
import Runtime from 'jest-runtime';
import {SnapshotState} from 'jest-snapshot';

const FRAMEWORK_INITIALIZER = require.resolve('./jestAdapterInit');

const jestAdapter = async (
globalConfig: Config.GlobalConfig,
config: Config.ProjectConfig,
environment: Environment.$JestEnvironment,
environment: JestEnvironment,
runtime: Runtime,
testPath: string,
): Promise<TestResult.TestResult> => {
Expand Down
12 changes: 11 additions & 1 deletion packages/jest-circus/tsconfig.json
Expand Up @@ -4,5 +4,15 @@
"outDir": "build",
"rootDir": "src"
},
"references": [{"path": "../jest-types"}, {"path": "../jest-snapshot"}, {"path": "../jest-matcher-utils"}, {"path": "../jest-message-util"}, {"path": "../jest-util"}, {"path": "../pretty-format"}, {"path": "../jest-diff"}]
"references": [
{"path": "../jest-diff"},
{"path": "../jest-environment"},
{"path": "../jest-matcher-utils"},
{"path": "../jest-message-util"},
{"path": "../jest-runtime"},
{"path": "../jest-snapshot"},
{"path": "../jest-types"},
{"path": "../jest-util"},
{"path": "../pretty-format"}
]
}
3 changes: 3 additions & 0 deletions packages/jest-environment/.npmignore
@@ -0,0 +1,3 @@
**/__mocks__/**
**/__tests__/**
src
22 changes: 22 additions & 0 deletions packages/jest-environment/package.json
@@ -0,0 +1,22 @@
{
"name": "@jest/environment",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly so I could reuse jest-mock types
It'll be useful for all test environments, though

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @lirbank relevant for your migrations

"version": "24.1.0",
"repository": {
"type": "git",
"url": "https://github.com/facebook/jest.git",
"directory": "packages/jest-environment"
},
"license": "MIT",
"main": "build/index.js",
"types": "build/index.d.ts",
"dependencies": {
"@jest/transform": "^24.1.0",
"@jest/types": "^24.1.0",
"@types/node": "*",
"jest-mock": "^24.0.0"
},
"engines": {
"node": ">= 6"
},
"gitHead": "b16789230fd45056a7f2fa199bae06c7a1780deb"
}
260 changes: 260 additions & 0 deletions packages/jest-environment/src/index.ts
@@ -0,0 +1,260 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import {Script} from 'vm';
import {Config, Global} from '@jest/types';
import moduleMocker from 'jest-mock';
import {ScriptTransformer} from '@jest/transform';

export type EnvironmentContext = {
console?: Console;
testPath?: Config.Path;
};

// TODO: type this better: https://nodejs.org/api/modules.html#modules_the_module_wrapper
type ModuleWrapper = (...args: Array<unknown>) => unknown;

export interface JestEnvironment {
new (
config: Config.ProjectConfig,
context?: EnvironmentContext,
): JestEnvironment;
runScript(
script: Script,
): {[ScriptTransformer.EVAL_RESULT_VARIABLE]: ModuleWrapper} | null;
global: Global.Global;
// TODO: When `jest-util` is ESM, this can just be `fakeTimers: import('jest-util').FakeTimers`
fakeTimers: {
clearAllTimers(): void;
runAllImmediates(): void;
runAllTicks(): void;
runAllTimers(): void;
advanceTimersByTime(msToRun: number): void;
runOnlyPendingTimers(): void;
runWithRealTimers(callback: () => void): void;
getTimerCount(): number;
useFakeTimers(): void;
useRealTimers(): void;
};
testFilePath: Config.Path;
moduleMocker: typeof moduleMocker;
setup(): Promise<void>;
teardown(): Promise<void>;
}

export type Module = typeof module;

export interface LocalModuleRequire extends NodeRequire {
requireActual(moduleName: string): unknown;
requireMock(moduleName: string): unknown;
}

// TODO: Move to some separate package
export interface Jest {
/**
* Provides a way to add Jasmine-compatible matchers into your Jest context.
*
* @deprecated Use `expect.extend` instead
*/
addMatchers(matchers: Object): void;
/**
* Disables automatic mocking in the module loader.
*/
autoMockOff(): Jest;
/**
* Enables automatic mocking in the module loader.
*/
autoMockOn(): Jest;
/**
* Clears the mock.calls and mock.instances properties of all mocks.
* Equivalent to calling .mockClear() on every mocked function.
*/
clearAllMocks(): Jest;
/**
* Removes any pending timers from the timer system. If any timers have been
* scheduled, they will be cleared and will never have the opportunity to
* execute in the future.
*/
clearAllTimers(): void;
/**
* Indicates that the module system should never return a mocked version
* of the specified module, including all of the specified module's
* dependencies.
*/
deepUnmock(moduleName: string): Jest;
/**
* Disables automatic mocking in the module loader.
*
* After this method is called, all `require()`s will return the real
* versions of each module (rather than a mocked version).
*/
disableAutomock(): Jest;
/**
* When using `babel-jest`, calls to mock will automatically be hoisted to
* the top of the code block. Use this method if you want to explicitly avoid
* this behavior.
*/
doMock(moduleName: string, moduleFactory?: () => unknown): Jest;
/**
* Indicates that the module system should never return a mocked version
* of the specified module from require() (e.g. that it should always return
* the real module).
*/
dontMock(moduleName: string): Jest;
/**
* Enables automatic mocking in the module loader.
*/
enableAutomock(): Jest;
/**
* Creates a mock function. Optionally takes a mock implementation.
*/
fn: typeof moduleMocker.fn;
/**
* Given the name of a module, use the automatic mocking system to generate a
* mocked version of the module for you.
*
* This is useful when you want to create a manual mock that extends the
* automatic mock's behavior.
*/
genMockFromModule(moduleName: string): unknown;
/**
* Determines if the given function is a mocked function.
*/
isMockFunction(fn: Function): fn is ReturnType<typeof moduleMocker.fn>;
/**
* Mocks a module with an auto-mocked version when it is being required.
*/
mock(
moduleName: string,
moduleFactory?: () => unknown,
options?: {virtual?: boolean},
): Jest;
/**
* Returns the actual module instead of a mock, bypassing all checks on
* whether the module should receive a mock implementation or not.
*/
requireActual: (moduleName: string) => unknown;
/**
* Returns a mock module instead of the actual module, bypassing all checks
* on whether the module should be required normally or not.
*/
requireMock: (moduleName: string) => unknown;
/**
* Resets the state of all mocks.
* Equivalent to calling .mockReset() on every mocked function.
*/
resetAllMocks(): Jest;
/**
* Resets the module registry - the cache of all required modules. This is
* useful to isolate modules where local state might conflict between tests.
*
* @deprecated Use `jest.resetModules()`
*/
resetModuleRegistry(): Jest;
/**
* Resets the module registry - the cache of all required modules. This is
* useful to isolate modules where local state might conflict between tests.
*/
resetModules(): Jest;
/**
* Restores all mocks back to their original value. Equivalent to calling
* `.mockRestore` on every mocked function.
*
* Beware that jest.restoreAllMocks() only works when mock was created with
* jest.spyOn; other mocks will require you to manually restore them.
*/
restoreAllMocks(): Jest;
/**
* Runs failed tests n-times until they pass or until the max number of
* retries is exhausted. This only works with `jest-circus`!
*/
retryTimes(numRetries: number): Jest;
/**
* Exhausts tasks queued by setImmediate().
*/
runAllImmediates(): void;
/**
* Exhausts the micro-task queue (usually interfaced in node via
* process.nextTick).
*/
runAllTicks(): void;
/**
* Exhausts the macro-task queue (i.e., all tasks queued by setTimeout()
* and setInterval()).
*/
runAllTimers(): void;
/**
* Executes only the macro-tasks that are currently pending (i.e., only the
* tasks that have been queued by setTimeout() or setInterval() up to this
* point). If any of the currently pending macro-tasks schedule new
* macro-tasks, those new tasks will not be executed by this call.
*/
runOnlyPendingTimers(): void;
/**
* Advances all timers by msToRun milliseconds. All pending "macro-tasks"
* that have been queued via setTimeout() or setInterval(), and would be
* executed within this timeframe will be executed.
*/
advanceTimersByTime(msToRun: number): void;
/**
* Executes only the macro task queue (i.e. all tasks queued by setTimeout()
* or setInterval() and setImmediate()).
*
* @deprecated Use `jest.advanceTimersByTime()`
*/
runTimersToTime(msToRun: number): void;
/**
* Returns the number of fake timers still left to run.
*/
getTimerCount(): number;
/**
* Explicitly supplies the mock object that the module system should return
* for the specified module.
*
* Note It is recommended to use `jest.mock()` instead. The `jest.mock`
* API's second argument is a module factory instead of the expected
* exported module object.
*/
setMock(moduleName: string, moduleExports: unknown): Jest;
/**
* Set the default timeout interval for tests and before/after hooks in
* milliseconds.
*
* Note: The default timeout interval is 5 seconds if this method is not
* called.
*/
setTimeout(timeout: number): Jest;
/**
* Creates a mock function similar to `jest.fn` but also tracks calls to
* `object[methodName]`.
*
* Note: By default, jest.spyOn also calls the spied method. This is
* different behavior from most other test libraries.
*/
spyOn: typeof moduleMocker.spyOn;
/**
* Indicates that the module system should never return a mocked version of
* the specified module from require() (e.g. that it should always return the
* real module).
*/
unmock(moduleName: string): Jest;
/**
* Instructs Jest to use fake versions of the standard timer functions.
*/
useFakeTimers(): Jest;
/**
* Instructs Jest to use the real versions of the standard timer functions.
*/
useRealTimers(): Jest;
/**
* `jest.isolateModules(fn)` goes a step further than `jest.resetModules()`
* and creates a sandbox registry for the modules that are loaded inside
* the callback function. This is useful to isolate specific modules for
* every test so that local module state doesn't conflict between tests.
*/
isolateModules(fn: () => void): Jest;
}
12 changes: 12 additions & 0 deletions packages/jest-environment/tsconfig.json
@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "build"
},
"references": [
{"path": "../jest-transform"},
{"path": "../jest-types"},
{"path": "../jest-util"}
]
}
4 changes: 2 additions & 2 deletions packages/jest-resolve/src/index.ts
Expand Up @@ -21,7 +21,7 @@ type FindNodeModuleConfig = {
extensions?: Array<string>;
moduleDirectory?: Array<string>;
paths?: Array<Config.Path>;
resolver?: Config.Path;
resolver?: Config.Path | null;
rootDir?: Config.Path;
};

Expand Down Expand Up @@ -403,7 +403,7 @@ const createNoMappedModuleFoundError = (
updatedName: string,
mappedModuleName: string,
regex: RegExp,
resolver: Function | string,
resolver?: Function | string | null,
) => {
const error = new Error(
chalk.red(`${chalk.bold('Configuration error')}:
Expand Down
6 changes: 3 additions & 3 deletions packages/jest-resolve/src/types.ts
Expand Up @@ -9,14 +9,14 @@ import {Config} from '@jest/types';

export type ResolverConfig = {
browser?: boolean;
defaultPlatform?: string;
defaultPlatform?: string | null;
extensions: Array<string>;
hasCoreModules: boolean;
moduleDirectories: Array<string>;
moduleNameMapper?: Array<ModuleNameMapperConfig>;
moduleNameMapper?: Array<ModuleNameMapperConfig> | null;
modulePaths: Array<Config.Path>;
platforms?: Array<string>;
resolver: Config.Path;
resolver?: Config.Path | null;
rootDir: Config.Path;
};

Expand Down