package lookup import "testing" // fakeDXCC resolves a handful of calls, enough to stand in for cty.dat. type fakeDXCC map[string]struct { num int country string cont string cqz, ituz int lat, lon float64 } func (f fakeDXCC) Resolve(call string) (int, string, string, int, int, float64, float64, bool) { e, ok := f[call] if !ok { return 0, "", "", 0, 0, 0, 0, false } return e.num, e.country, e.cont, e.cqz, e.ituz, e.lat, e.lon, true } func testDXCC() fakeDXCC { return fakeDXCC{ // Costa Rica, as cty.dat reads the OPERATING call. "TI8/W2RE": {num: 308, country: "Costa Rica", cont: "NA", cqz: 7, ituz: 11, lat: 9.9, lon: -84.1}, // The home call: United States. "W2RE": {num: 291, country: "United States", cont: "NA", cqz: 5, ituz: 8, lat: 39.8, lon: -98.5}, // A same-entity portable: still France either way. "F4BPO/P": {num: 227, country: "France", cont: "EU", cqz: 14, ituz: 27, lat: 46.2, lon: 2.2}, "F4BPO": {num: 227, country: "France", cont: "EU", cqz: 14, ituz: 27, lat: 46.2, lon: 2.2}, } } // A callbook record for a portable call routinely carries the operator's HOME // address — most QRZ pages for a portable call do — and a subdivision belongs to // an entity. Carrying the home county across an entity change is not cosmetic: // CNTY is defined as a US county, so TI8/W2RE was coming out as a Costa Rica // contact credited to Dutchess County, New York, with the distance and beam // heading taken from a square 3,600 km from where the station actually was. func TestPortableInAnotherEntityDropsTheHomeSubdivision(t *testing.T) { r := Result{ Callsign: "TI8/W2RE", Name: "Raymond", // who they are — kept QTH: "Poughquag", Address: "499 Pleasant Ridge Road", // cards still go there — kept State: "NY", County: "Dutchess", Grid: "FN31", Lat: 41.6, Lon: -73.7, DXCC: 291, } fillFromDXCC(&r, testDXCC()) if r.County != "" { t.Errorf("county = %q, want empty — a US county on a Costa Rica QSO is a false award credit", r.County) } if r.State != "" { t.Errorf("state = %q, want empty — a subdivision of the entity that is not being worked", r.State) } if r.Grid != "" { t.Errorf("grid = %q, want empty — it is the home square, 3,600 km from the operation", r.Grid) } // The entity and its centroid take over, so distance and bearing mean // something again. if r.DXCC != 308 || r.Country != "Costa Rica" { t.Errorf("entity = %d %q, want 308 Costa Rica", r.DXCC, r.Country) } if r.Lat != 9.9 || r.Lon != -84.1 { t.Errorf("lat/lon = %v/%v, want the Costa Rica centroid — the home coordinates must not survive", r.Lat, r.Lon) } // Who they are, and where their cards go, is unchanged. if r.Name != "Raymond" || r.Address != "499 Pleasant Ridge Road" { t.Errorf("name/address were cleared (%q / %q) — a portable operator's post still reaches home", r.Name, r.Address) } } // The other half of the rule: a portable WITHIN the same entity is at home as // far as the entity is concerned, and its details must survive untouched. func TestSameEntityPortableKeepsItsLocation(t *testing.T) { r := Result{ Callsign: "F4BPO/P", State: "77", County: "Seine-et-Marne", Grid: "JN18cs", Lat: 48.8, Lon: 2.4, DXCC: 227, } fillFromDXCC(&r, testDXCC()) if r.Grid != "JN18cs" || r.County != "Seine-et-Marne" || r.State != "77" { t.Errorf("a same-entity portable lost its location: grid=%q county=%q state=%q", r.Grid, r.County, r.State) } if r.Lat != 48.8 || r.Lon != 2.4 { t.Errorf("lat/lon = %v/%v — the precise home position was replaced by the entity centroid", r.Lat, r.Lon) } }