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

expect: Return false from asymmetric matchers if received value isn’t string #7107

Merged
merged 5 commits into from
Dec 24, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- `[jest-jasmine2`] Fix crash when test return Promise rejected with null ([#7049](https://github.com/facebook/jest/pull/7049))
- `[jest-runtime]` Check `_isMockFunction` is true rather than truthy on potential global mocks ([#7017](https://github.com/facebook/jest/pull/7017))
- `[jest-jasmine]` Show proper error message from async `assert` errors ([#6821](https://github.com/facebook/jest/pull/6821))
- `[expect]` Return false from asymmetric matchers if received value isn’t string ([#7107](https://github.com/facebook/jest/pull/7107))

### Chore & Maintenance

Expand Down
12 changes: 6 additions & 6 deletions docs/ExpectAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,31 +347,31 @@ describe('not.objectContaining', () => {

### `expect.not.stringContaining(string)`

`expect.not.stringContaining(string)` matches the received string that does not contain the exact expected string.
`expect.not.stringContaining(string)` matches the received value if it is not a string or if it is a string that does not contain the exact expected string.

It is the inverse of `expect.stringContaining`.

```js
describe('not.stringContaining', () => {
const expected = 'Hello world!';

it('matches if the actual string does not contain the expected substring', () => {
it('matches if the received value does not contain the expected substring', () => {
expect('How are you?').toEqual(expect.not.stringContaining(expected));
});
});
```

### `expect.not.stringMatching(string | regexp)`

`expect.not.stringMatching(string | regexp)` matches the received string that does not match the expected regexp.
`expect.not.stringMatching(string | regexp)` matches the received value if it is not a string or if it is a string that does not match the expected string or regular expression.

It is the inverse of `expect.stringMatching`.

```js
describe('not.stringMatching', () => {
const expected = /Hello world!/;

it('matches if the actual string does not match the expected regex', () => {
it('matches if the received value does not match the expected regex', () => {
expect('How are you?').toEqual(expect.not.stringMatching(expected));
});
});
Expand Down Expand Up @@ -400,11 +400,11 @@ test('onPress gets called with the right thing', () => {

### `expect.stringContaining(string)`

`expect.stringContaining(string)` matches the received string that contains the exact expected string.
`expect.stringContaining(string)` matches the received value if it is a string that contains the exact expected string.

### `expect.stringMatching(string | regexp)`

`expect.stringMatching(string | regexp)` matches the received string that matches the expected regexp.
`expect.stringMatching(string | regexp)` matches the received value if it is a string that matches the expected string or regular expression.

You can use it instead of a literal value:

Expand Down
36 changes: 18 additions & 18 deletions packages/expect/src/__tests__/asymmetric_matchers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,29 +199,29 @@ test('StringContaining matches string against string', () => {
jestExpect(stringContaining('en').asymmetricMatch('queue')).toBe(false);
});

test('StringContaining throws for non-strings', () => {
test('StringContaining throws if expected value is not string', () => {
jestExpect(() => {
stringContaining([1]).asymmetricMatch('queen');
}).toThrow();
});

jestExpect(() => {
stringContaining('en*').asymmetricMatch(1);
}).toThrow();
test('StringContaining returns false if received value is not string', () => {
jestExpect(stringContaining('en*').asymmetricMatch(1)).toBe(false);
});

test('StringNotContaining matches string against string', () => {
jestExpect(stringNotContaining('en*').asymmetricMatch('queen*')).toBe(false);
jestExpect(stringNotContaining('en').asymmetricMatch('queue')).toBe(true);
});

test('StringNotContaining throws for non-strings', () => {
test('StringNotContaining throws if expected value is not string', () => {
jestExpect(() => {
stringNotContaining([1]).asymmetricMatch('queen');
}).toThrow();
});

jestExpect(() => {
stringNotContaining('en*').asymmetricMatch(1);
}).toThrow();
test('StringNotContaining returns true if received value is not string', () => {
jestExpect(stringNotContaining('en*').asymmetricMatch(1)).toBe(true);
});

test('StringMatching matches string against regexp', () => {
Expand All @@ -234,16 +234,18 @@ test('StringMatching matches string against string', () => {
jestExpect(stringMatching('en').asymmetricMatch('queue')).toBe(false);
});

test('StringMatching throws for non-strings and non-regexps', () => {
test('StringMatching throws if expected value is neither string nor regexp', () => {
jestExpect(() => {
stringMatching([1]).asymmetricMatch('queen');
}).toThrow();
});

test('StringMatching throws for non-string actual values', () => {
jestExpect(() => {
stringMatching('en').asymmetricMatch(1);
}).toThrow();
test('StringMatching returns false if received value is not string', () => {
jestExpect(stringMatching('en').asymmetricMatch(1)).toBe(false);
});

test('StringMatching returns false even if coerced non-string received value matches pattern', () => {
jestExpect(stringMatching('null').asymmetricMatch(null)).toBe(false);
});

test('StringNotMatching matches string against regexp', () => {
Expand All @@ -256,14 +258,12 @@ test('StringNotMatching matches string against string', () => {
jestExpect(stringNotMatching('en').asymmetricMatch('queue')).toBe(true);
});

test('StringNotMatching throws for non-strings and non-regexps', () => {
test('StringNotMatching throws if expected value is neither string nor regexp', () => {
jestExpect(() => {
stringNotMatching([1]).asymmetricMatch('queen');
}).toThrow();
});

test('StringNotMatching throws for non-string actual values', () => {
jestExpect(() => {
stringNotMatching('en').asymmetricMatch(1);
}).toThrow();
test('StringNotMatching returns true if received value is not string', () => {
jestExpect(stringNotMatching('en').asymmetricMatch(1)).toBe(true);
});
16 changes: 4 additions & 12 deletions packages/expect/src/asymmetric_matchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,8 @@ class StringContaining extends AsymmetricMatcher {
this.inverse = inverse;
}

asymmetricMatch(other: string) {
if (!isA('String', other)) {
throw new Error('Actual is not a string');
}

const result = other.includes(this.sample);
asymmetricMatch(other: any) {
const result = isA('String', other) && other.includes(this.sample);

return this.inverse ? !result : result;
}
Expand All @@ -248,12 +244,8 @@ class StringMatching extends AsymmetricMatcher {
this.inverse = inverse;
}

asymmetricMatch(other: string) {
if (!isA('String', other)) {
throw new Error('Actual is not a string');
}

const result = this.sample.test(other);
asymmetricMatch(other: any) {
const result = isA('String', other) && this.sample.test(other);

return this.inverse ? !result : result;
}
Expand Down