Skip to content

Commit

Permalink
Merge branch 'main' into sumughan/aggregate-error-handling
Browse files Browse the repository at this point in the history
  • Loading branch information
sumupitchayan authored Jan 13, 2025
2 parents 5bb86c1 + a5bd76e commit d0c90b9
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 6 deletions.
2 changes: 2 additions & 0 deletions packages/aws-cdk-lib/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ module.exports = {
statements: 55,
},
},

testEnvironment: './testhelpers/jest-bufferedconsole.ts',
};
1 change: 1 addition & 0 deletions packages/aws-cdk-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@
"fast-check": "^3.22.0",
"jest": "^29.7.0",
"jest-each": "^29.7.0",
"jest-environment-node": "^29.7.0",
"lambda-tester": "^4.0.1",
"lodash": "^4.17.21",
"nock": "^13.5.5",
Expand Down
75 changes: 75 additions & 0 deletions packages/aws-cdk-lib/testhelpers/jest-bufferedconsole.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* eslint-disable import/no-extraneous-dependencies */
/**
* A Jest environment that buffers outputs to `console.log()` and only shows it for failing tests.
*/
import type { EnvironmentContext, JestEnvironment, JestEnvironmentConfig } from '@jest/environment';
import { Circus } from '@jest/types';
import { TestEnvironment as NodeEnvironment } from 'jest-environment-node';

interface ConsoleMessage {
type: 'log' | 'error' | 'warn' | 'info' | 'debug';
message: string;
}

export default class TestEnvironment extends NodeEnvironment implements JestEnvironment<unknown> {
private log = new Array<ConsoleMessage>();
private originalConsole!: typeof console;

constructor(config: JestEnvironmentConfig, context: EnvironmentContext) {
super(config, context);

// We need to set the event handler by assignment in the constructor,
// because if we declare it as an async member TypeScript's type derivation
// doesn't work properly.
(this as JestEnvironment<unknown>).handleTestEvent = (async (event, _state) => {
if (event.name === 'test_done' && event.test.errors.length > 0 && this.log.length > 0) {
this.originalConsole.log(`[Console output] ${fullTestName(event.test)}\n`);
for (const item of this.log) {
this.originalConsole[item.type](' ' + item.message);
}
this.originalConsole.log('\n');
}

if (event.name === 'test_done') {
this.log = [];
}
}) satisfies Circus.EventHandler;
}

async setup() {
await super.setup();

this.log = [];
this.originalConsole = console;

this.global.console = {
...console,
log: (message) => this.log.push({ type: 'log', message }),
error: (message) => this.log.push({ type: 'error', message }),
warn: (message) => this.log.push({ type: 'warn', message }),
info: (message) => this.log.push({ type: 'info', message }),
debug: (message) => this.log.push({ type: 'debug', message }),
};
}

async teardown() {
this.global.console = this.originalConsole;
await super.teardown();
}
}

// DescribeBlock is not exported from `@jest/types`, so we need to build the parts we are interested in
type TestDescription = PartialBy<Pick<Circus.TestEntry, 'name' | 'parent'>, 'parent'>;

// Utility type to make specific fields optional
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>

function fullTestName(test: TestDescription) {
let ret = test.name;
while (test.parent != null && test.parent.name !== 'ROOT_DESCRIBE_BLOCK') {
ret = test.parent.name + ' › ' + fullTestName;
test = test.parent;
}
return ret;
}

6 changes: 0 additions & 6 deletions tools/@aws-cdk/cdk-build-tools/config/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,4 @@ module.exports = {
],
coveragePathIgnorePatterns: ['\\.generated\\.[jt]s$', '<rootDir>/test/', '.warnings.jsii.js$', '/node_modules/'],
reporters: ['default', ['jest-junit', { suiteName: 'jest tests', outputDirectory: 'coverage' }]],
/**
* This will still show us helpful information when running tests but remove console statements.
* The exception is when we use our custom logger in the CLI or when other processes are spun up
* within tests. It has no impact there.
*/
silent: true,
};

0 comments on commit d0c90b9

Please sign in to comment.