From 37596e6be4cf05432dcba3838955484e512beca6 Mon Sep 17 00:00:00 2001 From: diegotry <33488603+diegotry@users.noreply.github.com> Date: Thu, 25 Nov 2021 02:09:59 -0800 Subject: [PATCH] fix(assert): support multiline strings with `stringLike()` (#17692) Updates the `RegExp` constructor to support multiline. Resolves https://github.com/aws/aws-cdk/issues/17691 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/assert-internal/README.md | 2 +- .../lib/assertions/have-resource-matchers.ts | 4 +-- .../test/have-resource.test.ts | 36 ++++++++++++++++++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/assert-internal/README.md b/packages/@aws-cdk/assert-internal/README.md index ae72469dc59e2..a74f9304f60d6 100644 --- a/packages/@aws-cdk/assert-internal/README.md +++ b/packages/@aws-cdk/assert-internal/README.md @@ -103,7 +103,7 @@ The following matchers exist: back to exact value matching. - `arrayWith(E, [F, ...])` - value must be an array containing the given elements (or matchers) in any order. - `stringLike(S)` - value must be a string matching `S`. `S` may contain `*` as wildcard to match any number - of characters. + of characters. Multiline strings are supported. - `anything()` - matches any value. - `notMatching(M)` - any value that does NOT match the given matcher (or exact value) given. - `encodedJson(M)` - value must be a string which, when decoded as JSON, matches the given matcher or diff --git a/packages/@aws-cdk/assert-internal/lib/assertions/have-resource-matchers.ts b/packages/@aws-cdk/assert-internal/lib/assertions/have-resource-matchers.ts index deb64b769ff16..d82b59feffea0 100644 --- a/packages/@aws-cdk/assert-internal/lib/assertions/have-resource-matchers.ts +++ b/packages/@aws-cdk/assert-internal/lib/assertions/have-resource-matchers.ts @@ -239,11 +239,11 @@ function isCallable(x: any): x is ((...args: any[]) => any) { } /** - * Do a glob-like pattern match (which only supports *s) + * Do a glob-like pattern match (which only supports *s). Supports multiline strings. */ export function stringLike(pattern: string): PropertyMatcher { // Replace * with .* in the string, escape the rest and brace with ^...$ - const regex = new RegExp(`^${pattern.split('*').map(escapeRegex).join('.*')}$`); + const regex = new RegExp(`^${pattern.split('*').map(escapeRegex).join('.*')}$`, 'm'); return annotateMatcher({ $stringContaining: pattern }, (value: any, failure: InspectionFailure) => { if (typeof value !== 'string') { diff --git a/packages/@aws-cdk/assert-internal/test/have-resource.test.ts b/packages/@aws-cdk/assert-internal/test/have-resource.test.ts index 324e221114df0..c43433e8ca14f 100644 --- a/packages/@aws-cdk/assert-internal/test/have-resource.test.ts +++ b/packages/@aws-cdk/assert-internal/test/have-resource.test.ts @@ -1,4 +1,14 @@ -import { ABSENT, arrayWith, exactValue, expect as cdkExpect, haveResource, haveResourceLike, Capture, anything } from '../lib/index'; +import { + ABSENT, + arrayWith, + exactValue, + expect as cdkExpect, + haveResource, + haveResourceLike, + Capture, + anything, + stringLike, +} from '../lib/index'; import { mkResource, mkStack } from './cloud-artifact'; test('support resource with no properties', () => { @@ -156,6 +166,30 @@ describe('property absence', () => { }).toThrowError(/Array did not contain expected element/); }); + test('can use matcher to test stringLike on single-line strings', () => { + const synthStack = mkResource({ + Content: 'something required something', + }); + + expect(() => { + cdkExpect(synthStack).to(haveResource('Some::Resource', { + Content: stringLike('*required*'), + })); + }).not.toThrowError(); + }); + + test('can use matcher to test stringLike on multi-line strings', () => { + const synthStack = mkResource({ + Content: 'something\nrequired\nsomething', + }); + + expect(() => { + cdkExpect(synthStack).to(haveResource('Some::Resource', { + Content: stringLike('*required*'), + })); + }).not.toThrowError(); + }); + test('arrayContaining must match all elements in any order', () => { const synthStack = mkResource({ List: ['a', 'b'],