use super::*;
fn stored(mode: &str, name: &str, id: u8) -> Vec<u8> {
let mut bytes: Vec<u8> = format!("{mode} {name}").into_bytes();
bytes.push(0);
bytes.extend_from_slice(&[id; 20]);
return bytes;
}
fn parse_subject_with_nul() -> Option<Vec<u8>> {
return subject_of(b"left\0right\n");
}
#[test]
fn trees_parse_and_malformed_ones_are_refused() {
let mut bytes = stored("100644", "a", 1);
bytes.extend(stored("40000", "dir", 2));
let entries = parse_tree(bytes.as_slice(), 20).expect("plain tree");
assert_eq!(entries.len(), 2);
assert!(is_tree_mode(entries[1].mode));
assert!(!is_tree_mode(entries[0].mode));
assert!(parse_tree(&bytes[..bytes.len() - 1], 20).is_none(), "a short name");
assert!(parse_tree(stored("0100644", "a", 1).as_slice(), 20).is_none(), "a leading zero");
assert!(parse_tree(stored("100644", "a/b", 1).as_slice(), 20).is_none(), "a slash in a name");
assert!(parse_tree(stored("10x644", "a", 1).as_slice(), 20).is_none(), "a non-octal mode");
assert!(parse_tree(stored("100664", "a", 1).as_slice(), 20).is_none(), "a mode Git canonicalizes to 100644");
assert!(parse_subject_with_nul().is_none(), "a message with a NUL");
}
#[test]
fn commits_parse_and_encodings_are_declined() {
let tree = "1".repeat(40);
let parent = "2".repeat(40);
let text = format!("tree {tree}\nparent {parent}\nauthor A <a@e> 1 +0000\ncommitter A <a@e> 1 +0000\n\nsubject\n\nbody\n");
let fields = parse_commit(text.as_bytes(), ObjectFormat::Sha1).expect("commit");
assert_eq!(fields.parents.len(), 1);
assert_eq!(fields.message, b"subject\n\nbody\n".to_vec());
let encoded = format!("tree {tree}\nauthor A <a@e> 1 +0000\ncommitter A <a@e> 1 +0000\nencoding latin1\n\nsubject\n");
assert!(parse_commit(encoded.as_bytes(), ObjectFormat::Sha1).is_none());
assert!(parse_commit(b"no header", ObjectFormat::Sha1).is_none());
}
#[test]
fn subjects_join_the_first_paragraph() {
assert_eq!(subject_of(b"one\ntwo\n\nbody\n"), Some(b"one two".to_vec()));
assert_eq!(subject_of(b"\n\nlead\n"), Some(b"lead".to_vec()));
assert_eq!(subject_of(b""), Some(Vec::new()));
assert!(subject_of(b"a\r\nb\n").is_none());
}