//@ts-nocheck import { test, expect, suite, it, vitest, vi } from 'vitest'; import { prefixMultiline, splitFirstLine, stripLastEol } from './fxsLoggerUtils'; import ConsoleTransformer, { FORCED_EOL } from './ConsoleTransformer'; import ConsoleLineEnum from './ConsoleLineEnum'; //MARK: splitFirstLine suite('splitFirstLine', () => { it('normal single full line', () => { const result = splitFirstLine('Hello\n'); expect(result).toEqual({ first: 'Hello\n', rest: undefined, eol: true }); }); it('should split a string with a newline into two parts', () => { const result = splitFirstLine('Hello\nWorld'); expect(result).toEqual({ first: 'Hello\n', rest: 'World', eol: false }); }); it('should return the whole string as the first part if there is no newline', () => { const result = splitFirstLine('HelloWorld'); expect(result).toEqual({ first: 'HelloWorld', rest: undefined, eol: false }); }); it('should handle an empty string', () => { const result = splitFirstLine(''); expect(result).toEqual({ first: '', rest: undefined, eol: false }); }); it('should handle multiple newlines correctly', () => { const result = splitFirstLine('Hello\nWorld\nAgain'); expect(result).toEqual({ first: 'Hello\n', rest: 'World\nAgain', eol: false }); }); }); //MARK: stripLastEol suite('stripLastEol', () => { it('should strip \\r\\n from the end of the string', () => { const result = stripLastEol('Hello World\r\n'); expect(result).toEqual({ str: 'Hello World', eol: '\r\n' }); }); it('should strip \\n from the end of the string', () => { const result = stripLastEol('Hello World\n'); expect(result).toEqual({ str: 'Hello World', eol: '\n' }); }); it('should return the same string if there is no EOL character', () => { const result = stripLastEol('Hello World'); expect(result).toEqual({ str: 'Hello World', eol: '' }); }); it('should return the same string if it ends with other characters', () => { const result = stripLastEol('Hello World!'); expect(result).toEqual({ str: 'Hello World!', eol: '' }); }); }); //MARK: prefixMultiline suite('prefixMultiline', () => { it('should prefix every line in a multi-line string', () => { const result = prefixMultiline('Hello\nWorld\nAgain', '!!'); expect(result).toBe('!!Hello\n!!World\n!!Again'); }); it('should prefix a single-line string', () => { const result = prefixMultiline('HelloWorld', '!!'); expect(result).toBe('!!HelloWorld'); }); it('should handle an empty string', () => { const result = prefixMultiline('', '!!'); expect(result).toBe(''); }); it('should handle a string with a newline at the end', () => { const result = prefixMultiline('Hello\n', '!!'); expect(result).toBe('!!Hello\n'); }); it('should handle a string with multiple newlines at the end', () => { const result = prefixMultiline('Hello\nWorld\n\n', '!!'); expect(result).toBe('!!Hello\n!!World\n!!\n'); }); it('should handle a string with newlines only', () => { const result = prefixMultiline('\n\n\n', '!!'); expect(result).toBe('!!\n!!\n!!\n'); }); it('should handle a string with two full lines', () => { const result = prefixMultiline('test\nabcde\n', '!!'); expect(result).toBe('!!test\n!!abcde\n'); }); }); //MARK: Transformer parts suite('transformer: prefixChunk', () => { const transformer = new ConsoleTransformer(); test('shortcut stdout string', () => { const result = transformer.prefixChunk(ConsoleLineEnum.StdOut, 'xxxx\nxxx\n'); expect(result.fileBuffer).toEqual('xxxx\nxxx\n'); }); test('empty string', () => { const result = transformer.prefixChunk(ConsoleLineEnum.StdOut, ''); expect(result.fileBuffer).toEqual(''); }); }); suite('transformer: marker', () => { test('0ms delay', () => { const transformer = new ConsoleTransformer(); vi.spyOn(Date, 'now').mockReturnValue(0); const res = transformer.getTimeMarker(); expect(res).toBe(''); expect(transformer.lastMarkerTs).toEqual(0); vi.restoreAllMocks(); }); test('250ms delay', () => { const transformer = new ConsoleTransformer(); vi.spyOn(Date, 'now').mockReturnValue(250); const res = transformer.getTimeMarker(); expect(res).toBe(''); expect(transformer.lastMarkerTs).toEqual(0); vi.restoreAllMocks(); }); test('1250ms delay', () => { const transformer = new ConsoleTransformer(); vi.spyOn(Date, 'now').mockReturnValue(1250); const res = transformer.getTimeMarker(); expect(res).toBeTruthy(); expect(transformer.lastMarkerTs).toEqual(1); vi.restoreAllMocks(); }); test('2250ms delay', () => { const transformer = new ConsoleTransformer(); vi.spyOn(Date, 'now').mockReturnValue(2250); const res = transformer.getTimeMarker(); expect(res).toBeTruthy(); expect(transformer.lastMarkerTs).toEqual(2); vi.restoreAllMocks(); }); }); //MARK: Transformer ingest const jp = (arr: string[]) => arr.join(''); const getPatchedTransformer = () => { const t = new ConsoleTransformer(); t.STYLES = { [ConsoleLineEnum.StdOut]: null, [ConsoleLineEnum.StdErr]: { web: {} }, [ConsoleLineEnum.MarkerAdminCmd]: { web: {} }, [ConsoleLineEnum.MarkerSystemCmd]: { web: {} }, [ConsoleLineEnum.MarkerInfo]: { web: {} }, }; t.PREFIX_SYSTEM = '-'; t.PREFIX_STDERR = '-'; return t; } suite('transformer: source', () => { suite('incomplete', () => { test('StdOut', () => { const transformer = getPatchedTransformer(); transformer.lastEol = false; transformer.process(ConsoleLineEnum.StdOut, 'x'); expect(transformer.lastSrc).toEqual('0:undefined'); }); test('StdErr', () => { const transformer = getPatchedTransformer(); transformer.lastEol = false; transformer.process(ConsoleLineEnum.StdErr, 'x'); expect(transformer.lastSrc).toEqual('1:undefined'); }); }); suite('no context', () => { test('StdOut', () => { const transformer = getPatchedTransformer(); transformer.process(ConsoleLineEnum.StdOut, 'x'); expect(transformer.lastSrc).toEqual('0:undefined'); }); test('StdErr', () => { const transformer = getPatchedTransformer(); transformer.process(ConsoleLineEnum.StdErr, 'x'); expect(transformer.lastSrc).toEqual('1:undefined'); }); }); suite('context', () => { test('StdOut', () => { const transformer = getPatchedTransformer(); transformer.process(ConsoleLineEnum.StdOut, 'x', 'y'); expect(transformer.lastSrc).toEqual('0:y'); }); test('StdErr', () => { const transformer = getPatchedTransformer(); transformer.process(ConsoleLineEnum.StdErr, 'x', 'y'); expect(transformer.lastSrc).toEqual('1:y'); }); }); }); suite('transformer: shortcuts', () => { test('empty string', () => { const transformer = getPatchedTransformer(); const result = transformer.process(ConsoleLineEnum.StdOut, ''); expect(result.webBuffer).toEqual(''); }); test('\\n', () => { const transformer = getPatchedTransformer(); const result = transformer.process(ConsoleLineEnum.StdErr, '\n'); expect(result.webBuffer).toEqual('\n'); }); test('\\r\\n', () => { const transformer = getPatchedTransformer(); const result = transformer.process(ConsoleLineEnum.StdErr, '\r\n'); expect(result.webBuffer).toEqual('\n'); }); }); suite('transformer: new line', () => { const expectedTimeMarker = `{§${Math.floor(Date.now() / 1000).toString(16)}}`; test('single line same src', () => { const transformer = getPatchedTransformer(); const result = transformer.process(ConsoleLineEnum.StdOut, 'test'); expect(result.webBuffer).toEqual(jp([expectedTimeMarker, 'test'])); expect(transformer.lastEol).toEqual(false); }); test('single line diff src', () => { const transformer = getPatchedTransformer(); const result = transformer.process(ConsoleLineEnum.StdErr, 'test'); expect(result.webBuffer).toEqual(jp([expectedTimeMarker, '- ', 'test'])); expect(transformer.lastEol).toEqual(false); }); test('multi line same src', () => { const transformer = getPatchedTransformer(); const result = transformer.process(ConsoleLineEnum.StdOut, 'test\ntest2'); expect(result.webBuffer).toEqual(jp([expectedTimeMarker, 'test\ntest2'])); expect(transformer.lastEol).toEqual(false); }); test('multi line diff src', () => { const transformer = getPatchedTransformer(); const result = transformer.process(ConsoleLineEnum.StdErr, 'test\ntest2'); expect(result.webBuffer).toEqual(jp([expectedTimeMarker, '- ', 'test\n', '- ', 'test2'])); expect(transformer.lastEol).toEqual(false); }); }); suite('transformer: postfix', () => { const expectedTimeMarker = `{§${Math.floor(Date.now() / 1000).toString(16)}}`; test('same source incomplete line', () => { const transformer = getPatchedTransformer(); transformer.lastEol = false; const result = transformer.process(ConsoleLineEnum.StdOut, 'test'); expect(result.webBuffer).toEqual(jp(['test'])); expect(transformer.lastEol).toEqual(false); }); test('same source complete line', () => { const transformer = getPatchedTransformer(); transformer.lastEol = false; const result = transformer.process(ConsoleLineEnum.StdOut, 'test\n'); expect(result.webBuffer).toEqual(jp(['test\n'])); expect(transformer.lastEol).toEqual(true); }); test('same source multi line', () => { const transformer = getPatchedTransformer(); transformer.lastEol = false; const result = transformer.process(ConsoleLineEnum.StdOut, 'test\nxx\n'); // console.dir(result); return; expect(result.webBuffer).toEqual(jp(['test\n', expectedTimeMarker, 'xx\n'])); expect(transformer.lastEol).toEqual(true); }); test('diff source incomplete line', () => { const transformer = getPatchedTransformer(); transformer.lastEol = false; const result = transformer.process(ConsoleLineEnum.StdErr, 'test'); expect(result.webBuffer).toEqual(jp([FORCED_EOL, expectedTimeMarker, '- ', 'test'])); expect(transformer.lastEol).toEqual(false); }); test('diff source complete line', () => { const transformer = getPatchedTransformer(); transformer.lastEol = false; const result = transformer.process(ConsoleLineEnum.StdErr, 'test\n'); expect(result.webBuffer).toEqual(jp([FORCED_EOL, expectedTimeMarker, '- ', 'test\n'])); expect(transformer.lastEol).toEqual(true); }); test('diff source multi line', () => { const transformer = getPatchedTransformer(); transformer.lastEol = false; const result = transformer.process(ConsoleLineEnum.StdErr, 'test\nabcde\n'); expect(result.webBuffer).toEqual(jp([FORCED_EOL, expectedTimeMarker, '- ', 'test\n', '- ', 'abcde\n'])); expect(transformer.lastEol).toEqual(true); }); });