package main import "testing" // Which rotors the satellite page may offer. Getting this wrong is not a // cosmetic fault: a rotor listed as az/el that has no elevation motor is a // tracker sending W commands into a controller that ignores them, and a pass // spent wondering why the antenna never lifts. func TestRotorHasElevation(t *testing.T) { cases := []struct { name string dev RotatorDevice want bool }{ {"ERC-M drives both axes of a G-5500", RotatorDevice{Type: "erc"}, true}, {"EasyComm is an az/el protocol", RotatorDevice{Type: "easycomm"}, true}, {"an ARCO is azimuth only", RotatorDevice{Type: "arco"}, false}, {"a Rotator Genius is azimuth only", RotatorDevice{Type: "rotgenius"}, false}, {"a DCU-1 is azimuth only", RotatorDevice{Type: "dcu1"}, false}, // SPID: the dialect decides. Rot1Prog has no elevation in its reply // format at all, so offering it would be offering a rotor that cannot // answer the question. {"SPID Rot2Prog has elevation", RotatorDevice{Type: "spid", SpidModel: "rot2prog"}, true}, {"SPID defaults to Rot2Prog", RotatorDevice{Type: "spid"}, true}, {"SPID Rot1Prog does not", RotatorDevice{Type: "spid", SpidModel: "rot1prog"}, false}, // PstRotator: the elevation belongs to the station, not the protocol. // PstRotator will happily forward EL to a controller that has no // elevation motor, so only the operator can answer this one. {"PstRotator with elevation declared", RotatorDevice{Type: "pst", HasElevation: true}, true}, {"PstRotator without", RotatorDevice{Type: "pst"}, false}, // An unknown type falls back to PstRotator, and must not fall back to // "has elevation" with it. {"an unknown backend", RotatorDevice{Type: "nonsense"}, false}, } for _, c := range cases { if got := rotorHasElevation(c.dev); got != c.want { t.Errorf("%s: got %v, want %v", c.name, got, c.want) } } } // The satellite page stores a rotor KEY, not a list index: deleting the first // rotor must not silently point the tracker at a different mast. func TestFlattenRotorsKeys(t *testing.T) { devs := []RotatorDevice{ {ID: "a", Name: "HF", Type: "pst"}, {ID: "b", Name: "Sat", Type: "erc"}, {ID: "c", Name: "RG", Type: "rotgenius", Dual: true, Name2: "RG 2"}, } got := flattenRotors(devs) want := []struct { key string hasEl bool }{ {"a", false}, {"b", true}, {"c", false}, {"c#2", false}, // the second port of a Dual Rotator Genius } if len(got) != len(want) { t.Fatalf("got %d logical rotors, want %d", len(got), len(want)) } for i, w := range want { if got[i].Key != w.key || got[i].HasEl != w.hasEl { t.Errorf("rotor %d: key %q el %v, want key %q el %v", i, got[i].Key, got[i].HasEl, w.key, w.hasEl) } } } // Each backend's default baud, because a blanket 9600 is silence on two of // them: a SPID runs at 600 and an ERC-M ships at 19200, and a wrong rate reads // exactly like a dead controller. func TestRotorDefaultBaud(t *testing.T) { cases := map[string]int{"spid": 600, "erc": 19200, "dcu1": 4800, "arco": 9600, "easycomm": 9600} for typ, want := range cases { if got := rotorTypeInfo(typ).DefaultBaud; got != want { t.Errorf("%s: default baud %d, want %d", typ, got, want) } } }