package main import ( "testing" "hamlog/internal/award" ) // relabelOnly decides whether a save can take the cheap path. A wrong "yes" // leaves stale references in the log, so every case that is not purely a // display change must fall through to the full recompute. func TestRelabelOnly(t *testing.T) { base := []award.Def{ {Code: "DDFM", Field: "note", RefDisplay: "ref", Valid: true}, {Code: "IOTA", Field: "iota", RefDisplay: "", Valid: true}, } cp := func() []award.Def { out := make([]award.Def, len(base)); copy(out, base); return out } // The case this exists for: one award's column switches to the description. next := cp() next[0].RefDisplay = "name" codes, ok := relabelOnly(base, next) if !ok || len(codes) != 1 || codes[0] != "DDFM" { t.Errorf("display-only change = (%v, %v), want ([DDFM], true)", codes, ok) } // Two at once is still a relabel. next = cp() next[0].RefDisplay = "both" next[1].RefDisplay = "name" if codes, ok := relabelOnly(base, next); !ok || len(codes) != 2 { t.Errorf("two display changes = (%v, %v), want two codes", codes, ok) } // Nothing changed: no relabel to do, and no full recompute claimed either. if codes, ok := relabelOnly(base, cp()); ok || codes != nil { t.Errorf("identical definitions must not report a relabel, got (%v, %v)", codes, ok) } // Anything that can change WHICH QSOs match must fail the test. for name, mutate := range map[string]func([]award.Def){ "field": func(d []award.Def) { d[0].Field = "comment" }, "pattern": func(d []award.Def) { d[0].Pattern = `\d{2}` }, "exact": func(d []award.Def) { d[0].ExactMatch = true }, "validity": func(d []award.Def) { d[0].ValidFrom = "2020-01-01" }, "dxcc": func(d []award.Def) { d[0].DXCCFilter = []int{227} }, "disabled": func(d []award.Def) { d[0].Valid = false }, "or rule": func(d []award.Def) { d[0].OrRules = []award.OrRule{{Field: "qth"}} }, "with disp": func(d []award.Def) { d[0].RefDisplay = "name"; d[0].Field = "comment" }, } { n := cp() mutate(n) if _, ok := relabelOnly(base, n); ok { t.Errorf("%s: took the relabel path — stale references would stay in the log", name) } } // An award added or removed changes the set, never a relabel. if _, ok := relabelOnly(base, append(cp(), award.Def{Code: "WWFF"})); ok { t.Errorf("an added award must force a full recompute") } if _, ok := relabelOnly(base, cp()[:1]); ok { t.Errorf("a removed award must force a full recompute") } }