From 19819cea1aaa1bd9c34863d2ea47fc8350cdbce5 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 25 May 2022 17:59:34 +0800 Subject: [PATCH] Some more thought about whitespace and empty input (#427) Also partially done with experimentation using `git rev-parse`. --- git-revision/src/spec.rs | 4 +++- git-revision/tests/spec/mod.rs | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/git-revision/src/spec.rs b/git-revision/src/spec.rs index 65e73bcca5..1bea872b44 100644 --- a/git-revision/src/spec.rs +++ b/git-revision/src/spec.rs @@ -32,7 +32,9 @@ pub mod parse { /// - **Navigation** - where to go once from the initial revision. /// - **range** - to learn if the specification is for a single or multiple references. pub trait Delegate { - fn resolve_ref(&mut self, input: &BStr) -> Option<()>; + /// Resolve `name` as reference which might not be a valid reference name. The name may be partial like `main` or full like + /// `refs/heads/main` solely depending on the users input. + fn resolve_ref(&mut self, name: &BStr) -> Option<()>; fn find_by_prefix(&mut self, input: &BStr) -> Option<()>; fn nth_ancestor(&mut self, n: usize) -> Option<()>; diff --git a/git-revision/tests/spec/mod.rs b/git-revision/tests/spec/mod.rs index 7d4cc60cf0..d01f307641 100644 --- a/git-revision/tests/spec/mod.rs +++ b/git-revision/tests/spec/mod.rs @@ -6,6 +6,7 @@ mod parse { struct Recorder { resolve_ref_input: Option, kind: Option, + calls: usize, } impl spec::parse::Delegate for Recorder { fn resolve_ref(&mut self, input: &BStr) -> Option<()> { @@ -15,6 +16,7 @@ mod parse { input ); self.resolve_ref_input = input.to_owned().into(); + self.calls += 1; Some(()) } @@ -31,6 +33,7 @@ mod parse { } fn kind(&mut self, kind: spec::Kind) { + self.calls += 1; self.kind = Some(kind); } } @@ -41,6 +44,26 @@ mod parse { rec } + #[test] + #[ignore] + fn empty_specs_are_valid() { + // they should of course be invalid for the delegate. CLIs may pre-process the input as well if they wish + // but git itself doesn't do that. + for spec in ["", " ", "\n\t"] { + let rec = parse(spec); + assert_eq!(rec.calls, 0); + } + } + + #[test] + #[ignore] + fn all_characters_are_taken_verbatim_which_includes_whitespace() { + let spec = " HEAD \n"; + let rec = parse(spec); + assert!(rec.kind.is_none()); + assert_eq!(rec.resolve_ref_input.unwrap(), spec); + } + #[test] #[ignore] fn leading_caret_is_range_kind() {