blob: 6ee363d6b5b0d4775937e5a4aa8b297930d86bc5 [file] [log] [blame]
use std::collections::HashMap;
use bstr::{BStr, BString, ByteSlice};
use gix_attributes::State;
use gix_pathspec::{MagicSignature, Pattern, SearchMode};
use once_cell::sync::Lazy;
#[test]
fn baseline() {
for (pattern, exit_code) in BASELINE.iter() {
let res = gix_pathspec::parse(pattern, Default::default());
assert_eq!(
res.is_ok(),
*exit_code == 0,
"{pattern:?} disagrees with baseline: {res:?}"
);
if let Ok(pat) = res {
let actual = pat.to_bstring();
assert_eq!(
pat,
gix_pathspec::parse(actual.as_ref(), Default::default()).expect("still valid"),
"{pattern} != {actual}: display must roundtrip into actual pattern"
);
}
let p = gix_pathspec::Pattern::from_literal(pattern, Default::default());
assert!(matches!(p.search_mode, SearchMode::Literal));
}
}
mod invalid;
mod valid;
/// A way to specify expectations more easily by simplifying assignments.
#[derive(Debug, Clone, PartialEq, Eq)]
struct NormalizedPattern {
path: BString,
signature: MagicSignature,
search_mode: SearchMode,
attributes: Vec<(BString, State)>,
}
impl From<Pattern> for NormalizedPattern {
fn from(p: Pattern) -> Self {
NormalizedPattern {
path: p.path().to_owned(),
signature: p.signature,
search_mode: p.search_mode,
attributes: p
.attributes
.into_iter()
.map(|attr| (attr.name.as_str().into(), attr.state))
.collect(),
}
}
}
static BASELINE: Lazy<HashMap<BString, usize>> = Lazy::new(|| {
let base = gix_testtools::scripted_fixture_read_only("parse_baseline.sh").unwrap();
(|| -> crate::Result<_> {
let mut map = HashMap::new();
let baseline = std::fs::read(base.join("baseline.git"))?;
let mut lines = baseline.lines();
while let Some(spec) = lines.next() {
let exit_code = lines.next().expect("two lines per baseline").to_str()?.parse()?;
map.insert(spec.into(), exit_code);
}
Ok(map)
})()
.unwrap()
});
fn check_valid_inputs<'a>(inputs: impl IntoIterator<Item = (&'a str, NormalizedPattern)>) {
for (input, expected) in inputs.into_iter() {
assert!(
check_against_baseline(input),
"This pathspec is invalid in git: {input}"
);
let pattern = gix_pathspec::parse(input.as_bytes(), Default::default())
.unwrap_or_else(|_| panic!("parsing should not fail with pathspec {input}"));
let pattern: NormalizedPattern = pattern.into();
assert_eq!(pattern, expected, "while checking input: \"{input}\"");
}
}
fn check_against_baseline(pathspec: &str) -> bool {
let key: &BStr = pathspec.into();
let base = BASELINE
.get(key)
.unwrap_or_else(|| panic!("missing baseline for pathspec: {pathspec:?}"));
*base == 0
}