c39a9ca18f
Add Scanner.ScanFiles (watcher-driven targeted scan returning changed album IDs) and a recursive fsnotify Watcher that debounces filesystem events and enriches just the affected albums inline. Pure classifyEvent/drainPending seams unit-tested; ScanFiles covered in the scanner integration test.
60 lines
1.8 KiB
Go
60 lines
1.8 KiB
Go
package library
|
|
|
|
import (
|
|
"sort"
|
|
"testing"
|
|
|
|
"github.com/fsnotify/fsnotify"
|
|
)
|
|
|
|
func TestClassifyEvent(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
op fsnotify.Op
|
|
isDir bool
|
|
isAudio bool
|
|
want watchAction
|
|
}{
|
|
{"create audio file enqueues", fsnotify.Create, false, true, watchEnqueueFile},
|
|
{"write audio file enqueues", fsnotify.Write, false, true, watchEnqueueFile},
|
|
{"create non-audio file ignored", fsnotify.Create, false, false, watchIgnore},
|
|
{"create directory scans it", fsnotify.Create, true, false, watchScanDir},
|
|
{"write on directory ignored", fsnotify.Write, true, false, watchIgnore},
|
|
{"remove audio file ignored (no pruning)", fsnotify.Remove, false, true, watchIgnore},
|
|
{"rename audio file ignored", fsnotify.Rename, false, true, watchIgnore},
|
|
{"chmod audio file ignored", fsnotify.Chmod, false, true, watchIgnore},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := classifyEvent(tt.op, tt.isDir, tt.isAudio); got != tt.want {
|
|
t.Fatalf("classifyEvent(%v, dir=%v, audio=%v) = %v, want %v",
|
|
tt.op, tt.isDir, tt.isAudio, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDrainPending(t *testing.T) {
|
|
t.Run("empty set returns nil", func(t *testing.T) {
|
|
if got := drainPending(map[string]struct{}{}); got != nil {
|
|
t.Fatalf("drainPending(empty) = %v, want nil", got)
|
|
}
|
|
})
|
|
|
|
t.Run("returns paths and clears the set", func(t *testing.T) {
|
|
pending := map[string]struct{}{
|
|
"/music/a.mp3": {},
|
|
"/music/b.flac": {},
|
|
}
|
|
got := drainPending(pending)
|
|
sort.Strings(got)
|
|
want := []string{"/music/a.mp3", "/music/b.flac"}
|
|
if len(got) != len(want) || got[0] != want[0] || got[1] != want[1] {
|
|
t.Fatalf("drainPending = %v, want %v", got, want)
|
|
}
|
|
if len(pending) != 0 {
|
|
t.Fatalf("pending not cleared: %v", pending)
|
|
}
|
|
})
|
|
}
|