pub use parser::*;
pub use items::*;
mod take_whole_line {
pub use super::*;
#[test]
fn it_returns_whole_line() {
let input = " yo 👋!";
let res = take_whole_line(input);
assert!(res.is_done());
assert_eq!(input, res.unwrap().1)
}
}
mod parse_comment {
pub use super::*;
#[test]
fn it_should_fail_when_not_starting_with_hash_char() {
let res = parse_comment("yo");
assert_eq!(true, res.is_err())
}
#[test]
fn it_should_be_done_when_starting_with_hash_char() {
let res = parse_comment("# yo");
assert_eq!(true, res.is_done())
}
#[test]
fn it_should_trim_whitespaces() {
let res = parse_comment("# yo ");
let expected = SystemdItem::Comment("yo");
assert_eq!(expected, res.unwrap().1)
}
}
mod parse_category {
pub use super::*;
#[test]
fn it_should_be_done() {
let input = "[Category]";
let res = parse_category(input);
assert!(res.is_done())
}
#[test]
fn it_should_consume_the_category() {
let input = "[ Category ]";
let res = parse_category(input);
let expected = SystemdItem::Category("Category");
assert_eq!(expected, res.unwrap().1);
}
#[test]
fn it_should_reject_more_than_one_word() {
let input = "[ Category wrong ]";
let res = parse_category(input);
assert!(res.is_err())
}
}
mod parse_directive {
pub use super::*;
#[test]
fn it_should_be_done() {
let input = "ExecStart=42";
let res = parse_directive(input);
assert!(res.is_done());
}
#[test]
fn it_should_consume_the_directive_key_and_value() {
let input = "ExecStart = 42";
let res = parse_directive(input);
let expected = SystemdItem::Directive("ExecStart", Some("42"));
assert_eq!(expected, res.unwrap().1);
}
#[test]
fn it_should_reject_the_directive_with_no_key() {
let input = " = 42";
let res = parse_directive(input);
assert!(res.is_err());
}
#[test]
fn it_should_accept_directives_with_no_values() {
let input = "Yo =";
let res = parse_directive(input);
assert!(res.is_done(), "expected {} to be accepted. got: {:?}", input, res);
assert_eq!(SystemdItem::Directive("Yo", None), res.unwrap().1)
}
#[test]
fn it_should_consume_path_in_values() {
let input = "ExecStart=/usr/sbin/some-fancy-httpd-server -p 3000 -h localhost -l server.log";
let res = parse_directive(input);
let expected = SystemdItem::Directive(
"ExecStart",
Some("/usr/sbin/some-fancy-httpd-server -p 3000 -h localhost -l server.log")
);
assert_eq!(expected, res.unwrap().1);
}
#[test]
fn it_doesnt_consume_comment_at_end_of_line() {
let input = "ExecStart=/usr/sbin/some-fancy-httpd-server # I like this one";
let res = parse_directive(input);
assert_eq!("# I like this one", res.unwrap().0)
}
#[test]
fn it_should_accept_exotic_output() {
let inputs = vec![
("!ConditionPathIsMountPoint=/mnt/plop", "bang in keys"),
("|ConditionPathIsMountPoint=/mnt/plop", "pipe in keys"),
("Alias=foo.service.wants/bar.service", "Alias=foo.service.wants/bar.service"),
("ExecStart=-/bin/false", "- in value"),
("ExecStart=@/bin/echo", "@ in value"),
("ExecStart=+/bin/true", "+ in value"),
("ExecStart=+@-/bin/true", "+@- in value"),
("ExecStart=/bin/echo $TERM", "$ in value"),
("Environment=\"https_proxy=http://squidaws.internet.iz.eu-west-1.aws:8080\"",
"inline quotes and URI"),
];
for (input, msg) in inputs {
let res = parse_directive(input);
assert!(res.is_done(), "it should accept {}", msg)
}
}
}
mod parse_line {
pub use super::*;
#[test]
fn it_is_present() {
let input = "[Unit]";
let res = parse_line(input);
assert!(res.is_done())
}
#[test]
fn it_can_parse_category() {
let input = "[Unit]";
let res = parse_line(input);
assert_eq!(SystemdItem::Category("Unit"), res.unwrap().1)
}
#[test]
fn it_can_parse_comment() {
let input = "# comment";
let res = parse_line(input);
assert_eq!(SystemdItem::Comment("comment"), res.unwrap().1)
}
#[test]
fn it_can_parse_directive() {
let input = "ExecStart=/usr/bin/true";
let res = parse_line(input);
assert_eq!(
SystemdItem::Directive("ExecStart", Some("/usr/bin/true")),
res.unwrap().1
)
}
}
mod parse_unit {
pub use super::*;
#[test]
fn it_returns_a_vec_of_parsed_lines() {
let input = "[Unit]
Description=This is a dummy unit file
[Service]
ExecStart=/usr/bin/true
";
let res = parse_unit(&input);
assert_eq!(
&SystemdItem::Category("Unit"),
res.unwrap().get(0).unwrap()
)
}
#[test]
fn it_skip_empty_lines() {
let input = "
[Unit]";
let res = parse_unit(&input);
assert_eq!(
&SystemdItem::Category("Unit"),
res.unwrap().get(0).unwrap()
)
}
#[test]
fn it_trim_whitespaces_at_beginning_and_end_of_line() {
let input = "\n \t [Unit] ";
let res = parse_unit(&input);
assert_eq!(
&SystemdItem::Category("Unit"),
res.unwrap().get(0).unwrap()
)
}
#[test]
fn it_works_with_the_dummy() {
let input = "[Unit]
Description=This is a dummy unit file
[Service]
ExecStart=/usr/bin/true
";
let dummy_unit_parsed = vec![
SystemdItem::Category("Unit"),
SystemdItem::Directive("Description", Some("This is a dummy unit file")),
SystemdItem::Category("Service"),
SystemdItem::Directive("ExecStart", Some("/usr/bin/true"))
];
let res = parse_unit(&input);
assert_eq!(dummy_unit_parsed, res.unwrap())
}
#[test]
fn it_returns_an_error_in_case_of_parse_error() {
let input = "[Unit]\nplop";
let res = parse_unit(&input);
assert!(res.is_err())
}
#[test]
fn it_keep_line_numbers_in_errors() {
let input = "[Unit]\nplop";
let res = parse_unit(&input);
assert_eq!(
2,
res.unwrap_err().get(0).unwrap().1
)
}
#[test]
fn it_keep_line_numbers_in_errors2() {
let input = "[Unit]\nplop\nPlop=42\n[Nice things]";
let res = parse_unit(&input);
assert_eq!(
4,
res.unwrap_err().get(1).unwrap().1
)
}
}