package pages import ( "testing" "time" "tasksquire/timewarrior" ) func TestInsertGaps(t *testing.T) { tests := []struct { name string intervals timewarrior.Intervals expectedCount int expectedGaps int description string }{ { name: "empty intervals", intervals: timewarrior.Intervals{}, expectedCount: 0, expectedGaps: 0, description: "Should return empty list for empty input", }, { name: "single interval", intervals: timewarrior.Intervals{ { ID: 1, Start: time.Now().Add(-1 * time.Hour).UTC().Format("20060102T150405Z"), End: time.Now().UTC().Format("20060102T150405Z"), Tags: []string{"test"}, }, }, expectedCount: 1, expectedGaps: 0, description: "Should return single interval without gaps", }, { name: "two intervals with gap (reverse chronological)", intervals: timewarrior.Intervals{ { ID: 1, Start: time.Now().Add(-1 * time.Hour).UTC().Format("20060102T150405Z"), End: time.Now().UTC().Format("20060102T150405Z"), Tags: []string{"test2"}, }, { ID: 2, Start: time.Now().Add(-3 * time.Hour).UTC().Format("20060102T150405Z"), End: time.Now().Add(-2 * time.Hour).UTC().Format("20060102T150405Z"), Tags: []string{"test1"}, }, }, expectedCount: 3, expectedGaps: 1, description: "Should insert one gap between two intervals (newest first order)", }, { name: "three intervals with two gaps (reverse chronological)", intervals: timewarrior.Intervals{ { ID: 1, Start: time.Now().Add(-1 * time.Hour).UTC().Format("20060102T150405Z"), End: time.Now().UTC().Format("20060102T150405Z"), Tags: []string{"test3"}, }, { ID: 2, Start: time.Now().Add(-3 * time.Hour).UTC().Format("20060102T150405Z"), End: time.Now().Add(-2 * time.Hour).UTC().Format("20060102T150405Z"), Tags: []string{"test2"}, }, { ID: 3, Start: time.Now().Add(-5 * time.Hour).UTC().Format("20060102T150405Z"), End: time.Now().Add(-4 * time.Hour).UTC().Format("20060102T150405Z"), Tags: []string{"test1"}, }, }, expectedCount: 5, expectedGaps: 2, description: "Should insert two gaps between three intervals (newest first order)", }, { name: "consecutive intervals with no gap (reverse chronological)", intervals: timewarrior.Intervals{ { ID: 1, Start: time.Now().Add(-1 * time.Hour).UTC().Format("20060102T150405Z"), End: time.Now().UTC().Format("20060102T150405Z"), Tags: []string{"test2"}, }, { ID: 2, Start: time.Now().Add(-2 * time.Hour).UTC().Format("20060102T150405Z"), End: time.Now().Add(-1 * time.Hour).UTC().Format("20060102T150405Z"), Tags: []string{"test1"}, }, }, expectedCount: 2, expectedGaps: 0, description: "Should not insert gap when intervals are consecutive (newest first order)", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := insertGaps(tt.intervals) if len(result) != tt.expectedCount { t.Errorf("insertGaps() returned %d intervals, expected %d. %s", len(result), tt.expectedCount, tt.description) } gapCount := 0 for _, interval := range result { if interval.IsGap { gapCount++ } } if gapCount != tt.expectedGaps { t.Errorf("insertGaps() created %d gaps, expected %d. %s", gapCount, tt.expectedGaps, tt.description) } // Verify gaps are properly interleaved with intervals for i := 0; i < len(result)-1; i++ { if result[i].IsGap && result[i+1].IsGap { t.Errorf("insertGaps() created consecutive gap rows at indices %d and %d", i, i+1) } } // Verify first and last items are never gaps if len(result) > 0 { if result[0].IsGap { t.Errorf("insertGaps() created gap as first item") } if result[len(result)-1].IsGap { t.Errorf("insertGaps() created gap as last item") } } }) } }