Skip to content

Commit dcd146f

Browse files
committed
feat: add tests
1 parent ff26f8c commit dcd146f

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

lib/screentracker/conversation_test.go

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,3 +406,140 @@ func TestPartsToString(t *testing.T) {
406406
),
407407
)
408408
}
409+
410+
func TestInitialPromptReadiness(t *testing.T) {
411+
now := time.Now()
412+
changing := st.ConversationStatusChanging
413+
stable := st.ConversationStatusStable
414+
415+
t.Run("agent not ready - status remains changing", func(t *testing.T) {
416+
cfg := st.ConversationConfig{
417+
GetTime: func() time.Time { return now },
418+
SnapshotInterval: 1 * time.Second,
419+
ScreenStabilityLength: 2 * time.Second,
420+
AgentIO: &testAgent{screen: "loading..."},
421+
IsAgentReadyForInitialPrompt: func(message string) bool {
422+
return message == "ready"
423+
},
424+
}
425+
c := st.NewConversation(context.Background(), cfg, "initial prompt here")
426+
427+
// Fill buffer with stable snapshots, but agent is not ready
428+
c.AddSnapshot("loading...")
429+
c.AddSnapshot("loading...")
430+
c.AddSnapshot("loading...")
431+
432+
// Even though screen is stable, status should be changing because agent is not ready
433+
assert.Equal(t, changing, c.Status())
434+
assert.False(t, c.AgentReadyForInitialPrompt)
435+
assert.False(t, c.InitialPromptSent)
436+
})
437+
438+
t.Run("agent becomes ready - status changes to stable", func(t *testing.T) {
439+
cfg := st.ConversationConfig{
440+
GetTime: func() time.Time { return now },
441+
SnapshotInterval: 1 * time.Second,
442+
ScreenStabilityLength: 2 * time.Second,
443+
AgentIO: &testAgent{screen: "loading..."},
444+
IsAgentReadyForInitialPrompt: func(message string) bool {
445+
return message == "ready"
446+
},
447+
}
448+
c := st.NewConversation(context.Background(), cfg, "initial prompt here")
449+
450+
// Agent not ready initially
451+
c.AddSnapshot("loading...")
452+
c.AddSnapshot("loading...")
453+
c.AddSnapshot("loading...")
454+
assert.Equal(t, changing, c.Status())
455+
456+
// Agent becomes ready
457+
c.AddSnapshot("ready")
458+
c.AddSnapshot("ready")
459+
c.AddSnapshot("ready")
460+
assert.Equal(t, stable, c.Status())
461+
assert.True(t, c.AgentReadyForInitialPrompt)
462+
assert.False(t, c.InitialPromptSent)
463+
})
464+
465+
t.Run("no initial prompt - normal status logic applies", func(t *testing.T) {
466+
cfg := st.ConversationConfig{
467+
GetTime: func() time.Time { return now },
468+
SnapshotInterval: 1 * time.Second,
469+
ScreenStabilityLength: 2 * time.Second,
470+
AgentIO: &testAgent{screen: "loading..."},
471+
IsAgentReadyForInitialPrompt: func(message string) bool {
472+
return false // Agent never ready
473+
},
474+
}
475+
// Empty initial prompt means no need to wait for readiness
476+
c := st.NewConversation(context.Background(), cfg, "")
477+
478+
c.AddSnapshot("loading...")
479+
c.AddSnapshot("loading...")
480+
c.AddSnapshot("loading...")
481+
482+
// Status should be stable because no initial prompt to wait for
483+
assert.Equal(t, stable, c.Status())
484+
assert.False(t, c.AgentReadyForInitialPrompt)
485+
assert.True(t, c.InitialPromptSent) // Set to true when initial prompt is empty
486+
})
487+
488+
t.Run("initial prompt sent - normal status logic applies", func(t *testing.T) {
489+
cfg := st.ConversationConfig{
490+
GetTime: func() time.Time { return now },
491+
SnapshotInterval: 1 * time.Second,
492+
ScreenStabilityLength: 2 * time.Second,
493+
AgentIO: &testAgent{screen: "processing..."},
494+
IsAgentReadyForInitialPrompt: func(message string) bool {
495+
return false // Agent never ready
496+
},
497+
}
498+
c := st.NewConversation(context.Background(), cfg, "initial prompt here")
499+
// Manually mark as sent to simulate that initial prompt was already sent
500+
c.InitialPromptSent = true
501+
502+
c.AddSnapshot("processing...")
503+
c.AddSnapshot("processing...")
504+
c.AddSnapshot("processing...")
505+
506+
// Status should be stable because initial prompt was already sent
507+
assert.Equal(t, stable, c.Status())
508+
assert.False(t, c.AgentReadyForInitialPrompt)
509+
assert.True(t, c.InitialPromptSent)
510+
})
511+
512+
t.Run("agent readiness detected once - stays ready", func(t *testing.T) {
513+
cfg := st.ConversationConfig{
514+
GetTime: func() time.Time { return now },
515+
SnapshotInterval: 1 * time.Second,
516+
ScreenStabilityLength: 2 * time.Second,
517+
AgentIO: &testAgent{screen: "ready"},
518+
IsAgentReadyForInitialPrompt: func(message string) bool {
519+
return message == "ready"
520+
},
521+
}
522+
c := st.NewConversation(context.Background(), cfg, "initial prompt here")
523+
524+
// Agent becomes ready
525+
c.AddSnapshot("ready")
526+
c.AddSnapshot("ready")
527+
c.AddSnapshot("ready")
528+
assert.Equal(t, stable, c.Status())
529+
assert.True(t, c.AgentReadyForInitialPrompt)
530+
531+
// After agent is detected as ready, normal status logic applies
532+
// Screen changes should cause changing status
533+
c.AddSnapshot("changing")
534+
assert.Equal(t, changing, c.Status())
535+
assert.True(t, c.AgentReadyForInitialPrompt)
536+
537+
// Once screen stabilizes again, status should be stable
538+
// AgentReadyForInitialPrompt remains true
539+
c.AddSnapshot("stable now")
540+
c.AddSnapshot("stable now")
541+
c.AddSnapshot("stable now")
542+
assert.Equal(t, stable, c.Status())
543+
assert.True(t, c.AgentReadyForInitialPrompt)
544+
})
545+
}

0 commit comments

Comments
 (0)