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) } } // Reading the KY status reply. // // The first version demanded exactly "KY0;" with the digit at byte 2, and on a // real FTDX10 that refused to send at all: the reply was phrased differently, // every poll read as "still full", and after four seconds the send gave up // having keyed nothing. Hence the asymmetry — only a clear "1" blocks. func TestYaesuCWBufferFull(t *testing.T) { cases := []struct { reply string full bool }{ {"KY0;", false}, {"KY1;", true}, {"KY 0;", false}, // a space before the digit {"KY 1;", true}, {"ky1;", true}, // lower case {" KY0; ", false}, // Shapes we have no sample of must NOT block: silence with no explanation // is a worse failure than sending a moment early. {"KY;", false}, {"", false}, {"FA014074000;", false}, // another command's reply arriving first {"KYX;", false}, } for _, c := range cases { if got := yaesuCWBufferFull(c.reply); got != c.full { t.Errorf("yaesuCWBufferFull(%q) = %v, want %v", c.reply, got, c.full) } } }