Show the window before slow location probes and wrap git.exe for commit, diff, and merge.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-24 16:31:56 +02:00
parent a3c54bbb03
commit 9efb306979
42 changed files with 3184 additions and 77 deletions

View File

@@ -0,0 +1,114 @@
using Explorer.Application;
using Explorer.Domain;
namespace Explorer.Application.Tests;
public class GitCommitPlannerTests
{
private static readonly HashSet<string> None = new(StringComparer.OrdinalIgnoreCase);
[Fact]
public void Rejects_an_empty_message()
{
var plan = GitCommitPlanner.Create(
" ",
[Change("src/App.cs")],
None,
None,
operationInProgress: false);
Assert.False(plan.CanCommit);
Assert.Equal("Enter a commit message.", plan.Error);
}
[Fact]
public void Rejects_merge_or_rebase_in_progress()
{
var plan = GitCommitPlanner.Create(
"wip",
[Change("src/App.cs")],
None,
None,
operationInProgress: true);
Assert.False(plan.CanCommit);
Assert.Contains("merge or rebase", plan.Error, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void Skips_unmerged_hydration_and_directories()
{
var plan = GitCommitPlanner.Create(
"save",
[
Change("conflict.txt", GitChangeState.Unmerged, 'U', 'U'),
Change("cloud.bin"),
Change("src"),
],
new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "cloud.bin" },
new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "src" },
operationInProgress: false);
Assert.False(plan.CanCommit);
Assert.Equal(["conflict.txt"], plan.SkippedUnmerged);
Assert.Equal(["cloud.bin"], plan.SkippedHydration);
Assert.Equal(["src"], plan.SkippedDirectories);
Assert.Contains("online-only", plan.Error, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void Dedupes_staged_and_unstaged_of_the_same_path()
{
var plan = GitCommitPlanner.Create(
"both",
[
Change("src/Both.cs", GitChangeState.Staged, 'M', '.'),
Change("src/Both.cs", GitChangeState.Unstaged, '.', 'M'),
],
None,
None,
operationInProgress: false);
Assert.True(plan.CanCommit);
Assert.Equal(["src/Both.cs"], plan.Paths);
}
[Fact]
public void Commits_files_and_deleted_paths_while_skipping_the_rest()
{
var plan = GitCommitPlanner.Create(
"mixed",
[
Change("keep.cs"),
Change("gone.cs", GitChangeState.Unstaged, '.', 'D'),
Change("conflict.txt", GitChangeState.Unmerged, 'U', 'U'),
Change("cloud.bin"),
Change("src"),
],
new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "cloud.bin" },
new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "src", "gone.cs" },
operationInProgress: false);
Assert.True(plan.CanCommit);
Assert.Equal(["keep.cs", "gone.cs"], plan.Paths);
Assert.Equal(["conflict.txt"], plan.SkippedUnmerged);
Assert.Equal(["cloud.bin"], plan.SkippedHydration);
Assert.Equal(["src"], plan.SkippedDirectories);
}
[Fact]
public void Requires_at_least_one_file()
{
var plan = GitCommitPlanner.Create("msg", [], None, None, operationInProgress: false);
Assert.False(plan.CanCommit);
Assert.Equal("Select at least one file to commit.", plan.Error);
}
private static GitChange Change(
string path,
GitChangeState state = GitChangeState.Unstaged,
char index = '.',
char workTree = 'M')
=> new()
{
Path = path,
State = state,
Index = index,
WorkTree = workTree
};
}