mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-20 08:01:46 +03:00
233 lines
7.4 KiB
Rust
233 lines
7.4 KiB
Rust
use anyhow::Result;
|
|
use gitbutler_branch_actions::BranchListingFilter;
|
|
|
|
#[test]
|
|
fn one_vbranch_on_integration() -> Result<()> {
|
|
init_env();
|
|
let list = list_branches(&project_ctx("one-vbranch-on-integration")?, None)?;
|
|
assert_eq!(list.len(), 1);
|
|
|
|
assert_equal(
|
|
&list[0],
|
|
ExpectedBranchListing {
|
|
identity: "virtual".into(),
|
|
virtual_branch_given_name: Some("virtual"),
|
|
virtual_branch_in_workspace: true,
|
|
has_local: false,
|
|
..Default::default()
|
|
},
|
|
"It's a bare virtual branch with no commit",
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn one_vbranch_on_integration_one_commit() -> Result<()> {
|
|
init_env();
|
|
let ctx = project_ctx("one-vbranch-on-integration-one-commit")?;
|
|
let list = list_branches(&ctx, None)?;
|
|
assert_eq!(list.len(), 1);
|
|
|
|
assert_equal(
|
|
&list[0],
|
|
ExpectedBranchListing {
|
|
identity: "virtual".into(),
|
|
virtual_branch_given_name: Some("virtual"),
|
|
virtual_branch_in_workspace: true,
|
|
has_local: false,
|
|
..Default::default()
|
|
},
|
|
"It's a bare virtual branch with a single commit",
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn two_vbranches_on_integration_one_commit() -> Result<()> {
|
|
init_env();
|
|
let ctx = project_ctx("two-vbranches-on-integration-one-applied")?;
|
|
let list = list_branches(
|
|
&ctx,
|
|
Some(BranchListingFilter {
|
|
local: Some(true),
|
|
applied: Some(true),
|
|
}),
|
|
)?;
|
|
assert_eq!(list.len(), 1, "only one of these is applied");
|
|
assert_equal(
|
|
&list[0],
|
|
ExpectedBranchListing {
|
|
identity: "other".into(),
|
|
virtual_branch_given_name: Some("other"),
|
|
virtual_branch_in_workspace: true,
|
|
has_local: false,
|
|
..Default::default()
|
|
},
|
|
"It's a bare virtual branch without any branches with the same identity",
|
|
);
|
|
|
|
let list = list_branches(
|
|
&ctx,
|
|
Some(BranchListingFilter {
|
|
local: Some(true),
|
|
applied: Some(false),
|
|
}),
|
|
)?;
|
|
assert_eq!(list.len(), 1, "only one of these is *not* applied");
|
|
assert_equal(
|
|
&list[0],
|
|
ExpectedBranchListing {
|
|
identity: "virtual".into(),
|
|
virtual_branch_given_name: Some("virtual"),
|
|
virtual_branch_in_workspace: false,
|
|
has_local: true,
|
|
..Default::default()
|
|
},
|
|
"It's a bare virtual branch without any branches with the same identity",
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn one_feature_branch_and_one_vbranch_on_integration_one_commit() -> Result<()> {
|
|
init_env();
|
|
let ctx = project_ctx("a-vbranch-named-like-target-branch-short-name")?;
|
|
let list = list_branches(&ctx, None)?;
|
|
assert_eq!(
|
|
list.len(),
|
|
1,
|
|
"it finds our single virtual branch despite it having the same 'identity' as the target branch: 'main'"
|
|
);
|
|
assert_equal(
|
|
&list[0],
|
|
ExpectedBranchListing {
|
|
identity: "main".into(),
|
|
remotes: vec!["origin"],
|
|
virtual_branch_given_name: Some("main"),
|
|
virtual_branch_in_workspace: true,
|
|
has_local: true,
|
|
},
|
|
"virtual branches can have the name of the target, even though it's probably not going to work when pushing. \
|
|
The remotes of the local `refs/heads/main` are shown."
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn one_branch_on_integration_multiple_remotes() -> Result<()> {
|
|
init_env();
|
|
let ctx = project_ctx("one-vbranch-on-integration-two-remotes")?;
|
|
let list = list_branches(&ctx, None)?;
|
|
assert_eq!(list.len(), 1, "a single virtual branch");
|
|
|
|
assert_equal(
|
|
&list[0],
|
|
ExpectedBranchListing {
|
|
identity: "main".into(),
|
|
remotes: vec!["origin", "other-remote"],
|
|
virtual_branch_given_name: Some("main"),
|
|
virtual_branch_in_workspace: true,
|
|
has_local: true,
|
|
},
|
|
"multiple remotes are detected",
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
mod util {
|
|
use anyhow::Result;
|
|
use bstr::BString;
|
|
use gitbutler_branch_actions::{BranchIdentity, BranchListing, BranchListingFilter};
|
|
use gitbutler_command_context::CommandContext;
|
|
|
|
/// A flattened and simplified mirror of `BranchListing` for comparing the actual and expected data.
|
|
#[derive(Debug, PartialEq)]
|
|
pub struct ExpectedBranchListing<'a> {
|
|
pub identity: BranchIdentity,
|
|
pub remotes: Vec<&'a str>,
|
|
pub virtual_branch_given_name: Option<&'a str>,
|
|
pub virtual_branch_in_workspace: bool,
|
|
pub has_local: bool,
|
|
}
|
|
|
|
impl Default for ExpectedBranchListing<'static> {
|
|
fn default() -> Self {
|
|
ExpectedBranchListing {
|
|
identity: "<invalid identity - should always be specified".into(),
|
|
remotes: vec![],
|
|
virtual_branch_given_name: None,
|
|
virtual_branch_in_workspace: false,
|
|
has_local: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn assert_equal(
|
|
BranchListing {
|
|
name,
|
|
remotes,
|
|
virtual_branch,
|
|
updated_at: _,
|
|
head: _, // NOTE: can't have stable commits while `gitbutler-change-id` is not stable/is a UUID.
|
|
last_commiter: _,
|
|
has_local,
|
|
}: &BranchListing,
|
|
expected: ExpectedBranchListing,
|
|
msg: &str,
|
|
) {
|
|
assert_eq!(*name, expected.identity, "identity: {msg}");
|
|
assert_eq!(
|
|
*remotes,
|
|
expected
|
|
.remotes
|
|
.into_iter()
|
|
.map(BString::from)
|
|
.collect::<Vec<_>>(),
|
|
"remotes: {msg}"
|
|
);
|
|
assert_eq!(
|
|
virtual_branch.as_ref().map(|b| b.given_name.as_str()),
|
|
expected.virtual_branch_given_name,
|
|
"virtual-branch-name: {msg}"
|
|
);
|
|
assert_eq!(
|
|
virtual_branch.as_ref().map_or(false, |b| b.in_workspace),
|
|
expected.virtual_branch_in_workspace,
|
|
"virtual-branch-in-workspace: {msg}"
|
|
);
|
|
assert_eq!(*has_local, expected.has_local, "{msg}");
|
|
}
|
|
|
|
/// This function affects all tests, but those who care should just call it, assuming
|
|
/// they all care for the same default value.
|
|
/// If not, they should be placed in their own integration test or run with `#[serial_test:serial]`.
|
|
/// For `list_branches` it's needed as it compares the current author with commit authors to determine ownership.
|
|
pub fn init_env() {
|
|
for (name, value) in [
|
|
("GIT_AUTHOR_DATE", "2000-01-01 00:00:00 +0000"),
|
|
("GIT_AUTHOR_EMAIL", "author@example.com"),
|
|
("GIT_AUTHOR_NAME", "author"),
|
|
("GIT_COMMITTER_DATE", "2000-01-02 00:00:00 +0000"),
|
|
("GIT_COMMITTER_EMAIL", "committer@example.com"),
|
|
("GIT_COMMITTER_NAME", "committer"),
|
|
] {
|
|
std::env::set_var(name, value);
|
|
}
|
|
}
|
|
|
|
pub fn project_ctx(name: &str) -> Result<CommandContext> {
|
|
gitbutler_testsupport::read_only::fixture("for-listing.sh", name)
|
|
}
|
|
|
|
pub fn list_branches(
|
|
ctx: &CommandContext,
|
|
filter: Option<BranchListingFilter>,
|
|
) -> Result<Vec<BranchListing>> {
|
|
let mut branches = gitbutler_branch_actions::list_branches(ctx, filter, None)?;
|
|
branches.sort_by(|a, b| a.name.cmp(&b.name));
|
|
Ok(branches)
|
|
}
|
|
}
|
|
use util::{assert_equal, init_env, list_branches, project_ctx, ExpectedBranchListing};
|