Skip to content

Commit

Permalink
fix(expect): do not rely on 'instanceof RegExp' (#5729)
Browse files Browse the repository at this point in the history
* fix(expect): do not rely on 'instanceof RegExp'

`instanceof RegExp` will not be true for RegExp objects created inside of a different NodeJS VM or Window.

This commit fixes this issue by checking for 'regexp.test' function instead.

* chore(CHANGELOG): entry for instanceof RegExp fix

* fix(expect): silence erroneous flow errors
  • Loading branch information
niieani authored and cpojer committed Mar 6, 2018
1 parent 3b0959a commit 469ad79
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

### Fixes

* `[expect]` Do not rely on `instanceof RegExp`, since it will not work for
RegExps created inside of a different VM
([#5729](https://github.com/facebook/jest/pull/5729))
* `[jest-resolve]` Update node module resolution algorithm to correctly handle
symlinked paths ([#5085](https://github.com/facebook/jest/pull/5085))
* `[jest-editor-support]` Update `Settings` to use spawn in shell option
Expand Down
17 changes: 17 additions & 0 deletions integration-tests/__tests__/expect_in_vm.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. 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.
*
* @flow
*/

'use strict';

const runJest = require('../runJest');

test('expect works correctly with RegExps created inside a VM', () => {
const result = runJest('expect-in-vm');
expect(result.status).toBe(0);
});
33 changes: 33 additions & 0 deletions integration-tests/expect-in-vm/__tests__/expect-in-vm.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. 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 vm = require('vm');

it('correctly expects RegExp inside a new VM context', () => {
const fn = vm.runInNewContext(
`(function(require, module, exports, __dirname, __filename, expect) {
expect('ab12cd').toMatch(/ab12cd/);
})`,
global
);

const module = {
exports: {},
};

fn.call(
module.exports,
require,
module,
module.exports,
__dirname,
__filename,
expect
);
});
5 changes: 5 additions & 0 deletions integration-tests/expect-in-vm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"jest": {
"testEnvironment": "node"
}
}
5 changes: 4 additions & 1 deletion packages/expect/src/matchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,10 @@ const matchers: MatchersObject = {
);
}

if (!(expected instanceof RegExp) && !(typeof expected === 'string')) {
if (
!(expected && typeof expected.test === 'function') &&
!(typeof expected === 'string')
) {
throw new Error(
matcherHint('[.not].toMatch', 'string', 'expected') +
'\n\n' +
Expand Down
11 changes: 8 additions & 3 deletions packages/expect/src/to_throw_matchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,15 @@ export const createMatcher = (matcherName: string, fromPromise?: boolean) => (

if (typeof expected === 'function') {
return toThrowMatchingError(matcherName, error, expected);
} else if (expected instanceof RegExp) {
return toThrowMatchingStringOrRegexp(matcherName, error, expected, value);
} else if (expected && typeof expected.test === 'function') {
return toThrowMatchingStringOrRegexp(
matcherName,
error,
(expected: any),
value,
);
} else if (expected && typeof expected === 'object') {
return toThrowMatchingErrorInstance(matcherName, error, expected);
return toThrowMatchingErrorInstance(matcherName, error, (expected: any));
} else if (expected === undefined) {
const pass = error !== undefined;
return {
Expand Down

0 comments on commit 469ad79

Please sign in to comment.