use std::fs;
use super::common::hyalo_no_hints;
use tempfile::TempDir;
#[test]
fn short_help_is_compact() {
let output = hyalo_no_hints().arg("-h").output().unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("Usage: hyalo"));
assert!(stdout.contains("Commands:"));
assert!(stdout.contains("Options:"));
assert!(stdout.contains("EXAMPLES:"));
assert!(
!stdout.contains("COMMAND REFERENCE:"),
"-h must not include COMMAND REFERENCE"
);
assert!(
!stdout.contains("COOKBOOK:"),
"-h must not include COOKBOOK"
);
assert!(
!stdout.contains("OUTPUT SHAPES"),
"-h must not include OUTPUT SHAPES"
);
}
#[test]
fn long_help_contains_enriched_sections() {
let output = hyalo_no_hints().arg("--help").output().unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(
stdout.contains("COMMAND REFERENCE:"),
"--help must include COMMAND REFERENCE"
);
assert!(stdout.contains("COOKBOOK:"), "--help must include COOKBOOK");
assert!(
stdout.contains("OUTPUT SHAPES"),
"--help must include OUTPUT SHAPES"
);
}
#[test]
fn long_help_command_reference_lists_all_commands() {
let output = hyalo_no_hints().arg("--help").output().unwrap();
let stdout = String::from_utf8(output.stdout).unwrap();
let expected = [
"hyalo find",
"hyalo read",
"hyalo set",
"hyalo remove",
"hyalo append",
"hyalo properties",
"hyalo tags",
"hyalo summary",
"hyalo task read",
"hyalo task toggle",
"hyalo task set",
"hyalo init",
"hyalo deinit",
"hyalo views list",
"hyalo views set",
"hyalo views remove",
];
for cmd in expected {
assert!(stdout.contains(cmd), "COMMAND REFERENCE missing: {cmd}");
}
}
#[test]
fn subcommand_help_unchanged_by_enriched_root() {
let output = hyalo_no_hints().args(["task", "--help"]).output().unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(
stdout.contains("Read, toggle, or set status on task checkboxes"),
"subcommand --help should contain its own long_about"
);
assert!(
!stdout.contains("COMMAND REFERENCE:"),
"subcommand --help must not include root COMMAND REFERENCE"
);
assert!(
!stdout.contains("COOKBOOK:"),
"subcommand --help must not include root COOKBOOK"
);
}
fn options_block(help: &str) -> &str {
let start = help
.find("\nOptions:\n")
.expect("no Options: block in help");
let start = start + 1;
let end = help[start..]
.find("\n\n")
.map_or(help.len(), |off| start + off);
&help[start..end]
}
#[test]
fn help_hides_dir_when_config_sets_it() {
let tmp = TempDir::new().unwrap();
fs::write(tmp.path().join(".hyalo.toml"), "dir = \"notes\"\n").unwrap();
let output = hyalo_no_hints()
.arg("--help")
.current_dir(tmp.path())
.output()
.unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let opts = options_block(&stdout);
assert!(
!opts.contains("--dir"),
"--dir should be hidden in Options: when config sets dir:\n{opts}"
);
}
#[test]
fn help_hides_format_when_config_sets_it() {
let tmp = TempDir::new().unwrap();
fs::write(tmp.path().join(".hyalo.toml"), "format = \"text\"\n").unwrap();
let output = hyalo_no_hints()
.arg("--help")
.current_dir(tmp.path())
.output()
.unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let opts = options_block(&stdout);
assert!(
!opts.contains("--format"),
"--format should be hidden in Options: when config sets format:\n{opts}"
);
}
#[test]
fn help_shows_dir_without_config() {
let tmp = TempDir::new().unwrap();
let output = hyalo_no_hints()
.arg("--help")
.current_dir(tmp.path())
.output()
.unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let opts = options_block(&stdout);
assert!(
opts.contains("--dir"),
"--dir should be visible in Options: when no config is present:\n{opts}"
);
}
fn examples_block(help: &str) -> &str {
let start = help.find("EXAMPLES:").expect("no EXAMPLES: block in help");
&help[start..]
}
fn cookbook_block(help: &str) -> &str {
let start = help.find("COOKBOOK:").expect("no COOKBOOK: block in help");
let slice = &help[start..];
if let Some(end_offset) = slice.find("\nOUTPUT SHAPES") {
&slice[..end_offset]
} else {
slice
}
}
#[test]
fn examples_omit_format_when_config_sets_it() {
let tmp = TempDir::new().unwrap();
fs::write(tmp.path().join(".hyalo.toml"), "format = \"text\"\n").unwrap();
let output = hyalo_no_hints()
.arg("-h")
.current_dir(tmp.path())
.output()
.unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let examples = examples_block(&stdout);
assert!(
!examples.contains("--format"),
"EXAMPLES should omit --format when config sets format:\n{examples}"
);
}
#[test]
fn examples_show_format_without_config() {
let tmp = TempDir::new().unwrap();
let output = hyalo_no_hints()
.arg("-h")
.current_dir(tmp.path())
.output()
.unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let examples = examples_block(&stdout);
assert!(
examples.contains("--format"),
"EXAMPLES should show --format when no config is present:\n{examples}"
);
}
#[test]
fn cookbook_omits_format_when_config_sets_it() {
let tmp = TempDir::new().unwrap();
fs::write(tmp.path().join(".hyalo.toml"), "format = \"text\"\n").unwrap();
let output = hyalo_no_hints()
.arg("--help")
.current_dir(tmp.path())
.output()
.unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let cookbook = cookbook_block(&stdout);
assert!(
!cookbook.contains("--format"),
"COOKBOOK should omit --format when config sets format:\n{cookbook}"
);
}
#[test]
fn cookbook_shows_format_without_config() {
let tmp = TempDir::new().unwrap();
let output = hyalo_no_hints()
.arg("--help")
.current_dir(tmp.path())
.output()
.unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let cookbook = cookbook_block(&stdout);
assert!(
cookbook.contains("--format"),
"COOKBOOK should show --format when no config is present:\n{cookbook}"
);
}
fn global_flags_block(help: &str) -> &str {
let start = help
.find("Global flags (apply to all commands):")
.expect("no 'Global flags' section in --help");
let slice = &help[start..];
if let Some(end_offset) = slice.find("\n\n") {
&slice[..end_offset]
} else {
slice
}
}
#[test]
fn command_reference_omits_dir_flag_when_config_sets_it() {
let tmp = TempDir::new().unwrap();
fs::write(tmp.path().join(".hyalo.toml"), "dir = \"notes\"\n").unwrap();
let output = hyalo_no_hints()
.arg("--help")
.current_dir(tmp.path())
.output()
.unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let flags = global_flags_block(&stdout);
assert!(
!flags.contains("-d/--dir"),
"Global flags table should omit -d/--dir when config sets dir:\n{flags}"
);
}
#[test]
fn command_reference_shows_dir_flag_without_config() {
let tmp = TempDir::new().unwrap();
let output = hyalo_no_hints()
.arg("--help")
.current_dir(tmp.path())
.output()
.unwrap();
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let flags = global_flags_block(&stdout);
assert!(
flags.contains("-d/--dir"),
"Global flags table should show -d/--dir when no config is present:\n{flags}"
);
}