]> git.proxmox.com Git - rustc.git/blob - vendor/gix-ref/src/store/file/loose/reflog/create_or_update/tests.rs
New upstream version 1.70.0+dfsg2
[rustc.git] / vendor / gix-ref / src / store / file / loose / reflog / create_or_update / tests.rs
1 use std::{convert::TryInto, path::Path};
2
3 use gix_actor::{Sign, Signature, Time};
4 use gix_object::bstr::ByteSlice;
5 use tempfile::TempDir;
6
7 use super::*;
8 use crate::{file::WriteReflog, FullNameRef};
9
10 type Result<T = ()> = std::result::Result<T, Box<dyn std::error::Error>>;
11
12 /// Convert a hexadecimal hash into its corresponding `ObjectId` or _panic_.
13 fn hex_to_id(hex: &str) -> gix_hash::ObjectId {
14 gix_hash::ObjectId::from_hex(hex.as_bytes()).expect("40 bytes hex")
15 }
16
17 fn empty_store(writemode: WriteReflog) -> Result<(TempDir, file::Store)> {
18 let dir = TempDir::new()?;
19 let store = file::Store::at(dir.path(), writemode, gix_hash::Kind::Sha1);
20 Ok((dir, store))
21 }
22
23 fn reflog_lines(store: &file::Store, name: &str, buf: &mut Vec<u8>) -> Result<Vec<crate::log::Line>> {
24 store
25 .reflog_iter(name, buf)?
26 .expect("existing reflog")
27 .map(|l| l.map(crate::log::Line::from))
28 .collect::<std::result::Result<Vec<_>, _>>()
29 .map_err(Into::into)
30 }
31
32 const WRITE_MODES: &[WriteReflog] = &[WriteReflog::Normal, WriteReflog::Disable, WriteReflog::Always];
33
34 #[test]
35 fn should_autocreate_is_unaffected_by_writemode() -> Result {
36 let (_keep, store) = empty_store(WriteReflog::Disable)?;
37 for should_create_name in &["HEAD", "refs/heads/main", "refs/remotes/any", "refs/notes/any"] {
38 assert!(store.should_autocreate_reflog(Path::new(should_create_name)));
39 }
40 for should_not_create_name in &["FETCH_HEAD", "SOMETHING", "refs/special/this", "refs/tags/0.1.0"] {
41 assert!(!store.should_autocreate_reflog(Path::new(should_not_create_name)));
42 }
43 Ok(())
44 }
45
46 #[test]
47 fn missing_reflog_creates_it_even_if_similarly_named_empty_dir_exists_and_append_log_lines() -> Result {
48 for mode in WRITE_MODES {
49 let (_keep, store) = empty_store(*mode)?;
50 let full_name_str = "refs/heads/main";
51 let full_name: &FullNameRef = full_name_str.try_into()?;
52 let new = hex_to_id("28ce6a8b26aa170e1de65536fe8abe1832bd3242");
53 let committer = Signature {
54 name: "committer".into(),
55 email: "committer@example.com".into(),
56 time: Time {
57 seconds_since_unix_epoch: 1234,
58 offset_in_seconds: 1800,
59 sign: Sign::Plus,
60 },
61 };
62 store.reflog_create_or_append(
63 full_name,
64 None,
65 &new,
66 committer.to_ref().into(),
67 b"the message".as_bstr(),
68 false,
69 )?;
70
71 let mut buf = Vec::new();
72 match mode {
73 WriteReflog::Normal | WriteReflog::Always => {
74 assert_eq!(
75 reflog_lines(&store, full_name_str, &mut buf)?,
76 vec![crate::log::Line {
77 previous_oid: gix_hash::Kind::Sha1.null(),
78 new_oid: new,
79 signature: committer.clone(),
80 message: "the message".into()
81 }]
82 );
83 let previous = hex_to_id("0000000000000000000000111111111111111111");
84 store.reflog_create_or_append(
85 full_name,
86 Some(previous),
87 &new,
88 committer.to_ref().into(),
89 b"next message".as_bstr(),
90 false,
91 )?;
92
93 let lines = reflog_lines(&store, full_name_str, &mut buf)?;
94 assert_eq!(lines.len(), 2, "now there is another line");
95 assert_eq!(
96 lines.last().expect("non-empty"),
97 &crate::log::Line {
98 previous_oid: previous,
99 new_oid: new,
100 signature: committer.clone(),
101 message: "next message".into()
102 }
103 );
104 }
105 WriteReflog::Disable => {
106 assert!(
107 store.reflog_iter(full_name, &mut buf)?.is_none(),
108 "there is no logs in disabled mode"
109 );
110 }
111 };
112
113 // create onto existing directory
114 let full_name_str = "refs/heads/other";
115 let full_name: &FullNameRef = full_name_str.try_into()?;
116 let reflog_path = store.reflog_path(full_name_str.try_into().expect("valid"));
117 let directory_in_place_of_reflog = reflog_path.join("empty-a").join("empty-b");
118 std::fs::create_dir_all(directory_in_place_of_reflog)?;
119
120 store.reflog_create_or_append(
121 full_name,
122 None,
123 &new,
124 committer.to_ref().into(),
125 b"more complicated reflog creation".as_bstr(),
126 false,
127 )?;
128
129 match mode {
130 WriteReflog::Normal | WriteReflog::Always => {
131 assert_eq!(
132 reflog_lines(&store, full_name_str, &mut buf)?.len(),
133 1,
134 "reflog was written despite directory"
135 );
136 assert!(
137 reflog_path.is_file(),
138 "the empty directory was replaced with the reflog file"
139 );
140 }
141 WriteReflog::Disable => {
142 assert!(
143 store.reflog_iter(full_name_str, &mut buf)?.is_none(),
144 "reflog still doesn't exist"
145 );
146 assert!(
147 store.reflog_iter_rev(full_name_str, &mut buf)?.is_none(),
148 "reflog still doesn't exist"
149 );
150 assert!(reflog_path.is_dir(), "reflog directory wasn't touched");
151 }
152 }
153 }
154 Ok(())
155 }