From 7dc331d89bfc174e3e9c2ae0bbcd0e9d87fbdb6e Mon Sep 17 00:00:00 2001 From: mts88 Date: Sun, 26 May 2024 13:12:12 +0200 Subject: [PATCH 1/2] feat: add toIncludeCaseInsensitive matcher Add the new String matcher .toIncludeCaseInsensitive --- .gitignore | 1 + src/matchers/index.js | 1 + src/matchers/toIncludeCaseInsensitive.js | 23 +++++++++++++++ .../toIncludeCaseInsensitive.test.js.snap | 28 ++++++++++++++++++ .../matchers/toIncludeCaseInsensitive.test.js | 29 +++++++++++++++++++ types/index.d.ts | 7 +++++ website/docs/matchers/String.mdx | 14 +++++++++ website/docs/matchers/index.md | 1 + 8 files changed, 104 insertions(+) create mode 100644 src/matchers/toIncludeCaseInsensitive.js create mode 100644 test/matchers/__snapshots__/toIncludeCaseInsensitive.test.js.snap create mode 100644 test/matchers/toIncludeCaseInsensitive.test.js diff --git a/.gitignore b/.gitignore index 79230970..4786c732 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ coverage .vs .vscode package-lock.json +yarn.lock \ No newline at end of file diff --git a/src/matchers/index.js b/src/matchers/index.js index 514b2b03..1c8e67ea 100644 --- a/src/matchers/index.js +++ b/src/matchers/index.js @@ -53,6 +53,7 @@ export { toHaveBeenCalledBefore } from './toHaveBeenCalledBefore'; export { toHaveBeenCalledOnce } from './toHaveBeenCalledOnce'; export { toHaveBeenCalledExactlyOnceWith } from './toHaveBeenCalledExactlyOnceWith'; export { toInclude } from './toInclude'; +export { toIncludeCaseInsensitive } from './toIncludeCaseInsensitive'; export { toIncludeAllMembers } from './toIncludeAllMembers'; export { toIncludeAllPartialMembers } from './toIncludeAllPartialMembers'; export { toIncludeAnyMembers } from './toIncludeAnyMembers'; diff --git a/src/matchers/toIncludeCaseInsensitive.js b/src/matchers/toIncludeCaseInsensitive.js new file mode 100644 index 00000000..20398b33 --- /dev/null +++ b/src/matchers/toIncludeCaseInsensitive.js @@ -0,0 +1,23 @@ +export function toIncludeCaseInsensitive(actual, expected) { + const { printReceived, printExpected, matcherHint } = this.utils; + + const pass = String(actual).toLocaleLowerCase().includes(String(expected).toLocaleLowerCase()); + + return { + pass, + message: () => + pass + ? matcherHint('.not.toIncludeCaseInsensitive') + + '\n\n' + + 'Expected string to not include while ignoring case:\n' + + ` ${printExpected(expected)}\n` + + 'Received:\n' + + ` ${printReceived(actual)}` + : matcherHint('.toIncludeCaseInsensitive') + + '\n\n' + + 'Expected string to include while ignoring case:\n' + + ` ${printExpected(expected)}\n` + + 'Received:\n' + + ` ${printReceived(actual)}`, + }; +} diff --git a/test/matchers/__snapshots__/toIncludeCaseInsensitive.test.js.snap b/test/matchers/__snapshots__/toIncludeCaseInsensitive.test.js.snap new file mode 100644 index 00000000..67b84c19 --- /dev/null +++ b/test/matchers/__snapshots__/toIncludeCaseInsensitive.test.js.snap @@ -0,0 +1,28 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`.not.toIncludeCaseInsensitive fails when a string does have a given substring 1`] = ` +"expect(received).not.toIncludeCaseInsensitive(expected) + +Expected string to not include while ignoring case: + "ell" +Received: + "hello world"" +`; + +exports[`.toIncludeCaseInsensitive fails if string is not included despite case 1`] = ` +"expect(received).toIncludeCaseInsensitive(expected) + +Expected string to include while ignoring case: + "bbbb" +Received: + "aaaa"" +`; + +exports[`.toIncludeCaseInsensitive passes if string is included despite case 1`] = ` +"expect(received).toIncludeCaseInsensitive(expected) + +Expected string to include while ignoring case: + "bbbb" +Received: + "aaaa"" +`; diff --git a/test/matchers/toIncludeCaseInsensitive.test.js b/test/matchers/toIncludeCaseInsensitive.test.js new file mode 100644 index 00000000..aa8b709e --- /dev/null +++ b/test/matchers/toIncludeCaseInsensitive.test.js @@ -0,0 +1,29 @@ +import * as matcher from 'src/matchers/toIncludeCaseInsensitive'; + +expect.extend(matcher); + +describe('.toIncludeCaseInsensitive', () => { + test('passes if string is included despite case', () => { + expect('a').toIncludeCaseInsensitive('A'); + expect('aAA').toIncludeCaseInsensitive('aa'); + expect('hello world').toIncludeCaseInsensitive('ell'); + expect('HELLO world').toIncludeCaseInsensitive('ell'); + expect('hello WORLD').toIncludeCaseInsensitive('ELL'); + expect('HELLO WORLD').toIncludeCaseInsensitive('ELL'); + expect(() => expect('aaaa').toIncludeCaseInsensitive('bbbb')).toThrowErrorMatchingSnapshot(); + }); + + test('fails if string is not included despite case', () => { + expect(() => expect('aaaa').toIncludeCaseInsensitive('bbbb')).toThrowErrorMatchingSnapshot(); + }); +}); + +describe('.not.toIncludeCaseInsensitive', () => { + test('passes when a string does not have a given substring', () => { + expect('hello world').not.toIncludeCaseInsensitive('bob'); + }); + + test('fails when a string does have a given substring', () => { + expect(() => expect('hello world').not.toIncludeCaseInsensitive('ell')).toThrowErrorMatchingSnapshot(); + }); +}); diff --git a/types/index.d.ts b/types/index.d.ts index 9436c25c..1b2acbf3 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -366,6 +366,13 @@ interface CustomMatchers extends Record { */ toInclude(substring: string): R; + /** + * Use `.toIncludeCaseInsensitive` when checking if a `String` includes the given `String` substring, despite case. + * + * @param {String} substring + */ + toIncludeCaseInsensitive(substring: string): R; + /** * Use `.toIncludeRepeated` when checking if a `String` includes the given `String` substring the correct number of times. * diff --git a/website/docs/matchers/String.mdx b/website/docs/matchers/String.mdx index 8f53463e..8c78b155 100644 --- a/website/docs/matchers/String.mdx +++ b/website/docs/matchers/String.mdx @@ -87,6 +87,20 @@ Use `.toInclude` when checking if a `String` includes the given `String` substri });`} +### .toIncludeCaseInsensitive(substring) + +Use `.toIncludeCaseInsensitive` when checking if a `String` includes the given `String` substring, despite case. + + + {`test('passes if string is included despite case', () => { + expect('hello world').toIncludeCaseInsensitive('ell'); + expect('HELLO world').toIncludeCaseInsensitive('ell'); + expect('hello WORLD').toIncludeCaseInsensitive('ELL'); + expect('HELLO WORLD').toIncludeCaseInsensitive('ELL'); + expect('hello world').not.toIncludeCaseInsensitive('bob'); +});`} + + ### .toIncludeRepeated(substring, times) Use `.toIncludeRepeated` when checking if a `String` includes the given `String` substring the correct number of times. diff --git a/website/docs/matchers/index.md b/website/docs/matchers/index.md index 7674400e..e05eaef4 100644 --- a/website/docs/matchers/index.md +++ b/website/docs/matchers/index.md @@ -98,6 +98,7 @@ sidebar_position: 1 - [.toStartWith(prefix)](/docs/matchers/string/#tostartwithprefix) - [.toEndWith(suffix)](/docs/matchers/string/#toendwithsuffix) - [.toInclude(substring)](/docs/matchers/string/#toincludesubstring) +- [.toIncludeCaseInsensitive(substring)](/docs/matchers/string/#toIncludeCaseInsensitivesubstring) - [.toIncludeRepeated(substring, times)](/docs/matchers/string/#toincluderepeatedsubstring-times) - [.toIncludeMultiple([substring])](/docs/matchers/string/#toincludemultiplesubstring) - [.toEqualIgnoringWhitespace(string)](/docs/matchers/string/#toequalignoringwhitespacestring) From ce4fbd875758d326731ebce99e340a745af49c9b Mon Sep 17 00:00:00 2001 From: mts88 Date: Sun, 26 May 2024 13:36:23 +0200 Subject: [PATCH 2/2] chore: add missing changeset --- .changeset/blue-sheep-run.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/blue-sheep-run.md diff --git a/.changeset/blue-sheep-run.md b/.changeset/blue-sheep-run.md new file mode 100644 index 00000000..71b65584 --- /dev/null +++ b/.changeset/blue-sheep-run.md @@ -0,0 +1,5 @@ +--- +'jest-extended': minor +--- + +Introduce new matcher `toIncludeCaseInsensitive`