Skip to content

Commit 75a28e6

Browse files
committed
Merge branch 'master' into ts-jest-core
2 parents 6110e0b + de52b48 commit 75a28e6

File tree

27 files changed

+383
-172
lines changed

27 files changed

+383
-172
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
- `[expect]`: Improve report when matcher fails, part 10 ([#7960](https://github.com/facebook/jest/pull/7960))
99
- `[pretty-format]` Support `React.memo` ([#7891](https://github.com/facebook/jest/pull/7891))
1010
- `[jest-config]` Print error information on preset normalization error ([#7935](https://github.com/facebook/jest/pull/7935))
11+
- `[jest-haste-map]` Add `skipPackageJson` option ([#7778](https://github.com/facebook/jest/pull/7778))
12+
- `[jest-get-type]` Add `isPrimitive` function ([#7708](https://github.com/facebook/jest/pull/7708))
1113

1214
### Fixes
1315

@@ -22,10 +24,14 @@
2224
- `[jest-transform]` Normalize config and remove unecessary checks, convert `TestUtils.js` to TypeScript ([#7801](https://github.com/facebook/jest/pull/7801))
2325
- `[jest-worker]` Fix `jest-worker` when using pre-allocated jobs ([#7934](https://github.com/facebook/jest/pull/7934))
2426
- `[jest-changed-files]` Fix `getChangedFilesFromRoots` to not return parts of the commit messages as if they were files, when the commit messages contained multiple paragraphs ([#7961](https://github.com/facebook/jest/pull/7961))
27+
- `[jest-haste-map]` Enforce uniqueness in names (mocks and haste ids) ([#8002](https://github.com/facebook/jest/pull/8002))
2528
- `[static]` Remove console log '-' on the front page
29+
- `[jest-jasmine2]`: Throw explicit error when errors happen after test is considered complete ([#8005](https://github.com/facebook/jest/pull/8005))
30+
- `[jest-circus]`: Throw explicit error when errors happen after test is considered complete ([#8005](https://github.com/facebook/jest/pull/8005))
2631

2732
### Chore & Maintenance
2833

34+
- `[jest-environment-jsdom]`: Migrate to TypeScript ([#7985](https://github.com/facebook/jest/pull/8003))
2935
- `[jest-environment-node]`: Migrate to TypeScript ([#7985](https://github.com/facebook/jest/pull/7985))
3036
- `[*]`: Setup building, linting and testing of TypeScript ([#7808](https://github.com/facebook/jest/pull/7808), [#7855](https://github.com/facebook/jest/pull/7855), [#7951](https://github.com/facebook/jest/pull/7951))
3137
- `[pretty-format]`: Migrate to TypeScript ([#7809](https://github.com/facebook/jest/pull/7809), [#7809](https://github.com/facebook/jest/pull/7972))
@@ -62,6 +68,7 @@
6268
- `[jest-runner]`: Migrate to TypeScript ([#7968](https://github.com/facebook/jest/pull/7968))
6369
- `[jest-runtime]`: Migrate to TypeScript ([#7964](https://github.com/facebook/jest/pull/7964), [#7988](https://github.com/facebook/jest/pull/7988))
6470
- `[@jest/fake-timers]`: Extract FakeTimers class from `jest-util` into a new separate package ([#7987](https://github.com/facebook/jest/pull/7987))
71+
- `[jest-repl]`: Migrate to TypeScript ([#8000](https://github.com/facebook/jest/pull/8000))
6572
- `[@jest/core]`: Migrate to TypeScript ([#7998](https://github.com/facebook/jest/pull/7998))
6673

6774
### Performance
@@ -93,6 +100,7 @@
93100
- `[jest-runtime]` Exclude setup/teardown files from coverage report ([#7790](https://github.com/facebook/jest/pull/7790)
94101
- `[babel-jest]` Throw an error if `babel-jest` tries to transform a file ignored by Babel ([#7797](https://github.com/facebook/jest/pull/7797))
95102
- `[babel-plugin-jest-hoist]` Ignore TS type references when looking for out-of-scope references ([#7799](https://github.com/facebook/jest/pull/7799)
103+
- `[expect]` fixed asymmetrical equality of cyclic objects ([#7730](https://github.com/facebook/jest/pull/7730))
96104

97105
### Chore & Maintenance
98106

e2e/__tests__/detectOpenHandles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ try {
2222
}
2323
}
2424

25-
function getTextAfterTest(stderr) {
25+
function getTextAfterTest(stderr: string) {
2626
return (stderr.split(/Ran all test suites(.*)\n/)[2] || '').trim();
2727
}
2828

e2e/__tests__/failures.test.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import runJest from '../runJest';
1212

1313
const dir = path.resolve(__dirname, '../failures');
1414

15-
const normalizeDots = text => text.replace(/\.{1,}$/gm, '.');
15+
const normalizeDots = (text: string) => text.replace(/\.{1,}$/gm, '.');
1616

17-
function cleanStderr(stderr) {
17+
function cleanStderr(stderr: string) {
1818
const {rest} = extractSummary(stderr);
1919
return rest
2020
.replace(/.*(jest-jasmine2|jest-circus).*\n/g, '')
@@ -182,3 +182,12 @@ test('works with named snapshot failures', () => {
182182
wrap(result.substring(0, result.indexOf('Snapshot Summary'))),
183183
).toMatchSnapshot();
184184
});
185+
186+
test('errors after test has completed', () => {
187+
const {stderr} = runJest(dir, ['errorAfterTestComplete.test.js']);
188+
189+
expect(stderr).toMatch(
190+
/Error: Caught error after test environment was torn down/,
191+
);
192+
expect(stderr).toMatch(/Failed: "fail async"/);
193+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @emails oncall+jsinfra
8+
*/
9+
'use strict';
10+
11+
test('a failing test', done => {
12+
setTimeout(() => done('fail async'), 5);
13+
done();
14+
});

packages/expect/src/__tests__/matchers.test.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,59 @@ describe('.toEqual()', () => {
606606
});
607607
expect(actual).toEqual({x: 3});
608608
});
609+
610+
describe('cyclic object equality', () => {
611+
test('properties with the same circularity are equal', () => {
612+
const a = {};
613+
a.x = a;
614+
const b = {};
615+
b.x = b;
616+
expect(a).toEqual(b);
617+
expect(b).toEqual(a);
618+
619+
const c = {};
620+
c.x = a;
621+
const d = {};
622+
d.x = b;
623+
expect(c).toEqual(d);
624+
expect(d).toEqual(c);
625+
});
626+
627+
test('properties with different circularity are not equal', () => {
628+
const a = {};
629+
a.x = {y: a};
630+
const b = {};
631+
const bx = {};
632+
b.x = bx;
633+
bx.y = bx;
634+
expect(a).not.toEqual(b);
635+
expect(b).not.toEqual(a);
636+
637+
const c = {};
638+
c.x = a;
639+
const d = {};
640+
d.x = b;
641+
expect(c).not.toEqual(d);
642+
expect(d).not.toEqual(c);
643+
});
644+
645+
test('are not equal if circularity is not on the same property', () => {
646+
const a = {};
647+
const b = {};
648+
a.a = a;
649+
b.a = {};
650+
b.a.a = a;
651+
expect(a).not.toEqual(b);
652+
expect(b).not.toEqual(a);
653+
654+
const c = {};
655+
c.x = {x: c};
656+
const d = {};
657+
d.x = d;
658+
expect(c).not.toEqual(d);
659+
expect(d).not.toEqual(c);
660+
});
661+
});
609662
});
610663

611664
describe('.toBeInstanceOf()', () => {

packages/expect/src/jasmineUtils.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ function asymmetricMatch(a: any, b: any) {
6464
function eq(
6565
a: any,
6666
b: any,
67-
aStack: any,
68-
bStack: any,
69-
customTesters: any,
67+
aStack: Array<unknown>,
68+
bStack: Array<unknown>,
69+
customTesters: Array<Tester>,
7070
hasKey: any,
7171
): boolean {
7272
var result = true;
@@ -149,14 +149,17 @@ function eq(
149149
return false;
150150
}
151151

152-
// Assume equality for cyclic structures. The algorithm for detecting cyclic
153-
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
152+
// Used to detect circular references.
154153
var length = aStack.length;
155154
while (length--) {
156155
// Linear search. Performance is inversely proportional to the number of
157156
// unique nested structures.
158-
if (aStack[length] == a) {
159-
return bStack[length] == b;
157+
// circular references at same depth are equal
158+
// circular reference is not equal to non-circular one
159+
if (aStack[length] === a) {
160+
return bStack[length] === b;
161+
} else if (bStack[length] === b) {
162+
return false;
160163
}
161164
}
162165
// Add the first object to the stack of traversed objects.

packages/jest-circus/src/utils.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,17 @@ const _makeTimeoutMessage = (timeout: number, isHook: boolean) =>
153153
// the original values in the variables before we require any files.
154154
const {setTimeout, clearTimeout} = global;
155155

156+
function checkIsError(error: any): error is Error {
157+
return !!(error && (error as Error).message && (error as Error).stack);
158+
}
159+
156160
export const callAsyncCircusFn = (
157161
fn: AsyncFn,
158162
testContext: TestContext | undefined,
159163
{isHook, timeout}: {isHook?: boolean | null; timeout: number},
160164
): Promise<any> => {
161165
let timeoutID: NodeJS.Timeout;
166+
let completed = false;
162167

163168
return new Promise((resolve, reject) => {
164169
timeoutID = setTimeout(
@@ -170,15 +175,20 @@ export const callAsyncCircusFn = (
170175
// soon as `done` called.
171176
if (fn.length) {
172177
const done = (reason?: Error | string): void => {
173-
const isError =
174-
reason && (reason as Error).message && (reason as Error).stack;
175-
return reason
176-
? reject(
177-
isError
178-
? reason
179-
: new Error(`Failed: ${prettyFormat(reason, {maxDepth: 3})}`),
180-
)
181-
: resolve();
178+
const errorAsErrorObject = checkIsError(reason)
179+
? reason
180+
: new Error(`Failed: ${prettyFormat(reason, {maxDepth: 3})}`);
181+
182+
// Consider always throwing, regardless if `reason` is set or not
183+
if (completed && reason) {
184+
errorAsErrorObject.message =
185+
'Caught error after test environment was torn down\n\n' +
186+
errorAsErrorObject.message;
187+
188+
throw errorAsErrorObject;
189+
}
190+
191+
return reason ? reject(errorAsErrorObject) : resolve();
182192
};
183193

184194
return fn.call(testContext, done);
@@ -221,12 +231,14 @@ export const callAsyncCircusFn = (
221231
return resolve();
222232
})
223233
.then(() => {
234+
completed = true;
224235
// If timeout is not cleared/unrefed the node process won't exit until
225236
// it's resolved.
226237
timeoutID.unref && timeoutID.unref();
227238
clearTimeout(timeoutID);
228239
})
229240
.catch(error => {
241+
completed = true;
230242
timeoutID.unref && timeoutID.unref();
231243
clearTimeout(timeoutID);
232244
throw error;

packages/jest-config/tsconfig.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
"rootDir": "src",
55
"outDir": "build"
66
},
7-
// TODO: This is missing `jest-validate`, in addition to
8-
// `jest-environment-jsdom` and `jest-jasmine2`, but those are just
9-
// `require.resolve`d, so no real use for their types
7+
// TODO: This is missing `jest-validate`, in addition to and `jest-jasmine2`,
8+
// but those are just `require.resolve`d, so no real use for their types
109
"references": [
10+
{"path": "../jest-environment-jsdom"},
1111
{"path": "../jest-environment-node"},
1212
{"path": "../jest-get-type"},
1313
{"path": "../jest-regex-util"},

packages/jest-each/src/bind.js

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import util from 'util';
1111
import chalk from 'chalk';
1212
import pretty from 'pretty-format';
13-
import getType from 'jest-get-type';
13+
import {isPrimitive} from 'jest-get-type';
1414
import {ErrorWithStack} from 'jest-util';
1515

1616
type Table = Array<Array<any>>;
@@ -24,13 +24,6 @@ const RECEIVED_COLOR = chalk.red;
2424
const SUPPORTED_PLACEHOLDERS = /%[sdifjoOp%]/g;
2525
const PRETTY_PLACEHOLDER = '%p';
2626
const INDEX_PLACEHOLDER = '%#';
27-
const PRIMITIVES = new Set([
28-
'string',
29-
'number',
30-
'boolean',
31-
'null',
32-
'undefined',
33-
]);
3427

3528
export default (cb: Function, supportsDone: boolean = true) => (...args: any) =>
3629
function eachBind(title: string, test: Function, timeout: number): void {
@@ -203,10 +196,9 @@ const getMatchingKeyPaths = title => (matches, key) =>
203196
const replaceKeyPathWithValue = data => (title, match) => {
204197
const keyPath = match.replace('$', '').split('.');
205198
const value = getPath(data, keyPath);
206-
const valueType = getType(value);
207199

208-
if (PRIMITIVES.has(valueType)) {
209-
return title.replace(match, value);
200+
if (isPrimitive(value)) {
201+
return title.replace(match, String(value));
210202
}
211203
return title.replace(match, pretty(value, {maxDepth: 1, min: true}));
212204
};

packages/jest-environment-jsdom/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@
88
},
99
"license": "MIT",
1010
"main": "build/index.js",
11+
"types": "build/index.d.ts",
1112
"dependencies": {
13+
"@jest/environment": "^24.1.0",
1214
"@jest/fake-timers": "^24.1.0",
15+
"@jest/types": "^24.1.0",
1316
"jest-mock": "^24.0.0",
1417
"jest-util": "^24.0.0",
1518
"jsdom": "^11.5.1"
1619
},
17-
"devDependencies": {
20+
"devDependencies": {
1821
"@types/jsdom": "^11.12.0"
1922
},
2023
"engines": {

0 commit comments

Comments
 (0)