import Testing @testable import 康康 /// 日记追问对话的 prompt 拼装契约:收尾/继续两种口径互斥、红线短语、 /// dataJSON 原文嵌入、蒸馏截断与 /no_think 结尾。 /// 对齐 DiaryOrganizePromptTests 风格:纯字符串断言,不涉隔离。 struct DiaryChatPromptTests { /// 唯一、易断言的注入片段。 private let dataJSON = #"{"indicators":[{"name":"收缩压","value":"145"}]}"# // MARK: 收尾口径(roundsLeft == 0) @Test func replyAtZeroRoundsForbidsFurtherQuestions() { let prompt = DiaryChatPrompts.reply( transcript: "我: 我今天头疼", latest: "我头疼", dataJSON: dataJSON, roundsLeft: 0 ) #expect(prompt.contains("不要再提任何问题")) #expect(!prompt.contains("最多问 1 个新问题")) } // MARK: 继续口径(roundsLeft > 0) @Test func replyWithRoundsLeftAllowsOneMoreQuestion() { let prompt = DiaryChatPrompts.reply( transcript: "我: 我今天头疼", latest: "我头疼", dataJSON: dataJSON, roundsLeft: 2 ) #expect(prompt.contains("最多问 1 个新问题")) #expect(!prompt.contains("不要再提任何问题")) } // MARK: 红线短语 + dataJSON 原文嵌入(opening 与 reply 都要有) @Test func openingCarriesNoReferralRuleAndEmbedsDataJSON() { let prompt = DiaryChatPrompts.opening(dataJSON: dataJSON) #expect(prompt.contains("不写「建议就医」")) #expect(prompt.contains(dataJSON)) } @Test func replyCarriesNoReferralRuleAndEmbedsDataJSON() { let prompt = DiaryChatPrompts.reply( transcript: "我: 我今天头疼", latest: "我头疼", dataJSON: dataJSON, roundsLeft: 1 ) #expect(prompt.contains("不写「建议就医」")) #expect(prompt.contains(dataJSON)) } // MARK: 蒸馏 prompt 的取材约束短语 @Test func distillContainsUserOnlyAndForbiddenRule() { let prompt = DiaryChatPrompts.distill(transcript: "我: 我今天头疼\n康康: 收到") #expect(prompt.contains("只取「我:」")) #expect(prompt.contains("绝对不许")) } // MARK: 三个 prompt trim 后都以 /no_think 结尾 @Test func openingEndsWithNoThink() { let prompt = DiaryChatPrompts.opening(dataJSON: dataJSON) #expect(prompt.trimmingCharacters(in: .whitespacesAndNewlines).hasSuffix("/no_think")) } @Test func replyEndsWithNoThink() { let prompt = DiaryChatPrompts.reply( transcript: "我: 我今天头疼", latest: "我头疼", dataJSON: dataJSON, roundsLeft: 1 ) #expect(prompt.trimmingCharacters(in: .whitespacesAndNewlines).hasSuffix("/no_think")) } @Test func distillEndsWithNoThink() { let prompt = DiaryChatPrompts.distill(transcript: "我: 我今天头疼") #expect(prompt.trimmingCharacters(in: .whitespacesAndNewlines).hasSuffix("/no_think")) } // MARK: 蒸馏对超长稿件截断到 distillTranscriptLimit(2000) @Test func distillTruncatesTranscriptBeyondLimit() { // 起始标记落在前 2000 内应保留;越限标记落在第 2500 字符附近应被截掉。 let earlyMark = "起始标记AAA" let lateMark = "越限标记ZZZ" let transcript = earlyMark + String(repeating: "文", count: 2500 - earlyMark.count) // 把越限标记推到 index≈2500 + lateMark + String(repeating: "字", count: 500) // 凑到 3000+ 字符 #expect(transcript.count > DiaryChatPrompts.distillTranscriptLimit) let prompt = DiaryChatPrompts.distill(transcript: transcript) #expect(prompt.contains(earlyMark)) #expect(!prompt.contains(lateMark)) } }