// Copyright (c) 2026 Lark Technologies Pte. Ltd.
// SPDX-License-Identifier: MIT
package output
import (
"bytes"
"strings"
"testing"
)
func TestJqFilterRaw_PreservesXMLInComplexValue(t *testing.T) {
data := map[string]interface{}{
"data": map[string]interface{}{
"document": map[string]interface{}{
"title": "
hello & welcome",
"content": "a < b & c > d
",
},
},
}
var raw bytes.Buffer
if err := JqFilterRaw(&raw, data, ".data.document"); err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Raw path must keep <, >, & as literal characters, not Go json-encoder's
// default < / > / & unicode escapes.
for _, unicodeEsc := range []string{"\\u003c", "\\u003e", "\\u0026"} {
if strings.Contains(raw.String(), unicodeEsc) {
t.Errorf("JqFilterRaw unexpectedly HTML-escaped %s: %s", unicodeEsc, raw.String())
}
}
if !strings.Contains(raw.String(), "") {
t.Errorf("JqFilterRaw dropped raw : %s", raw.String())
}
var escaped bytes.Buffer
if err := JqFilter(&escaped, data, ".data.document"); err != nil {
t.Fatalf("unexpected error: %v", err)
}
// JqFilter keeps Go's default HTML escaping for back-compat.
if !strings.Contains(escaped.String(), "\\u003c") {
t.Errorf("JqFilter should HTML-escape < for back-compat: %s", escaped.String())
}
}
func TestJqFilterRaw_ScalarMatchesJqFilter(t *testing.T) {
data := map[string]interface{}{"content": "hello"}
var raw, plain bytes.Buffer
if err := JqFilterRaw(&raw, data, ".content"); err != nil {
t.Fatalf("raw: %v", err)
}
if err := JqFilter(&plain, data, ".content"); err != nil {
t.Fatalf("plain: %v", err)
}
// Scalar string path is raw in both (matches jq -r), so output is identical.
if raw.String() != plain.String() {
t.Errorf("scalar output diverged: raw=%q plain=%q", raw.String(), plain.String())
}
if !strings.Contains(raw.String(), "") {
t.Errorf("scalar output dropped : %q", raw.String())
}
}