| 2043 | // ═════════════════════════════════════════════════════════════════════════════ |
| 2044 | |
| 2045 | void sectionEdge(RigctlClient& c, Runner& r) |
| 2046 | { |
| 2047 | r.section(QStringLiteral("Edge Cases")); |
| 2048 | |
| 2049 | // E1 Unknown command → RPRT -4 |
| 2050 | QStringList lines = c.send(QStringLiteral("\\nonexistent_command_xyz")); |
| 2051 | r.check(QStringLiteral("E1 unknown command returns RPRT -4"), |
| 2052 | c.rprt(lines) == -4, lines.join(QStringLiteral(" | "))); |
| 2053 | |
| 2054 | // E2 Batch commands via ';' — extended mode: get_freq=3 lines + get_mode=4 lines = 7 total |
| 2055 | QStringList raw = c.sendRaw(QStringLiteral("\\get_freq;\\get_mode"), 7); |
| 2056 | r.check(QStringLiteral("E2 batch commands (;-separated) return multiple values"), |
| 2057 | !c.field(raw, QStringLiteral("Frequency")).isEmpty() |
| 2058 | && !c.field(raw, QStringLiteral("Mode")).isEmpty(), |
| 2059 | raw.join(QStringLiteral(" | "))); |
| 2060 | |
| 2061 | // E3 chk_vfo → 1 (VFO mode always enabled since feat/rigctl-vfo-select) |
| 2062 | lines = c.send(QStringLiteral("\\chk_vfo")); |
| 2063 | r.check(QStringLiteral("E3 chk_vfo returns 1 (VFO mode always enabled)"), |
| 2064 | c.ok(lines) && c.field(lines, QStringLiteral("VFO Mode")) == QLatin1String("1"), |
| 2065 | lines.join(QStringLiteral(" | "))); |
| 2066 | |
| 2067 | // E4 get_trn → transceive always off |
| 2068 | lines = c.send(QStringLiteral("\\get_trn")); |
| 2069 | const QString trn = c.field(lines, QStringLiteral("Transceive")); |
| 2070 | r.check(QStringLiteral("E4 get_trn returns Transceive: 0 (unsupported)"), |
| 2071 | c.ok(lines) && trn == QLatin1String("0"), trn); |
| 2072 | |
| 2073 | // E5 set_trn 1 → silently accepted |
| 2074 | lines = c.send(QStringLiteral("\\set_trn 1")); |
| 2075 | r.check(QStringLiteral("E5 set_trn 1 accepted silently (RPRT 0)"), c.ok(lines)); |
| 2076 | |
| 2077 | // E6 send_morse smoke test — verify protocol accepts it without --cw flag |
| 2078 | // Does not verify radio keying; just that the command parses and queues |
| 2079 | lines = c.send(QStringLiteral("\\send_morse TEST")); |
| 2080 | r.check(QStringLiteral("E6 send_morse \"TEST\" accepted (RPRT 0, no --cw required)"), |
| 2081 | c.ok(lines), lines.join(QStringLiteral(" | "))); |
| 2082 | c.send(QStringLiteral("\\stop_morse")); |
| 2083 | |
| 2084 | // E7 q (short-form quit) — must return RPRT 0 so Hamlib closes cleanly |
| 2085 | // without triggering its 20-second command timeout |
| 2086 | QStringList qlines = c.sendRaw(QStringLiteral("q"), 1); |
| 2087 | r.check(QStringLiteral("E7 q (short-form quit) returns RPRT 0"), |
| 2088 | !qlines.isEmpty() && qlines[0].trimmed() == QLatin1String("RPRT 0"), |
| 2089 | qlines.value(0)); |
| 2090 | |
| 2091 | // E8 \quit (long-form quit) — same requirement |
| 2092 | qlines = c.sendRaw(QStringLiteral("\\quit"), 1); |
| 2093 | r.check(QStringLiteral("E8 \\quit (long-form quit) returns RPRT 0"), |
| 2094 | !qlines.isEmpty() && qlines[0].trimmed() == QLatin1String("RPRT 0"), |
| 2095 | qlines.value(0)); |
| 2096 | } |
| 2097 | |
| 2098 | // ═════════════════════════════════════════════════════════════════════════════ |
| 2099 | // Section 16 — PTY round-trip (Unix only; skips if device cannot be opened) |