Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions packages/core/test/prompts/text.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import color from 'picocolors';
import { cursor } from 'sisteransi';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import { default as TextPrompt } from '../../src/prompts/text.js';
import { MockReadable } from '../mock-readable.js';
import { MockWritable } from '../mock-writable.js';

describe('TextPrompt', () => {
let input: MockReadable;
let output: MockWritable;

beforeEach(() => {
input = new MockReadable();
output = new MockWritable();
});

afterEach(() => {
vi.restoreAllMocks();
});

test('renders render() result', () => {
const instance = new TextPrompt({
input,
output,
render: () => 'foo',
});
// leave the promise hanging since we don't want to submit in this test
instance.prompt();
expect(output.buffer).to.deep.equal([cursor.hide, 'foo']);
});

test('sets default value on finalize if no value', async () => {
const instance = new TextPrompt({
input,
output,
render: () => 'foo',
defaultValue: 'bleep bloop',
});
const resultPromise = instance.prompt();
input.emit('keypress', '', { name: 'return' });
const result = await resultPromise;
expect(result).to.equal('bleep bloop');
});

test('keeps value on finalize', async () => {
const instance = new TextPrompt({
input,
output,
render: () => 'foo',
defaultValue: 'bleep bloop',
});
const resultPromise = instance.prompt();
input.emit('keypress', 'x', { name: 'x' });
input.emit('keypress', '', { name: 'return' });
const result = await resultPromise;
expect(result).to.equal('x');
});

describe('cursor', () => {
test('can get cursor', () => {
const instance = new TextPrompt({
input,
output,
render: () => 'foo',
});

expect(instance.cursor).to.equal(0);
});
});

describe('valueWithCursor', () => {
test('returns value on submit', () => {
const instance = new TextPrompt({
input,
output,
render: () => 'foo',
});
instance.prompt();
input.emit('keypress', 'x', { name: 'x' });
input.emit('keypress', '', { name: 'return' });
expect(instance.valueWithCursor).to.equal('x');
});

test('highlights cursor position', () => {
const instance = new TextPrompt({
input,
output,
render: () => 'foo',
});
instance.prompt();
const keys = 'foo';
for (let i = 0; i < keys.length; i++) {
input.emit('keypress', keys[i], { name: keys[i] });
}
input.emit('keypress', 'left', { name: 'left' });
expect(instance.valueWithCursor).to.equal(`fo${color.inverse('o')}`);
});

test('shows cursor at end if beyond value', () => {
const instance = new TextPrompt({
input,
output,
render: () => 'foo',
});
instance.prompt();
const keys = 'foo';
for (let i = 0; i < keys.length; i++) {
input.emit('keypress', keys[i], { name: keys[i] });
}
input.emit('keypress', 'right', { name: 'right' });
expect(instance.valueWithCursor).to.equal('foo█');
});
});
});