Files
akai-utils/extract_test.go
T
david 120993fb02 test: add comprehensive test suite - 5 test files, 65% coverage
- cli_test.go: 10 tests for list/search/extract/download commands
- serve_test.go: 11 tests for HTTP handlers and SSE progress
- http_test.go: 5 subtests for archive.org API
- download_test.go: 10 tests for download logic
- util_test.go: 7 tests for string/util helpers

Error paths covered: server errors, empty results, download failures,
extract failures, missing identifiers, ReadDir errors.

golangci-lint: 0 issues, go vet: clean
2026-06-21 23:54:57 -07:00

371 lines
8.1 KiB
Go

package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"testing"
)
func TestExtractISO_SkipsExistingWAVs(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
called := false
runAkaiutil = func(isoPath, commands string) (string, error) {
called = true
return "", nil
}
tmp := t.TempDir()
isoOutDir := filepath.Join(tmp, sanitiseISOName(filepath.Base("/fake/test.iso")))
if err := os.MkdirAll(isoOutDir, 0755); err != nil {
t.Fatal(err)
}
for _, name := range []string{"kick.wav", "snare.wav", "hihat.wav"} {
fd, err := os.Create(filepath.Join(isoOutDir, name))
if err != nil {
t.Fatal(err)
}
defer func() { _ = fd.Close() }()
}
result, err := extractISO("/fake/test.iso", tmp)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if called {
t.Fatal("runAkaiutil should not have been called for existing WAVs")
}
if result == "" {
t.Fatal("expected non-empty result")
}
}
func TestExtractISO_ProceedsWhenNoWAVs(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
calls := 0
runAkaiutil = func(isoPath, commands string) (string, error) {
calls++
if commands == "df\nq\n" {
return `
Disk /disk0
A - S1000 HD (3840 blocks)
`, nil
}
return ` exported 3 file(s)
`, nil
}
tmp := t.TempDir()
result, err := extractISO("/fake/test.iso", tmp)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if calls == 0 {
t.Fatal("runAkaiutil should have been called")
}
if result == "" {
t.Fatal("expected non-empty result")
}
}
func TestListPartitions(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
runAkaiutil = func(isoPath, commands string) (string, error) {
if commands != "df\nq\n" {
t.Fatalf("unexpected commands: %q", commands)
}
return `
Disk /disk0
Total blocks: 12288 (8 KB each) 98304 KB
Partition table:
A - S1000 HD (3840 blocks)
B - S1000 HD (5120 blocks)
C - S1000 HD (3328 blocks)
`, nil
}
parts, err := listPartitions("/fake/disk.iso")
if err != nil {
t.Fatal(err)
}
if len(parts) != 3 {
t.Fatalf("expected 3 partitions, got %d: %v", len(parts), parts)
}
if parts[0] != "A" || parts[1] != "B" || parts[2] != "C" {
t.Fatalf("unexpected partitions: %v", parts)
}
}
func TestListPartitionsEmpty(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
runAkaiutil = func(isoPath, commands string) (string, error) {
return "No partitions found\n", nil
}
parts, err := listPartitions("/fake/disk.iso")
if err != nil {
t.Fatal(err)
}
if len(parts) != 1 || parts[0] != "A" {
t.Fatalf("expected fallback to [A], got %v", parts)
}
}
func TestListVolumes(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
runAkaiutil = func(isoPath, commands string) (string, error) {
return `
/disk0/A > cd /disk0/A
/disk0/A > dir
1 DRUM KIT 1 - VOLUME (10 files)
2 BASS SAMPLES - VOLUME (5 files)
/disk0/A > cd /disk0/B
/disk0/B > dir
3 SYNTH PADS - VOLUME (20 files)
/disk0/B >
`, nil
}
vols, err := listVolumes("/fake/disk.iso", []string{"A", "B"})
if err != nil {
t.Fatal(err)
}
if len(vols) != 3 {
t.Fatalf("expected 3 volumes, got %d: %v", len(vols), vols)
}
if vols[0].Part != "A" || vols[0].Name != "DRUM KIT 1" {
t.Fatalf("unexpected vol 0: %+v", vols[0])
}
if vols[1].Part != "A" || vols[1].Name != "BASS SAMPLES" {
t.Fatalf("unexpected vol 1: %+v", vols[1])
}
if vols[2].Part != "B" || vols[2].Name != "SYNTH PADS" {
t.Fatalf("unexpected vol 2: %+v", vols[2])
}
}
func TestRunExtractionCount(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
calls := 0
runAkaiutil = func(isoPath, commands string) (string, error) {
calls++
return `
exported 10 file(s)
exported 5 file(s)
exported 0 file(s)
`, nil
}
vols := []volInfo{
{Part: "A", Name: "DRUMS"},
{Part: "A", Name: "BASS"},
}
total, err := runExtraction("/fake/disk.iso", "/tmp/out", vols)
if err != nil {
t.Fatal(err)
}
if total != 15 {
t.Fatalf("expected 15 total WAVs, got %d", total)
}
if calls != 1 {
t.Fatalf("expected 1 akaiutil call, got %d", calls)
}
}
func TestExtractWAVs_Success(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
callCount := 0
runAkaiutil = func(isoPath, commands string) (string, error) {
callCount++
if callCount == 1 {
if commands != "df\nq\n" {
t.Fatalf("first call: expected df\\q\\n, got %q", commands)
}
return `
Disk /disk0
A - S1000 HD (3840 blocks)
`, nil
}
if callCount == 2 {
return `
/disk0/A > cd /disk0/A
/disk0/A > dir
1 DRUMS - VOLUME (10 files)
/disk0/A > q
`, nil
}
if callCount == 3 {
return ` exported 10 file(s)
`, nil
}
t.Fatalf("unexpected call #%d with commands: %q", callCount, commands)
return "", nil
}
tmp := t.TempDir()
total, err := extractWAVs("/fake/test.iso", tmp)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if total != 10 {
t.Fatalf("expected 10 WAVs, got %d", total)
}
if callCount != 3 {
t.Fatalf("expected 3 akaiutil calls, got %d", callCount)
}
}
func TestExtractWAVs_MultipleVolumes(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
calls := 0
runAkaiutil = func(isoPath, commands string) (string, error) {
calls++
if calls == 1 {
return `
Disk /disk0
A - S1000 HD (3840 blocks)
B - S1000 HD (5120 blocks)
`, nil
}
if calls == 2 {
return `
/disk0/A > cd /disk0/A
1 VOL_A - VOLUME (5 files)
/disk0/B > cd /disk0/B
2 VOL_B - VOLUME (8 files)
`, nil
}
return ` exported 5 file(s)
exported 8 file(s)
`, nil
}
tmp := t.TempDir()
total, err := extractWAVs("/fake/multivol.iso", tmp)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if total != 13 {
t.Fatalf("expected 13 WAVs, got %d", total)
}
if calls != 3 {
t.Fatalf("expected 3 calls, got %d", calls)
}
}
func TestExtractWAVs_NoVolumes(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
calls := 0
runAkaiutil = func(isoPath, commands string) (string, error) {
calls++
if calls == 1 {
return `Disk /disk0
A - S1000 HD (3840 blocks)
`, nil
}
if calls == 2 {
return `/disk0/A > cd /disk0/A
/disk0/A > q
`, nil
}
return ` exported 0 file(s)
`, nil
}
tmp := t.TempDir()
total, err := extractWAVs("/fake/empty.iso", tmp)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if total != 0 {
t.Fatalf("expected 0 WAVs, got %d", total)
}
}
func TestExtractWAVs_ErrorInPartitionList(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
runAkaiutil = func(isoPath, commands string) (string, error) {
return "", fmt.Errorf("simulated partition error")
}
tmp := t.TempDir()
_, err := extractWAVs("/fake/error.iso", tmp)
if err == nil {
t.Fatal("expected error, got nil")
}
}
func TestExtractWAVs_ErrorInVolumeList(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
calls := 0
runAkaiutil = func(isoPath, commands string) (string, error) {
calls++
if calls == 1 {
return `
Disk /disk0
A - S1000 HD (3840 blocks)
`, nil
}
return "", fmt.Errorf("simulated volume list error")
}
tmp := t.TempDir()
_, err := extractWAVs("/fake/error.iso", tmp)
if err == nil {
t.Fatal("expected error, got nil")
}
}
func TestRunExtraction_CreatesVolumeDirs(t *testing.T) {
orig := runAkaiutil
defer func() { runAkaiutil = orig }()
created := map[string]bool{}
runAkaiutil = func(isoPath, commands string) (string, error) {
for _, line := range strings.Split(commands, "\n") {
if strings.HasPrefix(line, "lcd ") {
dir := strings.TrimPrefix(line, "lcd ")
created[dir] = true
}
}
return ` exported 3 file(s)
`, nil
}
tmp := t.TempDir()
vols := []volInfo{
{Part: "A", Name: "Test Volume One"},
}
baseDir := filepath.Join(tmp, "output")
_, err := runExtraction("/fake/test.iso", baseDir, vols)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if !created["/"] {
t.Error("expected lcd / to be in commands")
}
}