mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-17 19:47:10 +08:00
test(cursor): make transcript adapter tests self-contained
Keep the transcript coverage independent from branch-specific projector helpers so it runs cleanly on the upstream main test layout.
This commit is contained in:
@@ -3,6 +3,7 @@ package forwarder
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -14,14 +15,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestProjectCursorTranscriptJSONLMatchesCursorContract(t *testing.T) {
|
func TestProjectCursorTranscriptJSONLMatchesCursorContract(t *testing.T) {
|
||||||
toolCall := testEditToolCall(t, "file.txt")
|
toolCall := transcriptTestEditToolCall(t, "file.txt")
|
||||||
conversation := testConversation([]HistoryEntry{
|
conversation := transcriptTestConversation([]HistoryEntry{
|
||||||
testUserMessageEntry(t, 1, "request-1", "<user_info>hidden</user_info>\n\nchange the file"),
|
transcriptTestUserMessageEntry(t, 1, "request-1", "<user_info>hidden</user_info>\n\nchange the file"),
|
||||||
newAssistantTextEntry(1, "request-1", "<thinking>hidden</thinking>\nDone", "checked carefully", ""),
|
newAssistantTextEntry(1, "request-1", "<thinking>hidden</thinking>\nDone", "checked carefully", ""),
|
||||||
newToolCallEntry(1, "request-1", "call-1", "Edit", "", "", toolCall),
|
newToolCallEntry(1, "request-1", "call-1", "Edit", "", "", toolCall),
|
||||||
newToolResultEntry(1, "request-1", "call-1", "Edit", `{"path":"file.txt"}`, "edited", "", toolCall),
|
newToolResultEntry(1, "request-1", "call-1", "Edit", `{"path":"file.txt"}`, "edited", "", toolCall),
|
||||||
newMetadataEntry(1, "request-1", "turn_completed", nil),
|
newMetadataEntry(1, "request-1", "turn_completed", nil),
|
||||||
testUserMessageEntry(t, 2, "request-2", "next question"),
|
transcriptTestUserMessageEntry(t, 2, "request-2", "next question"),
|
||||||
newMetadataEntry(2, "request-2", "turn_completed", nil),
|
newMetadataEntry(2, "request-2", "turn_completed", nil),
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -63,11 +64,11 @@ func TestConversationFileStoreSyncsCursorTranscript(t *testing.T) {
|
|||||||
historyRoot := filepath.Join(t.TempDir(), "history")
|
historyRoot := filepath.Join(t.TempDir(), "history")
|
||||||
transcriptsFolder := filepath.Join(t.TempDir(), "agent-transcripts")
|
transcriptsFolder := filepath.Join(t.TempDir(), "agent-transcripts")
|
||||||
store := NewConversationFileStore(historyRoot)
|
store := NewConversationFileStore(historyRoot)
|
||||||
conversation := testConversation(nil)
|
conversation := transcriptTestConversation(nil)
|
||||||
conversation.AgentTranscriptsFolder = transcriptsFolder
|
conversation.AgentTranscriptsFolder = transcriptsFolder
|
||||||
|
|
||||||
persisted, err := store.SaveConversationWithEntries(conversation.ConversationID, conversation, []HistoryEntry{
|
persisted, err := store.SaveConversationWithEntries(conversation.ConversationID, conversation, []HistoryEntry{
|
||||||
testUserMessageEntry(t, 1, "request-1", "hello"),
|
transcriptTestUserMessageEntry(t, 1, "request-1", "hello"),
|
||||||
newAssistantTextEntry(1, "request-1", "hi", "", ""),
|
newAssistantTextEntry(1, "request-1", "hi", "", ""),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -103,10 +104,10 @@ func TestConversationFileStoreBackfillsTranscriptOnStartup(t *testing.T) {
|
|||||||
t.Fatalf("create transcript root: %v", err)
|
t.Fatalf("create transcript root: %v", err)
|
||||||
}
|
}
|
||||||
store := NewConversationFileStore(historyRoot)
|
store := NewConversationFileStore(historyRoot)
|
||||||
conversation := testConversation(nil)
|
conversation := transcriptTestConversation(nil)
|
||||||
conversation.AgentTranscriptsFolder = transcriptsFolder
|
conversation.AgentTranscriptsFolder = transcriptsFolder
|
||||||
_, err := store.SaveConversationWithEntries(conversation.ConversationID, conversation, []HistoryEntry{
|
_, err := store.SaveConversationWithEntries(conversation.ConversationID, conversation, []HistoryEntry{
|
||||||
testUserMessageEntry(t, 1, "request-1", "hello"),
|
transcriptTestUserMessageEntry(t, 1, "request-1", "hello"),
|
||||||
newAssistantTextEntry(1, "request-1", "hi", "", ""),
|
newAssistantTextEntry(1, "request-1", "hi", "", ""),
|
||||||
newMetadataEntry(1, "request-1", "turn_completed", nil),
|
newMetadataEntry(1, "request-1", "turn_completed", nil),
|
||||||
})
|
})
|
||||||
@@ -169,7 +170,7 @@ func TestAgentTranscriptsFolderRecoveredFromLegacyRequestContext(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("marshal request context: %v", err)
|
t.Fatalf("marshal request context: %v", err)
|
||||||
}
|
}
|
||||||
conversation := testConversation([]HistoryEntry{{
|
conversation := transcriptTestConversation([]HistoryEntry{{
|
||||||
TurnSeq: 1,
|
TurnSeq: 1,
|
||||||
Role: "user",
|
Role: "user",
|
||||||
Kind: "request_context",
|
Kind: "request_context",
|
||||||
@@ -182,6 +183,49 @@ func TestAgentTranscriptsFolderRecoveredFromLegacyRequestContext(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func transcriptTestConversation(entries []HistoryEntry) *ConversationFile {
|
||||||
|
conversation := &ConversationFile{
|
||||||
|
ConversationID: "conversation-1",
|
||||||
|
RootConversationID: "conversation-1",
|
||||||
|
Mode: "agent",
|
||||||
|
NextTurnSeq: 1,
|
||||||
|
NextEntrySeq: 1,
|
||||||
|
Entries: make([]HistoryEntry, 0, len(entries)),
|
||||||
|
}
|
||||||
|
appendEntriesInPlace(conversation, entries)
|
||||||
|
return conversation
|
||||||
|
}
|
||||||
|
|
||||||
|
func transcriptTestUserMessageEntry(t *testing.T, turnSeq int64, requestID string, text string) HistoryEntry {
|
||||||
|
t.Helper()
|
||||||
|
payload, err := protojson.Marshal(&agentv1.UserMessage{Text: text, MessageId: fmt.Sprintf("message-%d", turnSeq)})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("marshal user message: %v", err)
|
||||||
|
}
|
||||||
|
return HistoryEntry{
|
||||||
|
TurnSeq: turnSeq,
|
||||||
|
RequestID: requestID,
|
||||||
|
Role: "user",
|
||||||
|
Kind: "user_message",
|
||||||
|
Payload: payload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func transcriptTestEditToolCall(t *testing.T, path string) []byte {
|
||||||
|
t.Helper()
|
||||||
|
payload, err := protojson.Marshal(&agentv1.ToolCall{
|
||||||
|
Tool: &agentv1.ToolCall_EditToolCall{
|
||||||
|
EditToolCall: &agentv1.EditToolCall{
|
||||||
|
Args: &agentv1.EditArgs{Path: path},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("marshal edit tool call: %v", err)
|
||||||
|
}
|
||||||
|
return payload
|
||||||
|
}
|
||||||
|
|
||||||
func decodeCursorTranscriptLines(t *testing.T, data []byte) []cursorTranscriptLine {
|
func decodeCursorTranscriptLines(t *testing.T, data []byte) []cursorTranscriptLine {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
lines := make([]cursorTranscriptLine, 0)
|
lines := make([]cursorTranscriptLine, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user