play_test.go (1606B)
1 package test 2 3 import ( 4 "testing" 5 "time" 6 7 "git.sr.ht/~jackmordaunt/nativeaudio/play" 8 ) 9 10 // TestPlayTwice plays one second of silence twice in the same process. 11 // 12 // Each call must take at least the file's duration: returning early means 13 // the tail of the audio was cut off. The second call must succeed at all: 14 // the playback context is process-wide and used to be re-created per call, 15 // which the audio backend refuses. 16 // 17 // Playback goes through oto on every platform, so this test is not 18 // platform-specific. It skips when no audio output is available. 19 func TestPlayTwice(t *testing.T) { 20 const seconds = 1 21 path := writeTemp(t, "silence.wav", silentWAV(44100, 2, seconds)) 22 for i := 1; i <= 2; i++ { 23 start := time.Now() 24 err := play.File(path) 25 elapsed := time.Since(start) 26 if err != nil { 27 // The first call doubles as the availability probe. CI 28 // runners have no sound hardware and each backend reports 29 // that differently, so any first-call failure is treated as 30 // "no audio here" rather than a bug. A second-call failure 31 // is the regression this test exists to catch, so it is 32 // always fatal. 33 if i == 1 { 34 t.Skipf("no audio output available: %v", err) 35 } 36 t.Fatalf("play %d: %v", i, err) 37 } 38 t.Logf("play %d took %v", i, elapsed.Round(time.Millisecond)) 39 if min := time.Duration(seconds) * time.Second * 9 / 10; elapsed < min { 40 t.Errorf("play %d returned after %v, want at least %v: audio tail was cut off", i, elapsed, min) 41 } 42 if max := 10 * time.Second; elapsed > max { 43 t.Errorf("play %d took %v, want under %v", i, elapsed, max) 44 } 45 } 46 }