@90poe/jest-performant-warnings-stats-reporter
Version:
A flexible jest reporter that provides ability to show statistics of warnings and group them
507 lines (444 loc) • 17.4 kB
text/typescript
import { bold, cyan, green, red, yellow } from 'chalk';
import { table } from 'table';
import {
TABLE_HEADER_WITH_WARNINGS_DATA,
TABLE_HEADER_WITHOUT_WARNINGS_DATA,
} from './constants';
import {
MockedAggregatedResultWithoutCoverage,
MockedAggregatedResultWithoutCoverage_multipleResultState,
MockedAggregatedResultWithoutCoverage_recursiveReporter,
MockedTest_default,
MockedTest_multipleResultState,
MockedTest_warnOnSlowerThan,
MockedTestResult_default,
MockedTestResult_showSlowest,
MockedTestResult_showWarnings,
MockedTestResult_showWarningsWithOther,
MockedTestResult_warnOnSlowerThan,
} from './mocks';
import CustomReporter from './reporter';
let reporter = null;
let expectedFinalTable: unknown[][] = [];
beforeEach(() => {
console.log = jest.fn();
console.warn = jest.fn();
console.error = jest.fn();
reporter = null;
expectedFinalTable = [TABLE_HEADER_WITH_WARNINGS_DATA];
});
describe('@90poe/jest-performant-warnings-stats-reporter', () => {
it('should work with No config provided, default set up', () => {
const globalC = {};
const customC = {};
const expectedTotalNumberOfTestSuites =
MockedAggregatedResultWithoutCoverage.numTotalTestSuites;
const expectedOnRunStartConsoleLog = cyan(
`\nRunning ${expectedTotalNumberOfTestSuites} test suites, quietly for speed 🏎️ `,
);
const expectedTableRow = [
MockedTestResult_default.testFilePath.split('/').slice(-1),
'0',
`${MockedTestResult_default.perfStats.runtime / 1000}s`,
];
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(MockedTest_default, MockedTestResult_default);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expectedFinalTable.push(expectedTableRow);
expect(console.log).toHaveBeenCalledWith(expectedOnRunStartConsoleLog);
expect(console.log).toHaveBeenCalledWith(table(expectedFinalTable));
expect(console.log).toBeCalledTimes(2);
});
it('should colour duration values in red when test duration is greater than "warnOnSlowerThan"', () => {
const globalC = {};
const customC = {
warnOnSlowerThan: 700,
};
const expectedTableRow = [
MockedTestResult_warnOnSlowerThan.testFilePath.split('/').slice(-1),
'0',
`${red(MockedTestResult_warnOnSlowerThan.perfStats.runtime / 1000)}s`,
];
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(
MockedTest_warnOnSlowerThan,
MockedTestResult_warnOnSlowerThan,
);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expectedFinalTable.push(expectedTableRow);
expect(console.log).toHaveBeenCalledWith(table(expectedFinalTable));
expect(console.log).toBeCalledTimes(2);
});
it('should show slowest tests when "showSlowest" flag is "true"', () => {
const globalC = {};
const customC = {
showSlowest: true,
};
const expectedSlowestTestsOutput = {
totalInfo: 'Top 5 slowest examples (3.5 seconds, 100.0% of total time):',
firstSlowTestTitle: ' testing test suite - 2',
firstSlowTestDuration: ' 0.9 seconds /src/test_showSlowest.test.ts',
secondSlowTestTitle: ' testing test suite - 1',
secondSlowTestDuration: ' 0.8 seconds /src/test_showSlowest.test.ts',
thirdSlowTestTitle: ' testing test suite - 3',
thirdSlowTestDuration: ' 0.7 seconds /src/test_showSlowest.test.ts',
fourthSlowTestTitle: ' testing test suite - 5',
fourthSlowTestDuration: ' 0.6 seconds /src/test_showSlowest.test.ts',
fifthSlowTestTitle: ' testing test suite - 4',
fifthSlowTestDuration: ' 0.5 seconds /src/test_showSlowest.test.ts',
};
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(MockedTest_default, MockedTestResult_showSlowest);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.totalInfo,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.firstSlowTestTitle,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.firstSlowTestDuration,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.secondSlowTestTitle,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.secondSlowTestDuration,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.thirdSlowTestTitle,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.thirdSlowTestDuration,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.fourthSlowTestTitle,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.fourthSlowTestDuration,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.fifthSlowTestTitle,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.fifthSlowTestDuration,
);
expect(console.log).toBeCalledTimes(13);
});
it('should show slowest tests when "showSlowest" flag is "true" & "maxSlowTests" is provided', () => {
const globalC = {};
const customC = {
showSlowest: true,
maxSlowTests: 2,
};
const expectedSlowestTestsOutput = {
totalInfo: 'Top 2 slowest examples (1.7 seconds, 48.6% of total time):',
firstSlowTestTitle: ' testing test suite - 1',
firstSlowTestDuration: ' 0.9 seconds /src/test_showSlowest.test.ts',
secondSlowTestTitle: ' testing test suite - 2',
secondSlowTestDuration: ' 0.8 seconds /src/test_showSlowest.test.ts',
};
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(MockedTest_default, MockedTestResult_showSlowest);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.totalInfo,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.firstSlowTestTitle,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.firstSlowTestDuration,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.secondSlowTestTitle,
);
expect(console.log).toHaveBeenCalledWith(
expectedSlowestTestsOutput.secondSlowTestDuration,
);
expect(console.log).toBeCalledTimes(7);
});
it('should Not show slowest tests when "showSlowest" flag is "false" & "maxSlowTests" is provided', () => {
const globalC = {};
const customC = {
maxSlowTests: 2,
};
const expectedSlowestTestsOutput = {
totalInfo: 'Top 2 slowest examples (1.7 seconds, 48.6% of total time):',
firstSlowTestTitle: ' testing test suite - 1',
firstSlowTestDuration: ' 0.9 seconds /src/test_showSlowest.test.ts',
};
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(MockedTest_default, MockedTestResult_showSlowest);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expect(console.log).not.toHaveBeenCalledWith(
expectedSlowestTestsOutput.totalInfo,
);
expect(console.log).not.toHaveBeenCalledWith(
expectedSlowestTestsOutput.firstSlowTestTitle,
);
expect(console.log).not.toHaveBeenCalledWith(
expectedSlowestTestsOutput.firstSlowTestDuration,
);
expect(console.log).toBeCalledTimes(2);
});
it('should show warnings details in finalTable if "showWarningSummary" flag is "true" & "warningsConfig" is provided', () => {
const globalC = {};
const customC = {
showWarningSummary: true,
warningsConfig: [
{
name: 'Warning on act(...)',
regex: /act(...)/,
},
{
name: 'Warning on Apollo',
regex: /Apollo/,
},
{
name: 'Warning on Unhandled',
regex: /Unhandled/,
},
],
};
const expectedWarningsOutput = {
actWarnings: {
title: ' > Warning on act(...)',
count: 3,
},
apolloWarnings: {
title: ' > Warning on Apollo',
count: 1,
},
unhandledWarning: {
title: ' > Warning on Unhandled',
count: 1,
},
other: {
title: ' > Other',
count: 3,
},
};
const expectedTableRow = [
MockedTestResult_showWarnings.testFilePath.split('/').slice(-1),
`${MockedTestResult_showWarnings.console.length}`,
`${MockedTestResult_showWarnings.perfStats.runtime / 1000}s`,
];
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(MockedTest_default, MockedTestResult_showWarnings);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expectedFinalTable.push(expectedTableRow);
Object.values(expectedWarningsOutput).forEach(({ title, count }) =>
expectedFinalTable.push([title, count, '']),
);
const tableWithWarningsInfo = table(expectedFinalTable);
expect(console.log).toHaveBeenCalledWith(tableWithWarningsInfo);
expect(console.log).toBeCalledTimes(2);
});
it('should Not show warnings details in finalTable if "showWarningSummary" flag is "false" & "warningsConfig" is provided', () => {
const globalC = {};
const customC = {
warningsConfig: [
{
name: 'Warning on act(...)',
regex: /act(...)/,
},
{
name: 'Warning on Apollo',
regex: /Apollo/,
},
{
name: 'Warning on Unhandled',
regex: /Unhandled/,
},
],
};
const expectedTableRow = [
MockedTestResult_showWarnings.testFilePath.split('/').slice(-1),
`${MockedTestResult_showWarnings.console.length}`,
`${MockedTestResult_showWarnings.perfStats.runtime / 1000}s`,
];
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(MockedTest_default, MockedTestResult_showWarnings);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expectedFinalTable.push(expectedTableRow);
const tableWithoutWarningsInfo = table(expectedFinalTable);
expect(console.log).toHaveBeenCalledWith(tableWithoutWarningsInfo);
expect(console.log).toBeCalledTimes(2);
});
it('should contain "Other" as a table row with number of warnings that do Not match any from the "warningConfig"', () => {
const globalC = {};
const customC = {
showWarningSummary: true,
warningsConfig: [
{
name: 'Warning on act(...)',
regex: /act(...)/,
},
{
name: 'Warning on Apollo',
regex: /Apollo/,
},
{
name: 'Warning on Unhandled',
regex: /Unhandled/,
},
],
};
const expectedWarningsOutput = {
actWarnings: {
title: ' > Warning on act(...)',
count: 3,
},
apolloWarnings: {
title: ' > Warning on Apollo',
count: 2,
},
unhandledWarning: {
title: ' > Warning on Unhandled',
count: 1,
},
other: {
title: ' > Other',
count: 2,
},
};
const expectedTableRow = [
MockedTestResult_showWarningsWithOther.testFilePath.split('/').slice(-1),
`${MockedTestResult_showWarningsWithOther.console.length}`,
`${MockedTestResult_showWarningsWithOther.perfStats.runtime / 1000}s`,
];
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(
MockedTest_default,
MockedTestResult_showWarningsWithOther,
);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expectedFinalTable.push(expectedTableRow);
Object.values(expectedWarningsOutput).forEach(({ title, count }) =>
expectedFinalTable.push([title, count, '']),
);
const tableWithWarningsInfo = table(expectedFinalTable);
expect(console.log).toHaveBeenCalledWith(tableWithWarningsInfo);
expect(console.log).toBeCalledTimes(2);
});
it('should log numPassedTests, numFailedTests, FailureMessage', () => {
const globalC = {};
const customC = {};
const expectedFailureMessage =
MockedAggregatedResultWithoutCoverage_multipleResultState.testResults[0]
.failureMessage;
const { numPassedTests: expectedNumPassedTests } =
MockedAggregatedResultWithoutCoverage_multipleResultState;
const { numFailedTests: expectedNumFailedTests } =
MockedAggregatedResultWithoutCoverage_multipleResultState;
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(
MockedAggregatedResultWithoutCoverage_multipleResultState,
);
reporter.onTestResult(
MockedTest_multipleResultState,
MockedTestResult_default,
);
reporter.onRunComplete(
new Set(),
MockedAggregatedResultWithoutCoverage_multipleResultState,
);
expect(console.log).toHaveBeenCalledWith(
green(`${expectedNumPassedTests} passed`),
);
expect(console.log).toHaveBeenCalledWith(`${expectedFailureMessage}`);
expect(console.log).toHaveBeenCalledWith(
bold(red(`${expectedNumFailedTests} failed`)),
);
expect(console.log).toBeCalledTimes(8);
});
it('should console warnings, errors in case config has "verbose"', () => {
const globalC = {
verbose: true,
};
const customC = {};
const fileName = bold('test_showWarnings');
const warningMessage = yellow(
'Warning Message - act(...) for MockedTestResult_showWarnings',
);
const errorMessage = red('Error message');
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(MockedTest_default, MockedTestResult_showWarnings);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expect(console.log).toBeCalledWith(fileName);
expect(console.warn).toBeCalledWith(warningMessage);
expect(console.error).toBeCalledWith(errorMessage);
expect(console.log).toBeCalledTimes(5);
expect(console.warn).toBeCalledTimes(10);
expect(console.error).toBeCalledTimes(2);
});
it('should not console final table in case number of watching tests is 0', () => {
const globalC = {
watch: true,
};
const customC = {};
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expect(console.log).not.toBeCalledWith(expectedFinalTable);
});
it('should console final table without warnings data in case config has "verbose"', () => {
const globalC = {
verbose: true,
};
const customC = {
showWarningSummary: true,
};
const expectedTableRow = [
MockedTestResult_showWarnings.testFilePath.split('/').slice(-1),
`${MockedTestResult_showWarnings.perfStats.runtime / 1000}s`,
];
expectedFinalTable = [TABLE_HEADER_WITHOUT_WARNINGS_DATA];
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(MockedTest_default, MockedTestResult_showWarnings);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expectedFinalTable.push(expectedTableRow);
const tableWithoutWarningsInfo = table(expectedFinalTable);
expect(console.log).toBeCalledWith(tableWithoutWarningsInfo);
});
it('should be quiet in case config has "verbose" and there are no warnings', () => {
const globalC = {
verbose: true,
};
const customC = {};
const anyWarningMessage = yellow(
'Warning Message - act(...) for MockedTestResult_showWarnings',
);
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage);
reporter.onTestResult(MockedTest_default, MockedTestResult_default);
reporter.onRunComplete(new Set(), MockedAggregatedResultWithoutCoverage);
expect(console.warn).not.toBeCalledWith(anyWarningMessage);
});
});
it('should work outside of describe block', () => {
const globalC = {};
const customC = {};
reporter = new CustomReporter(globalC, customC);
reporter.onRunStart(MockedAggregatedResultWithoutCoverage_recursiveReporter);
reporter.onTestResult(MockedTest_default, MockedTestResult_default);
reporter.onRunComplete(
new Set(),
MockedAggregatedResultWithoutCoverage_recursiveReporter,
);
expect(console.log).toHaveBeenCalledWith(
green('PASSED - Title in recursiveReporter'),
);
expect(console.log).toBeCalledTimes(3);
});