use super::*;
use serde_json::json;
#[test]
fn help_like_payload_restores_after_narrowing_multistage_pipeline() {
let output = run_guide_pipeline(help_like_guide(), "status | ? | S name | L 1");
let rebuilt = GuideView::try_from_output_result(&output).expect("guide should still restore");
assert_eq!(rebuilt.commands.len(), 1);
assert_eq!(rebuilt.commands[0].name, "status");
assert_eq!(rebuilt.commands[0].short_help, "Show deployment status");
assert!(
rebuilt.preamble.is_empty(),
"unmatched preamble should prune"
);
assert!(rebuilt.usage.is_empty(), "unmatched usage should prune");
assert!(rebuilt.notes.is_empty(), "unmatched notes should prune");
assert!(
rebuilt.epilogue.is_empty(),
"unmatched epilogue should prune"
);
assert!(
rebuilt.options.is_empty(),
"unmatched option entries should prune"
);
assert_eq!(rebuilt.sections.len(), 0);
}
#[test]
fn help_like_payload_quick_prunes_unmatched_root_fields_for_partial_match() {
let output = run_guide_pipeline(help_like_guide(), "status | ? | L 1");
let rebuilt = GuideView::try_from_output_result(&output).expect("guide should still restore");
assert!(
rebuilt.preamble.is_empty(),
"preamble should prune when only commands matched"
);
assert!(
rebuilt.usage.is_empty(),
"usage should prune when only commands matched"
);
assert_eq!(rebuilt.commands.len(), 1);
assert_eq!(rebuilt.commands[0].name, "status");
assert_eq!(rebuilt.sections.len(), 0);
}
#[test]
fn help_like_payload_does_not_restore_after_value_extraction_pipeline() {
let output = run_guide_pipeline(
help_like_guide(),
"P commands[].name | VALUE name | S value | L 2",
);
assert!(GuideView::try_from_output_result(&output).is_none());
let OutputItems::Rows(rows) = output.items else {
panic!("expected flat value rows");
};
assert_eq!(
rows,
vec![
row(json!({"value": "apply"})),
row(json!({"value": "doctor"})),
]
);
}
#[test]
fn help_like_payload_unroll_preserves_parent_section_shell() {
let output = run_guide_pipeline(help_like_guide(), "U entries");
assert!(GuideView::try_from_output_result(&output).is_none());
let document = output
.document
.expect("semantic document should remain attached");
assert_eq!(
document.value,
json!({
"preamble": ["Deploy commands"],
"usage": ["osp deploy <COMMAND>"],
"commands": [
{"name": "apply", "short_help": "Apply pending changes"},
{"name": "doctor", "short_help": "Inspect runtime health"},
{"name": "status", "short_help": "Show deployment status"}
],
"options": [
{"name": "--verbose", "short_help": "Show additional context"},
{"name": "--json", "short_help": "Render machine-readable output"}
],
"notes": ["Run `doctor` before applying production changes."],
"sections": [
{
"title": "Commands",
"kind": "commands",
"paragraphs": ["pick one"],
"entries": {"name": "apply", "short_help": "Apply pending changes"}
},
{
"title": "Commands",
"kind": "commands",
"paragraphs": ["pick one"],
"entries": {"name": "doctor", "short_help": "Inspect runtime health"}
},
{
"title": "Commands",
"kind": "commands",
"paragraphs": ["pick one"],
"entries": {"name": "status", "short_help": "Show deployment status"}
},
{
"title": "Options",
"kind": "options",
"paragraphs": ["rendering"],
"entries": {"name": "--verbose", "short_help": "Show additional context"}
},
{
"title": "Options",
"kind": "options",
"paragraphs": ["rendering"],
"entries": {"name": "--json", "short_help": "Render machine-readable output"}
}
],
"epilogue": ["footer text"]
})
);
}
#[test]
fn help_like_payload_fuzzy_quick_restores_typo_matched_command() {
let output = run_guide_pipeline(help_like_guide(), "%docter | ? | L 1");
let rebuilt = GuideView::try_from_output_result(&output).expect("guide should still restore");
assert!(
rebuilt.commands.iter().any(|entry| entry.name == "doctor"),
"doctor should survive typo-tolerant fuzzy narrowing"
);
assert!(
rebuilt.commands.iter().all(|entry| entry.name != "apply"),
"unrelated commands should not survive the narrowed guide"
);
assert_eq!(rebuilt.preamble, vec!["Deploy commands"]);
assert_eq!(rebuilt.options.len(), 0);
}
#[test]
fn help_like_payload_keeps_render_recommendation_through_non_structural_stages() {
for pipeline in ["doctor | ? | L 1", "S name", "Y"] {
let output = run_guide_pipeline(help_like_guide(), pipeline);
assert_eq!(
output.meta.render_recommendation,
Some(osp_cli::core::output_model::RenderRecommendation::Guide),
"pipeline={pipeline}"
);
}
}
#[test]
fn help_like_payload_clears_render_recommendation_after_structural_reshapes() {
for pipeline in ["P commands[].name", "U entries", "VALUE commands[].name"] {
let output = run_guide_pipeline(help_like_guide(), pipeline);
assert_eq!(
output.meta.render_recommendation, None,
"pipeline={pipeline}"
);
}
}