import { expect } from '@jest/globals'; import { type Stdio, CaptureStdio, StdioMultiplexer, TargetedStdio } from '../../src/stdio'; describe('CaptureStdio', () => { it('captured streams are initialized to empty string', () => { let stdio = new CaptureStdio(); expect(stdio.captured_stdout).toBe(""); expect(stdio.captured_stderr).toBe(""); }); it('stdout() and stderr() captures', () => { let stdio = new CaptureStdio(); stdio.stdout_writeline("hello"); stdio.stdout_writeline("world"); stdio.stderr_writeline("this is an error"); expect(stdio.captured_stdout).toBe("hello\nworld\n"); expect(stdio.captured_stderr).toBe("this is an error\n"); }); it('reset() works', () => { let stdio = new CaptureStdio(); stdio.stdout_writeline("aaa"); stdio.stderr_writeline("bbb"); stdio.reset(); expect(stdio.captured_stdout).toBe(""); expect(stdio.captured_stderr).toBe(""); }); }); describe('StdioMultiplexer', () => { let a: CaptureStdio; let b: CaptureStdio; let multi: StdioMultiplexer; beforeEach(() => { a = new CaptureStdio(); b = new CaptureStdio(); multi = new StdioMultiplexer(); }); it('works without listeners', () => { // no listeners, messages are ignored multi.stdout_writeline('out 1'); multi.stderr_writeline('err 1'); expect(a.captured_stdout).toBe(""); expect(a.captured_stderr).toBe(""); expect(b.captured_stdout).toBe(""); expect(b.captured_stderr).toBe(""); }); it('redirects to multiple listeners', () => { multi.addListener(a); multi.stdout_writeline('out 1'); multi.stderr_writeline('err 1'); multi.addListener(b); multi.stdout_writeline('out 2'); multi.stderr_writeline('err 2'); expect(a.captured_stdout).toBe("out 1\nout 2\n"); expect(a.captured_stderr).toBe("err 1\nerr 2\n"); expect(b.captured_stdout).toBe("out 2\n"); expect(b.captured_stderr).toBe("err 2\n"); }); }); describe('TargetedStdio', () => { let capture: CaptureStdio; let targeted: TargetedStdio; let error_targeted: TargetedStdio; let multi: StdioMultiplexer; beforeEach(() => { //DOM element to capture stdout and stderr let target_div = document.getElementById("output-id"); if (target_div=== null){ target_div = document.createElement('div'); target_div.id = "output-id"; document.body.appendChild(target_div); } else { target_div.innerHTML = ""; } //DOM element to capture stderr let error_div = document.getElementById("error-id"); if (error_div=== null){ error_div = document.createElement('div'); error_div.id = "error-id"; document.body.appendChild(error_div); } else { error_div.innerHTML = ""; } const tag = document.createElement('div'); tag.setAttribute("output", "output-id"); tag.setAttribute("stderr", "error-id"); capture = new CaptureStdio(); targeted = new TargetedStdio(tag, 'output', true, true); error_targeted = new TargetedStdio(tag, 'stderr', false, true); multi = new StdioMultiplexer(); multi.addListener(capture); multi.addListener(targeted); multi.addListener(error_targeted); }); it('targeted id is set by constructor', () =>{ expect(targeted.source_attribute).toBe("output"); }); it('targeted stdio/stderr also goes to multiplexer', () =>{ multi.stdout_writeline("out 1"); multi.stderr_writeline("out 2"); expect(capture.captured_stdout).toBe("out 1\n"); expect(capture.captured_stderr).toBe("out 2\n"); expect(document.getElementById("output-id")?.innerHTML).toBe("out 1
out 2
"); expect(document.getElementById("error-id")?.innerHTML).toBe("out 2
"); }); it('Add and remove targeted listener', () => { multi.stdout_writeline("out 1"); multi.removeListener(targeted); multi.stdout_writeline("out 2"); multi.addListener(targeted); multi.stdout_writeline("out 3"); //all three should be captured by multiplexer expect(capture.captured_stdout).toBe("out 1\nout 2\nout 3\n"); //out 2 should not be present in the DOM element expect(document.getElementById("output-id")?.innerHTML).toBe("out 1
out 3
"); }); });