aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/sound.rs33
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}"
);
}
}