| 1 | package calendar |
| 2 | |
| 3 | import ( |
| 4 | "testing" |
| 5 | "time" |
| 6 | ) |
| 7 | |
| 8 | func TestInvertedGapOccurrenceRefusesOnlyAffectedWindows(t *testing.T) { |
| 9 | r, err := ParseRule("FREQ=DAILY") |
| 10 | if err != nil { |
| 11 | t.Fatal(err) |
| 12 | } |
| 13 | for _, c := range []struct { |
| 14 | name, from, to, exclude string |
| 15 | complete bool |
| 16 | count int |
| 17 | }{ |
| 18 | {"gap", "2026-03-29T00:00:00Z", "2026-03-30T00:00:00Z", "", false, 0}, |
| 19 | {"between-endpoints", "2026-03-29T01:10:00Z", "2026-03-29T01:20:00Z", "", false, 0}, |
| 20 | {"resolved-start", "2026-03-29T01:30:00Z", "2026-03-29T02:00:00Z", "", false, 0}, |
| 21 | {"before-gap", "2026-03-28T00:00:00Z", "2026-03-29T00:00:00Z", "", true, 1}, |
| 22 | {"after-gap", "2026-04-01T00:00:00Z", "2026-04-02T00:00:00Z", "", true, 1}, |
| 23 | {"excluded", "2026-03-29T00:00:00Z", "2026-03-30T00:00:00Z", "2026-03-29T02:30", true, 0}, |
| 24 | {"walk-continues", "2026-03-29T00:00:00Z", "2026-03-31T00:00:00Z", "", false, 1}, |
| 25 | } { |
| 26 | t.Run(c.name, func(t *testing.T) { |
| 27 | from, _ := time.Parse(time.RFC3339, c.from) |
| 28 | to, _ := time.Parse(time.RFC3339, c.to) |
| 29 | got, complete := ExpandComplete("2026-03-01T01:30", "2026-03-01T02:00", "Europe/Dublin", false, r, c.exclude, from.Unix(), to.Unix()) |
| 30 | if complete != c.complete || len(got) != c.count { |
| 31 | t.Fatalf("got=%v complete=%v; want count=%d complete=%v", got, complete, c.count, c.complete) |
| 32 | } |
| 33 | for _, o := range got { |
| 34 | if o.EndUTC-o.StartUTC != 1800 { |
| 35 | t.Fatalf("ordinary occurrence changed: %+v", o) |
| 36 | } |
| 37 | } |
| 38 | }) |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | func TestCollapsedGapOccurrenceIsIncomplete(t *testing.T) { |
| 43 | r, err := ParseRule("FREQ=DAILY;COUNT=2") |
| 44 | if err != nil { |
| 45 | t.Fatal(err) |
| 46 | } |
| 47 | from := time.Date(2026, 3, 29, 0, 0, 0, 0, time.UTC).Unix() |
| 48 | got, complete := ExpandComplete("2026-03-28T01:30", "2026-03-28T02:30", "Europe/Dublin", false, r, "", from, from+86400) |
| 49 | if complete || len(got) != 0 { |
| 50 | t.Fatalf("collapsed gap got=%v complete=%v", got, complete) |
| 51 | } |
| 52 | } |
| 53 | |