Files
OpsLog/internal/dxcc/dxcc_test.go
T
rouggy 7ace2cc602 Initial codebase: Go + Wails amateur radio logbook
Backend (Go 1.25 / Wails v2):
- QSO storage on SQLite (modernc) with embedded migrations (0001..0005)
- Streaming ADIF import (batch insert) + WorkedBefore per callsign and DXCC
- Callsign lookup with QRZ.com + HamQTH providers (primary/failsafe routing)
  and SQLite-backed TTL cache
- DXCC resolver from cty.dat (auto-download, longest-prefix-match)
- Multi-profile operator identities (home/portable/SOTA/contest) — every
  QSO stamps MY_* from the active profile
- CAT control via OmniRig COM on a single OS-locked goroutine, with
  bidirectional sync (freq/mode/band/split/VFOs) and Rig1/Rig2 hot-swap
- Settings store (key/value), CAT debug log at %APPDATA%/HamLog/cat.log

Frontend (React 18 + TypeScript + Tailwind v4 + shadcn-style):
- Single-row entry strip with CAT-aware band/mode/freq, RST, Start/End
  UTC, per-field locks (band/mode/freq/start/end) for backdated QSOs
- Topbar: live freq (MHz.kHz.Hz dotted), live UTC, band/mode/SPLIT badges,
  CAT pill with rig selector and clickable Azimuth pill (rotor TODO)
- Settings tree: Profiles (Log4OM-style manager), Station Information
  (edits the active profile), unified Callsign Lookup with Test buttons,
  Bands/Modes lists, CAT
- Worked-before matrix (band × mode × class) with new-DXCC highlighting
- ADIF import from menu + Maintenance > Refresh cty.dat

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 00:16:45 +02:00

75 lines
1.9 KiB
Go

package dxcc
import (
"strings"
"testing"
)
const sampleCty = `Sov Mil Order of Malta: 15: 28: EU: 41.90: -12.43: -1.0: 1A:
1A;
Monaco: 14: 27: EU: 43.73: -7.40: -1.0: 3A:
3A;
France: 14: 27: EU: 46.00: -2.00: -1.0: F:
F,HW,HX,HY,TH,TM,TO,TP,TQ,TV,TX;
Germany: 14: 28: EU: 51.00: -10.00: -1.0: DL:
DA,DB,DC,DD,DE,DF,DG,DH,DI,DJ,DK,DL,DM,DN,DO,DP,DQ,DR;
United States: 05: 08: NA: 37.53: 91.67: 5.0: K:
=W1AW(5)[7],K,N,W,AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK;
`
func TestLookup(t *testing.T) {
db, err := Load(strings.NewReader(sampleCty))
if err != nil {
t.Fatalf("load: %v", err)
}
cases := []struct {
call string
wantEnt string
}{
{"F4NIE", "France"},
{"F4BPO", "France"},
{"F4BPO/P", "France"},
{"DL/F4NIE", "Germany"},
{"DL5XYZ", "Germany"},
{"K1ABC", "United States"},
{"N0CALL", "United States"},
{"3A2MD", "Monaco"},
{"W1AW", "United States"}, // exact match wins
}
for _, c := range cases {
m, ok := db.Lookup(c.call)
if !ok {
t.Errorf("%s: no match", c.call)
continue
}
if m.Entity.Name != c.wantEnt {
t.Errorf("%s: got %q, want %q", c.call, m.Entity.Name, c.wantEnt)
}
}
// W1AW exact match has CQ override 5 and ITU override 7.
m, _ := db.Lookup("W1AW")
if m.CQZone != 5 || m.ITUZone != 7 {
t.Errorf("W1AW overrides: got CQ=%d ITU=%d, want 5/7", m.CQZone, m.ITUZone)
}
}
func TestNormalize(t *testing.T) {
cases := map[string]string{
"F4BPO": "F4BPO",
"f4bpo": "F4BPO",
" F4BPO ": "F4BPO",
"F4BPO/P": "F4BPO",
"F4BPO/MM": "F4BPO",
"F4BPO/5": "F4BPO",
"DL/F4BPO": "DL",
"F4BPO/W6": "W6",
"VK9/F4BPO": "VK9",
}
for in, want := range cases {
if got := normalizeCallsign(in); got != want {
t.Errorf("normalize(%q) = %q, want %q", in, got, want)
}
}
}