diff options
| -rw-r--r-- | src/sound.rs | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/sound.rs b/src/sound.rs index d1b4fc90..b8870b8b 100644 --- a/src/sound.rs +++ b/src/sound.rs @@ -167,8 +167,18 @@ if ($script:timedOut) { throw 'sound playback timed out' } "# } +/// Builds the same player script with a shorter timer for tests. Production +/// keeps the fixed 15 second bound in `windows_media_player_script`. +#[cfg(test)] +fn windows_media_player_script_with_timeout(timeout_seconds: u64) -> String { + windows_media_player_script().replace( + "FromSeconds(15)", + &format!("FromSeconds({timeout_seconds})"), + ) +} + #[cfg(any(windows, test))] -fn windows_player_command(path: &Path) -> Command { +fn windows_player_command(path: &Path, script: &str) -> Command { let mut command = crate::noninteractive_process::command("powershell.exe"); command .args([ @@ -178,7 +188,7 @@ fn windows_player_command(path: &Path) -> Command { "-ExecutionPolicy", "Bypass", "-Command", - windows_media_player_script(), + script, ]) .env(WINDOWS_SOUND_PATH_ENV, path); command @@ -186,7 +196,7 @@ fn windows_player_command(path: &Path) -> Command { #[cfg(windows)] fn run_windows_player(path: &Path) -> Result<Output, String> { - windows_player_command(path) + windows_player_command(path, windows_media_player_script()) .output() .map_err(|e| format!("Windows MediaPlayer playback failed: {e}")) } @@ -430,7 +440,7 @@ mod tests { fn windows_media_player_uses_process_environment_and_dispatcher() { let script = windows_media_player_script(); let path = Path::new(r"C:\sound dir\döne.mp3"); - let command = windows_player_command(path); + let command = windows_player_command(path, script); let env_path = command.get_envs().find_map(|(key, value)| { (key == std::ffi::OsStr::new(WINDOWS_SOUND_PATH_ENV)) .then_some(value) @@ -443,23 +453,30 @@ mod tests { assert!(script.contains("Dispatcher]::PushFrame")); assert!(script.contains("add_MediaEnded")); assert!(script.contains("add_MediaFailed")); + assert!(script.contains("FromSeconds(15)")); + assert!(windows_media_player_script_with_timeout(2).contains("FromSeconds(2)")); assert_eq!(env_path, Some(path.as_os_str())); assert!(!command.get_args().any(|arg| arg == path.as_os_str())); } #[cfg(windows)] #[test] - fn windows_media_player_reports_invalid_media_without_waiting_for_timeout() { + fn windows_media_player_reports_invalid_media() { let _lock = crate::integration::integration_env_lock(); let path = temp_sound_path(); std::fs::write(&path, b"not an mp3").unwrap(); - let output = run_windows_player(&path).unwrap(); + let script = windows_media_player_script_with_timeout(2); + // Whether the host media stack raises MediaFailed before the playback + // timeout is environment-dependent, so use a short test-only timer and + // accept either terminal error instead of the production 15 second wait. + let output = windows_player_command(&path, &script).output().unwrap(); let _ = std::fs::remove_file(path); assert!(!output.status.success()); + let stderr = String::from_utf8_lossy(&output.stderr); assert!( - String::from_utf8_lossy(&output.stderr).contains("sound media failed"), - "stderr should identify a MediaFailed error" + stderr.contains("sound media failed") || stderr.contains("sound playback timed out"), + "stderr should report why playback stopped: {stderr}" ); } } |
