concurrently
Version:
Run commands concurrently
90 lines (89 loc) • 4.43 kB
JavaScript
import { beforeEach, expect, it } from 'vitest';
import { createMockInstance } from '../__fixtures__/create-mock-instance.js';
import { createFakeCloseEvent, FakeCommand } from '../__fixtures__/fake-command.js';
import { DateFormatter } from '../date-format.js';
import { Logger } from '../logger.js';
import { LogTimings } from './log-timings.js';
// shown in timing order
const startDate0 = new Date();
const startDate1 = new Date(startDate0.getTime() + 1000);
const endDate1 = new Date(startDate0.getTime() + 5000);
const endDate0 = new Date(startDate0.getTime() + 3000);
const timestampFormat = 'yyyy-MM-dd HH:mm:ss.SSS';
const getDurationText = (startDate, endDate) => `${(endDate.getTime() - startDate.getTime()).toLocaleString()}ms`;
const command0DurationTextMs = getDurationText(startDate0, endDate0);
const command1DurationTextMs = getDurationText(startDate1, endDate1);
let controller;
let logger;
let commands;
let command0ExitInfo;
let command1ExitInfo;
beforeEach(() => {
commands = [new FakeCommand('foo', 'command 1', 0), new FakeCommand('bar', 'command 2', 1)];
command0ExitInfo = createFakeCloseEvent({
command: commands[0],
timings: {
startDate: startDate0,
endDate: endDate0,
durationSeconds: endDate0.getTime() - startDate0.getTime(),
},
index: commands[0].index,
});
command1ExitInfo = createFakeCloseEvent({
command: commands[1],
timings: {
startDate: startDate1,
endDate: endDate1,
durationSeconds: endDate1.getTime() - startDate1.getTime(),
},
index: commands[1].index,
});
logger = createMockInstance(Logger);
controller = new LogTimings({ logger, timestampFormat });
});
it('returns same commands', () => {
expect(controller.handle(commands)).toMatchObject({ commands });
});
it("does not log timings and doesn't throw if no logger is provided", () => {
controller = new LogTimings({});
const { onFinish } = controller.handle(commands);
commands[0].timer.next({ startDate: startDate0 });
commands[1].timer.next({ startDate: startDate1 });
commands[1].timer.next({ startDate: startDate1, endDate: endDate1 });
commands[0].timer.next({ startDate: startDate0, endDate: endDate0 });
onFinish?.();
expect(logger.logCommandEvent).toHaveBeenCalledTimes(0);
});
it('logs the timings at the start and end (ie complete or error) event of each command', () => {
const formatter = new DateFormatter(timestampFormat);
controller.handle(commands);
commands[0].timer.next({ startDate: startDate0 });
commands[1].timer.next({ startDate: startDate1 });
commands[1].timer.next({ startDate: startDate1, endDate: endDate1 });
commands[0].timer.next({ startDate: startDate0, endDate: endDate0 });
expect(logger.logCommandEvent).toHaveBeenCalledTimes(4);
expect(logger.logCommandEvent).toHaveBeenCalledWith(`${commands[0].command} started at ${formatter.format(startDate0)}`, commands[0]);
expect(logger.logCommandEvent).toHaveBeenCalledWith(`${commands[1].command} started at ${formatter.format(startDate1)}`, commands[1]);
expect(logger.logCommandEvent).toHaveBeenCalledWith(`${commands[1].command} stopped at ${formatter.format(endDate1)} after ${command1DurationTextMs}`, commands[1]);
expect(logger.logCommandEvent).toHaveBeenCalledWith(`${commands[0].command} stopped at ${formatter.format(endDate0)} after ${command0DurationTextMs}`, commands[0]);
});
it('does not log timings summary if there was an error', () => {
const { onFinish } = controller.handle(commands);
commands[0].close.next(command0ExitInfo);
commands[1].error.next(undefined);
onFinish?.();
expect(logger.logTable).toHaveBeenCalledTimes(0);
});
it('logs the sorted timings summary when all processes close successfully after onFinish is called', () => {
const { onFinish } = controller.handle(commands);
commands[0].close.next(command0ExitInfo);
commands[1].close.next(command1ExitInfo);
expect(logger.logGlobalEvent).toHaveBeenCalledTimes(0);
onFinish?.();
expect(logger.logGlobalEvent).toHaveBeenCalledExactlyOnceWith('Timings:');
// sorted by duration
expect(logger.logTable).toHaveBeenCalledExactlyOnceWith([
LogTimings.mapCloseEventToTimingInfo(command1ExitInfo),
LogTimings.mapCloseEventToTimingInfo(command0ExitInfo),
]);
});