import Foundation import Testing @testable import TXCore @Suite("tmux 会话探测(连接前选择用)") struct TmuxSessionProbeTests { /// 命令里的标记必须是**拼接写法** —— 否则 PTY 回显会被误当成结果起点。 @Test("命令不含完整标记字面量,避免 PTY 回显误命中") func commandAvoidsEchoSelfMatch() { let cmd = TmuxSessionProbe.command #expect(!cmd.contains(TmuxSessionProbe.beginMark)) #expect(!cmd.contains(TmuxSessionProbe.endMark)) #expect(cmd.contains("tmux -V")) #expect(cmd.contains("list-sessions")) } @Test("解析会话列表(CRLF 行尾 + 版本行)") func parsesSessions() { var p = TmuxSessionProbe() // 先喂一段回显噪声(含拼接前的命令文本),不应触发。 #expect(p.feed("kid@Air ~> printf '%s\\n' \"__TX\"\"_SESSIONS_BEGIN\"\r\n") == nil) #expect(p.feed("\(TmuxSessionProbe.beginMark)\r\n") == nil) #expect(p.feed("tmux 3.7b\r\n") == nil) #expect(p.feed("S|:|main|:|5|:|0|:|1784988802\r\n") == nil) #expect(p.feed("S|:|demo|:|2|:|1|:|1784901778\r\n") == nil) let result = p.feed("\(TmuxSessionProbe.endMark)\r\n") guard case .available(let version, let sessions) = result else { Issue.record("期望 available,实际 \(String(describing: result))") return } #expect(version == "tmux 3.7b") #expect(sessions.count == 2) #expect(sessions[0] == TmuxSessionProbe.Session( name: "main", windows: 5, isAttached: false, lastActivity: Date(timeIntervalSince1970: 1784988802))) #expect(sessions[1].name == "demo") #expect(sessions[1].isAttached) // 一次性:命中后不再返回结果。 #expect(p.feed("S|:|late|:|1|:|0|:|1\r\n") == nil) } @Test("装了 tmux 但没有会话 → available 且列表为空(UI 只给新建/跳过)") func availableWithNoSessions() { var p = TmuxSessionProbe() _ = p.feed("\(TmuxSessionProbe.beginMark)\n") _ = p.feed("tmux 3.5a\n") let r = p.feed("\(TmuxSessionProbe.endMark)\n") #expect(r == .available(version: "tmux 3.5a", sessions: [])) } @Test("没装 tmux(无版本行)→ unavailable,直接走原生终端") func unavailableWithoutVersion() { var p = TmuxSessionProbe() _ = p.feed("\(TmuxSessionProbe.beginMark)\n") let r = p.feed("\(TmuxSessionProbe.endMark)\n") #expect(r == .unavailable) } @Test("畸形会话行被跳过而非崩溃") func skipsMalformedLines() { var p = TmuxSessionProbe() _ = p.feed("\(TmuxSessionProbe.beginMark)\ntmux 3.7\n") _ = p.feed("S|:|\n") // 字段不足 _ = p.feed("S|:||:|3|:|0\n") // 空名字 _ = p.feed("S|:|ok|:|x|:|0\n") // windows 非数字 let r = p.feed("\(TmuxSessionProbe.endMark)\n") #expect(r == .available(version: "tmux 3.7", sessions: [])) } }