use slash_lang::parser::ast::{Op, Priority, Urgency};
use slash_lang::parser::parse;
#[test]
fn parses_pipelines_and_ops() {
let input = "/A!! | /b && /c || /d";
let ast = parse(input).expect("parse should succeed");
assert_eq!(ast.pipelines.len(), 3);
}
#[test]
fn rejects_redirection_mid_pipeline() {
let input = "/a > out | /b";
assert!(parse(input).is_err());
}
#[test]
fn pipeline_operators_are_set_correctly() {
let prog = parse("/a && /b || /c").unwrap();
assert_eq!(prog.pipelines.len(), 3);
assert_eq!(prog.pipelines[0].operator, Some(Op::And));
assert_eq!(prog.pipelines[1].operator, Some(Op::Or));
assert!(prog.pipelines[2].operator.is_none());
}
#[test]
fn pipe_operator_is_on_sending_command() {
let prog = parse("/a | /b").unwrap();
let cmds = &prog.pipelines[0].commands;
assert_eq!(cmds[0].pipe, Some(Op::Pipe));
assert!(cmds[1].pipe.is_none());
}
#[test]
fn priority_inferred_from_casing() {
let prog = parse("/ALL_CAPS").unwrap();
assert_eq!(prog.pipelines[0].commands[0].priority, Priority::Max);
let prog = parse("/TitleCase").unwrap();
assert_eq!(prog.pipelines[0].commands[0].priority, Priority::High);
let prog = parse("/camelCase").unwrap();
assert_eq!(prog.pipelines[0].commands[0].priority, Priority::Medium);
let prog = parse("/kebab-case").unwrap();
assert_eq!(prog.pipelines[0].commands[0].priority, Priority::Low);
let prog = parse("/snake_case").unwrap();
assert_eq!(prog.pipelines[0].commands[0].priority, Priority::Lowest);
}
#[test]
fn urgency_inferred_from_bangs() {
let prog = parse("/cmd!").unwrap();
assert_eq!(prog.pipelines[0].commands[0].urgency, Urgency::Low);
let prog = parse("/cmd!!").unwrap();
assert_eq!(prog.pipelines[0].commands[0].urgency, Urgency::Medium);
let prog = parse("/cmd!!!").unwrap();
assert_eq!(prog.pipelines[0].commands[0].urgency, Urgency::High);
}
#[test]
fn builder_args_parsed_correctly() {
let prog = parse("/build.target(release).jobs(4).lto").unwrap();
let cmd = &prog.pipelines[0].commands[0];
assert_eq!(cmd.name, "build");
assert_eq!(cmd.args.len(), 3);
assert_eq!(cmd.args[0].name, "target");
assert_eq!(cmd.args[0].value.as_deref(), Some("release"));
assert_eq!(cmd.args[1].name, "jobs");
assert_eq!(cmd.args[1].value.as_deref(), Some("4"));
assert_eq!(cmd.args[2].name, "lto");
assert!(cmd.args[2].value.is_none());
}
#[test]
fn redirection_truncate_and_append() {
let prog = parse("/build > out.txt").unwrap();
let cmd = &prog.pipelines[0].commands[0];
assert!(
matches!(cmd.redirect, Some(slash_lang::parser::ast::Redirection::Truncate(ref f)) if f == "out.txt")
);
let prog = parse("/log >> audit.log").unwrap();
let cmd = &prog.pipelines[0].commands[0];
assert!(
matches!(cmd.redirect, Some(slash_lang::parser::ast::Redirection::Append(ref f)) if f == "audit.log")
);
}