Files
OpsLog/internal/award/modeclass_test.go
T
rouggy 3e22c4d1a3 feat: filter award references by mode class
All / CW / Phone / Digital, stacked on top of the worked/confirmed filter. The
question an operator actually has — which DXCC entities have I worked on CW but
not confirmed on CW — needs both at once; answering only one of them is what
sends people to a spreadsheet.

References carried bands but not modes, so the award computation now aggregates
mode CLASSES per reference, worked and confirmed separately. Classes, not ADIF
modes: nobody chasing CW cares whether the digital side was FT8 or RTTY, and a
list of twenty mode names would not answer the question. An unrecognised mode
counts as data rather than as nothing, so a new digital mode does not vanish
from the filter the day it appears.

Two rules the filter needs to be honest:

  - Not-confirmed means not confirmed ON THIS MODE. An entity worked on CW and
    confirmed on SSB is still a CW entity to chase, and that is exactly what the
    filter is for.
  - "Not worked" plus a mode is a contradiction — an unworked reference has no
    mode — so the mode filter stands aside there instead of emptying the list.
2026-07-31 16:09:11 +02:00

29 lines
1.1 KiB
Go

package award
import "testing"
// The three classes an operator thinks in — the ones the awards filter offers.
//
// "Which entities have I worked on CW but not confirmed" is the question this
// serves, so the classes must match how the question is asked: CW, phone, data.
// Which data mode it was does not enter into it.
func TestModeClass(t *testing.T) {
for _, c := range []struct{ mode, want string }{
{"CW", "CW"}, {"cw", "CW"}, {" CW ", "CW"}, {"CWR", "CW"},
{"SSB", "PHONE"}, {"USB", "PHONE"}, {"LSB", "PHONE"},
{"AM", "PHONE"}, {"FM", "PHONE"}, {"DV", "PHONE"},
{"FT8", "DIGI"}, {"FT4", "DIGI"}, {"RTTY", "DIGI"}, {"PSK31", "DIGI"},
{"JS8", "DIGI"}, {"Q65", "DIGI"}, {"OLIVIA", "DIGI"},
// A mode nobody has heard of yet is data, not nothing: the alternative
// is a new digital mode silently vanishing from the filter the day it
// appears.
{"SOMETHINGNEW", "DIGI"},
// No mode at all is not a class, and must not be counted as one.
{"", ""}, {" ", ""},
} {
if got := ModeClass(c.mode); got != c.want {
t.Errorf("ModeClass(%q) = %q, want %q", c.mode, got, c.want)
}
}
}