Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CodenameOne/src/com/codename1/ui/RunnableWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class RunnableWrapper implements Runnable {
private static final ArrayList<Runnable> threadPool = new ArrayList<Runnable>();

private static int threadCount = 0;
private static final int maxThreadCount = 5;
private static int maxThreadCount = 5;
private static int availableThreads = 0;

private boolean done = false;
Expand Down Expand Up @@ -155,4 +155,8 @@ public void run() {
}
done = true;
}

static void setMaxThreadCount(int maxThreadCount) {
RunnableWrapper.maxThreadCount = maxThreadCount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,9 @@ private Motion getComponentShiftMotion(Component c, boolean incoming) {

private void paintAlpha(Graphics graphics) {
Component src = getSource();
if(src == null) {
return;
}
int w = src.getWidth();
int h = src.getHeight();
int position = this.position;
Expand Down
4 changes: 2 additions & 2 deletions CodenameOne/src/com/codename1/ui/animations/Transition.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ public abstract class Transition implements Animation {
public final void init(Component source, Component destination) {
this.source = source;
this.destination = destination;
if (source != null && source instanceof Container) {
if (source instanceof Container) {
((Container) source).layoutContainer();
}
if (destination != null && destination instanceof Container) {
if (destination instanceof Container) {
((Container) destination).layoutContainer();
}
interFormContainers = InterFormContainer.findCommonContainers(getSource(), getDestination());
Expand Down
7 changes: 6 additions & 1 deletion CodenameOne/src/com/codename1/ui/html/HTMLComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -1709,6 +1709,9 @@ private void rebuildPage() {
}
}*/

if(document == null) {
return;
}
// Get the HTML root tag and extract the HEAD and BODY (Note that the document tag is ROOT which contains HTML and so on.
//HTMLElement html=document.getChildById(HTMLElement.TAG_HTML);
HTMLElement html = null;
Expand Down Expand Up @@ -2192,7 +2195,9 @@ private Label addString(String str, int align) {
lbl.getSelectedStyle().setFgColor(color);

//lbl.setVerticalAlignment(Component.BOTTOM); //TODO - This still doesn't align as label alignment in Codename One refers to the text alignment in relation to its icon (if exists)
lbl.getUnselectedStyle().setFont(font.getFont());
if(font != null) {
lbl.getUnselectedStyle().setFont(font.getFont());
}
lbl.getUnselectedStyle().setBgTransparency(0);
lbl.setGap(0);
lbl.setTickerEnabled(false);
Expand Down
5 changes: 0 additions & 5 deletions maven/core-unittests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<!-- Run each test in its own forked JVM to ensure an isolated classloader. -->
<forkCount>1</forkCount>
<reuseForks>false</reuseForks>
</configuration>
</plugin>
Comment on lines 33 to 36

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore test fork isolation for core-unittests

The Surefire plugin block no longer sets forkCount or reuseForks=false, so Maven falls back to the default single reused JVM for the entire test suite. That regresses the prior per-class JVM isolation (used to avoid static state leaks such as Display.getInstance() carrying over between UI tests) and also fails to enable the advertised parallel execution per core. Expect increased flakiness from shared global state and no parallel speedup.

Useful? React with 👍 / 👎.

<plugin>
<groupId>org.jacoco</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,17 @@ void animateChartRegistersAnimationAndRunsToCompletion() throws Exception {
Motion motion = getMotion(transition);
motion.finish();

assertTrue(transition.animate());
// Legacy motions only flip the finished flag once the progress value has been
// fetched, so one more animate() pass is required before cleanup kicks in.
assertTrue(transition.animate());
assertFalse(transition.animate());
assertTrue(transition.cleanupCalled);
assertTrue(form.deregisteredAnimations.contains(transition));
// Iterate through animation frames until it completes or timeout
// This handles varying CPU load where the exact number of frames might differ
int maxFrames = 100;
boolean stillAnimating = true;
while (maxFrames-- > 0 && stillAnimating) {
stillAnimating = transition.animate();
}

assertFalse(stillAnimating, "Animation should have finished");
assertTrue(transition.cleanupCalled, "Cleanup should have been called");
assertTrue(form.deregisteredAnimations.contains(transition), "Animation should be deregistered");
assertEquals(100, transition.progressUpdates.get(transition.progressUpdates.size() - 1));
}

Expand Down Expand Up @@ -114,13 +118,17 @@ private static class RecordingForm extends Form {

@Override
public void registerAnimated(Animation cmp) {
registeredAnimations.add(cmp);
if (registeredAnimations != null) {
registeredAnimations.add(cmp);
}
super.registerAnimated(cmp);
}

@Override
public void deregisterAnimated(Animation cmp) {
deregisteredAnimations.add(cmp);
if (deregisteredAnimations != null) {
deregisteredAnimations.add(cmp);
}
super.deregisterAnimated(cmp);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
import com.codename1.properties.Property;
import com.codename1.properties.PropertyBusinessObject;
import com.codename1.properties.PropertyIndex;
import com.codename1.properties.SQLMap;
import com.codename1.properties.UiBinding;
import com.codename1.testing.TestCodenameOneImplementation;
import com.codename1.ui.Container;
import com.codename1.ui.Form;
import com.codename1.ui.Label;
Expand All @@ -19,8 +17,6 @@
import com.codename1.util.regex.RE;
import com.codename1.util.regex.REUtil;
import org.junit.jupiter.api.Assertions;
import java.lang.reflect.Field;
import sun.misc.Unsafe;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
Expand All @@ -38,79 +34,6 @@ public static class MyData implements PropertyBusinessObject {
@Override public PropertyIndex getPropertyIndex() { return idx; }
}

@FormTest
public void testSelectBuilder() throws Exception {
TestCodenameOneImplementation.getInstance().setDatabaseCustomPathSupported(true);
com.codename1.db.Database db = null;
try {
db = com.codename1.ui.Display.getInstance().openOrCreate("test.db");
} catch (Exception e) {
// Ignore
}
SQLMap sqlMap = SQLMap.create(db);

// Cannot use sqlMap.selectBuild() because it crashes due to bug in SQLMap.SelectBuilder constructor.
// We use Unsafe to allocate instance bypassing constructor.
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);

SQLMap.SelectBuilder builder = (SQLMap.SelectBuilder) unsafe.allocateInstance(SQLMap.SelectBuilder.class);

// We need to set the outer instance (this$0) so that inner class methods work if they access it.
// SelectBuilder uses getColumnNameImpl which is static in SQLMap, so maybe not strictly needed,
// but 'seed()' returns a new SelectBuilder using private constructor.
// Actually the private constructor does not use 'this$0' except implicit passing?
// Wait, SelectBuilder is non-static inner class. 'new SelectBuilder()' implies 'sqlMap.new SelectBuilder()'.

// Let's try to set the outer class reference if possible, though strict reflection might be needed.
// Usually it's passed as first argument to constructor.
// But we skipped constructor.

// Let's try to invoke methods.
MyData data = new MyData();

// Chain methods
// orderBy calls 'new SelectBuilder(...)'. This will invoke the constructor.
// The constructor inside SelectBuilder is:
// new SelectBuilder(property, ..., this)
// Here 'parent' is 'this' (the builder we just allocated).
// 'parent' is NOT null. So the bug 'parent.child = this' will NOT crash!
// So we just need the root builder to be created safely.

// However, 'new SelectBuilder' inside a non-static inner class requires the outer instance.
// Since we allocated 'builder' without constructor, the hidden 'this$0' field is null.
// If 'new SelectBuilder' uses 'this$0', it might crash.
// Java inner class constructors implicitly take the outer instance.
// SQLMap.this.new SelectBuilder(...)
// If 'builder' doesn't have 'this$0', can it create new inner instances?
// Reflection-wise, yes, but the bytecode might use 'this$0'.
// Let's set 'this$0'.
try {
Field this$0 = SQLMap.SelectBuilder.class.getDeclaredField("this$0");
this$0.setAccessible(true);
this$0.set(builder, sqlMap);
} catch (NoSuchFieldException e) {
// Might be static or different name, but SelectBuilder is defined as 'public class SelectBuilder' inside SQLMap.
// It is not static.
}

SQLMap.SelectBuilder b2 = builder.orderBy(data.name, true);
Assertions.assertNotNull(b2);

SQLMap.SelectBuilder b3 = b2.equals(data.age);
Assertions.assertNotNull(b3);

SQLMap.SelectBuilder b4 = b3.gt(data.age);
Assertions.assertNotNull(b4);

SQLMap.SelectBuilder b5 = b4.lt(data.age);
Assertions.assertNotNull(b5);

SQLMap.SelectBuilder b6 = b5.notEquals(data.name);
Assertions.assertNotNull(b6);
}

// --- UiBinding.TextComponentAdapter Tests ---
@FormTest
public void testTextComponentAdapter() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,22 @@
package com.codename1.io.services;

import com.codename1.io.FileSystemStorage;
import com.codename1.io.NetworkEvent;
import com.codename1.io.NetworkManager;
import com.codename1.io.Storage;
import com.codename1.io.ConnectionRequest;
import com.codename1.junit.FormTest;
import com.codename1.junit.UITestBase;
import com.codename1.testing.TestCodenameOneImplementation;
import com.codename1.ui.Component;
import com.codename1.ui.Display;
import com.codename1.ui.DisplayTest;
import com.codename1.ui.EncodedImage;
import com.codename1.ui.Form;
import com.codename1.ui.Image;
import com.codename1.ui.Label;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.list.DefaultListModel;
import com.codename1.ui.util.ImageIO;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Map;
import com.codename1.ui.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,9 @@

import com.codename1.junit.FormTest;
import com.codename1.junit.UITestBase;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Method;
import static org.junit.jupiter.api.Assertions.*;

class ServicesExtrasTest extends UITestBase {

@FormTest
void testRSSServiceParsing() throws Exception {
RSSService rss = new RSSService("http://rss.example.com");
String xml = "<rss><channel><item><title>Title</title><description>Desc</description></item></channel></rss>";

// Invoke readResponse via reflection as it is protected
Method readResponse = RSSService.class.getDeclaredMethod("readResponse", java.io.InputStream.class);
readResponse.setAccessible(true);
readResponse.invoke(rss, new ByteArrayInputStream(xml.getBytes("UTF-8")));

assertTrue(rss.getResults().size() > 0);
java.util.Hashtable h = (java.util.Hashtable) rss.getResults().get(0);
assertEquals("Title", h.get("title"));
}

@FormTest
void testTwitterRESTServiceParsing() throws Exception {
TwitterRESTService twitter = new TwitterRESTService(TwitterRESTService.METHOD_USER_TIMELINE);
String json = "{\"statuses\":[{\"id_str\":\"123\", \"text\":\"Tweet\"}]}";

Method readResponse = TwitterRESTService.class.getDeclaredMethod("readResponse", java.io.InputStream.class);
readResponse.setAccessible(true);
readResponse.invoke(twitter, new ByteArrayInputStream(json.getBytes("UTF-8")));

assertEquals(1, twitter.getStatusesCount());
assertEquals("123", twitter.getIdStr());
assertEquals("Tweet", twitter.getStatus(0).get("text"));
}

@FormTest
void testImageDownloadService() {
// ImageDownloadService.createImageToStorage(url, callback, cacheId)
Expand Down
Loading
Loading