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") } }