feat(watchlist): exact match by default, * for a family

The prefix matching ported from DXHunter swallowed too much: a three-letter
special-event entry N8W lit up NEEDED for N8WCR, a different station entirely.
The implicit becomes explicit — a bare entry matches exactly that call, a
trailing star makes it a family: VK9* catches every VK9…, RI0SP* the
expedition's portable forms. A star anywhere else (or alone) is refused at Add
rather than silently matching nothing. Same rule in the backend Match and the
tab's own matcher, pinned by test.
This commit is contained in:
2026-08-29 01:25:34 +02:00
parent 72253f99fa
commit c9e98d5fdd
5 changed files with 60 additions and 19 deletions
+21 -7
View File
@@ -7,22 +7,36 @@ import (
"testing"
)
func TestPrefixMatch(t *testing.T) {
func TestGlobMatch(t *testing.T) {
s := New(filepath.Join(t.TempDir(), "watchlist.json"))
if err := s.Add("RI0SP", false); err != nil {
if err := s.Add("RI0SP*", false); err != nil {
t.Fatal(err)
}
// The reason prefix matching exists: expeditions sign portable.
if err := s.Add("N8W", false); err != nil {
t.Fatal(err)
}
// A starred entry is a family: the expedition's portable forms.
for _, call := range []string{"RI0SP", "RI0SP/MM", "RI0SP/P"} {
if _, ok := s.Match(call); !ok {
t.Errorf("Match(%q) = false, want true", call)
}
}
if _, ok := s.Match("RI0S"); ok {
t.Error("a SHORTER call must not match the entry")
// A bare entry is THAT call — the reported bug was N8W lighting up for
// N8WCR, a different station entirely.
if _, ok := s.Match("N8W"); !ok {
t.Error("exact entry must match its own call")
}
if _, ok := s.Match("F4BPO"); ok {
t.Error("an unrelated call matched")
if _, ok := s.Match("N8WCR"); ok {
t.Error("exact entry must NOT match a longer call")
}
if _, ok := s.Match("RI0S"); ok {
t.Error("a SHORTER call must not match a starred entry")
}
if err := s.Add("VK*9", false); err == nil {
t.Error("a mid-string star must be refused")
}
if err := s.Add("*", false); err == nil {
t.Error("a bare star must be refused")
}
}