using ClaudeDo.Data.Models; using ClaudeDo.Ui.ViewModels.Islands; using TaskStatus = ClaudeDo.Data.Models.TaskStatus; namespace ClaudeDo.Worker.Tests.UiVm; public class ParseDiffStatTests { [Fact] public void Null_Returns_Zero() { var (add, del) = DetailsIslandViewModel.ParseDiffStat(null); Assert.Equal(0, add); Assert.Equal(0, del); } [Fact] public void Empty_Returns_Zero() { var (add, del) = DetailsIslandViewModel.ParseDiffStat(""); Assert.Equal(0, add); Assert.Equal(0, del); } [Fact] public void Full_Stat_Parses_Both() { var (add, del) = DetailsIslandViewModel.ParseDiffStat("2 files changed, 10 insertions(+), 3 deletions(-)"); Assert.Equal(10, add); Assert.Equal(3, del); } [Fact] public void Insertions_Only_Returns_Zero_Deletions() { var (add, del) = DetailsIslandViewModel.ParseDiffStat("1 file changed, 5 insertions(+)"); Assert.Equal(5, add); Assert.Equal(0, del); } [Fact] public void Deletions_Only_Returns_Zero_Insertions() { var (add, del) = DetailsIslandViewModel.ParseDiffStat("1 file changed, 4 deletions(-)"); Assert.Equal(0, add); Assert.Equal(4, del); } // German-Windows git localizes "insertion(s)"/"deletion(s)" (e.g. "Einfügung(en)"/ // "Löschung(en)") but keeps the (+)/(-) suffix untranslated — the regex anchors on that. [Fact] public void German_Locale_Stat_Parses_Both() { var (add, del) = DetailsIslandViewModel.ParseDiffStat("2 Dateien geändert, 10 Einfügungen(+), 3 Löschungen(-)"); Assert.Equal(10, add); Assert.Equal(3, del); } [Fact] public void German_Locale_Insertions_Only_Returns_Zero_Deletions() { var (add, del) = DetailsIslandViewModel.ParseDiffStat("1 Datei geändert, 5 Einfügung(en)(+)"); Assert.Equal(5, add); Assert.Equal(0, del); } // TaskRowViewModel used to run its own broken parser (expecting "+12"/"-3" tokens that // `git diff --stat` never emits) — pin it to the same shared, correct parser as the detail badge. [Fact] public void TaskRowViewModel_UpdateFromEntity_Parses_Real_DiffStat_Format() { var task = new TaskEntity { Id = "t1", ListId = "l1", Title = "task", CreatedAt = DateTime.UtcNow, Status = TaskStatus.Done, Worktree = new WorktreeEntity { TaskId = "t1", Path = "/tmp/wt", BranchName = "claudedo/t1", BaseCommit = "abc", DiffStat = "2 files changed, 10 insertions(+), 3 deletions(-)", CreatedAt = DateTime.UtcNow, }, }; var row = TaskRowViewModel.FromEntity(task); Assert.Equal(10, row.DiffAdditions); Assert.Equal(3, row.DiffDeletions); } }