use crate::lexer::Token;
use crate::parser::{parse, Ast};
#[test]
fn test_negation_with_and_operator() {
let tokens = vec![
Token::Bang,
Token::Word("false".to_string()),
Token::And,
Token::Word("echo".to_string()),
Token::Word("success".to_string()),
];
let result = parse(tokens).unwrap();
if let Ast::And { left, right } = result {
if let Ast::Negation { command } = *left {
if let Ast::Pipeline(cmds) = *command {
assert_eq!(cmds[0].args, vec!["false"]);
} else {
panic!("Expected Pipeline in negation");
}
} else {
panic!("Expected Negation on left side of And");
}
if let Ast::Pipeline(cmds) = *right {
assert_eq!(cmds[0].args, vec!["echo", "success"]);
} else {
panic!("Expected Pipeline on right side of And");
}
} else {
panic!("Expected And node, got: {:?}", result);
}
}
#[test]
fn test_negation_with_or_operator() {
let tokens = vec![
Token::Bang,
Token::Word("true".to_string()),
Token::Or,
Token::Word("echo".to_string()),
Token::Word("fallback".to_string()),
];
let result = parse(tokens).unwrap();
if let Ast::Or { left, right } = result {
if let Ast::Negation { command } = *left {
if let Ast::Pipeline(cmds) = *command {
assert_eq!(cmds[0].args, vec!["true"]);
} else {
panic!("Expected Pipeline in negation");
}
} else {
panic!("Expected Negation on left side of Or");
}
if let Ast::Pipeline(cmds) = *right {
assert_eq!(cmds[0].args, vec!["echo", "fallback"]);
} else {
panic!("Expected Pipeline on right side of Or");
}
} else {
panic!("Expected Or node, got: {:?}", result);
}
}
#[test]
fn test_negation_and_semicolon_sequence() {
let tokens = vec![
Token::Bang,
Token::Word("false".to_string()),
Token::And,
Token::Word("echo".to_string()),
Token::Word("second".to_string()),
Token::Semicolon,
Token::Word("echo".to_string()),
Token::Word("third".to_string()),
];
let result = parse(tokens).unwrap();
if let Ast::Sequence(commands) = result {
assert_eq!(commands.len(), 2);
if let Ast::And { left, right } = &commands[0] {
if let Ast::Negation { command } = &**left {
if let Ast::Pipeline(cmds) = &**command {
assert_eq!(cmds[0].args, vec!["false"]);
} else {
panic!("Expected Pipeline in negation");
}
} else {
panic!("Expected Negation");
}
if let Ast::Pipeline(cmds) = &**right {
assert_eq!(cmds[0].args, vec!["echo", "second"]);
} else {
panic!("Expected Pipeline");
}
} else {
panic!("Expected And node");
}
if let Ast::Pipeline(cmds) = &commands[1] {
assert_eq!(cmds[0].args, vec!["echo", "third"]);
} else {
panic!("Expected Pipeline");
}
} else {
panic!("Expected Sequence, got: {:?}", result);
}
}
#[test]
fn test_nested_logical_operators() {
let tokens = vec![
Token::Word("true".to_string()),
Token::And,
Token::Bang,
Token::Word("false".to_string()),
Token::Or,
Token::Word("echo".to_string()),
Token::Word("fallback".to_string()),
];
let result = parse(tokens).unwrap();
if let Ast::Or { left, right } = result {
if let Ast::And {
left: and_left,
right: and_right,
} = *left
{
if let Ast::Pipeline(cmds) = *and_left {
assert_eq!(cmds[0].args, vec!["true"]);
} else {
panic!("Expected Pipeline");
}
if let Ast::Negation { command } = *and_right {
if let Ast::Pipeline(cmds) = *command {
assert_eq!(cmds[0].args, vec!["false"]);
} else {
panic!("Expected Pipeline in negation");
}
} else {
panic!("Expected Negation");
}
} else {
panic!("Expected And node on left side of Or");
}
if let Ast::Pipeline(cmds) = *right {
assert_eq!(cmds[0].args, vec!["echo", "fallback"]);
} else {
panic!("Expected Pipeline");
}
} else {
panic!("Expected Or node, got: {:?}", result);
}
}
#[test]
fn test_multiple_and_operators_in_sequence() {
let tokens = vec![
Token::Word("true".to_string()),
Token::And,
Token::Word("echo".to_string()),
Token::Word("second".to_string()),
Token::And,
Token::Word("echo".to_string()),
Token::Word("third".to_string()),
];
let result = parse(tokens).unwrap();
if let Ast::And { left, right } = result {
if let Ast::And {
left: inner_left,
right: inner_right,
} = *left
{
if let Ast::Pipeline(cmds) = *inner_left {
assert_eq!(cmds[0].args, vec!["true"]);
} else {
panic!("Expected Pipeline");
}
if let Ast::Pipeline(cmds) = *inner_right {
assert_eq!(cmds[0].args, vec!["echo", "second"]);
} else {
panic!("Expected Pipeline");
}
} else {
panic!("Expected nested And node on left");
}
if let Ast::Pipeline(cmds) = *right {
assert_eq!(cmds[0].args, vec!["echo", "third"]);
} else {
panic!("Expected Pipeline on right");
}
} else {
panic!("Expected And node, got: {:?}", result);
}
}
#[test]
fn test_negation_in_pipeline() {
let tokens = vec![
Token::Bang,
Token::Word("grep".to_string()),
Token::Word("pattern".to_string()),
Token::Pipe,
Token::Word("wc".to_string()),
Token::Word("-l".to_string()),
];
let result = parse(tokens).unwrap();
if let Ast::Negation { command } = result {
if let Ast::Pipeline(cmds) = *command {
assert_eq!(cmds.len(), 2);
assert_eq!(cmds[0].args, vec!["grep", "pattern"]);
assert_eq!(cmds[1].args, vec!["wc", "-l"]);
} else {
panic!("Expected Pipeline in negation");
}
} else {
panic!("Expected Negation, got: {:?}", result);
}
}