Skip to content

Commit

Permalink
feat(ci): include count of errors in ci status messages (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio committed May 13, 2021
1 parent 081380c commit d34660f
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 4 deletions.
2 changes: 2 additions & 0 deletions lib/progress-logger/log-templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,10 @@ export const REPOSITORIES_STATUS_TEMPLATE = (

export const CI_STATUS_TEMPLATE = (
scannedRepositories: number,
errorCount: number,
tasks: Task[]
): string => `[INFO/STATUS] ${REPOSITORIES_STATUS_TEMPLATE(scannedRepositories)}
[INFO/STATUS] Errors (${errorCount})
${tasks.map(task => CI_TASK_TEMPLATE(task)).join('\n')}\n`;

const CI_TASK_TEMPLATE = (task: Task): string =>
Expand Down
11 changes: 10 additions & 1 deletion lib/progress-logger/progress-logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ class ProgressLogger {
/** Count of finished repositories */
scannedRepositories = 0;

/** Total count of errors */
private errorCount = 0;

/** Event listeners */
private listeners: Listeners = {
exit: [],
Expand Down Expand Up @@ -94,7 +97,10 @@ class ProgressLogger {
/**
* Subscribe on logger's events
*/
on<T = ListenerType>(event: T & ListenerType, listener: Listener<T>) {
on<T extends ListenerType = ListenerType>(
event: T & ListenerType,
listener: Listener<T>
) {
const eventListeners = this.listeners[event];

if (eventListeners) {
Expand Down Expand Up @@ -260,6 +266,8 @@ class ProgressLogger {
const hasErrors = resultCount > 0;

this.scannedRepositories++;
this.errorCount += resultCount;

this.addNewMessage({
content: Templates.LINT_END_TEMPLATE(repository, resultCount),
color: hasErrors ? 'red' : 'green',
Expand Down Expand Up @@ -412,6 +420,7 @@ class ProgressLogger {
if (['verbose', 'info'].includes(config.logLevel)) {
const message = Templates.CI_STATUS_TEMPLATE(
this.scannedRepositories,
this.errorCount,
this.tasks
);

Expand Down
9 changes: 9 additions & 0 deletions test/unit/__mocks__/@config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Config } from '@config/types';

const DEFAULT_MOCK_CONFIG = {
repositories: ['mock-repo-1', 'mock-repo-2', 'mock-repo-3'],
logLevel: 'verbose',
Expand All @@ -10,6 +12,13 @@ export const restoreMockConfig = (): void => {
mockConfig.mockReturnValue(DEFAULT_MOCK_CONFIG);
};

export function mockConfigValue(value: Partial<Config>): void {
mockConfig.mockReturnValue({
...DEFAULT_MOCK_CONFIG,
...value,
});
}

export default new Proxy(mockConfig, {
get: (target, prop) => (target() || {})[prop],
});
Expand Down
56 changes: 53 additions & 3 deletions test/unit/progress-logger.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import ProgressLogger from '@progress-logger';
import ActualProgressLogger from '@progress-logger';
import { LogMessage } from '@progress-logger/types';
import { mockConfig } from '__mocks__/@config';
import { mockConfigValue, restoreMockConfig } from '__mocks__/@config';
import { getLastCallArguments } from '../utils';

jest.unmock('@progress-logger');

describe('progress-logger', () => {
let ProgressLogger: typeof ActualProgressLogger;

beforeEach(() => {
restoreMockConfig();

jest.isolateModules(() => {
ProgressLogger = require('../../lib/progress-logger').default;
});
});

test('listeners are notified about new messages', () => {
const onMessage = jest.fn();
const message: LogMessage = { content: 'A', level: 'warn' };
Expand All @@ -16,7 +27,7 @@ describe('progress-logger', () => {
});

test('messages are filterd by config.logLevel', () => {
mockConfig.mockReturnValue({ logLevel: 'warn' });
mockConfigValue({ logLevel: 'warn' });

const onMessage = jest.fn();
const message: LogMessage = { content: 'A', level: 'info' };
Expand All @@ -26,4 +37,43 @@ describe('progress-logger', () => {

expect(onMessage).not.toHaveBeenCalled();
});

test('ci status messages include repositories and error count', () => {
// Expected to affect repository count in status message
mockConfigValue({ repositories: ['1', '2', '3', '4', '5'] });

const onCiKeepAlive = jest.fn();
ProgressLogger.on('ciKeepAlive', onCiKeepAlive);

ProgressLogger.onLintEnd('mock-repository', 5);
ProgressLogger.onCiStatus();

expect(getLastCallArguments(onCiKeepAlive)).toMatchInlineSnapshot(`
"[INFO/STATUS] Repositories (1/5)
[INFO/STATUS] Errors (5)
"
`);
});

test('ci status messages include current tasks', () => {
const onCiKeepAlive = jest.fn();
ProgressLogger.on('ciKeepAlive', onCiKeepAlive);

ProgressLogger.onLintStart('repository-one', 12);
ProgressLogger.onRepositoryClone('repositry-two');
ProgressLogger.onRepositoryRead('repository-three');
ProgressLogger.onRepositoryPull('repository-four');
ProgressLogger.onCiStatus();

expect(getLastCallArguments(onCiKeepAlive)).toMatchInlineSnapshot(`
"[INFO/STATUS] Repositories (0/3)
[INFO/STATUS] Errors (0)
[INFO/LINTING] repository-one - 12 files
[INFO/CLONING] repositry-two
[INFO/READING] repository-three
[INFO/PULLING] repository-four
"
`);
});
});
13 changes: 13 additions & 0 deletions test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,16 @@ export function addFailureLogger(): void {

jasmine.getEnv().addReporter({ specDone });
}

/**
* Get last call arguments of given mocked callback
* - Returns array incase of multiple call arguments
* - Returns a single value incase of single call argument
*/
export function getLastCallArguments(callback: jest.Mock): unknown {
if (!callback.mock.calls) return null;

const [lastCall] = callback.mock.calls;

return lastCall.length > 1 ? lastCall : lastCall[0];
}

0 comments on commit d34660f

Please sign in to comment.