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

Improve chai support (with detailed output, to match jest exceptions) #8454

Merged
merged 13 commits into from May 17, 2019
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,8 @@

### Features

- `[jest-cli]` Improve chai support (with detailed output, to match jest exceptions) ([#8454](https://github.com/facebook/jest/pull/8454))

### Fixes

- `[babel-plugin-jest-hoist]` Expand list of whitelisted globals in global mocks ([#8429](https://github.com/facebook/jest/pull/8429)
Expand Down
91 changes: 91 additions & 0 deletions e2e/__tests__/__snapshots__/chaiAssertionLibrary.ts.snap
@@ -0,0 +1,91 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`chai assertion errors should display properly 1`] = `
FAIL __tests__/chai_assertion.js
● chai.js assertion library test › expect

assert.(received, expected)
rpgeeganage marked this conversation as resolved.
Show resolved Hide resolved

Expected value "hello sunshine"
Received:
"hello world"

Message:
expected 'hello world' to equal 'hello sunshine'

Difference:

- Expected
+ Received

- hello sunshine
+ hello world

11 | describe('chai.js assertion library test', () => {
12 | it('expect', () => {
> 13 | chai.expect('hello world').to.equal('hello sunshine');
| ^
14 | });
15 |
16 | it('should', () => {

at Object.equal (__tests__/chai_assertion.js:13:35)

● chai.js assertion library test › should

assert.(received, expected)

Expected value "hello sunshine"
Received:
"hello world"

Message:
expected 'hello world' to equal 'hello sunshine'

Difference:

- Expected
+ Received

- hello sunshine
+ hello world

18 | const stringExpected = 'hello world';
19 | const actualExpected = 'hello sunshine';
> 20 | stringExpected.should.to.equal(actualExpected);
| ^
21 | });
22 |
23 | it('assert', () => {

at Object.equal (__tests__/chai_assertion.js:20:30)

● chai.js assertion library test › assert

assert.(received, expected)

Expected value "hello sunshine"
Received:
"hello world"

Message:
expected 'hello world' to equal 'hello sunshine'

Difference:

- Expected
+ Received

- hello sunshine
+ hello world

22 |
23 | it('assert', () => {
> 24 | chai.assert.strictEqual('hello world', 'hello sunshine');
| ^
25 | });
26 | });
27 |

at Object.strictEqual (__tests__/chai_assertion.js:24:17)
`;
20 changes: 20 additions & 0 deletions e2e/__tests__/chaiAssertionLibrary.ts
@@ -0,0 +1,20 @@
/**
* 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 path from 'path';
import {wrap} from 'jest-snapshot-serializer-raw';
import runJest from '../runJest';
import {extractSummary, run} from '../Utils';

test('chai assertion errors should display properly', () => {
const dir = path.resolve(__dirname, '../chai-assertion-library-errors');
run('yarn', dir);

const {stderr} = runJest('chai-assertion-library-errors');
const {rest} = extractSummary(stderr);
expect(wrap(rest)).toMatchSnapshot();
});
26 changes: 26 additions & 0 deletions e2e/chai-assertion-library-errors/__tests__/chai_assertion.js
@@ -0,0 +1,26 @@
/**
* 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.
*/

'use strict';
const chai = require('chai');

describe('chai.js assertion library test', () => {
it('expect', () => {
chai.expect('hello world').to.equal('hello sunshine');
});

it('should', () => {
chai.should();
const stringExpected = 'hello world';
const actualExpected = 'hello sunshine';
stringExpected.should.to.equal(actualExpected);
rpgeeganage marked this conversation as resolved.
Show resolved Hide resolved
});

it('assert', () => {
chai.assert.strictEqual('hello world', 'hello sunshine');
});
});
9 changes: 9 additions & 0 deletions e2e/chai-assertion-library-errors/package.json
@@ -0,0 +1,9 @@
{
"jest": {
"testEnvironment": "node",
"verbose": false
},
"dependencies": {
"chai": "^4.2.0"
}
}
47 changes: 47 additions & 0 deletions e2e/chai-assertion-library-errors/yarn.lock
@@ -0,0 +1,47 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


assertion-error@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==

chai@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5"
integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==
dependencies:
assertion-error "^1.1.0"
check-error "^1.0.2"
deep-eql "^3.0.1"
get-func-name "^2.0.0"
pathval "^1.1.0"
type-detect "^4.0.5"

check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=

deep-eql@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==
dependencies:
type-detect "^4.0.0"

get-func-name@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=

pathval@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0"
integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA=

type-detect@^4.0.0, type-detect@^4.0.5:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
10 changes: 9 additions & 1 deletion packages/jest-circus/src/formatNodeAssertErrors.ts
Expand Up @@ -60,7 +60,7 @@ const formatNodeAssertErrors = (event: Circus.Event, state: Circus.State) => {
} else {
error = errors;
}
return error.code === 'ERR_ASSERTION'
return isAssertionError(error)
? {message: assertionErrorMessage(error, {expand: state.expand})}
: errors;
});
Expand Down Expand Up @@ -168,4 +168,12 @@ function assertionErrorMessage(
);
}

function isAssertionError(error: Circus.TestError) {
rpgeeganage marked this conversation as resolved.
Show resolved Hide resolved
return (
error instanceof AssertionError ||
(error &&
(error.name === AssertionError.name || error.code === 'ERR_ASSERTION'))
);
rpgeeganage marked this conversation as resolved.
Show resolved Hide resolved
}

export default formatNodeAssertErrors;
5 changes: 4 additions & 1 deletion packages/jest-jasmine2/src/jasmine/Env.ts
Expand Up @@ -663,7 +663,10 @@ export default function(j$: Jasmine) {
let checkIsError;
let message;

if (error instanceof AssertionError) {
if (
error instanceof AssertionError ||
(error && error.name === AssertionError.name)
) {
checkIsError = false;
// @ts-ignore TODO Possible error: j$.Spec does not have expand property
message = assertionErrorMessage(error, {expand: j$.Spec.expand});
Expand Down
14 changes: 10 additions & 4 deletions packages/jest-jasmine2/src/jasmine/Spec.ts
Expand Up @@ -236,10 +236,9 @@ export default class Spec {
passed: false,
expected: '',
actual: '',
error:
error instanceof AssertionError
? assertionErrorMessage(error, {expand: this.expand})
: error,
error: this.isAssertionError(error)
? assertionErrorMessage(error, {expand: this.expand})
: error,
},
true,
);
Expand Down Expand Up @@ -292,6 +291,13 @@ export default class Spec {
getFullName() {
return this.getSpecName(this);
}

isAssertionError(error: Error) {
return (
error instanceof AssertionError ||
(error && error.name === AssertionError.name)
);
}
}

Spec.pendingSpecExceptionMessage = '=> marked Pending';
Expand Down