extern crate conch_parser;
use conch_parser::ast::builder::*;
use conch_parser::parse::ParseError::*;
use conch_parser::token::Token;
mod parse_support;
use parse_support::*;
#[test]
fn test_if_command_valid_with_else() {
let guard1 = cmd("guard1");
let guard2 = cmd("guard2");
let guard3 = cmd("guard3");
let body1 = cmd("body1");
let body2 = cmd("body2");
let els = cmd("else");
let correct = IfFragments {
conditionals: vec!(
GuardBodyPairGroup {
guard: CommandGroup {
commands: vec!(guard1, guard2),
trailing_comments: vec!(Newline(Some("#guard_comment_a".into()))),
},
body: CommandGroup {
commands: vec!(body1),
trailing_comments: vec!(Newline(Some("#body_comment_a".into()))),
},
},
GuardBodyPairGroup {
guard: CommandGroup {
commands: vec!(guard3),
trailing_comments: vec!(Newline(Some("#guard_comment_b".into()))),
},
body: CommandGroup {
commands: vec!(body2),
trailing_comments: vec!(Newline(Some("#body_comment_b".into()))),
},
},
),
else_branch: Some(CommandGroup {
commands: vec!(els),
trailing_comments: vec!(Newline(Some("#else_comment".into()))),
}),
};
let mut p = make_parser("\
if guard1; guard2;
#guard_comment_a
then body1
#body_comment_a
elif guard3;
#guard_comment_b
then body2;
#body_comment_b
else else;
#else_comment
fi
");
assert_eq!(correct, p.if_command().unwrap());
}
#[test]
fn test_if_command_valid_without_else() {
let guard1 = cmd("guard1");
let guard2 = cmd("guard2");
let guard3 = cmd("guard3");
let body1 = cmd("body1");
let body2 = cmd("body2");
let correct = IfFragments {
conditionals: vec!(
GuardBodyPairGroup {
guard: CommandGroup {
commands: vec!(guard1, guard2),
trailing_comments: vec!(Newline(Some("#guard_comment_a".into()))),
},
body: CommandGroup {
commands: vec!(body1),
trailing_comments: vec!(Newline(Some("#body_comment_a".into()))),
},
},
GuardBodyPairGroup {
guard: CommandGroup {
commands: vec!(guard3),
trailing_comments: vec!(Newline(Some("#guard_comment_b".into()))),
},
body: CommandGroup {
commands: vec!(body2),
trailing_comments: vec!(Newline(Some("#body_comment_b".into()))),
},
},
),
else_branch: None,
};
let mut p = make_parser("\
if guard1; guard2;
#guard_comment_a
then body1
#body_comment_a
elif guard3;
#guard_comment_b
then body2;
#body_comment_b
fi
");
assert_eq!(correct, p.if_command().unwrap());
}
#[test]
fn test_if_command_invalid_missing_separator() {
let mut p = make_parser("if guard; then body1; elif guard2; then body2; else else fi");
assert_eq!(Err(IncompleteCmd("if", src(0,1,1), "fi", src(59,1,60))), p.if_command());
}
#[test]
fn test_if_command_invalid_missing_keyword() {
let mut p = make_parser("guard1; then body1; elif guard2; then body2; else else; fi");
assert_eq!(Err(Unexpected(Token::Name(String::from("guard1")), src(0,1,1))), p.if_command());
let mut p = make_parser("if guard1; then body1; elif guard2; then body2; else else;");
assert_eq!(Err(IncompleteCmd("if", src(0,1,1), "fi", src(58,1,59))), p.if_command());
}
#[test]
fn test_if_command_invalid_missing_guard() {
let mut p = make_parser("if; then body1; elif guard2; then body2; else else; fi");
assert_eq!(Err(Unexpected(Token::Semi, src(2,1,3))), p.if_command());
}
#[test]
fn test_if_command_invalid_missing_body() {
let mut p = make_parser("if guard; then; elif guard2; then body2; else else; fi");
assert_eq!(Err(Unexpected(Token::Semi, src(14, 1, 15))), p.if_command());
let mut p = make_parser("if guard1; then body1; elif; then body2; else else; fi");
assert_eq!(Err(Unexpected(Token::Semi, src(27, 1, 28))), p.if_command());
let mut p = make_parser("if guard1; then body1; elif guard2; then body2; else; fi");
assert_eq!(Err(Unexpected(Token::Semi, src(52, 1, 53))), p.if_command());
}
#[test]
fn test_if_command_invalid_quoted() {
let cmds = [
("'if' guard1; then body1; elif guard2; then body2; else else; fi", Unexpected(Token::SingleQuote, src(0,1,1))),
("if guard1; then body1; elif guard2; then body2; else else; 'fi'", IncompleteCmd("if", src(0,1,1), "fi", src(63,1,64))),
("\"if\" guard1; then body1; elif guard2; then body2; else else; fi", Unexpected(Token::DoubleQuote, src(0,1,1))),
("if guard1; then body1; elif guard2; then body2; else else; \"fi\"", IncompleteCmd("if", src(0,1,1), "fi", src(63,1,64))),
];
for &(s, ref e) in cmds.into_iter() {
match make_parser(s).if_command() {
Ok(result) => panic!("Unexpectedly parsed \"{}\" as\n{:#?}", s, result),
Err(ref err) => if err != e {
panic!("Expected the source \"{}\" to return the error `{:?}`, but got `{:?}`",
s, e, err);
},
}
}
}
#[test]
fn test_if_command_invalid_concat() {
let mut p = make_parser_from_tokens(vec!(
Token::Literal(String::from("i")), Token::Literal(String::from("f")),
Token::Newline, Token::Literal(String::from("guard1")), Token::Newline,
Token::Literal(String::from("then")),
Token::Newline, Token::Literal(String::from("body1")), Token::Newline,
Token::Literal(String::from("elif")),
Token::Newline, Token::Literal(String::from("guard2")), Token::Newline,
Token::Literal(String::from("then")),
Token::Newline, Token::Literal(String::from("body2")), Token::Newline,
Token::Literal(String::from("else")),
Token::Newline, Token::Literal(String::from("else part")), Token::Newline,
Token::Literal(String::from("fi")),
));
assert_eq!(Err(Unexpected(Token::Literal(String::from("i")), src(0,1,1))), p.if_command());
let mut p = make_parser_from_tokens(vec!(
Token::Literal(String::from("if")),
Token::Newline, Token::Literal(String::from("guard1")), Token::Newline,
Token::Literal(String::from("then")),
Token::Newline, Token::Literal(String::from("body1")), Token::Newline,
Token::Literal(String::from("elif")),
Token::Newline, Token::Literal(String::from("guard2")), Token::Newline,
Token::Literal(String::from("then")),
Token::Newline, Token::Literal(String::from("body2")), Token::Newline,
Token::Literal(String::from("else")),
Token::Newline, Token::Literal(String::from("else part")), Token::Newline,
Token::Literal(String::from("f")), Token::Literal(String::from("i")),
));
assert_eq!(Err(IncompleteCmd("if", src(0,1,1), "fi", src(61,11,3))), p.if_command());
}
#[test]
fn test_if_command_should_recognize_literals_and_names() {
for if_tok in vec!(Token::Literal(String::from("if")), Token::Name(String::from("if"))) {
for then_tok in vec!(Token::Literal(String::from("then")), Token::Name(String::from("then"))) {
for elif_tok in vec!(Token::Literal(String::from("elif")), Token::Name(String::from("elif"))) {
for else_tok in vec!(Token::Literal(String::from("else")), Token::Name(String::from("else"))) {
for fi_tok in vec!(Token::Literal(String::from("fi")), Token::Name(String::from("fi"))) {
let mut p = make_parser_from_tokens(vec!(
if_tok.clone(),
Token::Whitespace(String::from(" ")),
Token::Literal(String::from("guard1")),
Token::Newline,
then_tok.clone(),
Token::Newline,
Token::Literal(String::from("body1")),
elif_tok.clone(),
Token::Whitespace(String::from(" ")),
Token::Literal(String::from("guard2")),
Token::Newline,
then_tok.clone(),
Token::Whitespace(String::from(" ")),
Token::Literal(String::from("body2")),
else_tok.clone(),
Token::Whitespace(String::from(" ")),
Token::Whitespace(String::from(" ")),
Token::Literal(String::from("else part")),
Token::Newline,
fi_tok,
));
p.if_command().unwrap();
}
}
}
}
}
}