package qso import "testing" // baseCall picks the operator's OWN callsign out of a portable form. The slash // carries a qualifier on either side and which side depends on what it is, so // this is the whole difficulty. func TestBaseCall(t *testing.T) { for in, want := range map[string]string{ "RK3DWA": "RK3DWA", "RK3DWA/3": "RK3DWA", // call-area digit "RK3DWA/P": "RK3DWA", // portable "RK3DWA/QRP": "RK3DWA", "RK3DWA/MM": "RK3DWA", "ZA/OE8NDR": "OE8NDR", // an Austrian in Albania — the case that prompted this "ZA/IZ2DPX": "IZ2DPX", "F/DL1ABC": "DL1ABC", "F/DL1ABC/P": "DL1ABC", "KH6/K6ABC": "K6ABC", "VP2E/W1ABC": "W1ABC", "3DA0/ZS1ABC": "ZS1ABC", "9A/S51AB": "S51AB", "/RK3DWA": "RK3DWA", } { if got := baseCall(in); got != want { t.Errorf("baseCall(%q) = %q, want %q", in, got, want) } } } // The predicate behind "Worked before". Exact when folding is off; with it on, // a station's portable forms are one operator — and the fold has to work from // either end, because you may type the base call or the portable one. func TestCallMatch(t *testing.T) { if pred, args := callMatch("RK3DWA", false); pred != "callsign = ?" || len(args) != 1 || args[0] != "RK3DWA" { t.Errorf("exact: got %q %v", pred, args) } // Typing the base call: match it, everything suffixed off it, and every // prefixed form of it. _, args := callMatch("RK3DWA", true) want := []any{"RK3DWA", "RK3DWA/%", "%/RK3DWA", "%/RK3DWA/%"} assertArgs(t, "base call", args, want) // Typing a portable form must reach the plain call too — the qualifier is // stripped from the INPUT, not just matched in the column. _, args = callMatch("RK3DWA/3", true) assertArgs(t, "portable input", args, want) } // A prefixed call is the same operator, and NOT every other visitor to that // country. // // Matching on the part before the slash made ZA/OE8NDR the station "ZA", so the // worked-before list for one Austrian operating from Albania showed every other // ZA/ guest — two Italians — and counted them as four contacts "with this // call". Reported from a screenshot of exactly that. func TestCallMatchPrefixedIsTheOperatorNotTheCountry(t *testing.T) { _, args := callMatch("ZA/OE8NDR", true) assertArgs(t, "ZA/OE8NDR", args, []any{"OE8NDR", "OE8NDR/%", "%/OE8NDR", "%/OE8NDR/%"}) for _, a := range args { if s, _ := a.(string); s == "ZA" || s == "ZA/%" { t.Fatalf("the country prefix is still being matched as a station: %v", args) } } // And the two are not each other: nothing in one operator's predicate can // select the other's call. _, other := callMatch("ZA/IZ2DPX", true) assertArgs(t, "ZA/IZ2DPX", other, []any{"IZ2DPX", "IZ2DPX/%", "%/IZ2DPX", "%/IZ2DPX/%"}) } // A base too short to be a callsign falls back to an exact match. "F/DL1ABC" // resolves fine, but a malformed entry must never produce a LIKE that selects // half the logbook. func TestCallMatchRefusesAShortBase(t *testing.T) { for _, call := range []string{"F/", "9A", "/P", "K/M"} { pred, args := callMatch(call, true) if pred != "callsign = ?" || len(args) != 1 { t.Errorf("%q produced %q %v — want an exact match", call, pred, args) } } } func assertArgs(t *testing.T, what string, got, want []any) { t.Helper() if len(got) != len(want) { t.Fatalf("%s: args %v, want %v", what, got, want) } for i := range want { if got[i] != want[i] { t.Fatalf("%s: args %v, want %v", what, got, want) } } }