scroll/src/common/all_test.ts

178 lines
4.8 KiB
JavaScript

import { getTestRunner } from './runtime.ts';
import { Ansi, KeyCommand, readKey } from './ansi.ts';
import { Document, Row } from './document.ts';
import Buffer from './buffer.ts';
import {
chars,
ctrl_key,
is_ascii,
is_control,
noop,
ord,
strlen,
truncate,
} from './utils.ts';
import { Editor } from './editor.ts';
import { defaultTerminalSize } from './termios.ts';
const t = await getTestRunner();
const testObj = {
'ANSI::ANSI utils': {
'Ansi.moveCursor': () => {
t.assertEquals(Ansi.moveCursor(1, 2), '\x1b[2;3H');
},
'Ansi.moveCursorForward': () => {
t.assertEquals(Ansi.moveCursorForward(2), '\x1b[2C');
},
'Ansi.moveCursorDown': () => {
t.assertEquals(Ansi.moveCursorDown(7), '\x1b[7B');
},
},
'ANSI::readKey()': {
'readKey passthrough': () => {
// Ignore unhandled escape sequences
t.assertEquals(readKey('\x1b[]'), '\x1b[]');
// Pass explicitly mapped values right through
t.assertEquals(readKey(KeyCommand.ArrowUp), KeyCommand.ArrowUp);
t.assertEquals(readKey(KeyCommand.Home), KeyCommand.Home);
t.assertEquals(readKey(KeyCommand.Delete), KeyCommand.Delete);
},
'readKey Home': () => {
['\x1b[1~', '\x1b[7~', '\x1b[H', '\x1bOH'].forEach((code) => {
t.assertEquals(readKey(code), KeyCommand.Home);
});
},
'readKey End': () => {
['\x1b[4~', '\x1b[8~', '\x1b[F', '\x1bOF'].forEach((code) => {
t.assertEquals(readKey(code), KeyCommand.End);
});
},
},
Buffer: {
'Buffer exists': () => {
const b = new Buffer();
t.assertInstanceOf(b, Buffer);
t.assertEquals(b.strlen(), 0);
},
'Buffer.appendLine': () => {
const b = new Buffer();
// Carriage return and line feed
b.appendLine();
t.assertEquals(b.strlen(), 2);
b.clear();
t.assertEquals(b.strlen(), 0);
b.appendLine('foo');
t.assertEquals(b.strlen(), 5);
},
'Buffer.append': () => {
const b = new Buffer();
b.append('foobar');
t.assertEquals(b.strlen(), 6);
b.clear();
b.append('foobar', 3);
t.assertEquals(b.strlen(), 3);
},
'Buffer.flush': async () => {
const b = new Buffer();
b.appendLine('foobarbaz' + Ansi.ClearLine);
t.assertEquals(b.strlen(), 14);
await b.flush();
t.assertEquals(b.strlen(), 0);
},
},
Document: {
'Document.empty': () => {
const doc = Document.empty();
t.assertEquals(doc.numRows, 0);
t.assertTrue(doc.isEmpty());
t.assertEquals(doc.row(0), null);
},
'Document.appendRow': () => {
const doc = Document.empty();
doc.appendRow('foobar');
t.assertEquals(doc.numRows, 1);
t.assertFalse(doc.isEmpty());
t.assertInstanceOf(doc.row(0), Row);
},
},
'Document::Row': {
'new Row': () => {
const row = new Row();
t.assertEquals(row.toString(), '');
},
},
Editor: {
'new Editor': () => {
const e = new Editor(defaultTerminalSize);
t.assertInstanceOf(e, Editor);
},
},
'Util::Misc fns': {
'noop fn': () => {
t.assertExists(noop);
t.assertEquals(noop(), undefined);
},
},
'Util::String fns': {
'ord() returns 256 on invalid string': () => {
t.assertEquals(ord(''), 256);
},
'ord() returns number on valid string': () => {
t.assertEquals(ord('a'), 97);
},
'chars() properly splits strings into unicode characters': () => {
t.assertEquals(chars('😺😸😹'), ['😺', '😸', '😹']);
},
'ctrl_key() returns expected values': () => {
const ctrl_a = ctrl_key('a');
t.assertTrue(is_control(ctrl_a));
t.assertEquals(ctrl_a, String.fromCodePoint(0x01));
const invalid = ctrl_key('😺');
t.assertFalse(is_control(invalid));
t.assertEquals(invalid, '😺');
},
'is_ascii() properly discerns ascii chars': () => {
t.assertTrue(is_ascii('asjyverkjhsdf1928374'));
t.assertFalse(is_ascii('😺acalskjsdf'));
t.assertFalse(is_ascii('ab😺ac'));
},
'is_control() works as expected': () => {
t.assertFalse(is_control('abc'));
t.assertTrue(is_control(String.fromCodePoint(0x01)));
t.assertFalse(is_control('😺'));
},
'strlen() returns expected length for ascii strings': () => {
t.assertEquals(strlen('abc'), 'abc'.length);
},
'strlen() returns expected length for multibyte characters': () => {
t.assertEquals(strlen('😺😸😹'), 3);
t.assertNotEquals('😺😸😹'.length, strlen('😺😸😹'));
// Skin tone modifier + base character
t.assertEquals(strlen('🤰🏼'), 2);
t.assertNotEquals('🤰🏼'.length, strlen('🤰🏼'));
// This has 4 sub-characters, and 3 zero-width-joiners
t.assertEquals(strlen('👨‍👩‍👧‍👦'), 7);
t.assertNotEquals('👨‍👩‍👧‍👦'.length, strlen('👨‍👩‍👧‍👦'));
},
'truncate() shortens strings': () => {
t.assertEquals(truncate('😺😸😹', 1), '😺');
t.assertEquals(truncate('😺😸😹', 5), '😺😸😹');
t.assertEquals(truncate('👨‍👩‍👧‍👦', 5), '👨‍👩‍👧');
},
},
};
t.testSuite(testObj);