Skip to content

Commit 54a0c02

Browse files
committed
feat: make test syntax more expressive. Allow specifying line numbers that just got added
1 parent c987381 commit 54a0c02

File tree

1 file changed

+108
-33
lines changed

1 file changed

+108
-33
lines changed

helix-vcs/src/git/blame.rs

+108-33
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ pub fn blame_line(
191191
})
192192
}
193193

194+
// attributes on expressions are not allowed
195+
// however, in our macro its possible that sometimes the
196+
// assignment to the mutable variable will not be read.
197+
//
198+
// when the last line has no expected blame commit
199+
#[allow(unused_assignments)]
194200
#[cfg(test)]
195201
mod test {
196202
use std::fs::File;
@@ -199,75 +205,144 @@ mod test {
199205

200206
use super::*;
201207

202-
macro_rules! assert_blamed_lines {
203-
($repo:ident, $file:ident @ $($commit_msg:literal => $($line:literal $expected:literal),+);+ $(;)?) => {{
208+
macro_rules! no_commit_flag {
209+
(no_commit, $commit_msg:literal) => {
210+
false
211+
};
212+
(, $commit_msg:literal) => {
213+
true
214+
};
215+
($any:tt, $commit_msg:literal) => {
216+
compile_error!(concat!(
217+
"expected no_commit or nothing for commit ",
218+
$commit_msg
219+
))
220+
};
221+
}
222+
223+
macro_rules! add_flag {
224+
(add, $commit_msg:literal, $line:expr) => {
225+
true
226+
};
227+
(, $commit_msg:literal, $line:expr) => {
228+
false
229+
};
230+
($any:tt, $commit_msg:literal, $line:expr) => {
231+
compile_error!(concat!(
232+
"expected no_commit or nothing for commit ",
233+
$commit_msg,
234+
" line ",
235+
$line
236+
))
237+
};
238+
}
239+
240+
/// Helper macro to create a history of the same file being modified.
241+
///
242+
/// Each $commit_msg is a unique identifier for a commit message.
243+
/// Each $line is a string line of the file. These $lines are collected into a single String
244+
/// which then becomes the new contents of the $file
245+
///
246+
/// Each $line gets blamed using blame_line. The $expected is the commit identifier that we are expecting for that line.
247+
macro_rules! assert_line_blame_progress {
248+
($($commit_msg:literal $($no_commit:ident)? => $($line:literal $($expected:literal)? $($added:ident)? ),+);+ $(;)?) => {{
204249
use std::fs::OpenOptions;
205250
use std::io::Write;
206251

252+
let repo = empty_git_repo();
253+
let file = repo.path().join("file.txt");
254+
File::create(&file).expect("could not create file");
255+
207256
let write_file = |content: &str| {
208257
let mut f = OpenOptions::new()
209258
.write(true)
210259
.truncate(true)
211-
.open(&$file)
260+
.open(&file)
212261
.unwrap();
213262
f.write_all(content.as_bytes()).unwrap();
214263
};
215264

216-
let commit = |msg| create_commit_with_message($repo.path(), true, msg);
265+
let commit = |msg| create_commit_with_message(repo.path(), true, msg);
217266

218267
$(
219268
let file_content = concat!($($line, "\n"),*);
269+
eprintln!("at commit {}:\n\n{file_content}", stringify!($commit_msg));
220270
write_file(file_content);
221-
commit(stringify!($commit_msg));
271+
272+
let should_commit = no_commit_flag!($($no_commit)?, $commit_msg);
273+
if should_commit {
274+
commit(stringify!($commit_msg));
275+
}
222276

223277
let mut line_number = 0;
278+
let mut added_lines = 0;
224279

225280
$(
226281
line_number += 1;
227-
let blame_result = blame_line(&$file, line_number, 0, 0).unwrap().commit_message;
228-
assert_eq!(
229-
blame_result,
230-
Some(concat!(stringify!($expected), "\n").to_owned()),
231-
"Blame mismatch at line {}: expected '{}', got {:?}",
232-
line_number,
233-
stringify!($expected),
234-
blame_result
235-
);
282+
let has_add_flag = add_flag!($($added)?, $commit_msg, $line);
283+
if has_add_flag {
284+
added_lines += 1;
285+
}
286+
// if there is no $expected, then we don't care what blame_line returns
287+
// because we won't show it to the user.
288+
$(
289+
290+
let blame_result = blame_line(&file, line_number, added_lines, 0).unwrap().commit_message;
291+
assert_eq!(
292+
blame_result,
293+
Some(concat!(stringify!($expected), "\n").to_owned()),
294+
"Blame mismatch\nat commit: {}\nat line: {}\nline contents: {}\nexpected commit: {}\nbut got commit: {}",
295+
$commit_msg,
296+
line_number,
297+
file_content.lines().nth(line_number.try_into().unwrap()).unwrap(),
298+
stringify!($expected),
299+
blame_result.as_ref().map(|blame| blame.trim_end()).unwrap_or("<no commit>")
300+
);
301+
)?
236302
)*
237303
)*
238304
}};
239305
}
240306

241-
fn bob() -> BlameInformation {
242-
BlameInformation {
243-
commit_hash: Some("f14ab1cf".to_owned()),
244-
author_name: Some("Bob TheBuilder".to_owned()),
245-
author_email: Some("[email protected]".to_owned()),
246-
commit_date: Some("2028-01-10".to_owned()),
247-
commit_message: Some("feat!: extend house".to_owned()),
248-
commit_body: Some("BREAKING CHANGE: Removed door".to_owned()),
249-
}
250-
}
251-
252307
#[test]
253-
pub fn blame_lin() {
254-
let repo = empty_git_repo();
255-
let file = repo.path().join("file.txt");
256-
File::create(&file).unwrap();
257-
258-
assert_blamed_lines! {
259-
repo, file @
308+
pub fn blamed_lines() {
309+
assert_line_blame_progress! {
260310
1 =>
261311
"fn main() {" 1,
262312
"" 1,
263313
"}" 1;
264314
2 =>
265315
"fn main() {" 1,
266-
" lol" 2,
316+
" one" 2,
317+
"}" 1;
318+
3 =>
319+
"fn main() {" 1,
320+
" one" 2,
321+
" two" 3,
322+
"}" 1;
323+
4 =>
324+
"fn main() {" 1,
325+
" two" 3,
326+
"}" 1;
327+
5 no_commit =>
328+
"fn main() {" 1,
329+
" hello world" add,
330+
" two" 3,
267331
"}" 1;
268332
};
269333
}
270334

335+
fn bob() -> BlameInformation {
336+
BlameInformation {
337+
commit_hash: Some("f14ab1cf".to_owned()),
338+
author_name: Some("Bob TheBuilder".to_owned()),
339+
author_email: Some("[email protected]".to_owned()),
340+
commit_date: Some("2028-01-10".to_owned()),
341+
commit_message: Some("feat!: extend house".to_owned()),
342+
commit_body: Some("BREAKING CHANGE: Removed door".to_owned()),
343+
}
344+
}
345+
271346
#[test]
272347
pub fn inline_blame_format_parser() {
273348
let default_values = "{author}, {date} • {message} • {commit}";

0 commit comments

Comments
 (0)