package main import ( "math" "testing" ) // sine builds `ms` milliseconds of a 16 kHz tone at the given amplitude, so we // can exercise the energy gate without real audio or whisper. func sine(ms int, amp float64) []float32 { n := whisperSampleRate * ms / 1000 out := make([]float32, n) for i := range out { out[i] = float32(amp * math.Sin(2*math.Pi*440*float64(i)/whisperSampleRate)) } return out } func TestGateReason(t *testing.T) { const ( minMs = 300 minRMS = 0.01 ) tests := []struct { name string samples []float32 gated bool // true ⇒ expect a non-empty reason (dropped) }{ {"empty", nil, true}, {"too short", sine(100, 0.5), true}, // 100ms < 300ms {"long but silent", make([]float32, whisperSampleRate), true}, // 1s of zeros {"long but near-silent", sine(500, 0.005), true}, // rms ~0.0035 < floor {"real speech-ish", sine(500, 0.3), false}, // loud enough, long enough } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { reason := gateReason(tc.samples, whisperSampleRate, minMs, minRMS) if (reason != "") != tc.gated { t.Fatalf("gateReason=%q, want gated=%v", reason, tc.gated) } }) } }