diff --git a/packages/aws-cdk-api/lib/api.ts b/packages/aws-cdk-api/lib/api.ts index 4bbf2442273d0..f3e94188c3ea6 100644 --- a/packages/aws-cdk-api/lib/api.ts +++ b/packages/aws-cdk-api/lib/api.ts @@ -27,7 +27,7 @@ export interface IAwsCdk { /** * cdk list */ - list(options: ListOptions): Promise; + list(options?: ListOptions): Promise; } /** @@ -96,11 +96,11 @@ export class AwsCdkApi extends Construct implements IAwsCdk { private validateArgs(options: SharedOptions): void { if (!options.stacks && !options.all) { - throw new Error('one of "app" or "stacks" must be provided'); + throw new Error('one of "all" or "stacks" must be provided'); } } - public async list(options: ListOptions) { + public async list(options: ListOptions = { all: true }) { const listCommandArgs: string[] = [ ...renderBooleanArg('long', options.long), ...this.createDefaultArguments(options), diff --git a/packages/aws-cdk-api/test/aws-cdk-api.test.ts b/packages/aws-cdk-api/test/aws-cdk-api.test.ts new file mode 100644 index 0000000000000..77ca8233d91b7 --- /dev/null +++ b/packages/aws-cdk-api/test/aws-cdk-api.test.ts @@ -0,0 +1,309 @@ +import * as core from '@aws-cdk/core'; +import * as cli from 'aws-cdk/lib'; +import { AwsCdkApi } from '../lib'; +import { RequireApproval, StackActivityProgress } from '../lib/commands'; + +jest.mock('aws-cdk/lib'); +jest.mocked(cli.exec).mockResolvedValue(0); + +const app = new core.App(); +new core.Stack(app, 'Stack1'); +new core.Stack(app, 'Stack2'); + +const cdk = AwsCdkApi.fromApp(app); + +describe('commands', () => { + afterEach(() => { + jest.mocked(cli.exec).mockClear(); + }); + + describe('deploy', () => { + test('default deploy', async () => { + // WHEN + await await cdk.deploy({ + stacks: ['Stack1'], + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + ['deploy', '--progress', 'events', 'Stack1'], + expect.anything(), + ); + }); + + + test('deploy with all arguments', async () => { + // WHEN + await await cdk.deploy({ + stacks: ['Stack1'], + ci: false, + json: true, + color: false, + debug: false, + force: true, + proxy: 'https://proxy', + trace: false, + output: 'cdk.out', + strict: false, + execute: true, + lookups: false, + notices: true, + profile: 'my-profile', + roleArn: 'arn:aws:iam::1111111111:role/my-role', + staging: false, + verbose: true, + ec2Creds: true, + rollback: false, + exclusively: true, + outputsFile: 'outputs.json', + reuseAssets: [ + 'asset1234', + 'asset5678', + ], + caBundlePath: '/some/path', + ignoreErrors: false, + pathMetadata: false, + assetMetadata: true, + changeSetName: 'my-change-set', + requireApproval: RequireApproval.NEVER, + toolkitStackName: 'Toolkit', + versionReporting: true, + usePreviousParameters: true, + progress: StackActivityProgress.BAR, + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + expect.arrayContaining([ + 'deploy', + '--no-strict', + '--no-trace', + '--no-lookups', + '--no-ignore-errors', + '--json', + '--verbose', + '--no-debug', + '--ec2creds', + '--version-reporting', + '--no-path-metadata', + '--asset-metadata', + '--notices', + '--no-color', + '--profile', 'my-profile', + '--proxy', 'https://proxy', + '--ca-bundle-path', '/some/path', + '--role-arn', 'arn:aws:iam::1111111111:role/my-role', + '--output', 'cdk.out', + '--no-ci', + '--execute', + '--exclusively', + '--force', + '--no-rollback', + '--no-staging', + '--reuse-assets', 'asset1234', + '--reuse-assets', 'asset5678', + '--outputs-file', 'outputs.json', + '--require-approval', 'never', + '--change-set-name', 'my-change-set', + '--toolkit-stack-name', 'Toolkit', + '--previous-parameters', + '--progress', 'bar', + 'Stack1', + ]), + expect.anything(), + ); + }); + + + test('can parse boolean arguments', async () => { + // WHEN + await await cdk.deploy({ + stacks: ['Stack1'], + json: true, + color: false, + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + [ + 'deploy', + '--progress', 'events', + '--json', + '--no-color', + 'Stack1', + ], + expect.anything(), + ); + }); + + test('can parse parameters', async() => { + // WHEN + await await cdk.deploy({ + stacks: ['Stack1'], + parameters: { + 'myparam': 'test', + 'Stack1:myotherparam': 'test', + }, + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + [ + 'deploy', + '--parameters', 'myparam=test', + '--parameters', 'Stack1:myotherparam=test', + '--progress', 'events', + 'Stack1', + ], + expect.anything(), + ); + }); + + + test('can parse context', async () => { + // WHEN + await cdk.deploy({ + stacks: ['Stack1'], + context: { + 'myContext': 'value', + 'Stack1:OtherContext': 'otherValue', + }, + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + [ + 'deploy', + '--progress', 'events', + '--context', 'myContext=value', + '--context', 'Stack1:OtherContext=otherValue', + 'Stack1', + ], + expect.anything(), + ); + }); + + test('can parse array arguments', async () => { + // WHEN + await cdk.deploy({ + stacks: ['Stack1'], + notificationArns: [ + 'arn:aws:us-east-1:1111111111:some:resource', + 'arn:aws:us-east-1:1111111111:some:other-resource', + ], + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + [ + 'deploy', + '--notification-arns', 'arn:aws:us-east-1:1111111111:some:resource', + '--notification-arns', 'arn:aws:us-east-1:1111111111:some:other-resource', + '--progress', 'events', + 'Stack1', + ], + expect.anything(), + ); + }); + }); + + describe('synth', () => { + test('default synth', async () => { + // WHEN + await cdk.synth({ + stacks: ['Stack1'], + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + ['synth', 'Stack1'], + expect.anything(), + ); + }); + + test('synth arguments', async () => { + // WHEN + await cdk.destroy({ + stacks: ['Stack1'], + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + ['destroy', 'Stack1'], + expect.anything(), + ); + }); + }); + + describe('destroy', () => { + test('default destroy', async () => { + // WHEN + await cdk.destroy({ + stacks: ['Stack1'], + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + ['destroy', 'Stack1'], + expect.anything(), + ); + }); + + test('destroy arguments', async () => { + // WHEN + await cdk.destroy({ + stacks: ['Stack1'], + force: true, + exclusively: false, + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + ['destroy', '--force', '--no-exclusively', 'Stack1'], + expect.anything(), + ); + }); + }); + + + describe('list', () => { + + test('default list', async () => { + // WHEN + await cdk.list({ + stacks: ['*'], + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + ['ls', '*'], + expect.anything(), + ); + }); + + test('list arguments', async () => { + // WHEN + await cdk.list({ + stacks: ['*'], + long: true, + }); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + ['ls', '--long', '*'], + expect.anything(), + ); + }); + + test('list without options', async () => { + // WHEN + await cdk.list(); + + // THEN + expect(jest.mocked(cli.exec)).toHaveBeenCalledWith( + ['ls', '--all'], + expect.anything(), + ); + }); + }); +}); \ No newline at end of file