feat(terminal): add optional live timers and spinners to terminal tasks
This commit is contained in:
@@ -2,6 +2,10 @@ import { tap, expect } from '@git.zone/tstest/tapbundle';
|
||||
|
||||
import * as smartcli from '../ts/index.js';
|
||||
|
||||
const delay = async (millisecondsArg: number) => {
|
||||
await new Promise((resolve) => setTimeout(resolve, millisecondsArg));
|
||||
};
|
||||
|
||||
class TestWritable implements smartcli.ISmartcliWritable {
|
||||
public chunks: string[] = [];
|
||||
public isTTY: boolean;
|
||||
@@ -109,6 +113,29 @@ tap.test('should collapse failed terminal tasks into permanent output', async ()
|
||||
expect(terminal.getTasks()).toHaveLength(0);
|
||||
});
|
||||
|
||||
tap.test('should prefix every non-interactive multiline message with the task name', async () => {
|
||||
const stream = new TestWritable(false);
|
||||
const terminal = new smartcli.SmartcliTerminal({
|
||||
stream,
|
||||
interactive: false,
|
||||
colors: false,
|
||||
nonInteractiveThrottleMs: 0,
|
||||
});
|
||||
const updateTask = terminal.task('multiline update');
|
||||
|
||||
updateTask.update('line one\nline two');
|
||||
updateTask.complete('done');
|
||||
|
||||
const failedTask = terminal.task('multiline failure');
|
||||
failedTask.fail('first failure line\nsecond failure line');
|
||||
|
||||
const output = stream.toString();
|
||||
expect(output).toInclude('update multiline update: line one');
|
||||
expect(output).toInclude('update multiline update: line two');
|
||||
expect(output).toInclude('fail multiline failure in');
|
||||
expect(output).toInclude('fail multiline failure: second failure line');
|
||||
});
|
||||
|
||||
tap.test('should set task progress', async () => {
|
||||
const stream = new TestWritable(true);
|
||||
const terminal = new smartcli.SmartcliTerminal({
|
||||
@@ -127,6 +154,49 @@ tap.test('should set task progress', async () => {
|
||||
terminal.clear();
|
||||
});
|
||||
|
||||
tap.test('should render an optional second-precision timer', async () => {
|
||||
const stream = new TestWritable(true);
|
||||
const terminal = new smartcli.SmartcliTerminal({
|
||||
stream,
|
||||
interactive: true,
|
||||
colors: false,
|
||||
symbols: 'ascii',
|
||||
cleanup: false,
|
||||
});
|
||||
const task = terminal.task('timed task', { rows: 2, showTimer: true });
|
||||
|
||||
expect(task.getTimerText()).toEqual('0s');
|
||||
expect(task.renderPlainRows(80)[0]).toInclude('0s');
|
||||
task.complete('timed complete');
|
||||
|
||||
expect(stream.toString()).toInclude('timed complete');
|
||||
});
|
||||
|
||||
tap.test('should render an optional spinner', async () => {
|
||||
const stream = new TestWritable(true);
|
||||
const terminal = new smartcli.SmartcliTerminal({
|
||||
stream,
|
||||
interactive: true,
|
||||
colors: false,
|
||||
symbols: 'ascii',
|
||||
cleanup: false,
|
||||
});
|
||||
const task = terminal.task('spinner task', {
|
||||
rows: 2,
|
||||
showSpinner: true,
|
||||
spinnerFrames: ['a', 'b'],
|
||||
spinnerIntervalMs: 20,
|
||||
});
|
||||
|
||||
await delay(90);
|
||||
|
||||
const output = stream.toString();
|
||||
expect(output).toInclude('spinner task');
|
||||
expect(output.includes('a spinner task') || output.includes('b spinner task')).toBeTrue();
|
||||
expect(task.getLiveRenderIntervalMs()).toEqual(20);
|
||||
task.complete('spinner complete');
|
||||
});
|
||||
|
||||
tap.test('should auto-complete task.run', async () => {
|
||||
const stream = new TestWritable(false);
|
||||
const terminal = new smartcli.SmartcliTerminal({
|
||||
|
||||
Reference in New Issue
Block a user