mod common;
use std::fs;
use 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-status",
"hyalo init",
];
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 a single task"),
"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}"
);
}