feat: refactor

This commit is contained in:
leonardotrapani
2026-02-01 17:24:43 +01:00
parent 13b1de4e04
commit 8df3021a9d
33 changed files with 1290 additions and 1577 deletions
+58 -73
View File
@@ -1,115 +1,100 @@
package tui
import (
"strings"
"testing"
"github.com/leonardotrapani/hyprvoice/internal/provider"
)
func TestGetTranscriptionModelOptions_GroupsModels(t *testing.T) {
// test elevenlabs - has both batch and streaming
func TestGetTranscriptionModelOptions_ShowsCapabilities(t *testing.T) {
// test elevenlabs - has batch-only and streaming-only models
options := getTranscriptionModelOptions("elevenlabs", "")
// find headers
var batchHeaderIdx, streamingHeaderIdx int
batchHeaderIdx = -1
streamingHeaderIdx = -1
for i, opt := range options {
if opt.Value == "" {
if opt.Key == "─── Batch ───" {
batchHeaderIdx = i
}
if opt.Key == "─── Streaming ───" {
streamingHeaderIdx = i
}
}
// should have 3 models: scribe_v1, scribe_v2, scribe_v2_realtime
if len(options) != 3 {
t.Errorf("expected 3 options for elevenlabs, got %d", len(options))
}
if batchHeaderIdx == -1 {
t.Error("expected Batch header for provider with both types")
}
if streamingHeaderIdx == -1 {
t.Error("expected Streaming header for provider with both types")
}
if batchHeaderIdx >= streamingHeaderIdx {
t.Errorf("Batch header should come before Streaming header: batch=%d, streaming=%d", batchHeaderIdx, streamingHeaderIdx)
}
// verify models are grouped correctly
for i, opt := range options {
if opt.Value == "" {
continue // skip headers
}
// verify models show capability tags
for _, opt := range options {
model, _, _ := provider.FindModelByID(opt.Value)
if model == nil {
continue // unknown model
continue
}
if i < streamingHeaderIdx && model.Streaming {
t.Errorf("streaming model %s found before streaming header", opt.Value)
}
if i > streamingHeaderIdx && !model.Streaming {
t.Errorf("batch model %s found after streaming header", opt.Value)
if model.SupportsStreaming && !model.SupportsBatch {
// streaming-only should have [streaming] tag
if !strings.Contains(opt.Key, "[streaming]") {
t.Errorf("streaming-only model %s should have [streaming] tag in label: %s", opt.Value, opt.Key)
}
} else if model.SupportsBothModes() {
// both modes should have [batch+streaming] tag
if !strings.Contains(opt.Key, "[batch+streaming]") {
t.Errorf("both-modes model %s should have [batch+streaming] tag in label: %s", opt.Value, opt.Key)
}
}
// batch-only models don't need a tag
}
}
func TestGetTranscriptionModelOptions_NoHeadersForSingleType(t *testing.T) {
// test groq - batch only (no streaming models)
options := getTranscriptionModelOptions("groq-transcription", "")
func TestGetTranscriptionModelOptions_NoHeadersAnymore(t *testing.T) {
// we removed batch/streaming section headers
options := getTranscriptionModelOptions("elevenlabs", "")
for _, opt := range options {
if opt.Value == "" {
t.Errorf("expected no headers for provider with only one model type, got: %s", opt.Key)
t.Errorf("should not have headers anymore, got: %s", opt.Key)
}
}
}
func TestGetTranscriptionModelOptions_OpenAI_GroupsCorrectly(t *testing.T) {
func TestGetTranscriptionModelOptions_OpenAI_ShowsCapabilities(t *testing.T) {
options := getTranscriptionModelOptions("openai", "")
var batchHeaderIdx, streamingHeaderIdx int
batchHeaderIdx = -1
streamingHeaderIdx = -1
// OpenAI has 3 transcription models: whisper-1, gpt-4o-transcribe, gpt-4o-mini-transcribe
if len(options) != 3 {
t.Errorf("expected 3 options for openai, got %d", len(options))
}
for i, opt := range options {
if opt.Value == "" {
if opt.Key == "─── Batch ───" {
batchHeaderIdx = i
}
if opt.Key == "─── Streaming ───" {
streamingHeaderIdx = i
// gpt-4o-transcribe and gpt-4o-mini-transcribe should have [batch+streaming]
for _, opt := range options {
if strings.Contains(opt.Value, "gpt-4o") {
if !strings.Contains(opt.Key, "[batch+streaming]") {
t.Errorf("gpt-4o model %s should have [batch+streaming] tag: %s", opt.Value, opt.Key)
}
}
}
}
// OpenAI has 3 batch + 1 streaming
if batchHeaderIdx == -1 {
t.Error("expected Batch header for OpenAI")
}
if streamingHeaderIdx == -1 {
t.Error("expected Streaming header for OpenAI")
func TestGetTranscriptionModelOptions_Deepgram_ShowsBothModes(t *testing.T) {
options := getTranscriptionModelOptions("deepgram", "")
// Deepgram has 2 models: nova-3, nova-2 - both support batch+streaming
if len(options) != 2 {
t.Errorf("expected 2 options for deepgram, got %d", len(options))
}
// count models (not headers) by position
batchCount := 0
streamingCount := 0
for i, opt := range options {
if opt.Value == "" {
continue // skip headers
}
if i > batchHeaderIdx && i < streamingHeaderIdx {
batchCount++
} else if i > streamingHeaderIdx {
streamingCount++
for _, opt := range options {
if !strings.Contains(opt.Key, "[batch+streaming]") {
t.Errorf("deepgram model %s should have [batch+streaming] tag: %s", opt.Value, opt.Key)
}
}
}
if batchCount < 3 {
t.Errorf("expected at least 3 batch models for OpenAI, got %d", batchCount)
func TestGetTranscriptionModelOptions_Groq_BatchOnly(t *testing.T) {
// test groq - batch only (no streaming models)
options := getTranscriptionModelOptions("groq-transcription", "")
// should have 2 models: whisper-large-v3, whisper-large-v3-turbo
if len(options) != 2 {
t.Errorf("expected 2 options for groq, got %d", len(options))
}
if streamingCount < 1 {
t.Errorf("expected at least 1 streaming model for OpenAI, got %d", streamingCount)
// batch-only models should not have any mode tags
for _, opt := range options {
if strings.Contains(opt.Key, "[streaming]") || strings.Contains(opt.Key, "[batch]") {
t.Errorf("batch-only model should not have mode tags: %s", opt.Key)
}
}
}