diff --git a/internal/app/transcode_test.go b/internal/app/transcode_test.go new file mode 100644 index 0000000..1669012 --- /dev/null +++ b/internal/app/transcode_test.go @@ -0,0 +1,66 @@ +package app + +import ( + "os" + "os/exec" + "path/filepath" + "testing" +) + +func TestFFmpegArgs(t *testing.T) { + args := ffmpegArgs("/in/a.flac", "/out/a.mp3", "128k", "Neon Rain", "AI Radio") + joined := "" + for _, a := range args { + joined += a + " " + } + for _, want := range []string{ + "-i /in/a.flac", + "libmp3lame", + "-b:a 128k", + "-ar 44100", + "-ac 2", + "-id3v2_version 3", + "-write_id3v1 1", + "-metadata title=Neon Rain", + "-metadata album=AI Radio", + "/out/a.mp3", + } { + if !contains(joined, want) { + t.Fatalf("args missing %q:\n%s", want, joined) + } + } +} + +func contains(hay, needle string) bool { + return len(hay) >= len(needle) && (func() bool { + for i := 0; i+len(needle) <= len(hay); i++ { + if hay[i:i+len(needle)] == needle { + return true + } + } + return false + })() +} + +// TestTranscodeReal actually runs ffmpeg if present; skips otherwise. +func TestTranscodeReal(t *testing.T) { + if _, err := exec.LookPath("ffmpeg"); err != nil { + t.Skip("ffmpeg not installed") + } + dir := t.TempDir() + src := filepath.Join(dir, "s.flac") + // generate a 1s sine flac + cmd := exec.Command("ffmpeg", "-y", "-hide_banner", "-loglevel", "error", + "-f", "lavfi", "-i", "sine=frequency=440:duration=1", "-c:a", "flac", src) + if err := cmd.Run(); err != nil { + t.Fatalf("fixture gen: %v", err) + } + dst := filepath.Join(dir, "s.mp3") + if err := Transcode(src, dst, "128k", "Test", "Station"); err != nil { + t.Fatalf("Transcode: %v", err) + } + st, err := os.Stat(dst) + if err != nil || st.Size() == 0 { + t.Fatal("mp3 not produced") + } +}