package escape_test
import (
stdjson "encoding/json"
"strings"
"testing"
"mercemay.top/src/lambdalog/internal/encoder/json/escape"
"mercemay.top/src/lambdalog/internal/encoder/json/fast"
)
func TestString_NoEscapeNeeded(t *testing.T) {
b := fast.Get()
t.Cleanup(func() { fast.Put(b) })
escape.String(b, "hello world", false)
if got := string(b.Bytes()); got != "hello world" {
t.Fatalf("got %q", got)
}
}
func TestString_Escapes(t *testing.T) {
cases := []struct {
name string
in string
want string
}{
{"quote", `he "said"`, `he \"said\"`},
{"backslash", `a\b`, `a\\b`},
{"newline", "a\nb", `a\nb`},
{"control", string([]byte{0x01}), ``},
{"html-sensitive-off", "<a>&b", "<a>&b"},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Helper()
b := fast.Get()
t.Cleanup(func() { fast.Put(b) })
escape.String(b, tc.in, false)
if got := string(b.Bytes()); got != tc.want {
t.Fatalf("got %q, want %q", got, tc.want)
}
})
}
}
func TestString_HTMLMode(t *testing.T) {
b := fast.Get()
t.Cleanup(func() { fast.Put(b) })
escape.String(b, "<a>&b", true)
got := string(b.Bytes())
for _, want := range []string{`<`, `>`, `&`} {
if !strings.Contains(got, want) {
t.Fatalf("html mode missing %s: %q", want, got)
}
}
}
func TestString_LineSeparatorEscaped(t *testing.T) {
b := fast.Get()
t.Cleanup(func() { fast.Put(b) })
escape.String(b, "x
y", false)
if !strings.Contains(string(b.Bytes()), `
`) {
t.Fatalf("U+2028 not escaped: %q", b.Bytes())
}
}
func TestString_IsValidJSON(t *testing.T) {
b := fast.Get()
t.Cleanup(func() { fast.Put(b) })
b.AppendByte('"')
escape.String(b, "control\x00tab\there\n", false)
b.AppendByte('"')
var out string
if err := stdjson.Unmarshal(b.Bytes(), &out); err != nil {
t.Fatalf("not valid JSON: %v: %q", err, b.Bytes())
}
if !strings.Contains(out, "control") {
t.Fatalf("round trip lost content: %q", out)
}
}
func TestBytes_SameAsString(t *testing.T) {
a := fast.Get()
t.Cleanup(func() { fast.Put(a) })
bs := fast.Get()
t.Cleanup(func() { fast.Put(bs) })
escape.String(a, "plain \"text\"", false)
escape.Bytes(bs, []byte("plain \"text\""), false)
if string(a.Bytes()) != string(bs.Bytes()) {
t.Fatalf("mismatch: %q vs %q", a.Bytes(), bs.Bytes())
}
}