use crate::commit::parse::{parse, ParseError};
#[derive(Debug)]
struct AlwaysFails;
#[derive(Debug)]
struct AlwaysFailsErr;
impl std::fmt::Display for AlwaysFailsErr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "always fails to parse")
}
}
impl std::error::Error for AlwaysFailsErr {}
impl std::str::FromStr for AlwaysFails {
type Err = AlwaysFailsErr;
fn from_str(_s: &str) -> Result<Self, Self::Err> {
Err(AlwaysFailsErr)
}
}
#[test]
fn missing_header_body_separator() {
let raw = "tree abc123\nauthor Alice Liddell <alice@example.com> 1700000000 +0000\ncommitter Alice Liddell <alice@example.com> 1700000000 +0000\nno blank line follows";
let err = parse::<String, String>(raw).unwrap_err();
assert!(
matches!(err, ParseError::InvalidFormat { .. }),
"unexpected error: {err}"
);
}
#[test]
fn missing_tree_empty_header() {
let raw = "\n\nMessage";
let err = parse::<String, String>(raw).unwrap_err();
assert!(
matches!(err, ParseError::MissingTree),
"unexpected error: {err}"
);
}
#[test]
fn missing_tree_wrong_first_line() {
let raw = "author Alice Liddell <alice@example.com> 1700000000 +0000\ncommitter Alice Liddell <alice@example.com> 1700000000 +0000\n\nMessage";
let err = parse::<String, String>(raw).unwrap_err();
assert!(
matches!(err, ParseError::MissingTree),
"unexpected error: {err}"
);
}
#[test]
fn invalid_tree() {
let raw = "tree abc123\nauthor Alice Liddell <alice@example.com> 1700000000 +0000\ncommitter Alice Liddell <alice@example.com> 1700000000 +0000\n\nMessage";
let err = parse::<AlwaysFails, String>(raw).unwrap_err();
assert!(
matches!(err, ParseError::InvalidTree(_)),
"unexpected error: {err}"
);
}
#[test]
fn invalid_parent() {
let raw = "tree abc123\nparent bad-oid\nauthor Alice Liddell <alice@example.com> 1700000000 +0000\ncommitter Alice Liddell <alice@example.com> 1700000000 +0000\n\nMessage";
let err = parse::<String, AlwaysFails>(raw).unwrap_err();
assert!(
matches!(err, ParseError::InvalidParent(_)),
"unexpected error: {err}"
);
}
#[test]
fn invalid_format_continuation_without_preceding_header() {
let raw = "tree abc123\nauthor Alice Liddell <alice@example.com> 1700000000 +0000\ncommitter Alice Liddell <alice@example.com> 1700000000 +0000\n spurious continuation\n\nMessage";
let err = parse::<String, String>(raw).unwrap_err();
assert!(
matches!(err, ParseError::InvalidFormat { .. }),
"unexpected error: {err}"
);
}
#[test]
fn missing_author() {
let raw =
"tree abc123\ncommitter Alice Liddell <alice@example.com> 1700000000 +0000\n\nMessage";
let err = parse::<String, String>(raw).unwrap_err();
assert!(
matches!(err, ParseError::MissingAuthor),
"unexpected error: {err}"
);
}
#[test]
fn invalid_author() {
let raw = "tree abc123\nauthor not-a-valid-author\ncommitter Alice Liddell <alice@example.com> 1700000000 +0000\n\nMessage";
let err = parse::<String, String>(raw).unwrap_err();
assert!(
matches!(err, ParseError::InvalidAuthor(_)),
"unexpected error: {err}"
);
}
#[test]
fn missing_committer() {
let raw = "tree abc123\nauthor Alice Liddell <alice@example.com> 1700000000 +0000\n\nMessage";
let err = parse::<String, String>(raw).unwrap_err();
assert!(
matches!(err, ParseError::MissingCommitter),
"unexpected error: {err}"
);
}
#[test]
fn invalid_committer() {
let raw = "tree abc123\nauthor Alice Liddell <alice@example.com> 1700000000 +0000\ncommitter not-a-valid-committer\n\nMessage";
let err = parse::<String, String>(raw).unwrap_err();
assert!(
matches!(err, ParseError::InvalidCommitter(_)),
"unexpected error: {err}"
);
}