Skip to content

Commit

Permalink
Merge branch 'master' into update-architecture-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Luanf committed Feb 26, 2019
2 parents dd16b3e + 16fe18d commit cb6f551
Show file tree
Hide file tree
Showing 25 changed files with 164 additions and 62 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -15,6 +15,7 @@
- `[jest-cli]` Refactor `-o` and `--coverage` combined ([#7611](https://github.com/facebook/jest/pull/7611))
- `[expect]` Fix custom async matcher stack trace ([#7652](https://github.com/facebook/jest/pull/7652))
- `[expect]` Fix `toStrictEqual` not considering arrays with objects having undefined values correctly ([#7938](https://github.com/facebook/jest/pull/7938))
- `[expect]` Fix non-symmetric equal for Number ([#7948](https://github.com/facebook/jest/pull/7948))
- `[jest-changed-files]` Improve default file selection for Mercurial repos ([#7880](https://github.com/facebook/jest/pull/7880))
- `[jest-validate]` Fix validating async functions ([#7894](https://github.com/facebook/jest/issues/7894))
- `[jest-circus]` Fix bug with test.only ([#7888](https://github.com/facebook/jest/pull/7888))
Expand Down Expand Up @@ -58,7 +59,8 @@
- `[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))
- `[jest-runtime]`: Migrate to TypeScript ([#7964](https://github.com/facebook/jest/pull/7964), [#7988](https://github.com/facebook/jest/pull/7988))
- `[@jest/fake-timers]`: Extract FakeTimers class from `jest-util` into a new separate package ([#7987](https://github.com/facebook/jest/pull/7987))
- `[docs]` Update Architecture docs with additonal information ([#7984](https://github.com/facebook/jest/pull/7984))

### Performance
Expand Down
49 changes: 49 additions & 0 deletions packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap
Expand Up @@ -1818,6 +1818,13 @@ Expected: <green>\\"abc\\"</>
Received: <red>\\"abc\\"</>"
`;

exports[`.toEqual() {pass: false} expect("abc").not.toEqual({"0": "a", "1": "b", "2": "c"}) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expected: <green>{\\"0\\": \\"a\\", \\"1\\": \\"b\\", \\"2\\": \\"c\\"}</>
Received: <red>\\"abc\\"</>"
`;

exports[`.toEqual() {pass: false} expect("abcd").not.toEqual(StringContaining "bc") 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expand Down Expand Up @@ -1931,6 +1938,13 @@ Expected: <green>Any<Function></>
Received: <red>[Function anonymous]</>"
`;

exports[`.toEqual() {pass: false} expect({"0": "a", "1": "b", "2": "c"}).not.toEqual("abc") 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expected: <green>\\"abc\\"</>
Received: <red>{\\"0\\": \\"a\\", \\"1\\": \\"b\\", \\"2\\": \\"c\\"}</>"
`;

exports[`.toEqual() {pass: false} expect({"a": 1, "b": [Function b], "c": true}).not.toEqual({"a": 1, "b": Any<Function>, "c": Anything}) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expand Down Expand Up @@ -2006,13 +2020,34 @@ Expected: <green>{}</>
Received: <red>{}</>"
`;

exports[`.toEqual() {pass: false} expect({}).not.toEqual(0) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expected: <green>0</>
Received: <red>{}</>"
`;

exports[`.toEqual() {pass: false} expect(0).not.toEqual({}) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expected: <green>{}</>
Received: <red>0</>"
`;

exports[`.toEqual() {pass: false} expect(0).toEqual(-0) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Expected: <green>-0</>
Received: <red>0</>"
`;

exports[`.toEqual() {pass: false} expect(0).toEqual(5e-324) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Expected: <green>5e-324</>
Received: <red>0</>"
`;

exports[`.toEqual() {pass: false} expect(1).not.toEqual(1) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expand All @@ -2034,6 +2069,13 @@ Expected: <green>ArrayContaining [1, 2]</>
Received: <red>1</>"
`;

exports[`.toEqual() {pass: false} expect(5e-324).toEqual(0) 1`] = `
"<dim>expect(</><red>received</><dim>).toEqual(</><green>expected</><dim>)</>

Expected: <green>0</>
Received: <red>5e-324</>"
`;

exports[`.toEqual() {pass: false} expect(Immutable.List [1, 2]).not.toEqual(Immutable.List [1, 2]) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expand Down Expand Up @@ -2394,6 +2436,13 @@ Expected: <green>Map {2 => [\\"two\\"], 1 => [\\"one\\"]}</>
Received: <red>Map {1 => [\\"one\\"], 2 => [\\"two\\"]}</>"
`;

exports[`.toEqual() {pass: false} expect(NaN).not.toEqual(NaN) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expected: <green>NaN</>
Received: <red>NaN</>"
`;

exports[`.toEqual() {pass: false} expect(Set {[1], [2], [3], [3]}).not.toEqual(Set {[3], [3], [2], [1]}) 1`] = `
"<dim>expect(</><red>received</><dim>).</>not<dim>.toEqual(</><green>expected</><dim>)</>

Expand Down
11 changes: 11 additions & 0 deletions packages/expect/src/__tests__/matchers.test.js
Expand Up @@ -344,6 +344,8 @@ describe('.toEqual()', () => {
[true, false],
[1, 2],
[0, -0],
[0, Number.MIN_VALUE], // issues/7941
[Number.MIN_VALUE, 0],
[{a: 5}, {b: 6}],
['banana', 'apple'],
[null, undefined],
Expand Down Expand Up @@ -426,7 +428,16 @@ describe('.toEqual()', () => {
[
[true, true],
[1, 1],
[NaN, NaN],
// eslint-disable-next-line no-new-wrappers
[0, new Number(0)],
// eslint-disable-next-line no-new-wrappers
[new Number(0), 0],
['abc', 'abc'],
// eslint-disable-next-line no-new-wrappers
[new String('abc'), 'abc'],
// eslint-disable-next-line no-new-wrappers
['abc', new String('abc')],
[[1], [1]],
[[1, 2], [1, 2]],
[Immutable.List([1]), Immutable.List([1])],
Expand Down
4 changes: 1 addition & 3 deletions packages/expect/src/jasmineUtils.ts
Expand Up @@ -106,9 +106,7 @@ function eq(
// $FlowFixMe – Flow sees `a` as a number
return a == String(b);
case '[object Number]':
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
// other numeric values.
return a != +a ? b != +b : a === 0 ? 1 / a == 1 / b : a == +b;
return Object.is(Number(a), Number(b));
case '[object Date]':
case '[object Boolean]':
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
Expand Down
Expand Up @@ -47,7 +47,8 @@ const jestAdapter = async (
});

if (config.timers === 'fake') {
environment.fakeTimers.useFakeTimers();
// during setup, this cannot be null (and it's fine to explode if it is)
environment.fakeTimers!.useFakeTimers();
}

globals.beforeEach(() => {
Expand All @@ -63,7 +64,8 @@ const jestAdapter = async (
runtime.resetAllMocks();

if (config.timers === 'fake') {
environment.fakeTimers.useFakeTimers();
// during setup, this cannot be null (and it's fine to explode if it is)
environment.fakeTimers!.useFakeTimers();
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/jest-environment-jsdom/package.json
Expand Up @@ -9,6 +9,7 @@
"license": "MIT",
"main": "build/index.js",
"dependencies": {
"@jest/fake-timers": "^24.1.0",
"jest-mock": "^24.0.0",
"jest-util": "^24.0.0",
"jsdom": "^11.5.1"
Expand Down
3 changes: 2 additions & 1 deletion packages/jest-environment-jsdom/src/index.js
Expand Up @@ -12,7 +12,8 @@ import type {EnvironmentContext} from 'types/Environment';
import type {Global} from 'types/Global';
import type {ModuleMocker} from 'jest-mock';

import {FakeTimers, installCommonGlobals} from 'jest-util';
import {JestFakeTimers as FakeTimers} from '@jest/fake-timers';
import {installCommonGlobals} from 'jest-util';
import mock from 'jest-mock';
import {JSDOM, VirtualConsole} from 'jsdom';

Expand Down
1 change: 1 addition & 0 deletions packages/jest-environment-node/package.json
Expand Up @@ -9,6 +9,7 @@
"license": "MIT",
"main": "build/index.js",
"dependencies": {
"@jest/fake-timers": "^24.1.0",
"jest-mock": "^24.0.0",
"jest-util": "^24.0.0"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/jest-environment-node/src/index.js
Expand Up @@ -13,7 +13,8 @@ import type {Global} from 'types/Global';
import type {ModuleMocker} from 'jest-mock';

import vm from 'vm';
import {FakeTimers, installCommonGlobals} from 'jest-util';
import {JestFakeTimers as FakeTimers} from '@jest/fake-timers';
import {installCommonGlobals} from 'jest-util';
import mock from 'jest-mock';

type Timer = {|
Expand Down
1 change: 1 addition & 0 deletions packages/jest-environment/package.json
Expand Up @@ -10,6 +10,7 @@
"main": "build/index.js",
"types": "build/index.d.ts",
"dependencies": {
"@jest/fake-timers": "^24.1.0",
"@jest/transform": "^24.1.0",
"@jest/types": "^24.1.0",
"@types/node": "*",
Expand Down
39 changes: 14 additions & 25 deletions packages/jest-environment/src/index.ts
Expand Up @@ -7,8 +7,12 @@

import {Script} from 'vm';
import {Config, Global} from '@jest/types';
import moduleMocker from 'jest-mock';
import jestMock, {ModuleMocker} from 'jest-mock';
import {ScriptTransformer} from '@jest/transform';
import {JestFakeTimers as FakeTimers} from '@jest/fake-timers';

type JestMockFn = typeof jestMock.fn;
type JestMockSpyOn = typeof jestMock.spyOn;

export type EnvironmentContext = {
console?: Console;
Expand All @@ -18,30 +22,15 @@ export type EnvironmentContext = {
// 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;
export declare class JestEnvironment {
constructor(config: Config.ProjectConfig);
constructor(config: Config.ProjectConfig, context: EnvironmentContext);
global: Global.Global;
fakeTimers: FakeTimers<unknown> | null;
moduleMocker: ModuleMocker | null;
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>;
}
Expand Down Expand Up @@ -112,7 +101,7 @@ export interface Jest {
/**
* Creates a mock function. Optionally takes a mock implementation.
*/
fn: typeof moduleMocker.fn;
fn: JestMockFn;
/**
* Given the name of a module, use the automatic mocking system to generate a
* mocked version of the module for you.
Expand All @@ -124,7 +113,7 @@ export interface Jest {
/**
* Determines if the given function is a mocked function.
*/
isMockFunction(fn: Function): fn is ReturnType<typeof moduleMocker.fn>;
isMockFunction(fn: Function): fn is ReturnType<JestMockFn>;
/**
* Mocks a module with an auto-mocked version when it is being required.
*/
Expand Down Expand Up @@ -235,7 +224,7 @@ export interface Jest {
* Note: By default, jest.spyOn also calls the spied method. This is
* different behavior from most other test libraries.
*/
spyOn: typeof moduleMocker.spyOn;
spyOn: JestMockSpyOn;
/**
* 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
Expand Down
1 change: 1 addition & 0 deletions packages/jest-environment/tsconfig.json
Expand Up @@ -5,6 +5,7 @@
"outDir": "build"
},
"references": [
{"path": "../jest-fake-timers"},
{"path": "../jest-transform"},
{"path": "../jest-types"},
{"path": "../jest-util"}
Expand Down
3 changes: 3 additions & 0 deletions packages/jest-fake-timers/.npmignore
@@ -0,0 +1,3 @@
**/__mocks__/**
**/__tests__/**
src
22 changes: 22 additions & 0 deletions packages/jest-fake-timers/package.json
@@ -0,0 +1,22 @@
{
"name": "@jest/fake-timers",
"version": "24.1.0",
"repository": {
"type": "git",
"url": "https://github.com/facebook/jest.git",
"directory": "packages/jest-fake-timers"
},
"license": "MIT",
"main": "build/index.js",
"types": "build/index.d.ts",
"dependencies": {
"@jest/types": "^24.1.0",
"@types/node": "*",
"jest-message-util": "^24.0.0",
"jest-mock": "^24.0.0"
},
"engines": {
"node": ">= 6"
},
"gitHead": "b16789230fd45056a7f2fa199bae06c7a1780deb"
}
Expand Up @@ -7,9 +7,7 @@

import vm from 'vm';
import mock from 'jest-mock';
import FakeTimers from '../FakeTimers';
// TODO: import this type directly from jest-mock once TS migration is done
type ModuleMocker = typeof mock;
import FakeTimers from '../jestFakeTimers';

const timerConfig = {
idToRef: (id: number) => id,
Expand All @@ -22,7 +20,7 @@ const config = {
};

describe('FakeTimers', () => {
let moduleMocker: ModuleMocker;
let moduleMocker: mock.ModuleMocker;

beforeEach(() => {
const global = vm.runInNewContext('this');
Expand Down
8 changes: 8 additions & 0 deletions packages/jest-fake-timers/src/index.ts
@@ -0,0 +1,8 @@
/**
* 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.
*/

export {default as JestFakeTimers} from './jestFakeTimers';
Expand Up @@ -5,18 +5,10 @@
* LICENSE file in the root directory of this source tree.
*/

import mock from 'jest-mock';
import {ModuleMocker} from 'jest-mock';
import {formatStackTrace, StackTraceConfig} from 'jest-message-util';
import setGlobal from './setGlobal';

type ModuleMocker = typeof mock;

/**
* We don't know the type of arguments for a callback ahead of time which is why
* we are disabling the flowtype/no-weak-types rule here.
*/

type Callback = (...args: any) => void;
type Callback = (...args: Array<unknown>) => void;

type TimerID = string;

Expand Down Expand Up @@ -50,6 +42,16 @@ type TimerConfig<Ref> = {

const MS_IN_A_YEAR = 31536000000;

// TODO: Copied from `jest-util` to avoid cyclic dependency. Import from `jest-util` in the next major
const setGlobal = (
globalToMutate: NodeJS.Global | Window,
key: string,
value: unknown,
) => {
// @ts-ignore: no index
globalToMutate[key] = value;
};

export default class FakeTimers<TimerRef> {
private _cancelledImmediates!: {[key: string]: boolean};
private _cancelledTicks!: {[key: string]: boolean};
Expand Down

0 comments on commit cb6f551

Please sign in to comment.