package alerts import "testing" // The spot that started it: RI1FJL on 10131.5, an FT8 station in the 30 m data // segment. The cluster list showed DATA and the alert announced SSB, because // this side's table stopped its CW range at 10.130 and called everything above // it phone. func TestInferModeDoesNotCallThirtyMetresSSB(t *testing.T) { if got := InferMode("", 10_131_500); got != "DATA" { t.Errorf("10131.5 kHz → %q, want DATA (there is no SSB on 30 m)", got) } // And the CW half of the same band still reads as CW. if got := InferMode("", 10_110_000); got != "CW" { t.Errorf("10110 kHz → %q, want CW", got) } } // The comment beats the band plan. A spotter who names the mode knows something // no table does — an FT8 station calling outside the usual watering hole, a CW // operation in a data segment during a contest. func TestInferModeTrustsTheCommentFirst(t *testing.T) { cases := map[string]struct { comment string freqHz int64 want string }{ "FT8 said outright": {"-14 dB FT8", 14_200_000, "FT8"}, "CW in a data segment": {"CW 599", 14_080_000, "CW"}, "RBN reports WPM not CW": {"18 dB 25 WPM CQ", 14_080_000, "CW"}, "phone below the split": {"SSB net", 7_010_000, "SSB"}, } for name, c := range cases { t.Run(name, func(t *testing.T) { if got := InferMode(c.comment, c.freqHz); got != c.want { t.Errorf("InferMode(%q, %d) = %q, want %q", c.comment, c.freqHz, got, c.want) } }) } } // The watering holes are listed before the wide data blocks they sit inside, and // the table is scanned in order — so sorting it by frequency would quietly turn // every FT8 hole into "DATA". This is what would fail if somebody did. func TestBandPlanKeepsTheWateringHolesAheadOfTheDataBlocks(t *testing.T) { holes := map[int64]string{ 3_573_500: "FT8", 7_074_500: "FT8", 7_048_000: "FT4", 14_074_500: "FT8", 14_080_500: "FT4", 21_074_500: "FT8", 28_074_500: "FT8", 50_313_500: "FT8", } for hz, want := range holes { if got := modeFromFrequency(hz); got != want { t.Errorf("%d Hz → %q, want %q", hz, got, want) } } } // Nothing is claimed for a frequency the plan does not cover. Answering "SSB" // for whatever fell through is the exact fault this file exists to fix. func TestModeFromFrequencyIsSilentWhenItDoesNotKnow(t *testing.T) { for _, hz := range []int64{500_000, 6_000_000, 70_200_000, 432_100_000} { if got := modeFromFrequency(hz); got != "" { t.Errorf("%d Hz → %q, want \"\" (outside the plan)", hz, got) } } }