Files
yellowjacket/backend/metadata/mp3duration_test.go
T
yonlu 81793975b4 improved library scan speeds, added library manager component
-libraries tab now opens a library manager
-choose library directory, manually soft scan and rescan
-batched db queues
-mp3 header-based duration extraction
2026-02-19 10:17:09 -05:00

118 lines
2.4 KiB
Go

package metadata
import (
"os"
"path/filepath"
"testing"
)
// testMP3Files returns the paths to all .mp3 files in the test_data
// directory. It skips the test if none are found.
func testMP3Files(t *testing.T) []string {
t.Helper()
root := filepath.Join("..", "..", "test_data")
var files []string
err := filepath.Walk(root, func(
path string, info os.FileInfo, err error,
) error {
if err != nil {
return err
}
if !info.IsDir() && filepath.Ext(path) == ".mp3" {
files = append(files, path)
}
return nil
})
if err != nil {
t.Fatalf("walking test_data: %v", err)
}
if len(files) == 0 {
t.Skip("no .mp3 test fixtures found in test_data/")
}
return files
}
// TestGetMP3Duration_MatchesBeepDecode verifies that the fast
// header-only parser produces a duration within 1 second of the
// full decode via beep, for every test MP3 file.
func TestGetMP3Duration_MatchesBeepDecode(t *testing.T) {
for _, path := range testMP3Files(t) {
t.Run(filepath.Base(path), func(t *testing.T) {
// Reference value: full beep decode.
refMS, err := GetTrackLengthMillis(path)
if err != nil {
t.Fatalf(
"beep decode failed: %v", err,
)
}
// Fast path.
f, err := os.Open(path)
if err != nil {
t.Fatalf("open: %v", err)
}
defer func() { _ = f.Close() }()
fastMS, err := getMP3Duration(f)
if err != nil {
t.Fatalf(
"getMP3Duration failed: %v", err,
)
}
diffMS := refMS - fastMS
if diffMS < 0 {
diffMS = -diffMS
}
// Allow up to 1 second of difference to account
// for rounding and the slight inaccuracy of the
// CBR fallback for VBR-without-Xing files.
const toleranceMS = 1000
t.Logf(
"beep=%dms fast=%dms diff=%dms",
refMS, fastMS, diffMS,
)
if diffMS > toleranceMS {
t.Errorf(
"duration mismatch: beep=%dms fast=%dms "+
"(diff %dms exceeds %dms tolerance)",
refMS, fastMS, diffMS, toleranceMS,
)
}
})
}
}
// TestGetMP3Duration_BasicParsing exercises the parser on a single
// file and verifies a positive duration is returned.
func TestGetMP3Duration_BasicParsing(t *testing.T) {
files := testMP3Files(t)
f, err := os.Open(files[0])
if err != nil {
t.Fatalf("open: %v", err)
}
defer func() { _ = f.Close() }()
ms, err := getMP3Duration(f)
if err != nil {
t.Fatalf("getMP3Duration: %v", err)
}
if ms <= 0 {
t.Errorf("expected positive duration, got %d", ms)
}
}