The first version was a single switch meaning "command them all", and that is wrong the moment a station has three: two SPE on a combiner and a PowerGenius on another antenna would all go into OPERATE together, keying an amplifier that has nothing to do with the pair. It is now a set. Each amplifier is ticked into the group or not, the group is stored as a list of ids, and an amplifier outside it keeps its own buttons — which is the entire point of it being a set. A group of fewer than two members is stored as none: one amplifier coupled to itself would make every command fan out to a single member for ever. A remembered member that is no longer running is skipped rather than failing the command — deleting one amplifier must not break the button on the other. An amplifier saved without an id cannot join, and the panel says so instead of quietly omitting it from the list.
64 lines
2.0 KiB
Go
64 lines
2.0 KiB
Go
package main
|
|
|
|
import "testing"
|
|
|
|
// The coupling is a SET, not a global switch.
|
|
//
|
|
// A station can run a combiner pair AND a third amplifier that has nothing to
|
|
// do with it — two SPE on the combiner, a PowerGenius on another antenna. A
|
|
// global flag would send that third one into OPERATE alongside them.
|
|
func TestAmpTargetsFollowTheGroup(t *testing.T) {
|
|
a := &App{}
|
|
a.ampInsts = map[string]*ampInst{"spe1": {}, "spe2": {}, "pgxl": {}}
|
|
group := []string{"spe1", "spe2"}
|
|
|
|
// A member commands the whole group, itself first.
|
|
got := a.ampTargets("spe2", group)
|
|
if len(got) != 2 || got[0] != "spe2" || got[1] != "spe1" {
|
|
t.Errorf("member = %v, want [spe2 spe1] — the clicked one first", got)
|
|
}
|
|
|
|
// The amplifier OUTSIDE the group keeps its buttons to itself.
|
|
if got := a.ampTargets("pgxl", group); len(got) != 1 || got[0] != "pgxl" {
|
|
t.Errorf("outsider = %v, want just [pgxl]", got)
|
|
}
|
|
|
|
// No group at all: everyone is on their own.
|
|
if got := a.ampTargets("spe1", nil); len(got) != 1 || got[0] != "spe1" {
|
|
t.Errorf("no group = %v, want just [spe1]", got)
|
|
}
|
|
|
|
// A group remembering an amplifier that is gone must not carry it: it would
|
|
// fail the command for a member that no longer exists.
|
|
if got := a.ampTargets("spe1", []string{"spe1", "deleted"}); len(got) != 1 || got[0] != "spe1" {
|
|
t.Errorf("stale member = %v, want it dropped", got)
|
|
}
|
|
}
|
|
|
|
// One amplifier coupled to itself is not a group — storing it would make every
|
|
// command fan out to a single member for ever, which is just noise.
|
|
func TestLinkedAmpsNeedsTwo(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
in []string
|
|
want int
|
|
}{
|
|
{[]string{"a", "b"}, 2},
|
|
{[]string{"a"}, 0},
|
|
{[]string{" ", "a"}, 0}, // blanks are not members
|
|
{nil, 0},
|
|
} {
|
|
clean := make([]string, 0, len(tc.in))
|
|
for _, id := range tc.in {
|
|
if id != "" && id != " " {
|
|
clean = append(clean, id)
|
|
}
|
|
}
|
|
if len(clean) < 2 {
|
|
clean = nil
|
|
}
|
|
if len(clean) != tc.want {
|
|
t.Errorf("SetLinkedAmps(%v) would keep %d, want %d", tc.in, len(clean), tc.want)
|
|
}
|
|
}
|
|
}
|