Skip to content

Commit 08dc6ea

Browse files
committed
Add tests
1 parent 1fce725 commit 08dc6ea

File tree

3 files changed

+655
-0
lines changed

3 files changed

+655
-0
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
package io.split.android.client.service.sseclient.sseclient;
2+
3+
import static org.junit.Assert.assertEquals;
4+
import static org.mockito.ArgumentMatchers.any;
5+
import static org.mockito.ArgumentMatchers.anyLong;
6+
import static org.mockito.ArgumentMatchers.eq;
7+
import static org.mockito.ArgumentMatchers.isNull;
8+
import static org.mockito.Mockito.mock;
9+
import static org.mockito.Mockito.never;
10+
import static org.mockito.Mockito.times;
11+
import static org.mockito.Mockito.verify;
12+
import static org.mockito.Mockito.when;
13+
14+
import org.junit.Before;
15+
import org.junit.Test;
16+
import org.mockito.ArgumentCaptor;
17+
18+
import io.split.android.client.service.executor.SplitTask;
19+
import io.split.android.client.service.executor.SplitTaskExecutionInfo;
20+
import io.split.android.client.service.executor.SplitTaskExecutionListener;
21+
import io.split.android.client.service.executor.SplitTaskExecutionStatus;
22+
import io.split.android.client.service.executor.SplitTaskExecutor;
23+
import io.split.android.client.service.executor.SplitTaskType;
24+
import io.split.android.client.service.sseclient.spi.StreamingScheduler;
25+
26+
public class SplitTaskExecutorStreamingSchedulerTest {
27+
28+
private SplitTaskExecutor mTaskExecutor;
29+
private SplitTaskExecutorStreamingScheduler mScheduler;
30+
31+
@Before
32+
public void setUp() {
33+
mTaskExecutor = mock(SplitTaskExecutor.class);
34+
mScheduler = new SplitTaskExecutorStreamingScheduler(mTaskExecutor);
35+
}
36+
37+
@Test
38+
public void scheduleReturnsTaskIdFromExecutor() {
39+
when(mTaskExecutor.schedule(any(SplitTask.class), eq(10L), any(SplitTaskExecutionListener.class)))
40+
.thenReturn("task-123");
41+
42+
String taskId = mScheduler.schedule(() -> {}, 10L, null);
43+
44+
assertEquals("task-123", taskId);
45+
}
46+
47+
@Test
48+
public void scheduleUsesCorrectDelay() {
49+
Runnable task = mock(Runnable.class);
50+
51+
mScheduler.schedule(task, 42L, null);
52+
53+
verify(mTaskExecutor).schedule(any(SplitTask.class), eq(42L), any(SplitTaskExecutionListener.class));
54+
}
55+
56+
@Test
57+
public void scheduledTaskExecutesRunnable() {
58+
Runnable task = mock(Runnable.class);
59+
ArgumentCaptor<SplitTask> taskCaptor = ArgumentCaptor.forClass(SplitTask.class);
60+
61+
when(mTaskExecutor.schedule(taskCaptor.capture(), eq(10L), any(SplitTaskExecutionListener.class)))
62+
.thenReturn("task-id");
63+
64+
mScheduler.schedule(task, 10L, null);
65+
66+
// Execute the captured SplitTask
67+
SplitTask splitTask = taskCaptor.getValue();
68+
splitTask.execute();
69+
70+
verify(task).run();
71+
}
72+
73+
@Test
74+
public void scheduledTaskReturnsSuccessWhenRunnableCompletesNormally() {
75+
Runnable task = () -> { /* normal execution */ };
76+
ArgumentCaptor<SplitTask> taskCaptor = ArgumentCaptor.forClass(SplitTask.class);
77+
78+
when(mTaskExecutor.schedule(taskCaptor.capture(), anyLong(), any()))
79+
.thenReturn("task-id");
80+
81+
mScheduler.schedule(task, 10L, null);
82+
83+
SplitTask splitTask = taskCaptor.getValue();
84+
SplitTaskExecutionInfo result = splitTask.execute();
85+
86+
assertEquals(SplitTaskExecutionStatus.SUCCESS, result.getStatus());
87+
assertEquals(SplitTaskType.GENERIC_TASK, result.getTaskType());
88+
}
89+
90+
@Test
91+
public void scheduledTaskReturnsErrorWhenRunnableThrowsException() {
92+
Runnable task = () -> {
93+
throw new RuntimeException("Task failed");
94+
};
95+
ArgumentCaptor<SplitTask> taskCaptor = ArgumentCaptor.forClass(SplitTask.class);
96+
97+
when(mTaskExecutor.schedule(taskCaptor.capture(), anyLong(), any()))
98+
.thenReturn("task-id");
99+
100+
mScheduler.schedule(task, 10L, null);
101+
102+
SplitTask splitTask = taskCaptor.getValue();
103+
SplitTaskExecutionInfo result = splitTask.execute();
104+
105+
assertEquals(SplitTaskExecutionStatus.ERROR, result.getStatus());
106+
assertEquals(SplitTaskType.GENERIC_TASK, result.getTaskType());
107+
}
108+
109+
@Test
110+
public void listenerIsCalledWhenTaskCompletes() {
111+
StreamingScheduler.TaskExecutionListener listener = mock(StreamingScheduler.TaskExecutionListener.class);
112+
ArgumentCaptor<SplitTaskExecutionListener> listenerCaptor =
113+
ArgumentCaptor.forClass(SplitTaskExecutionListener.class);
114+
115+
when(mTaskExecutor.schedule(any(SplitTask.class), anyLong(), listenerCaptor.capture()))
116+
.thenReturn("task-id");
117+
118+
mScheduler.schedule(() -> {}, 10L, listener);
119+
120+
// Simulate task completion
121+
SplitTaskExecutionListener splitListener = listenerCaptor.getValue();
122+
splitListener.taskExecuted(SplitTaskExecutionInfo.success(SplitTaskType.GENERIC_TASK));
123+
124+
verify(listener).onTaskExecuted();
125+
}
126+
127+
@Test
128+
public void listenerIsNotCalledWhenNull() {
129+
ArgumentCaptor<SplitTaskExecutionListener> listenerCaptor =
130+
ArgumentCaptor.forClass(SplitTaskExecutionListener.class);
131+
132+
when(mTaskExecutor.schedule(any(SplitTask.class), anyLong(), listenerCaptor.capture()))
133+
.thenReturn("task-id");
134+
135+
// Schedule with null listener - should not throw
136+
mScheduler.schedule(() -> {}, 10L, null);
137+
138+
// Simulate task completion - should not throw
139+
SplitTaskExecutionListener splitListener = listenerCaptor.getValue();
140+
splitListener.taskExecuted(SplitTaskExecutionInfo.success(SplitTaskType.GENERIC_TASK));
141+
142+
// No exception means test passes
143+
}
144+
145+
@Test
146+
public void cancelWithNullTaskIdDoesNotCallStopTask() {
147+
mScheduler.cancel(null);
148+
149+
// When taskId is null, stopTask should not be called
150+
verify(mTaskExecutor, never()).stopTask(any());
151+
}
152+
153+
@Test
154+
public void cancelWithNonNullTaskIdCallsStopTask() {
155+
mScheduler.cancel("task-456");
156+
157+
verify(mTaskExecutor).stopTask("task-456");
158+
}
159+
160+
@Test
161+
public void scheduledTaskHandlesDifferentExceptionTypes() {
162+
// Test with different exception types to ensure all are caught
163+
Runnable task1 = () -> {
164+
throw new IllegalArgumentException("Invalid argument");
165+
};
166+
Runnable task2 = () -> {
167+
throw new NullPointerException("Null pointer");
168+
};
169+
170+
ArgumentCaptor<SplitTask> taskCaptor = ArgumentCaptor.forClass(SplitTask.class);
171+
when(mTaskExecutor.schedule(taskCaptor.capture(), anyLong(), any()))
172+
.thenReturn("task-id");
173+
174+
// Test IllegalArgumentException
175+
mScheduler.schedule(task1, 10L, null);
176+
SplitTask splitTask1 = taskCaptor.getValue();
177+
SplitTaskExecutionInfo result1 = splitTask1.execute();
178+
assertEquals(SplitTaskExecutionStatus.ERROR, result1.getStatus());
179+
180+
// Test NullPointerException
181+
mScheduler.schedule(task2, 10L, null);
182+
SplitTask splitTask2 = taskCaptor.getAllValues().get(1);
183+
SplitTaskExecutionInfo result2 = splitTask2.execute();
184+
assertEquals(SplitTaskExecutionStatus.ERROR, result2.getStatus());
185+
}
186+
187+
@Test
188+
public void multipleScheduleCallsWorkIndependently() {
189+
when(mTaskExecutor.schedule(any(SplitTask.class), eq(10L), any()))
190+
.thenReturn("task-1");
191+
when(mTaskExecutor.schedule(any(SplitTask.class), eq(20L), any()))
192+
.thenReturn("task-2");
193+
194+
String taskId1 = mScheduler.schedule(() -> {}, 10L, null);
195+
String taskId2 = mScheduler.schedule(() -> {}, 20L, null);
196+
197+
assertEquals("task-1", taskId1);
198+
assertEquals("task-2", taskId2);
199+
verify(mTaskExecutor).schedule(any(SplitTask.class), eq(10L), any());
200+
verify(mTaskExecutor).schedule(any(SplitTask.class), eq(20L), any());
201+
}
202+
203+
@Test
204+
public void scheduleWithZeroDelay() {
205+
when(mTaskExecutor.schedule(any(SplitTask.class), eq(0L), any()))
206+
.thenReturn("immediate-task");
207+
208+
String taskId = mScheduler.schedule(() -> {}, 0L, null);
209+
210+
assertEquals("immediate-task", taskId);
211+
verify(mTaskExecutor).schedule(any(SplitTask.class), eq(0L), any());
212+
}
213+
214+
@Test
215+
public void scheduleWithLargeDelay() {
216+
long largeDelay = 3600L; // 1 hour
217+
when(mTaskExecutor.schedule(any(SplitTask.class), eq(largeDelay), any()))
218+
.thenReturn("delayed-task");
219+
220+
String taskId = mScheduler.schedule(() -> {}, largeDelay, null);
221+
222+
assertEquals("delayed-task", taskId);
223+
verify(mTaskExecutor).schedule(any(SplitTask.class), eq(largeDelay), any());
224+
}
225+
226+
@Test
227+
public void listenerReceivesTaskInfoRegardlessOfStatus() {
228+
StreamingScheduler.TaskExecutionListener listener = mock(StreamingScheduler.TaskExecutionListener.class);
229+
ArgumentCaptor<SplitTaskExecutionListener> listenerCaptor =
230+
ArgumentCaptor.forClass(SplitTaskExecutionListener.class);
231+
232+
when(mTaskExecutor.schedule(any(SplitTask.class), anyLong(), listenerCaptor.capture()))
233+
.thenReturn("task-id");
234+
235+
mScheduler.schedule(() -> {}, 10L, listener);
236+
SplitTaskExecutionListener splitListener = listenerCaptor.getValue();
237+
238+
// Test with success status
239+
splitListener.taskExecuted(SplitTaskExecutionInfo.success(SplitTaskType.GENERIC_TASK));
240+
verify(listener).onTaskExecuted();
241+
242+
// Test with error status
243+
splitListener.taskExecuted(SplitTaskExecutionInfo.error(SplitTaskType.GENERIC_TASK));
244+
verify(listener, times(2)).onTaskExecuted(); // Should be called twice now
245+
}
246+
}

0 commit comments

Comments
 (0)