Skip to content

Commit dad96ff

Browse files
authored
Merge branch 'master' into huijbers/synthesizers
2 parents e0858a9 + edac101 commit dad96ff

333 files changed

Lines changed: 9097 additions & 1583 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616
},
1717
"devDependencies": {
1818
"@yarnpkg/lockfile": "^1.1.0",
19-
"cdk-generate-synthetic-examples": "^0.1.5",
19+
"cdk-generate-synthetic-examples": "^0.1.6",
2020
"conventional-changelog-cli": "^2.2.2",
2121
"fs-extra": "^9.1.0",
2222
"graceful-fs": "^4.2.9",
2323
"jest-junit": "^13.0.0",
24-
"jsii-diff": "^1.53.0",
25-
"jsii-pacmak": "^1.53.0",
26-
"jsii-reflect": "^1.53.0",
27-
"jsii-rosetta": "^1.53.0",
24+
"jsii-diff": "^1.54.0",
25+
"jsii-pacmak": "^1.54.0",
26+
"jsii-reflect": "^1.54.0",
27+
"jsii-rosetta": "^1.54.0",
2828
"lerna": "^4.0.0",
2929
"patch-package": "^6.4.7",
3030
"standard-version": "^9.3.2",

packages/@aws-cdk/app-delivery/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"@aws-cdk/cdk-integ-tools": "0.0.0",
7474
"@aws-cdk/pkglint": "0.0.0",
7575
"@types/jest": "^27.4.0",
76-
"fast-check": "^2.21.0",
76+
"fast-check": "^2.22.0",
7777
"jest": "^27.5.1"
7878
},
7979
"repository": {

packages/@aws-cdk/assertions/lib/annotations.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,10 @@ function constructMessage(type: 'info' | 'warning' | 'error', message: any): {[k
102102
}
103103

104104
function convertArrayToMessagesType(messages: SynthesisMessage[]): Messages {
105-
return messages.reduce((obj, item) => {
105+
return messages.reduce((obj, item, index) => {
106106
return {
107107
...obj,
108-
[item.id]: item,
108+
[index]: item,
109109
};
110110
}, {}) as Messages;
111111
}

packages/@aws-cdk/assertions/lib/private/cyclic.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,16 @@ function findExpressionDependencies(obj: any): Set<string> {
7070
} else if (keys.length === 1 && keys[0] === 'Fn::Sub') {
7171
const argument = x[keys[0]];
7272
const pattern = Array.isArray(argument) ? argument[0] : argument;
73-
for (const logId of logicalIdsInSubString(pattern)) {
74-
ret.add(logId);
73+
74+
// pattern should always be a string, but we've encountered some cases in which
75+
// it isn't. Better safeguard.
76+
if (typeof pattern === 'string') {
77+
for (const logId of logicalIdsInSubString(pattern)) {
78+
ret.add(logId);
79+
}
7580
}
7681
const contextDict = Array.isArray(argument) ? argument[1] : undefined;
77-
if (contextDict) {
82+
if (contextDict && typeof contextDict === 'object') {
7883
Object.values(contextDict).forEach(recurse);
7984
}
8085
} else {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { SynthesisMessage } from '@aws-cdk/cx-api';
22

33
export type Messages = {
4-
[logicalId: string]: SynthesisMessage;
4+
[key: string]: SynthesisMessage;
55
}
Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { MatchResult } from '../matcher';
1+
import { SynthesisMessage } from '@aws-cdk/cx-api';
22
import { Messages } from './message';
3-
import { filterLogicalId, formatFailure, matchSection } from './section';
3+
import { formatFailure, matchSection } from './section';
44

5-
export function findMessage(messages: Messages, logicalId: string, props: any = {}): { [key: string]: { [key: string]: any } } {
6-
const section: { [key: string]: {} } = messages;
7-
const result = matchSection(filterLogicalId(section, logicalId), props);
5+
export function findMessage(messages: Messages, constructPath: string, props: any = {}): { [key: string]: { [key: string]: any } } {
6+
const section: { [key: string]: SynthesisMessage } = messages;
7+
const result = matchSection(filterPath(section, constructPath), props);
88

99
if (!result.match) {
1010
return {};
@@ -13,9 +13,9 @@ export function findMessage(messages: Messages, logicalId: string, props: any =
1313
return result.matches;
1414
}
1515

16-
export function hasMessage(messages: Messages, logicalId: string, props: any): string | void {
17-
const section: { [key: string]: {} } = messages;
18-
const result = matchSection(filterLogicalId(section, logicalId), props);
16+
export function hasMessage(messages: Messages, constructPath: string, props: any): string | void {
17+
const section: { [key: string]: SynthesisMessage } = messages;
18+
const result = matchSection(filterPath(section, constructPath), props);
1919

2020
if (result.match) {
2121
return;
@@ -25,17 +25,26 @@ export function hasMessage(messages: Messages, logicalId: string, props: any): s
2525
return 'No messages found in the stack';
2626
}
2727

28+
handleTrace(result.closestResult.target);
2829
return [
2930
`Stack has ${result.analyzedCount} messages, but none match as expected.`,
30-
formatFailure(formatMessage(result.closestResult)),
31+
formatFailure(result.closestResult),
3132
].join('\n');
3233
}
3334

3435
// We redact the stack trace by default because it is unnecessarily long and unintelligible.
3536
// If there is a use case for rendering the trace, we can add it later.
36-
function formatMessage(match: MatchResult, renderTrace: boolean = false): MatchResult {
37-
if (!renderTrace) {
38-
match.target.entry.trace = 'redacted';
39-
}
40-
return match;
37+
function handleTrace(match: any, redact: boolean = true): void {
38+
if (redact && match.entry?.trace !== undefined) {
39+
match.entry.trace = 'redacted';
40+
};
41+
}
42+
43+
function filterPath(section: { [key: string]: SynthesisMessage }, path: string): { [key: string]: SynthesisMessage } {
44+
// default signal for all paths is '*'
45+
if (path === '*') return section;
46+
47+
return Object.entries(section ?? {})
48+
.filter(([_, v]) => v.id === path)
49+
.reduce((agg, [k, v]) => { return { ...agg, [k]: v }; }, {});
4150
}

packages/@aws-cdk/assertions/test/annotations.test.ts

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ describe('Messages', () => {
5353
describe('findError', () => {
5454
test('match', () => {
5555
const result = annotations.findError('*', Match.anyValue());
56-
expect(Object.keys(result).length).toEqual(2);
56+
expect(result.length).toEqual(2);
5757
});
5858

5959
test('no match', () => {
6060
const result = annotations.findError('*', 'no message looks like this');
61-
expect(Object.keys(result).length).toEqual(0);
61+
expect(result.length).toEqual(0);
6262
});
6363
});
6464

@@ -75,12 +75,12 @@ describe('Messages', () => {
7575
describe('findWarning', () => {
7676
test('match', () => {
7777
const result = annotations.findWarning('*', Match.anyValue());
78-
expect(Object.keys(result).length).toEqual(1);
78+
expect(result.length).toEqual(1);
7979
});
8080

8181
test('no match', () => {
8282
const result = annotations.findWarning('*', 'no message looks like this');
83-
expect(Object.keys(result).length).toEqual(0);
83+
expect(result.length).toEqual(0);
8484
});
8585
});
8686

@@ -97,19 +97,19 @@ describe('Messages', () => {
9797
describe('findInfo', () => {
9898
test('match', () => {
9999
const result = annotations.findInfo('/Default/Qux', 'this is an info');
100-
expect(Object.keys(result).length).toEqual(1);
100+
expect(result.length).toEqual(1);
101101
});
102102

103103
test('no match', () => {
104104
const result = annotations.findInfo('*', 'no message looks like this');
105-
expect(Object.keys(result).length).toEqual(0);
105+
expect(result.length).toEqual(0);
106106
});
107107
});
108108

109109
describe('with matchers', () => {
110110
test('anyValue', () => {
111111
const result = annotations.findError('*', Match.anyValue());
112-
expect(Object.keys(result).length).toEqual(2);
112+
expect(result.length).toEqual(2);
113113
});
114114

115115
test('not', () => {
@@ -123,6 +123,45 @@ describe('Messages', () => {
123123
});
124124
});
125125

126+
describe('Multiple Messages on the Resource', () => {
127+
let stack: Stack;
128+
let annotations: _Annotations;
129+
beforeAll(() => {
130+
stack = new Stack();
131+
new CfnResource(stack, 'Foo', {
132+
type: 'Foo::Bar',
133+
properties: {
134+
Fred: 'Thud',
135+
},
136+
});
137+
138+
const bar = new CfnResource(stack, 'Bar', {
139+
type: 'Foo::Bar',
140+
properties: {
141+
Baz: 'Qux',
142+
},
143+
});
144+
bar.node.setContext('disable-stack-trace', false);
145+
146+
Aspects.of(stack).add(new MultipleAspectsPerNode());
147+
annotations = _Annotations.fromStack(stack);
148+
});
149+
150+
test('succeeds on hasXxx APIs', () => {
151+
annotations.hasError('/Default/Foo', 'error: this is an error');
152+
annotations.hasError('/Default/Foo', 'error: unsupported type Foo::Bar');
153+
annotations.hasWarning('/Default/Foo', 'warning: Foo::Bar is deprecated');
154+
});
155+
156+
test('succeeds on findXxx APIs', () => {
157+
const result1 = annotations.findError('*', Match.stringLikeRegexp('error:.*'));
158+
expect(result1.length).toEqual(4);
159+
const result2 = annotations.findError('/Default/Bar', Match.stringLikeRegexp('error:.*'));
160+
expect(result2.length).toEqual(2);
161+
const result3 = annotations.findWarning('/Default/Bar', 'warning: Foo::Bar is deprecated');
162+
expect(result3[0].entry.data).toEqual('warning: Foo::Bar is deprecated');
163+
});
164+
});
126165
class MyAspect implements IAspect {
127166
public visit(node: IConstruct): void {
128167
if (node instanceof CfnResource) {
@@ -147,4 +186,22 @@ class MyAspect implements IAspect {
147186
protected info(node: IConstruct, message: string): void {
148187
Annotations.of(node).addInfo(message);
149188
}
189+
}
190+
191+
class MultipleAspectsPerNode implements IAspect {
192+
public visit(node: IConstruct): void {
193+
if (node instanceof CfnResource) {
194+
this.error(node, 'error: this is an error');
195+
this.error(node, `error: unsupported type ${node.cfnResourceType}`);
196+
this.warn(node, `warning: ${node.cfnResourceType} is deprecated`);
197+
}
198+
}
199+
200+
protected warn(node: IConstruct, message: string): void {
201+
Annotations.of(node).addWarning(message);
202+
}
203+
204+
protected error(node: IConstruct, message: string): void {
205+
Annotations.of(node).addError(message);
206+
}
150207
}

packages/@aws-cdk/aws-applicationautoscaling/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
"@aws-cdk/cfn2ts": "0.0.0",
8585
"@aws-cdk/pkglint": "0.0.0",
8686
"@types/jest": "^27.4.0",
87-
"fast-check": "^2.21.0",
87+
"fast-check": "^2.22.0",
8888
"jest": "^27.5.1"
8989
},
9090
"dependencies": {

packages/@aws-cdk/aws-autoscaling-common/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
"@aws-cdk/cdk-integ-tools": "0.0.0",
7676
"@aws-cdk/pkglint": "0.0.0",
7777
"@types/jest": "^27.4.0",
78-
"fast-check": "^2.21.0",
78+
"fast-check": "^2.22.0",
7979
"jest": "^27.5.1"
8080
},
8181
"dependencies": {

0 commit comments

Comments
 (0)