use git_revision::spec; use crate::spec::parse::{try_parse, try_parse_opts, Options}; #[test]fn cannot_declare_ranges_multiple_times() { for invalid_spec in ["^HEAD..", "^HEAD..."] { let err = try_parse(invalid_spec).unwrap_err(); assert!(matches!(err, spec::parse::Error::KindSetTwice { .. })); }} #[test]fn delegate_can_refuse_spec_kinds() { let err = try_parse_opts( "^HEAD", Options { reject_kind: true, ..Default::default() }, ) .unwrap_err(); assert!( matches!(err, spec::parse::Error::Delegate), "Delegates can refuse spec kind changes to abort parsing early in case they want single-specs only" );} mod include_parents { use git_revision::spec; use crate::spec::parse::{kind::prefix, parse, try_parse, Call}; #[test] fn trailing_caret_at_symbol() { let rec = parse("HEAD^@"); assert_eq!(rec.kind.unwrap(), spec::Kind::IncludeReachableFromParents); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.order, [Call::FindRef, Call::Kind]); assert!(rec.done); let rec = parse("abcd^@"); assert_eq!(rec.kind.unwrap(), spec::Kind::IncludeReachableFromParents); assert_eq!(rec.prefix[0], prefix("abcd").into()); assert_eq!(rec.order, [Call::DisambiguatePrefix, Call::Kind]); assert!(rec.done); let rec = parse("r1^@"); assert_eq!(rec.kind.unwrap(), spec::Kind::IncludeReachableFromParents); assert_eq!(rec.get_ref(0), "r1"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.order, [Call::FindRef, Call::Kind]); assert!(rec.done); } #[test] fn trailing_caret_exclamation_mark_must_end_the_input() { let err = try_parse("r1^@~1").unwrap_err(); assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. })); }} mod exclude_parents { use git_revision::spec; use crate::spec::parse::{kind::prefix, parse, try_parse, Call}; #[test] fn trailing_caret_exclamation_mark() { let rec = parse("HEAD^!"); assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachableFromParents); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.order, [Call::FindRef, Call::Kind]); assert!(rec.done); let rec = parse("abcd^!"); assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachableFromParents); assert_eq!(rec.prefix[0], prefix("abcd").into()); assert_eq!(rec.order, [Call::DisambiguatePrefix, Call::Kind]); assert!(rec.done); let rec = parse("r1^!"); assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachableFromParents); assert_eq!(rec.get_ref(0), "r1"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.order, [Call::FindRef, Call::Kind]); assert!(rec.done); } #[test] fn trailing_caret_exclamation_mark_must_end_the_input() { let err = try_parse("r1^!~1").unwrap_err(); assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. })); }} mod exclusive { use git_revision::spec; use crate::spec::parse::{kind::prefix, parse}; #[test] fn leading_caret() { let rec = parse("^HEAD"); assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachable); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.calls, 2); let rec = parse("^abcd"); assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachable); assert_eq!(rec.find_ref[0], None); assert_eq!(rec.prefix[0], prefix("abcd").into()); assert_eq!(rec.calls, 2); let rec = parse("^r1"); assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachable); assert_eq!(rec.get_ref(0), "r1"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.calls, 2); let rec = parse("^hello-0-gabcd-dirty"); assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachable); assert_eq!(rec.find_ref[0], None); assert_eq!(rec.prefix[0], prefix("abcd").into()); assert_eq!(rec.calls, 2); }} mod range { use git_revision::{spec, spec::parse::delegate::Traversal}; use crate::spec::parse::{kind::prefix, parse, try_parse, Call}; #[test] fn minus_with_n_omitted() { let rec = parse("r1^-"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.get_ref(0), "r1"); assert_eq!(rec.traversal, [Traversal::NthParent(1)], "default is 1"); assert_eq!(rec.get_ref(1), "r1"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.order, [Call::FindRef, Call::Traverse, Call::Kind, Call::FindRef]); assert!(rec.done); let rec = parse("@^-"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.traversal, [Traversal::NthParent(1)], "default is 1"); assert_eq!(rec.get_ref(1), "HEAD"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.order, [Call::FindRef, Call::Traverse, Call::Kind, Call::FindRef]); assert!(rec.done); let rec = parse("abcd^-"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.prefix[0], prefix("abcd").into()); assert_eq!(rec.traversal, [Traversal::NthParent(1)], "default is 1"); assert_eq!(rec.prefix[1], prefix("abcd").into()); assert_eq!( rec.order, [ Call::DisambiguatePrefix, Call::Traverse, Call::Kind, Call::DisambiguatePrefix ] ); assert!(rec.done); } #[test] fn minus_with_n() { let rec = parse("r1^-42"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.get_ref(0), "r1"); assert_eq!(rec.traversal, [Traversal::NthParent(42)]); assert_eq!(rec.get_ref(1), "r1"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.order, [Call::FindRef, Call::Traverse, Call::Kind, Call::FindRef]); assert!(rec.done); let rec = parse("@^-42"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.traversal, [Traversal::NthParent(42)]); assert_eq!(rec.get_ref(1), "HEAD"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.order, [Call::FindRef, Call::Traverse, Call::Kind, Call::FindRef]); assert!(rec.done); let rec = parse("abcd^-42"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.prefix[0], prefix("abcd").into()); assert_eq!(rec.traversal, [Traversal::NthParent(42)]); assert_eq!(rec.prefix[1], prefix("abcd").into()); assert_eq!( rec.order, [ Call::DisambiguatePrefix, Call::Traverse, Call::Kind, Call::DisambiguatePrefix ] ); assert!(rec.done); } #[test] fn minus_with_n_omitted_has_to_end_there() { let err = try_parse("r1^-^").unwrap_err(); assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. })); } #[test] fn minus_with_n_has_to_end_there() { let err = try_parse("r1^-42^").unwrap_err(); assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. })); } #[test] fn minus_with_n_has_to_end_there_and_handle_range_suffix() { let err = try_parse("r1^-42..").unwrap_err(); assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. })); } #[test] fn minus_with_n_omitted_has_to_end_there_and_handle_range_suffix() { let err = try_parse("r1^-..").unwrap_err(); assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. })); } #[test] fn trailing_dot_dot() { let rec = parse("r1.."); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.get_ref(0), "r1"); assert_eq!(rec.get_ref(1), "HEAD"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.order, [Call::FindRef, Call::Kind, Call::FindRef]); } #[test] fn leading_dot_dot() { let rec = parse("..r2"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.get_ref(1), "r2"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.order, [Call::FindRef, Call::Kind, Call::FindRef]); } #[test] fn middle_dot_dot() { let rec = parse("@..r2"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.get_ref(1), "r2"); assert_eq!(rec.calls, 3); let rec = parse("r1..r2"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.get_ref(0), "r1"); assert_eq!(rec.get_ref(1), "r2"); assert_eq!(rec.calls, 3); let rec = parse("abcd..1234"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.prefix[0], prefix("abcd").into()); assert_eq!(rec.prefix[1], prefix("1234").into()); assert_eq!(rec.calls, 3); let rec = parse("r1..abcd"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.get_ref(0), "r1"); assert_eq!(rec.prefix[0], prefix("abcd").into()); assert_eq!(rec.calls, 3); let rec = parse("abcd-dirty..v1.2-42-g1234"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.find_ref[0], None); assert_eq!(rec.prefix[0], prefix("abcd").into()); assert_eq!(rec.prefix[1], prefix("1234").into()); assert_eq!(rec.calls, 3); let rec = parse("v1.2-42-g1234..abcd-dirty"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.find_ref[0], None); assert_eq!(rec.prefix[0], prefix("1234").into()); assert_eq!(rec.prefix[1], prefix("abcd").into()); assert_eq!(rec.calls, 3); let rec = parse("v1.2.4@{1}~~^10..r1@{2}~10^2"); assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween); assert_eq!(rec.get_ref(0), "v1.2.4"); assert_eq!(rec.get_ref(1), "r1"); assert_eq!(&rec.prefix, &[None, None]); assert_eq!( rec.traversal, [ Traversal::NthAncestor(1), Traversal::NthAncestor(1), Traversal::NthParent(10), Traversal::NthAncestor(10), Traversal::NthParent(2) ] ); assert_eq!(rec.calls, 10); assert!(rec.done); }} mod mergebase { use git_revision::{spec, spec::parse::delegate::Traversal}; use crate::spec::parse::{kind::prefix, parse}; #[test] fn trailing_dot_dot_dot() { let rec = parse("HEAD..."); assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.calls, 3); } #[test] fn leading_dot_dot_dot() { let rec = parse("...r2"); assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.get_ref(1), "r2"); assert_eq!(rec.prefix[0], None); assert_eq!(rec.calls, 3); } #[test] fn middle_dot_dot_dot() { let rec = parse("HEAD...@"); assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.get_ref(1), "HEAD"); assert_eq!(rec.calls, 3); let rec = parse("@...HEAD"); assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase); assert_eq!(rec.get_ref(0), "HEAD"); assert_eq!(rec.get_ref(1), "HEAD"); assert_eq!(rec.calls, 3); let rec = parse("r1...abcd"); assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase); assert_eq!(rec.get_ref(0), "r1"); assert_eq!(rec.prefix[0], prefix("abcd").into()); assert_eq!(rec.calls, 3); let rec = parse("v1.2.3-beta.1-42-g1234-dirty...abcd-dirty"); assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase); assert_eq!(rec.find_ref[0], None); assert_eq!(rec.prefix[0], prefix("1234").into()); assert_eq!(rec.prefix[1], prefix("abcd").into()); assert_eq!(rec.calls, 3); let rec = parse("r1@{1}~~^10...@{2}~10^2"); assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase); assert_eq!(rec.get_ref(0), "r1"); assert_eq!(rec.find_ref[1], None, "HEAD is implied"); assert_eq!(&rec.prefix, &[None, None]); assert_eq!( rec.traversal, [ Traversal::NthAncestor(1), Traversal::NthAncestor(1), Traversal::NthParent(10), Traversal::NthAncestor(10), Traversal::NthParent(2) ] ); assert_eq!(rec.calls, 9); assert!(rec.done); }} fn prefix(hex: &str) -> git_hash::Prefix { git_hash::Prefix::from_hex(hex).unwrap()}
use git_revision::spec;
use crate::spec::parse::{try_parse, try_parse_opts, Options};
#[test]
fn cannot_declare_ranges_multiple_times() {
for invalid_spec in ["^HEAD..", "^HEAD..."] {
let err = try_parse(invalid_spec).unwrap_err();
assert!(matches!(err, spec::parse::Error::KindSetTwice { .. }));
}
}
#[test]
fn delegate_can_refuse_spec_kinds() {
let err = try_parse_opts(
"^HEAD",
Options {
reject_kind: true,
..Default::default()
},
)
.unwrap_err();
assert!(
matches!(err, spec::parse::Error::Delegate),
"Delegates can refuse spec kind changes to abort parsing early in case they want single-specs only"
);
}
mod include_parents {
use git_revision::spec;
use crate::spec::parse::{kind::prefix, parse, try_parse, Call};
#[test]
fn trailing_caret_at_symbol() {
let rec = parse("HEAD^@");
assert_eq!(rec.kind.unwrap(), spec::Kind::IncludeReachableFromParents);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.order, [Call::FindRef, Call::Kind]);
assert!(rec.done);
let rec = parse("abcd^@");
assert_eq!(rec.kind.unwrap(), spec::Kind::IncludeReachableFromParents);
assert_eq!(rec.prefix[0], prefix("abcd").into());
assert_eq!(rec.order, [Call::DisambiguatePrefix, Call::Kind]);
assert!(rec.done);
let rec = parse("r1^@");
assert_eq!(rec.kind.unwrap(), spec::Kind::IncludeReachableFromParents);
assert_eq!(rec.get_ref(0), "r1");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.order, [Call::FindRef, Call::Kind]);
assert!(rec.done);
}
#[test]
fn trailing_caret_exclamation_mark_must_end_the_input() {
let err = try_parse("r1^@~1").unwrap_err();
assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. }));
}
}
mod exclude_parents {
use git_revision::spec;
use crate::spec::parse::{kind::prefix, parse, try_parse, Call};
#[test]
fn trailing_caret_exclamation_mark() {
let rec = parse("HEAD^!");
assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachableFromParents);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.order, [Call::FindRef, Call::Kind]);
assert!(rec.done);
let rec = parse("abcd^!");
assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachableFromParents);
assert_eq!(rec.prefix[0], prefix("abcd").into());
assert_eq!(rec.order, [Call::DisambiguatePrefix, Call::Kind]);
assert!(rec.done);
let rec = parse("r1^!");
assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachableFromParents);
assert_eq!(rec.get_ref(0), "r1");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.order, [Call::FindRef, Call::Kind]);
assert!(rec.done);
}
#[test]
fn trailing_caret_exclamation_mark_must_end_the_input() {
let err = try_parse("r1^!~1").unwrap_err();
assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. }));
}
}
mod exclusive {
use git_revision::spec;
use crate::spec::parse::{kind::prefix, parse};
#[test]
fn leading_caret() {
let rec = parse("^HEAD");
assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachable);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.calls, 2);
let rec = parse("^abcd");
assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachable);
assert_eq!(rec.find_ref[0], None);
assert_eq!(rec.prefix[0], prefix("abcd").into());
assert_eq!(rec.calls, 2);
let rec = parse("^r1");
assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachable);
assert_eq!(rec.get_ref(0), "r1");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.calls, 2);
let rec = parse("^hello-0-gabcd-dirty");
assert_eq!(rec.kind.unwrap(), spec::Kind::ExcludeReachable);
assert_eq!(rec.find_ref[0], None);
assert_eq!(rec.prefix[0], prefix("abcd").into());
assert_eq!(rec.calls, 2);
}
}
mod range {
use git_revision::{spec, spec::parse::delegate::Traversal};
use crate::spec::parse::{kind::prefix, parse, try_parse, Call};
#[test]
fn minus_with_n_omitted() {
let rec = parse("r1^-");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.get_ref(0), "r1");
assert_eq!(rec.traversal, [Traversal::NthParent(1)], "default is 1");
assert_eq!(rec.get_ref(1), "r1");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.order, [Call::FindRef, Call::Traverse, Call::Kind, Call::FindRef]);
assert!(rec.done);
let rec = parse("@^-");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.traversal, [Traversal::NthParent(1)], "default is 1");
assert_eq!(rec.get_ref(1), "HEAD");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.order, [Call::FindRef, Call::Traverse, Call::Kind, Call::FindRef]);
assert!(rec.done);
let rec = parse("abcd^-");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.prefix[0], prefix("abcd").into());
assert_eq!(rec.traversal, [Traversal::NthParent(1)], "default is 1");
assert_eq!(rec.prefix[1], prefix("abcd").into());
assert_eq!(
rec.order,
[
Call::DisambiguatePrefix,
Call::Traverse,
Call::Kind,
Call::DisambiguatePrefix
]
);
assert!(rec.done);
}
#[test]
fn minus_with_n() {
let rec = parse("r1^-42");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.get_ref(0), "r1");
assert_eq!(rec.traversal, [Traversal::NthParent(42)]);
assert_eq!(rec.get_ref(1), "r1");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.order, [Call::FindRef, Call::Traverse, Call::Kind, Call::FindRef]);
assert!(rec.done);
let rec = parse("@^-42");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.traversal, [Traversal::NthParent(42)]);
assert_eq!(rec.get_ref(1), "HEAD");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.order, [Call::FindRef, Call::Traverse, Call::Kind, Call::FindRef]);
assert!(rec.done);
let rec = parse("abcd^-42");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.prefix[0], prefix("abcd").into());
assert_eq!(rec.traversal, [Traversal::NthParent(42)]);
assert_eq!(rec.prefix[1], prefix("abcd").into());
assert_eq!(
rec.order,
[
Call::DisambiguatePrefix,
Call::Traverse,
Call::Kind,
Call::DisambiguatePrefix
]
);
assert!(rec.done);
}
#[test]
fn minus_with_n_omitted_has_to_end_there() {
let err = try_parse("r1^-^").unwrap_err();
assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. }));
}
#[test]
fn minus_with_n_has_to_end_there() {
let err = try_parse("r1^-42^").unwrap_err();
assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. }));
}
#[test]
fn minus_with_n_has_to_end_there_and_handle_range_suffix() {
let err = try_parse("r1^-42..").unwrap_err();
assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. }));
}
#[test]
fn minus_with_n_omitted_has_to_end_there_and_handle_range_suffix() {
let err = try_parse("r1^-..").unwrap_err();
assert!(matches!(err, spec::parse::Error::UnconsumedInput { .. }));
}
#[test]
fn trailing_dot_dot() {
let rec = parse("r1..");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.get_ref(0), "r1");
assert_eq!(rec.get_ref(1), "HEAD");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.order, [Call::FindRef, Call::Kind, Call::FindRef]);
}
#[test]
fn leading_dot_dot() {
let rec = parse("..r2");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.get_ref(1), "r2");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.order, [Call::FindRef, Call::Kind, Call::FindRef]);
}
#[test]
fn middle_dot_dot() {
let rec = parse("@..r2");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.get_ref(1), "r2");
assert_eq!(rec.calls, 3);
let rec = parse("r1..r2");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.get_ref(0), "r1");
assert_eq!(rec.get_ref(1), "r2");
assert_eq!(rec.calls, 3);
let rec = parse("abcd..1234");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.prefix[0], prefix("abcd").into());
assert_eq!(rec.prefix[1], prefix("1234").into());
assert_eq!(rec.calls, 3);
let rec = parse("r1..abcd");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.get_ref(0), "r1");
assert_eq!(rec.prefix[0], prefix("abcd").into());
assert_eq!(rec.calls, 3);
let rec = parse("abcd-dirty..v1.2-42-g1234");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.find_ref[0], None);
assert_eq!(rec.prefix[0], prefix("abcd").into());
assert_eq!(rec.prefix[1], prefix("1234").into());
assert_eq!(rec.calls, 3);
let rec = parse("v1.2-42-g1234..abcd-dirty");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.find_ref[0], None);
assert_eq!(rec.prefix[0], prefix("1234").into());
assert_eq!(rec.prefix[1], prefix("abcd").into());
assert_eq!(rec.calls, 3);
let rec = parse("v1.2.4@{1}~~^10..r1@{2}~10^2");
assert_eq!(rec.kind.unwrap(), spec::Kind::RangeBetween);
assert_eq!(rec.get_ref(0), "v1.2.4");
assert_eq!(rec.get_ref(1), "r1");
assert_eq!(&rec.prefix, &[None, None]);
assert_eq!(
rec.traversal,
[
Traversal::NthAncestor(1),
Traversal::NthAncestor(1),
Traversal::NthParent(10),
Traversal::NthAncestor(10),
Traversal::NthParent(2)
]
);
assert_eq!(rec.calls, 10);
assert!(rec.done);
}
}
mod mergebase {
use git_revision::{spec, spec::parse::delegate::Traversal};
use crate::spec::parse::{kind::prefix, parse};
#[test]
fn trailing_dot_dot_dot() {
let rec = parse("HEAD...");
assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.calls, 3);
}
#[test]
fn leading_dot_dot_dot() {
let rec = parse("...r2");
assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.get_ref(1), "r2");
assert_eq!(rec.prefix[0], None);
assert_eq!(rec.calls, 3);
}
#[test]
fn middle_dot_dot_dot() {
let rec = parse("HEAD...@");
assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.get_ref(1), "HEAD");
assert_eq!(rec.calls, 3);
let rec = parse("@...HEAD");
assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase);
assert_eq!(rec.get_ref(0), "HEAD");
assert_eq!(rec.get_ref(1), "HEAD");
assert_eq!(rec.calls, 3);
let rec = parse("r1...abcd");
assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase);
assert_eq!(rec.get_ref(0), "r1");
assert_eq!(rec.prefix[0], prefix("abcd").into());
assert_eq!(rec.calls, 3);
let rec = parse("v1.2.3-beta.1-42-g1234-dirty...abcd-dirty");
assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase);
assert_eq!(rec.find_ref[0], None);
assert_eq!(rec.prefix[0], prefix("1234").into());
assert_eq!(rec.prefix[1], prefix("abcd").into());
assert_eq!(rec.calls, 3);
let rec = parse("r1@{1}~~^10...@{2}~10^2");
assert_eq!(rec.kind.unwrap(), spec::Kind::ReachableToMergeBase);
assert_eq!(rec.get_ref(0), "r1");
assert_eq!(rec.find_ref[1], None, "HEAD is implied");
assert_eq!(&rec.prefix, &[None, None]);
assert_eq!(
rec.traversal,
[
Traversal::NthAncestor(1),
Traversal::NthAncestor(1),
Traversal::NthParent(10),
Traversal::NthAncestor(10),
Traversal::NthParent(2)
]
);
assert_eq!(rec.calls, 9);
assert!(rec.done);
}
}
fn prefix(hex: &str) -> git_hash::Prefix {
git_hash::Prefix::from_hex(hex).unwrap()
}