Skip to content

Commit 9b85c43

Browse files
committed
Ensure Robolectric test launches Codename One UI
1 parent 1b432e3 commit 9b85c43

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

scripts/templates/HelloCodenameOneUiTest.java.tmpl

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ public class @MAIN_NAME@UiTest {
5050
private @MAIN_NAME@Stub activity;
5151

5252
@Before
53-
public void setUp() {
53+
public void setUp() throws Exception {
5454
controller = Robolectric.buildActivity(@[email protected]);
5555
activity = controller.setup().get();
56+
bootstrapCodenameOneApp();
5657
waitForCodenameOneForm();
5758
}
5859

@@ -224,6 +225,36 @@ public class @MAIN_NAME@UiTest {
224225
throw new AssertionError("Timed out waiting for Codename One main form to be displayed");
225226
}
226227

228+
private void bootstrapCodenameOneApp() throws Exception {
229+
runOnMainSync(() -> AndroidImplementation.startContext(activity));
230+
if (!Display.isInitialized()) {
231+
runOnMainSync(() -> Display.init(activity));
232+
}
233+
if (!Display.isInitialized()) {
234+
throw new AssertionError("Codename One Display failed to initialize");
235+
}
236+
callSeriallyAndWait(() -> {
237+
@MAIN_NAME@ app = @[email protected]();
238+
boolean needsInit = isStubFirstStart(app);
239+
if (app == null) {
240+
app = new @MAIN_NAME@();
241+
assignStubAppInstance(app);
242+
needsInit = true;
243+
}
244+
if (needsInit) {
245+
app.init(activity);
246+
}
247+
app.start();
248+
markStubFirstTimeConsumed();
249+
return null;
250+
});
251+
}
252+
253+
private void runOnMainSync(Runnable runnable) {
254+
activity.runOnUiThread(runnable);
255+
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
256+
}
257+
227258
private static Image captureCodenameOneScreenshot() throws Exception {
228259
return callSeriallyAndWait(() -> Display.getInstance().captureScreen());
229260
}
@@ -341,6 +372,50 @@ public class @MAIN_NAME@UiTest {
341372
}
342373
}
343374

375+
private static void assignStubAppInstance(@MAIN_NAME@ app) {
376+
try {
377+
Field appField = @[email protected]("i");
378+
appField.setAccessible(true);
379+
appField.set(null, app);
380+
} catch (NoSuchFieldException | IllegalAccessException e) {
381+
throw new RuntimeException("Unable to assign Codename One application instance", e);
382+
}
383+
}
384+
385+
private boolean isStubFirstStart(@MAIN_NAME@ appInstance) {
386+
try {
387+
Field firstTimeField = @[email protected]("firstTime");
388+
firstTimeField.setAccessible(true);
389+
boolean firstTimeValue;
390+
if (java.lang.reflect.Modifier.isStatic(firstTimeField.getModifiers())) {
391+
firstTimeValue = firstTimeField.getBoolean(null);
392+
} else {
393+
firstTimeValue = firstTimeField.getBoolean(activity);
394+
}
395+
return firstTimeValue || appInstance == null;
396+
} catch (NoSuchFieldException ignored) {
397+
return appInstance == null;
398+
} catch (IllegalAccessException e) {
399+
throw new RuntimeException("Unable to inspect Codename One stub firstTime flag", e);
400+
}
401+
}
402+
403+
private void markStubFirstTimeConsumed() {
404+
try {
405+
Field firstTimeField = @[email protected]("firstTime");
406+
firstTimeField.setAccessible(true);
407+
if (java.lang.reflect.Modifier.isStatic(firstTimeField.getModifiers())) {
408+
firstTimeField.setBoolean(null, false);
409+
} else {
410+
firstTimeField.setBoolean(activity, false);
411+
}
412+
} catch (NoSuchFieldException ignored) {
413+
// Field absent in some stub variants; nothing to update.
414+
} catch (IllegalAccessException e) {
415+
throw new RuntimeException("Unable to update Codename One stub firstTime flag", e);
416+
}
417+
}
418+
344419
private static <T> T callSeriallyAndWait(Callable<T> callable) throws Exception {
345420
CountDownLatch latch = new CountDownLatch(1);
346421
AtomicReference<T> result = new AtomicReference<>();

0 commit comments

Comments
 (0)