Revert "[test] add tests for --no-interaction and its alias to ensure non-interactive mode skips prompts and uses defaults"

This reverts commit b7f0ddda37.
This commit is contained in:
2025-08-12 06:00:09 +02:00
parent b9308be930
commit 9d12507cf5
5 changed files with 7 additions and 114 deletions

View File

@@ -36,17 +36,7 @@ pub fn set_no_interaction(b: bool) {
}
/// Return current non-interactive state.
pub fn is_no_interaction() -> bool {
if NO_INTERACTION.load(Ordering::Relaxed) {
return true;
}
// Also honor NO_INTERACTION=1/true environment variable for convenience/testing
match std::env::var("NO_INTERACTION") {
Ok(v) => {
let v = v.trim();
v == "1" || v.eq_ignore_ascii_case("true")
}
Err(_) => false,
}
NO_INTERACTION.load(Ordering::Relaxed)
}
/// Set verbose level (0 = normal, 1 = verbose, 2 = super-verbose)
@@ -648,13 +638,8 @@ where
}
// Print a blank line before the selection prompt to keep output synchronized.
printer("");
let idx = if crate::is_no_interaction() || !crate::stdin_is_tty() {
// Non-interactive: auto-select the first candidate deterministically (as listed)
0
} else {
crate::ui::prompt_select_index("Select a Whisper model", &display_names)
.context("Failed to read selection")?
};
let idx = crate::ui::prompt_select_index("Select a Whisper model", &display_names)
.context("Failed to read selection")?;
let chosen = candidates.swap_remove(idx);
let _ = std::fs::write(models_dir.join(".last_model"), chosen.display().to_string());
// Print an empty line after selection input

View File

@@ -67,8 +67,7 @@ struct Args {
quiet: bool,
/// Non-interactive mode: never prompt; use defaults instead.
/// Deprecated alias supported: --no-interation (typo)
#[arg(long = "no-interaction", alias = "no-interation", global = true)]
#[arg(long = "no-interaction", global = true)]
no_interaction: bool,
/// Disable progress bars (also respects NO_PROGRESS=1). Progress bars render on stderr only when attached to a TTY.
@@ -504,17 +503,14 @@ fn run() -> Result<()> {
if let Some(out) = &args.output {
// Merge target: either only merged, or merged plus separate
let outp = PathBuf::from(out);
// Ensure target directory exists appropriately for the chosen mode
if let Some(parent) = outp.parent() { create_dir_all(parent).ok(); }
// Name: <date>_out or <date>_merged depending on flag
if args.merge_and_separate {
// When writing inside an output directory, create it directly
create_dir_all(&outp).ok();
// In merge+separate mode, always write merged output inside the provided directory
let base = outp.join(format!("{}_merged", polyscribe::date_prefix()));
let base = PathBuf::from(out).join(format!("{}_merged", polyscribe::date_prefix()));
let root = OutputRoot { items: merged_items.clone() };
write_outputs(&base, &root, &out_formats)?;
} else {
// For single merged file, ensure the parent dir exists
if let Some(parent) = outp.parent() { create_dir_all(parent).ok(); }
let base = outp.with_file_name(format!("{}_{}", polyscribe::date_prefix(), outp.file_name().and_then(|s| s.to_str()).unwrap_or("out")));
let root = OutputRoot { items: merged_items.clone() };
write_outputs(&base, &root, &out_formats)?;
@@ -919,26 +915,4 @@ mod tests {
std_env::remove_var("POLYSCRIBE_TEST_FORCE_VULKAN");
}
}
#[test]
fn test_no_interaction_disables_speaker_prompt() {
use polyscribe::ui;
// Ensure non-interactive via env and global flag
unsafe {
std_env::set_var("NO_INTERACTION", "1");
}
polyscribe::set_no_interaction(true);
ui::testing_reset_prompt_call_counters();
// Build a minimal progress manager
let pf = polyscribe::progress::ProgressFactory::from_config(&polyscribe::Config::default());
let pm = pf.make_manager(polyscribe::progress::ProgressMode::Single);
let dummy = std::path::PathBuf::from("example.wav");
let got = super::prompt_speaker_name_for_path(&dummy, "DefaultSpeaker", /*enabled:*/ true, &pm);
assert_eq!(got, "DefaultSpeaker");
assert_eq!(ui::testing_prompt_call_count(), 0, "no prompt functions should be called when NO_INTERACTION=1");
// Cleanup
unsafe {
std_env::remove_var("NO_INTERACTION");
}
}
}

View File

@@ -1135,7 +1135,6 @@ mod tests {
#[test]
fn test_format_model_list_spacing_and_structure() {
use std::env as std_env;
let models = vec![
ModelEntry {
name: "tiny.en-q5_1".to_string(),
@@ -1376,22 +1375,6 @@ mod tests {
}
}
#[test]
fn test_no_interaction_models_downloader_skips_prompts() {
// Force non-interactive; verify that no UI prompt functions are invoked
unsafe { std::env::set_var("NO_INTERACTION", "1"); }
crate::set_no_interaction(true);
crate::ui::testing_reset_prompt_call_counters();
let models = vec![
ModelEntry { name: "tiny.en-q5_1".to_string(), base: "tiny".to_string(), subtype: "en-q5_1".to_string(), size: 1024, sha256: None, repo: "ggerganov/whisper.cpp".to_string() },
ModelEntry { name: "tiny-q5_1".to_string(), base: "tiny".to_string(), subtype: "q5_1".to_string(), size: 2048, sha256: None, repo: "ggerganov/whisper.cpp".to_string() },
];
let picked = super::prompt_select_models_two_stage(&models).unwrap();
assert!(picked.is_empty(), "non-interactive should not select any models by default");
assert_eq!(crate::ui::testing_prompt_call_count(), 0, "no prompt functions should be called in non-interactive mode");
unsafe { std::env::remove_var("NO_INTERACTION"); }
}
#[test]
fn test_wrong_hash_deletes_temp_and_errors() {
use std::sync::{Mutex, OnceLock};

View File

@@ -4,24 +4,6 @@
// If you need a new prompt type, add it here so callers don't depend on a specific library.
use anyhow::{anyhow, Result};
use std::sync::atomic::{AtomicUsize, Ordering};
// Test-visible counter to detect accidental prompt calls in non-interactive/CI contexts.
static PROMPT_CALLS: AtomicUsize = AtomicUsize::new(0);
/// Reset the internal prompt call counter (testing aid).
pub fn testing_reset_prompt_call_counters() {
PROMPT_CALLS.store(0, Ordering::Relaxed);
}
/// Get current prompt call count (testing aid).
pub fn testing_prompt_call_count() -> usize {
PROMPT_CALLS.load(Ordering::Relaxed)
}
fn note_prompt_call() {
PROMPT_CALLS.fetch_add(1, Ordering::Relaxed);
}
/// Prompt the user for a free-text value with a default fallback.
///
@@ -30,7 +12,6 @@ fn note_prompt_call() {
/// - On any prompt error (e.g., non-TTY, read error), returns an error; callers should
/// handle it and typically fall back to `default` in non-interactive contexts.
pub fn prompt_text(prompt: &str, default: &str) -> Result<String> {
note_prompt_call();
let res: Result<String, _> = cliclack::input(prompt)
.default_input(default)
.interact();
@@ -48,7 +29,6 @@ pub fn prompt_text(prompt: &str, default: &str) -> Result<String> {
///
/// Returns the selected boolean. Any underlying prompt error is returned as an error.
pub fn prompt_confirm(prompt: &str, default: bool) -> Result<bool> {
note_prompt_call();
let res: Result<bool, _> = cliclack::confirm(prompt)
.initial_value(default)
.interact();
@@ -63,7 +43,6 @@ pub fn prompt_select_index<T: std::fmt::Display>(prompt: &str, items: &[T]) -> R
if items.is_empty() {
return Err(anyhow!("prompt_select_index called with empty items"));
}
note_prompt_call();
let mut sel = cliclack::select(prompt);
for (i, it) in items.iter().enumerate() {
sel = sel.item(i, format!("{}", it), "");
@@ -95,7 +74,6 @@ pub fn prompt_multiselect_indices<T: std::fmt::Display>(
for (i, it) in items.iter().enumerate() {
ms = ms.item(i, format!("{}", it), "");
}
note_prompt_call();
let indices: Vec<usize> = ms
.initial_values(defaults.to_vec())
.required(false)

View File

@@ -950,30 +950,3 @@ fn out_format_multiple_json_and_srt() {
}
*/
#[test]
fn cli_no_interation_alias_skips_speaker_prompts_and_uses_defaults() {
let exe = env!("CARGO_BIN_EXE_polyscribe");
let input1 = manifest_path("input/1-s0wlz.json");
let input2 = manifest_path("input/2-vikingowl.json");
let output = Command::new(exe)
.arg(input1.as_os_str())
.arg(input2.as_os_str())
.arg("-m")
.arg("--set-speaker-names")
.arg("--no-interation")
.output()
.expect("failed to spawn polyscribe");
assert!(output.status.success(), "CLI did not exit successfully");
let stdout = String::from_utf8(output.stdout).expect("stdout not UTF-8");
let root: OutputRoot = serde_json::from_str(&stdout).unwrap();
let speakers: std::collections::HashSet<String> =
root.items.into_iter().map(|e| e.speaker).collect();
assert!(speakers.contains("s0wlz"), "default s0wlz not used (alias)");
assert!(speakers.contains("vikingowl"), "default vikingowl not used (alias)");
}