| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "sync" |
| 5 | "testing" |
| 6 | ) |
| 7 | |
| 8 | func TestTopicActivationTerminalClaimSurvivesPendingPrune(t *testing.T) { |
| 9 | for _, cancelBuild := range []bool{false, true} { |
| 10 | name := "direct-tab-switch" |
| 11 | if cancelBuild { |
| 12 | name = "topic-switch" |
| 13 | } |
| 14 | t.Run(name, func(t *testing.T) { |
| 15 | app := NewApp() |
| 16 | app.tabs["old"] = &WorkspaceTab{ID: "old", Ready: true, Ctrl: &activationStubController{}} |
| 17 | app.activationGen = 1 |
| 18 | app.latestActivationRequestID, app.pendingActivationTabID = "first", "old" |
| 19 | entered, release, done := make(chan struct{}), make(chan struct{}), make(chan bool, 1) |
| 20 | unblock := sync.OnceFunc(func() { close(release) }) |
| 21 | defer unblock() |
| 22 | app.activationEventHook = func(ev TopicActivationEvent) { |
| 23 | if ev.RequestID != "first" || ev.Phase != topicActivationPhaseReady { |
| 24 | t.Errorf("unexpected terminal: %+v", ev) |
| 25 | } |
| 26 | close(entered) |
| 27 | <-release // readiness is published; prune has not started |
| 28 | } |
| 29 | go func() { done <- app.emitTopicActivationReadyIfCurrent(1, "first", "old") }() |
| 30 | <-entered |
| 31 | app.mu.Lock() |
| 32 | previous, _ := app.supersedePendingTopicActivationLocked("new", cancelBuild) |
| 33 | app.latestActivationRequestID, app.pendingActivationTabID = "second", "new" |
| 34 | app.mu.Unlock() |
| 35 | if previous != "" { |
| 36 | t.Errorf("ready activation was cancelled again: %s", previous) |
| 37 | } |
| 38 | unblock() |
| 39 | if !<-done { |
| 40 | t.Fatal("ready activation did not claim its terminal event") |
| 41 | } |
| 42 | app.finishTopicActivation(1, "first") |
| 43 | if app.latestActivationRequestID != "second" || app.pendingActivationTabID != "new" { |
| 44 | t.Fatal("late completion cleared the newer navigation") |
| 45 | } |
| 46 | app.mu.Lock() |
| 47 | previous, _ = app.supersedePendingTopicActivationLocked("third", cancelBuild) |
| 48 | app.mu.Unlock() |
| 49 | if previous != "second" { |
| 50 | t.Fatal("unfinished sibling activation lost its cancellation") |
| 51 | } |
| 52 | if app.emitTopicActivationReadyIfCurrent(1, "first", "old") { |
| 53 | t.Fatal("superseded generation emitted readiness") |
| 54 | } |
| 55 | }) |
| 56 | } |
| 57 | } |
| 58 |