Skip to content

Commit

Permalink
fix: Report stack metadata in assertions (#1547)
Browse files Browse the repository at this point in the history
`expect(stack).at(path)` is broken because it relies on construct tree metadata
to determine the logical ID for a given path, however the metadata is hard-coded
to an empty object. This fixes the behavior by correctly collecting the metadata
from the construct tree and recording it on the `SynthesizedStack`.
  • Loading branch information
RomainMuller authored Jan 15, 2019
1 parent 9d7e050 commit c2d17f5
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 18 deletions.
18 changes: 15 additions & 3 deletions packages/@aws-cdk/assert/lib/expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ export function expect(stack: api.SynthesizedStack | cdk.Stack, skipValidation =
}

sstack = {
name: 'test',
name: stack.name,
template: stack.toCloudFormation(),
metadata: {},
metadata: collectStackMetadata(stack.node),
environment: {
name: 'test',
account: 'test',
Expand All @@ -37,4 +37,16 @@ export function expect(stack: api.SynthesizedStack | cdk.Stack, skipValidation =

function isStackClassInstance(x: api.SynthesizedStack | cdk.Stack): x is cdk.Stack {
return 'toCloudFormation' in x;
}
}

function collectStackMetadata(root: cdk.ConstructNode): api.StackMetadata {
const result: api.StackMetadata = {};
for (const construct of root.findAll(cdk.ConstructOrder.DepthFirst)) {
const path = `/${root.id}/${construct.node.path}`;
for (const entry of construct.node.metadata) {
result[path] = result[path] || [];
result[path].push(root.resolve(entry));
}
}
return result;
}
37 changes: 22 additions & 15 deletions packages/@aws-cdk/assert/test/test.assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,35 @@ import { Test } from 'nodeunit';
import { Stack } from '@aws-cdk/cdk';
import { countResources, exist, expect, haveType, MatchStyle, matchTemplate } from '../lib/index';

passingExample('expect <stack> at <some path> to have <some type>', () => {
passingExample('expect <synthStack> at <some path> to have <some type>', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'TestResource', { type: resourceType });
});
expect(synthStack).at('/TestResource').to(haveType(resourceType));
});
passingExample('expect <stack> at <some path> *not* to have <some type>', () => {
passingExample('expect <synthStack> at <some path> to have <some type>', () => {
const resourceType = 'Test::Resource';
const stack = new cdk.Stack();
new TestResource(stack, 'TestResource', { type: resourceType });

expect(stack).at('/TestResource').to(haveType(resourceType));
});
passingExample('expect <synthStack> at <some path> *not* to have <some type>', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'TestResource', { type: resourceType });
});
expect(synthStack).at('/TestResource').notTo(haveType('Foo::Bar'));
});
passingExample('expect <stack> at <some path> to exist', () => {
passingExample('expect <synthStack> at <some path> to exist', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'TestResource', { type: resourceType });
});
expect(synthStack).at('/TestResource').to(exist());
});
passingExample('expect <stack> to match (exactly) <template>', () => {
passingExample('expect <synthStack> to match (exactly) <template>', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'TestResource', { type: resourceType });
Expand All @@ -40,15 +47,15 @@ passingExample('expect <stack> to match (exactly) <template>', () => {
};
expect(synthStack).to(matchTemplate(expected, MatchStyle.EXACT));
});
passingExample('expect <stack> to match (no replaces) <template>', () => {
passingExample('expect <synthStack> to match (no replaces) <template>', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'TestResource', { type: resourceType });
});
const expected = {};
expect(synthStack).to(matchTemplate(expected, MatchStyle.NO_REPLACES));
});
passingExample('expect <stack> to be a superset of <template>', () => {
passingExample('expect <synthStack> to be a superset of <template>', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
// Added
Expand Down Expand Up @@ -77,28 +84,28 @@ passingExample('sugar for matching stack to a template', () => {
});
});

failingExample('expect <stack> at <some path> *not* to have <some type>', () => {
failingExample('expect <synthStack> at <some path> *not* to have <some type>', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'TestResource', { type: resourceType });
});
expect(synthStack).at('/TestResource').notTo(haveType(resourceType));
});
failingExample('expect <stack> at <some path> to have <some type>', () => {
failingExample('expect <synthStack> at <some path> to have <some type>', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'TestResource', { type: resourceType });
});
expect(synthStack).at('/TestResource').to(haveType('Foo::Bar'));
});
failingExample('expect <stack> at <some path> to exist', () => {
failingExample('expect <synthStack> at <some path> to exist', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'TestResource', { type: resourceType });
});
expect(synthStack).at('/Foo/Bar').to(exist());
});
failingExample('expect <stack> to match (exactly) <template>', () => {
failingExample('expect <synthStack> to match (exactly) <template>', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'TestResource', { type: resourceType });
Expand All @@ -110,7 +117,7 @@ failingExample('expect <stack> to match (exactly) <template>', () => {
};
expect(synthStack).to(matchTemplate(expected, MatchStyle.EXACT));
});
failingExample('expect <stack> to match (no replaces) <template>', () => {
failingExample('expect <synthStack> to match (no replaces) <template>', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'TestResource', { type: resourceType });
Expand All @@ -122,7 +129,7 @@ failingExample('expect <stack> to match (no replaces) <template>', () => {
};
expect(synthStack).to(matchTemplate(expected, MatchStyle.NO_REPLACES));
});
failingExample('expect <stack> to be a superset of <template>', () => {
failingExample('expect <synthStack> to be a superset of <template>', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
// Added
Expand All @@ -143,7 +150,7 @@ failingExample('expect <stack> to be a superset of <template>', () => {

// countResources

passingExample('expect <stack> to count resources - as expected', () => {
passingExample('expect <synthStack> to count resources - as expected', () => {
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'R1', { type: 'Bar' });
new TestResource(stack, 'R2', { type: 'Bar' });
Expand All @@ -160,7 +167,7 @@ passingExample('expect <stack> to count resources - expected no resources', () =
expect(stack).to(countResources(resourceType, 0));
});

failingExample('expect <stack> to count resources - more than expected', () => {
failingExample('expect <synthStack> to count resources - more than expected', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'R1', { type: resourceType });
Expand All @@ -170,7 +177,7 @@ failingExample('expect <stack> to count resources - more than expected', () => {
expect(synthStack).to(countResources(resourceType, 1));
});

failingExample('expect <stack> to count resources - less than expected', () => {
failingExample('expect <synthStack> to count resources - less than expected', () => {
const resourceType = 'Test::Resource';
const synthStack = synthesizedStack(stack => {
new TestResource(stack, 'R1', { type: resourceType });
Expand Down

0 comments on commit c2d17f5

Please sign in to comment.