package dayzxml
import (
"strings"
"testing"
)
func TestDetectKind(t *testing.T) {
cases := []struct {
in string
want FileKind
}{
{``, KindTypes},
{``, KindEvents},
{``, KindSpawnableTypes},
{``, KindMessages},
{``, KindRandomPresets},
{``, KindEventSpawns},
}
for _, c := range cases {
got, err := DetectKind([]byte(c.in))
if err != nil {
t.Errorf("DetectKind(%q) err: %v", c.in, err)
continue
}
if got != c.want {
t.Errorf("DetectKind(%q) = %v, want %v", c.in, got, c.want)
}
}
if _, err := DetectKind([]byte(``)); err == nil {
t.Error("expected error for unknown root")
}
}
func TestMergeTypes_AddAndReplace(t *testing.T) {
base := []byte(`
52
31
`)
snippet := []byte(`
84
11
`)
res, err := Merge(KindTypes, base, snippet, false)
if err != nil {
t.Fatal(err)
}
if len(res.Plan.Added) != 1 || res.Plan.Added[0] != "NewItem" {
t.Errorf("Added = %v, want [NewItem]", res.Plan.Added)
}
if len(res.Plan.Replaced) != 1 || res.Plan.Replaced[0] != "AKM" {
t.Errorf("Replaced = %v, want [AKM]", res.Plan.Replaced)
}
out := string(res.Bytes)
if !strings.Contains(out, `name="NewItem"`) {
t.Error("merged output missing NewItem")
}
if !strings.Contains(out, `8`) {
t.Error("merged output missing updated AKM nominal value")
}
if !strings.Contains(out, `name="M4A1"`) {
t.Error("merged output dropped untouched M4A1 entry")
}
}
func TestMergeTypes_Unchanged(t *testing.T) {
xml := []byte(`
5
`)
res, err := Merge(KindTypes, xml, xml, true)
if err != nil {
t.Fatal(err)
}
if len(res.Plan.Unchanged) != 1 || res.Plan.Unchanged[0] != "AKM" {
t.Errorf("Unchanged = %v, want [AKM]", res.Plan.Unchanged)
}
if len(res.Plan.Replaced) != 0 {
t.Errorf("Replaced = %v, want []", res.Plan.Replaced)
}
}
func TestMergeEvents_AppendsChildren(t *testing.T) {
base := []byte(`
3
`)
snippet := []byte(`
5
`)
res, err := Merge(KindEvents, base, snippet, false)
if err != nil {
t.Fatal(err)
}
out := string(res.Bytes)
// nominal overridden
if !strings.Contains(out, `5`) {
t.Error("event scalar child not overridden")
}
// new child appended, existing child not duplicated
if strings.Count(out, `type="UAZ_Base"`) != 1 {
t.Errorf("existing child duplicated; output:\n%s", out)
}
if !strings.Contains(out, `type="UAZ_Mod1"`) {
t.Error("new child not appended")
}
if got := res.Plan.AppendedChildren["VehicleSpawn"]; len(got) != 1 || got[0] != "UAZ_Mod1" {
t.Errorf("AppendedChildren[VehicleSpawn] = %v, want [UAZ_Mod1]", got)
}
}
func TestMergeMessages_AppendOnly(t *testing.T) {
base := []byte(`
1Welcome
`)
snippet := []byte(`
2Restart in 10m
`)
res, err := Merge(KindMessages, base, snippet, false)
if err != nil {
t.Fatal(err)
}
if len(res.Plan.Added) != 1 {
t.Errorf("Added count = %d, want 1", len(res.Plan.Added))
}
if !strings.Contains(string(res.Bytes), "Restart in 10m") {
t.Error("appended message not present")
}
}
func TestStripBOM(t *testing.T) {
bom := []byte{0xEF, 0xBB, 0xBF}
raw := append(bom, []byte(``)...)
k, err := DetectKind(raw)
if err != nil {
t.Fatal(err)
}
if k != KindTypes {
t.Errorf("kind = %v, want %v", k, KindTypes)
}
}
func TestRootMismatch(t *testing.T) {
base := []byte(``)
snippet := []byte(``)
if _, err := Merge(KindTypes, base, snippet, true); err == nil {
t.Error("expected error when snippet root doesn't match")
}
}
func TestPreserveCRLF(t *testing.T) {
base := []byte("\r\n 5\r\n")
snippet := []byte(`1`)
res, err := Merge(KindTypes, base, snippet, false)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(res.Bytes), "\r\n") {
t.Error("output dropped CRLF line endings; base had CRLF")
}
}