package main import ( "strings" "testing" "time" ) func TestLiveCaptionDisplayTextFitsOverlayBuffer(t *testing.T) { input := strings.Repeat("这是一句实时字幕", 12) got := liveCaptionDisplayText(input) if got == "" { t.Fatal("caption should not be empty") } if len([]byte(got)) > liveCaptionMaxBytes { t.Fatalf("caption bytes = %d, want <= %d", len([]byte(got)), liveCaptionMaxBytes) } if !strings.HasPrefix(got, "...") { t.Fatalf("caption = %q, want leading truncation marker", got) } } func TestReleaseTailCaptureDelayUsesEngineCapability(t *testing.T) { a := &App{} a.replaceEngine(tailCaptureTestEngine{delay: 300 * time.Millisecond}) if got := a.releaseTailCaptureDelay(); got != 300*time.Millisecond { t.Fatalf("releaseTailCaptureDelay() = %v, want 300ms", got) } } func TestReleaseTailCaptureDelayDefaultsToZero(t *testing.T) { a := &App{} a.replaceEngine(plainTestEngine{}) if got := a.releaseTailCaptureDelay(); got != 0 { t.Fatalf("releaseTailCaptureDelay() = %v, want 0", got) } } func TestHoldPreCaptureUsesEngineCapability(t *testing.T) { a := &App{} a.replaceEngine(holdPreCaptureTestEngine{enabled: true}) if !a.holdPreCaptureEnabled.Load() { t.Fatal("hold pre-capture should be enabled by engine capability") } } func TestHoldPreCaptureDefaultsToFalse(t *testing.T) { a := &App{} a.replaceEngine(plainTestEngine{}) if a.holdPreCaptureEnabled.Load() { t.Fatal("hold pre-capture should default to false") } } func TestShouldStartHoldPreCaptureLocked(t *testing.T) { a := &App{} a.holdPreCaptureEnabled.Store(true) if !a.shouldStartHoldPreCaptureLocked() { t.Fatal("expected hold pre-capture to start when enabled and idle") } a.isRecording = true if a.shouldStartHoldPreCaptureLocked() { t.Fatal("should not pre-capture while already recording") } a.isRecording = false a.isStoppingRecording = true if a.shouldStartHoldPreCaptureLocked() { t.Fatal("should not pre-capture while stopping") } a.isStoppingRecording = false a.isFreetalking = true if a.shouldStartHoldPreCaptureLocked() { t.Fatal("should not pre-capture while tap recording is active") } a.isFreetalking = false a.lastStopTime = time.Now() if a.shouldStartHoldPreCaptureLocked() { t.Fatal("should not pre-capture during post-stop debounce") } } func TestStartRecordingIgnoredWhileStoppingRecording(t *testing.T) { a := &App{isStoppingRecording: true} a.startRecordingLocked() if a.isRecording { t.Fatal("startRecordingLocked should not start while stop tail capture is pending") } } func TestStartTapRecordingIgnoredWhileStoppingRecording(t *testing.T) { a := &App{isStoppingRecording: true} a.startTapRecordingLocked() if a.isRecording || a.isFreetalking { t.Fatal("startTapRecordingLocked should not start while stop tail capture is pending") } } type plainTestEngine struct{} func (plainTestEngine) Recognize([]float32) (string, error) { return "", nil } func (plainTestEngine) HardwareInfo() string { return "test" } func (plainTestEngine) Close() {} type tailCaptureTestEngine struct { plainTestEngine delay time.Duration } func (e tailCaptureTestEngine) ReleaseTailCaptureDelay() time.Duration { return e.delay } type holdPreCaptureTestEngine struct { plainTestEngine enabled bool } func (e holdPreCaptureTestEngine) HoldPreCaptureEnabled() bool { return e.enabled }