115 lines
3.7 KiB
C#
115 lines
3.7 KiB
C#
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
|
|
};
|
|
}
|