hugin/cli/internal/reconcile/json_test.go
2026-10-27 08:33:21 +01:00

83 lines
3.2 KiB
Go

package reconcile
import (
"encoding/json"
"testing"
)
func TestJsonSet(t *testing.T) {
munin := json.RawMessage(`{"type":"http","url":"https://m"}`)
tests := []struct {
name, before string
path []string
value json.RawMessage
expected string
}{
{"neue Datei", "", []string{"mcpServers", "munin"}, munin,
"{\n \"mcpServers\": {\n \"munin\": {\n \"type\": \"http\",\n \"url\": \"https://m\"\n }\n }\n}\n"},
{"Einrückung der Datei", "{\n \"a\": 1\n}\n", []string{"mcpServers", "munin"}, munin,
"{\n \"a\": 1,\n \"mcpServers\": {\n \"munin\": {\n \"type\": \"http\",\n \"url\": \"https://m\"\n }\n }\n}\n"},
{"Kommentare bleiben", "{\n // Modell\n \"model\": \"x\"\n}\n", []string{"mcp", "munin"}, json.RawMessage(`{"enabled":true}`),
"{\n // Modell\n \"model\": \"x\",\n \"mcp\": {\n \"munin\": {\n \"enabled\": true\n }\n }\n}\n"},
{"einzeilige Datei bleibt einzeilig", `{"a": 1}`, []string{"b"}, json.RawMessage(`{"c": 2}`),
`{"a": 1, "b": {"c":2}}` + "\n"},
{"vorhandenen Wert ersetzen", "{\n \"a\": 1,\n \"b\": 2\n}\n", []string{"a"}, json.RawMessage(`[1,2]`),
"{\n \"a\": [\n 1,\n 2\n ],\n \"b\": 2\n}\n"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
d, err := readJson([]byte(tt.before), tt.before == "")
if err != nil {
t.Fatal(err)
}
if err := d.set(tt.path, tt.value); err != nil {
t.Fatal(err)
}
if got := string(d.bytes()); got != tt.expected {
t.Errorf("\n got:\n%s\nwant:\n%s", got, tt.expected)
}
})
}
}
func TestJsonList(t *testing.T) {
entry := json.RawMessage(`".hugin/rules/*.md"`)
tests := []struct{ name, before, expected string }{
{"Liste fehlt", "{\n \"model\": \"x\"\n}\n",
"{\n \"model\": \"x\",\n \"instructions\": [\n \".hugin/rules/*.md\"\n ]\n}\n"},
{"einzeilige Liste", "{\n \"instructions\": [\"docs/a.md\"]\n}\n",
"{\n \"instructions\": [\"docs/a.md\", \".hugin/rules/*.md\"]\n}\n"},
{"mehrzeilige Liste", "{\n \"instructions\": [\n \"docs/a.md\"\n ]\n}\n",
"{\n \"instructions\": [\n \"docs/a.md\",\n \".hugin/rules/*.md\"\n ]\n}\n"},
{"schon vorhanden", "{\"instructions\": [\".hugin/rules/*.md\"]}\n",
"{\"instructions\": [\".hugin/rules/*.md\"]}\n"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
d, _ := readJson([]byte(tt.before), false)
if err := d.addToList([]string{"instructions"}, entry); err != nil {
t.Fatal(err)
}
if got := string(d.bytes()); got != tt.expected {
t.Errorf("\n got:\n%s\nwant:\n%s", got, tt.expected)
}
if err := d.removeFromList([]string{"instructions"}, entry); err != nil {
t.Fatal(err)
}
value, ok := d.read([]string{"instructions"})
if items, _ := value.([]any); ok && (len(items) == 0 || index(items, entry) >= 0) {
t.Errorf("Eintrag nicht entfernt oder leere Liste übrig: %v", value)
}
})
}
}
func TestJsonSpecialCharsInKey(t *testing.T) {
d, _ := readJson(nil, true)
if err := d.set([]string{"a/b", "c~d", "e.f"}, json.RawMessage(`1`)); err != nil {
t.Fatal(err)
}
if value, ok := d.read([]string{"a/b", "c~d", "e.f"}); !ok || value != float64(1) {
t.Errorf("lesen: %v %v\n%s", value, ok, d.bytes())
}
}