Skip to content

Commit

Permalink
Support unicode output from commands (#87)
Browse files Browse the repository at this point in the history
* Support unicode output from commands

* Update visual snapshot
  • Loading branch information
ianthomas23 authored Dec 12, 2024
1 parent fdd61f1 commit e7c7ec3
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ name as the package unless otherwise specified:
- `coreutils`: multiple core commands including `cat`, `cp`, `echo`, `ls`, `mkdir`, `mv`, `rm`, `touch`, `uname`, and `wc`
- `grep`
- `lua`
- `tree`
- `vim`

## Build
Expand Down
3 changes: 3 additions & 0 deletions demo/cockle-config-in.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
"package": "local-cmd",
"local_directory": "../test/local-packages"
},
{
"package": "tree"
},
{
"package": "vim"
}
Expand Down
3 changes: 0 additions & 3 deletions demo/ui-tests/demo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ test('visual test', async ({ page }) => {

await page.locator('div.xterm-screen').click(); // sets focus for keyboard input

await inputLine(page, 'ls'); // avoid timestamps
await page.waitForTimeout(wait);

await inputLine(page, 'cp file.txt file2.txt');
await page.waitForTimeout(wait);

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions src/buffered_io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ abstract class BufferedIO {
return this._enabled;
}

utf8ArrayToString(chars: Int8Array): string {
if (this._utf8Decoder === undefined) {
this._utf8Decoder = new TextDecoder('utf8');
}
return this._utf8Decoder.decode(chars);
}

protected _clear() {
this._readArray[READ_MAIN] = 0;
this._readArray[READ_WORKER] = 0;
Expand Down Expand Up @@ -92,6 +99,8 @@ abstract class BufferedIO {

protected _maxWriteChars: number = 256; // Multiples of this can be sent consecutively.
protected _writeArray: Int32Array;

private _utf8Decoder?: TextDecoder;
}

export namespace MainBufferedIO {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/wasm_command_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export abstract class WasmCommandRunner implements ICommandRunner {
}

const chars = buffer.slice(offset, offset + length);
const text = String.fromCharCode(...chars);
const text = bufferedIO.utf8ArrayToString(chars);
const isStderr = stream.path === '/dev/tty1';

if (isStderr && cmdName === 'touch' && args.length > 1) {
Expand Down
3 changes: 3 additions & 0 deletions test/cockle-config-in.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
{
"package": "lua"
},
{
"package": "tree"
},
{
"package": "vim"
},
Expand Down
24 changes: 24 additions & 0 deletions test/tests/command/tree.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { expect } from '@playwright/test';
import { shellLineSimple, test } from '../utils';

test.describe('tree command', () => {
test('should write version', async ({ page }) => {
const output = await shellLineSimple(page, 'tree --version');
expect(output).toMatch(
'\r\ntree v2.2.1 © 1996 - 2024 by Steve Baker, Thomas Moore, Francesc Rocher, Florian Sesser, Kyosuke Tokoro\r\n'
);
});

test('should write tree', async ({ page }) => {
const output = await shellLineSimple(page, 'tree');
expect(output).toMatch(
'tree\r\n' +
'.\r\n' +
'├── dirA\r\n' +
'├── file1\r\n' +
'└── file2\r\n' +
'\r\n' +
'2 directories, 2 files\r\n'
);
});
});
9 changes: 7 additions & 2 deletions test/tests/shell.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ test.describe('Shell', () => {
expect(output[14]).toMatch(/Error: cd: too many arguments/);
expect(output[15]).toMatch('\r\n?=1\r\n');
});

test('should support unicode', async ({ page }) => {
const output = await shellLineSimple(page, 'echo 🚀');
expect(output).toMatch(/^echo 🚀\r\n🚀\r\n/);
});
});

test.describe('echo input', () => {
Expand Down Expand Up @@ -207,8 +212,8 @@ test.describe('Shell', () => {
const ret1 = output.textAndClear();
return [ret0, ret1];
});
expect(output[0]).toMatch(/^t\r\ntail\r\ntouch\r\ntr\r\ntty\r\n/);
expect(output[1]).toMatch(/^\r\ntail {3}tr\r\ntouch {2}tty\r\n/);
expect(output[0]).toMatch(/^t\r\ntail\r\ntouch\r\ntr\r\ntree\r\ntty\r\n/);
expect(output[1]).toMatch(/^\r\ntail {3}tree\r\ntouch {2}tty\r\ntr\r\n/);
});

test('should add common startsWith', async ({ page }) => {
Expand Down

0 comments on commit e7c7ec3

Please sign in to comment.