Skip to content

Commit a9e193a

Browse files
committed
test: add unit tests for LifecycleEventManager to cover event handling and error paths
1 parent 26a2647 commit a9e193a

1 file changed

Lines changed: 199 additions & 0 deletions

File tree

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
*--------------------------------------------------------------------------------------------*/
4+
5+
package com.github.copilot.sdk;
6+
7+
import static org.junit.jupiter.api.Assertions.*;
8+
9+
import java.util.ArrayList;
10+
11+
import org.junit.jupiter.api.BeforeEach;
12+
import org.junit.jupiter.api.Test;
13+
14+
import com.github.copilot.sdk.json.SessionLifecycleEvent;
15+
16+
/**
17+
* Unit tests for {@link LifecycleEventManager} covering subscribe, unsubscribe,
18+
* dispatch, typed handlers, wildcard handlers, and error handling paths
19+
* identified as gaps by JaCoCo.
20+
*/
21+
class LifecycleEventManagerTest {
22+
23+
private LifecycleEventManager manager;
24+
25+
@BeforeEach
26+
void setup() {
27+
manager = new LifecycleEventManager();
28+
}
29+
30+
private static SessionLifecycleEvent event(String type) {
31+
var e = new SessionLifecycleEvent();
32+
e.setType(type);
33+
return e;
34+
}
35+
36+
// ===== wildcard subscribe / dispatch =====
37+
38+
@Test
39+
void wildcardHandlerReceivesAllEvents() {
40+
var received = new ArrayList<SessionLifecycleEvent>();
41+
manager.subscribe(received::add);
42+
43+
manager.dispatch(event("created"));
44+
manager.dispatch(event("deleted"));
45+
46+
assertEquals(2, received.size());
47+
assertEquals("created", received.get(0).getType());
48+
assertEquals("deleted", received.get(1).getType());
49+
}
50+
51+
@Test
52+
void wildcardUnsubscribeStopsDelivery() throws Exception {
53+
var received = new ArrayList<SessionLifecycleEvent>();
54+
AutoCloseable sub = manager.subscribe(received::add);
55+
56+
manager.dispatch(event("created"));
57+
assertEquals(1, received.size());
58+
59+
sub.close();
60+
61+
manager.dispatch(event("deleted"));
62+
assertEquals(1, received.size(), "Should not receive events after unsubscribe");
63+
}
64+
65+
// ===== typed subscribe / dispatch =====
66+
67+
@Test
68+
void typedHandlerReceivesOnlyMatchingEvents() {
69+
var received = new ArrayList<SessionLifecycleEvent>();
70+
manager.subscribe("created", received::add);
71+
72+
manager.dispatch(event("created"));
73+
manager.dispatch(event("deleted"));
74+
75+
assertEquals(1, received.size());
76+
assertEquals("created", received.get(0).getType());
77+
}
78+
79+
@Test
80+
void typedUnsubscribeStopsDelivery() throws Exception {
81+
var received = new ArrayList<SessionLifecycleEvent>();
82+
AutoCloseable sub = manager.subscribe("created", received::add);
83+
84+
manager.dispatch(event("created"));
85+
assertEquals(1, received.size());
86+
87+
sub.close();
88+
89+
manager.dispatch(event("created"));
90+
assertEquals(1, received.size(), "Should not receive events after unsubscribe");
91+
}
92+
93+
// ===== both typed + wildcard =====
94+
95+
@Test
96+
void bothTypedAndWildcardReceiveEvent() {
97+
var typedReceived = new ArrayList<SessionLifecycleEvent>();
98+
var wildcardReceived = new ArrayList<SessionLifecycleEvent>();
99+
100+
manager.subscribe("created", typedReceived::add);
101+
manager.subscribe(wildcardReceived::add);
102+
103+
manager.dispatch(event("created"));
104+
105+
assertEquals(1, typedReceived.size());
106+
assertEquals(1, wildcardReceived.size());
107+
}
108+
109+
// ===== dispatch with no handlers =====
110+
111+
@Test
112+
void dispatchWithNoHandlersDoesNotThrow() {
113+
assertDoesNotThrow(() -> manager.dispatch(event("created")));
114+
}
115+
116+
@Test
117+
void dispatchWithNoTypedMatchDoesNotThrow() {
118+
var received = new ArrayList<SessionLifecycleEvent>();
119+
manager.subscribe("deleted", received::add);
120+
121+
assertDoesNotThrow(() -> manager.dispatch(event("created")));
122+
assertTrue(received.isEmpty());
123+
}
124+
125+
// ===== error handling =====
126+
127+
@Test
128+
void typedHandlerExceptionDoesNotPreventOtherHandlers() {
129+
var received = new ArrayList<SessionLifecycleEvent>();
130+
131+
// First handler throws
132+
manager.subscribe("created", e -> {
133+
throw new RuntimeException("typed handler error");
134+
});
135+
// Second handler should still receive the event
136+
manager.subscribe("created", received::add);
137+
138+
assertDoesNotThrow(() -> manager.dispatch(event("created")));
139+
assertEquals(1, received.size());
140+
}
141+
142+
@Test
143+
void wildcardHandlerExceptionDoesNotPreventOtherHandlers() {
144+
var received = new ArrayList<SessionLifecycleEvent>();
145+
146+
manager.subscribe(e -> {
147+
throw new RuntimeException("wildcard handler error");
148+
});
149+
manager.subscribe(received::add);
150+
151+
assertDoesNotThrow(() -> manager.dispatch(event("created")));
152+
assertEquals(1, received.size());
153+
}
154+
155+
@Test
156+
void typedAndWildcardErrorsDoNotAffectEachOther() {
157+
var wildcardReceived = new ArrayList<SessionLifecycleEvent>();
158+
159+
// Typed handler throws
160+
manager.subscribe("created", e -> {
161+
throw new RuntimeException("typed error");
162+
});
163+
// Wildcard still receives
164+
manager.subscribe(wildcardReceived::add);
165+
166+
assertDoesNotThrow(() -> manager.dispatch(event("created")));
167+
assertEquals(1, wildcardReceived.size());
168+
}
169+
170+
// ===== multiple handlers =====
171+
172+
@Test
173+
void multipleWildcardHandlersAllReceive() {
174+
var list1 = new ArrayList<SessionLifecycleEvent>();
175+
var list2 = new ArrayList<SessionLifecycleEvent>();
176+
177+
manager.subscribe(list1::add);
178+
manager.subscribe(list2::add);
179+
180+
manager.dispatch(event("updated"));
181+
182+
assertEquals(1, list1.size());
183+
assertEquals(1, list2.size());
184+
}
185+
186+
@Test
187+
void multipleTypedHandlersAllReceive() {
188+
var list1 = new ArrayList<SessionLifecycleEvent>();
189+
var list2 = new ArrayList<SessionLifecycleEvent>();
190+
191+
manager.subscribe("updated", list1::add);
192+
manager.subscribe("updated", list2::add);
193+
194+
manager.dispatch(event("updated"));
195+
196+
assertEquals(1, list1.size());
197+
assertEquals(1, list2.size());
198+
}
199+
}

0 commit comments

Comments
 (0)