Skip to content

Commit 0490591

Browse files
committed
Add comprehensive tests for audio, document, image, video converters and TUI
- Implement tests for AudioConverter including supported extensions, conversion errors, and integration tests. - Add DocumentConverter tests covering supported extensions, conversion errors, and integration tests for various formats. - Create tests for ImageConverter to validate supported formats and conversion functionality. - Introduce VideoConverter tests to ensure proper handling of supported formats and conversion processes. - Add unit tests for TUI model initialization and updates. - Include version comparison tests to check versioning logic. - Update Taskfile to enhance test command descriptions and coverage.
1 parent 7d54fa1 commit 0490591

File tree

8 files changed

+1200
-3
lines changed

8 files changed

+1200
-3
lines changed

Taskfile.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ tasks:
4545
- echo "Clean complete!"
4646

4747
test:
48-
desc: Run tests
48+
desc: Run all tests with coverage
4949
cmds:
50-
- echo "Running tests..."
51-
- '{{.GO}} test -v ./...'
50+
- echo "Running all tests..."
51+
- '{{.GO}} test -v -cover ./...'
5252

5353
fmt:
5454
desc: Format code

internal/converter/audio_test.go

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
package converter
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
"path/filepath"
8+
"strings"
9+
"testing"
10+
)
11+
12+
func TestAudioConverter_SupportedExtensions(t *testing.T) {
13+
c := &AudioConverter{}
14+
15+
// Test SupportedSourceExtensions
16+
srcExts := c.SupportedSourceExtensions()
17+
if len(srcExts) == 0 {
18+
t.Error("SupportedSourceExtensions returned empty list")
19+
}
20+
expectedSrc := []string{".mp3", ".wav", ".ogg", ".flac", ".m4a", ".aac"}
21+
for _, exp := range expectedSrc {
22+
found := false
23+
for _, got := range srcExts {
24+
if got == exp {
25+
found = true
26+
break
27+
}
28+
}
29+
if !found {
30+
t.Errorf("SupportedSourceExtensions missing %s", exp)
31+
}
32+
}
33+
34+
// Test SupportedTargetFormats
35+
for _, ext := range expectedSrc {
36+
targets := c.SupportedTargetFormats(ext)
37+
if len(targets) == 0 {
38+
t.Errorf("SupportedTargetFormats(%s) returned empty list", ext)
39+
}
40+
}
41+
42+
// Test unsupported target formats
43+
if c.SupportedTargetFormats(".txt") != nil {
44+
t.Error("SupportedTargetFormats(.txt) should return nil")
45+
}
46+
}
47+
48+
func TestAudioConverter_Convert_Error(t *testing.T) {
49+
c := &AudioConverter{}
50+
51+
// Test non-existent file
52+
err := c.Convert("non_existent.wav", "out.mp3", Options{})
53+
if err == nil {
54+
t.Error("Convert should fail for non-existent file")
55+
}
56+
}
57+
58+
func TestAudioConverter_Convert_Integration_Exhaustive(t *testing.T) {
59+
// Check for ffmpeg
60+
if _, err := exec.LookPath("ffmpeg"); err != nil {
61+
t.Skip("ffmpeg not found, skipping integration test")
62+
}
63+
64+
tmpDir, err := os.MkdirTemp("", "golter_audio_test")
65+
if err != nil {
66+
t.Fatalf("failed to create temp dir: %v", err)
67+
}
68+
defer os.RemoveAll(tmpDir)
69+
70+
c := &AudioConverter{}
71+
formats := []string{".mp3", ".wav", ".ogg", ".flac", ".m4a", ".aac"}
72+
qualities := []string{"High", "Balanced", "Low"}
73+
74+
// Generate source files
75+
for _, ext := range formats {
76+
srcPath := filepath.Join(tmpDir, "src"+ext)
77+
// Generate 0.5s stereo audio
78+
cmd := exec.Command("ffmpeg", "-f", "lavfi", "-i", "sine=frequency=1000:duration=0.5", "-ac", "2", "-y", srcPath)
79+
if out, err := cmd.CombinedOutput(); err != nil {
80+
t.Logf("Failed to generate %s: %v\nOutput: %s", ext, err, out)
81+
continue
82+
}
83+
}
84+
85+
for _, srcExt := range formats {
86+
srcPath := filepath.Join(tmpDir, "src"+srcExt)
87+
if _, err := os.Stat(srcPath); os.IsNotExist(err) {
88+
continue
89+
}
90+
91+
for _, targetExt := range formats {
92+
if srcExt == targetExt {
93+
continue
94+
}
95+
96+
for _, quality := range qualities {
97+
testName := fmt.Sprintf("%s->%s (%s)", srcExt, targetExt, quality)
98+
t.Run(testName, func(t *testing.T) {
99+
targetName := fmt.Sprintf("out_%s_%s%s", srcExt[1:], quality, targetExt)
100+
targetPath := filepath.Join(tmpDir, targetName)
101+
102+
opts := Options{"quality": quality}
103+
err := c.Convert(srcPath, targetPath, opts)
104+
if err != nil {
105+
t.Errorf("Convert failed: %v", err)
106+
return
107+
}
108+
109+
if _, err := os.Stat(targetPath); os.IsNotExist(err) {
110+
t.Errorf("Target file not created: %s", targetPath)
111+
}
112+
})
113+
}
114+
}
115+
}
116+
}
117+
118+
func TestAudioConverter_Name(t *testing.T) {
119+
c := &AudioConverter{}
120+
if !strings.Contains(c.Name(), "Audio Converter") {
121+
t.Errorf("Name() = %v, want it to contain 'Audio Converter'", c.Name())
122+
}
123+
}
124+
125+
func TestAudioConverter_CanConvert(t *testing.T) {
126+
c := &AudioConverter{}
127+
tests := []struct {
128+
src string
129+
target string
130+
want bool
131+
}{
132+
{".mp3", ".wav", true},
133+
{".wav", ".mp3", true},
134+
{".flac", ".m4a", true},
135+
{".txt", ".mp3", false},
136+
{".mp3", ".txt", false},
137+
}
138+
139+
for _, tt := range tests {
140+
if got := c.CanConvert(tt.src, tt.target); got != tt.want {
141+
t.Errorf("CanConvert(%q, %q) = %v, want %v", tt.src, tt.target, got, tt.want)
142+
}
143+
}
144+
}
145+
146+
func TestParseAudioQuality(t *testing.T) {
147+
tests := []struct {
148+
name string
149+
opts Options
150+
want audioQuality
151+
}{
152+
{"Default", Options{}, audioQuality{bitrate: "192k", sampleRate: "44100"}},
153+
{"High", Options{"quality": "High"}, audioQuality{bitrate: "320k", sampleRate: "48000"}},
154+
{"Compact", Options{"quality": "Compact"}, audioQuality{bitrate: "128k", sampleRate: "44100"}},
155+
}
156+
157+
for _, tt := range tests {
158+
t.Run(tt.name, func(t *testing.T) {
159+
got := parseAudioQuality(tt.opts)
160+
if got != tt.want {
161+
t.Errorf("parseAudioQuality() = %v, want %v", got, tt.want)
162+
}
163+
})
164+
}
165+
}
166+
167+
func TestBuildAudioFFmpegArgs(t *testing.T) {
168+
q := audioQuality{bitrate: "192k", sampleRate: "44100"}
169+
170+
tests := []struct {
171+
name string
172+
src string
173+
target string
174+
check func([]string) bool
175+
}{
176+
{
177+
"MP3 Conversion", "input.wav", "output.mp3",
178+
func(args []string) bool {
179+
return contains(args, "-c:a", "libmp3lame")
180+
},
181+
},
182+
{
183+
"FLAC Conversion", "input.mp3", "output.flac",
184+
func(args []string) bool {
185+
return contains(args, "-c:a", "flac")
186+
},
187+
},
188+
{
189+
"WAV Conversion", "input.mp3", "output.wav",
190+
func(args []string) bool {
191+
return contains(args, "-c:a", "pcm_s16le")
192+
},
193+
},
194+
}
195+
196+
for _, tt := range tests {
197+
t.Run(tt.name, func(t *testing.T) {
198+
args := buildAudioFFmpegArgs(tt.src, tt.target, q)
199+
if !tt.check(args) {
200+
t.Errorf("buildAudioFFmpegArgs() args = %v, failed check", args)
201+
}
202+
})
203+
}
204+
}

0 commit comments

Comments
 (0)