package cat import ( "strings" "testing" ) // What reaches the rig's keyer. // // An unsupported byte does not produce an error on a Yaesu — it can abort the // whole buffer, so the rest of the message is lost silently. Filtering is // therefore part of correctness, not tidiness. func TestFilterYaesuCW(t *testing.T) { cases := []struct{ in, want string }{ {"cq cq de f4bpo", "CQ CQ DE F4BPO"}, {"F4BPO/P", "F4BPO/P"}, {"599 tu 73", "599 TU 73"}, // Accents and symbols the keyer has no code for. {"héllo", "HLLO"}, {"a*b#c", "ABC"}, // Runs of whitespace collapse: the rig sends each space as a word gap, so // three in a row is three gaps and the message crawls. {"cq cq", "CQ CQ"}, {" padded ", "PADDED"}, {"\tcq\ncq\t", "CQ CQ"}, {"", ""}, {" ", ""}, } for _, c := range cases { if got := filterYaesuCW(c.in); got != c.want { t.Errorf("filterYaesuCW(%q) = %q, want %q", c.in, got, c.want) } } } // Long macros have to be split: one KY command carries 24 characters and the rig // DROPS what does not fit rather than reporting an error, so a contest CQ would // lose its tail with no sign anywhere. func TestYaesuCWChunking(t *testing.T) { msg := filterYaesuCW("cq cq cq de f4bpo f4bpo f4bpo pse k") if len(msg) <= yaesuCWChunk { t.Fatalf("test message is %d chars — too short to exercise chunking", len(msg)) } var chunks []string for rest := msg; len(rest) > 0; { n := yaesuCWChunk if len(rest) < n { n = len(rest) } chunks = append(chunks, rest[:n]) rest = rest[n:] } for i, c := range chunks { if len(c) > yaesuCWChunk { t.Errorf("chunk %d is %d chars, over the %d limit", i, len(c), yaesuCWChunk) } } // Nothing added, nothing lost: the message the operator typed is what the // keyer receives. if joined := strings.Join(chunks, ""); joined != msg { t.Errorf("chunks rejoin to %q, want %q", joined, msg) } }