diff --git a/src/ansi.test.ts b/src/ansi.test.ts new file mode 100644 index 0000000..55eb5ba --- /dev/null +++ b/src/ansi.test.ts @@ -0,0 +1,426 @@ +import { expect, test } from "bun:test"; +import { ansiToHtml, trimLineEndPreserveAnsi } from "./ansi"; + +// 1. XSS/HTML escaping tests + +test("escapes < to <", () => { + const result = ansiToHtml("
"); + expect(result).toBe("<div>"); +}); + +test("escapes > to >", () => { + const result = ansiToHtml("a > b"); + expect(result).toBe("a > b"); +}); + +test("escapes & to &", () => { + const result = ansiToHtml("foo & bar"); + expect(result).toBe("foo & bar"); +}); + +test("escapes "); + expect(result).toBe("<script>alert('xss')</script>"); +}); + +test("escapes HTML in styled text", () => { + const result = ansiToHtml("\x1b[31m\x1b[0m"); + expect(result).toContain("<script>"); + expect(result).toContain("</script>"); + expect(result).not.toContain("\x1b[0m"); + expect(result).toContain("<script>"); + expect(result).toContain("&alert"); + expect(result).toContain("color:#f85149"); +}); + +test("preserves internal spaces", () => { + const result = ansiToHtml("hello world"); + expect(result).toBe("hello world"); +}); + +test("handles only ANSI codes with no text", () => { + const result = ansiToHtml("\x1b[31m\x1b[0m"); + // Opens and closes span even with no text + expect(result).toBe(''); +});