Skip to content

Commit 512acab

Browse files
authored
Add high coverage unit tests for Component, Container, Display, and CN (#4054)
* Add comprehensive unit tests for core UI utilities * Adjust Component strip margin test to match core behavior * Fix Component stripMarginAndPadding assertions
1 parent 9db1fda commit 512acab

File tree

4 files changed

+319
-0
lines changed

4 files changed

+319
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.codename1.ui;
2+
3+
import com.codename1.test.UITestBase;
4+
import org.junit.jupiter.api.AfterEach;
5+
import org.junit.jupiter.api.Test;
6+
7+
import static org.junit.jupiter.api.Assertions.*;
8+
import static org.mockito.ArgumentMatchers.anyString;
9+
import static org.mockito.ArgumentMatchers.eq;
10+
import static org.mockito.Mockito.verify;
11+
import static org.mockito.Mockito.when;
12+
13+
class CNTest extends UITestBase {
14+
15+
@AfterEach
16+
void restoreFlags() {
17+
Component.revalidateOnStyleChange = true;
18+
}
19+
20+
@Test
21+
void testSetPropertyUpdatesComponentFlags() {
22+
CN.setProperty("Component.revalidateOnStyleChange", "false");
23+
assertFalse(Component.revalidateOnStyleChange);
24+
25+
CN.setProperty("Component.revalidateOnStyleChange", "true");
26+
assertTrue(Component.revalidateOnStyleChange);
27+
}
28+
29+
@Test
30+
void testRequestFullScreenDelegatesToImplementation() {
31+
when(implementation.requestFullScreen()).thenReturn(true);
32+
33+
assertTrue(CN.requestFullScreen());
34+
verify(implementation).requestFullScreen();
35+
}
36+
37+
@Test
38+
void testCanExecuteDelegatesToImplementation() {
39+
when(implementation.canExecute("scheme:test")).thenReturn(Boolean.TRUE);
40+
41+
assertTrue(CN.canExecute("scheme:test"));
42+
verify(implementation).canExecute("scheme:test");
43+
}
44+
45+
@Test
46+
void testPropertyAndDisplayAccessors() {
47+
when(implementation.getProperty(eq("key"), anyString())).thenReturn("value");
48+
49+
assertEquals("value", CN.getProperty("key", "default"));
50+
assertEquals(implementation.getDisplayWidth(), CN.getDisplayWidth());
51+
assertEquals(implementation.getDisplayHeight(), CN.getDisplayHeight());
52+
}
53+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.codename1.ui;
2+
3+
import com.codename1.test.UITestBase;
4+
import com.codename1.ui.geom.Dimension;
5+
import com.codename1.ui.plaf.Border;
6+
import com.codename1.ui.plaf.Style;
7+
import org.junit.jupiter.api.Test;
8+
9+
import static org.junit.jupiter.api.Assertions.*;
10+
11+
class ComponentTest extends UITestBase {
12+
13+
@Test
14+
void testPutClientPropertyStoresAndRemovesValues() {
15+
Component component = new Component();
16+
17+
assertNull(component.getClientProperty("missing"));
18+
19+
component.putClientProperty("key", "value");
20+
assertEquals("value", component.getClientProperty("key"));
21+
22+
component.putClientProperty("key", null);
23+
assertNull(component.getClientProperty("key"));
24+
25+
component.putClientProperty("another", Integer.valueOf(42));
26+
assertEquals(Integer.valueOf(42), component.getClientProperty("another"));
27+
28+
component.clearClientProperties();
29+
assertNull(component.getClientProperty("another"));
30+
}
31+
32+
@Test
33+
void testStripMarginAndPaddingResetsStyleAndBorder() {
34+
Component component = new Component();
35+
Style style = component.getAllStyles();
36+
37+
style.setMargin(3, 4, 5, 6);
38+
style.setPadding(7, 8, 9, 10);
39+
style.setBorder(Border.createLineBorder(2));
40+
41+
Component chained = component.stripMarginAndPadding();
42+
assertSame(component, chained);
43+
44+
Style[] states = new Style[]{
45+
component.getUnselectedStyle(),
46+
component.getSelectedStyle(),
47+
component.getPressedStyle(),
48+
component.getDisabledStyle()
49+
};
50+
51+
for (Style state : states) {
52+
assertEquals(0f, state.getMarginFloatValue(false, Component.TOP));
53+
assertEquals(0f, state.getMarginFloatValue(false, Component.BOTTOM));
54+
assertEquals(0f, state.getMarginFloatValue(false, Component.LEFT));
55+
assertEquals(0f, state.getMarginFloatValue(false, Component.RIGHT));
56+
57+
assertEquals(0f, state.getPaddingFloatValue(false, Component.TOP));
58+
assertEquals(0f, state.getPaddingFloatValue(false, Component.BOTTOM));
59+
assertEquals(0f, state.getPaddingFloatValue(false, Component.LEFT));
60+
assertEquals(0f, state.getPaddingFloatValue(false, Component.RIGHT));
61+
62+
assertTrue(state.getBorder().isEmptyBorder());
63+
}
64+
}
65+
66+
@Test
67+
void testSetEnabledTriggersRepaintOnlyWhenStateChanges() {
68+
CountingComponent component = new CountingComponent();
69+
70+
component.setEnabled(false);
71+
assertEquals(1, component.repaintCalls, "Disabling should trigger a repaint");
72+
73+
component.setEnabled(false);
74+
assertEquals(1, component.repaintCalls, "Setting the same state should not repaint");
75+
76+
component.setEnabled(true);
77+
assertEquals(2, component.repaintCalls, "Re-enabling should repaint exactly once");
78+
}
79+
80+
private static class CountingComponent extends Component {
81+
int repaintCalls;
82+
83+
@Override
84+
public void repaint() {
85+
repaintCalls++;
86+
}
87+
88+
@Override
89+
public void repaint(int x, int y, int w, int h) {
90+
repaintCalls++;
91+
}
92+
93+
@Override
94+
public Dimension getScrollDimension() {
95+
return new Dimension(0, 0);
96+
}
97+
}
98+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.codename1.ui;
2+
3+
import com.codename1.test.UITestBase;
4+
import com.codename1.ui.geom.Dimension;
5+
import com.codename1.ui.layouts.BorderLayout;
6+
import com.codename1.ui.layouts.FlowLayout;
7+
import com.codename1.ui.Label;
8+
import org.junit.jupiter.api.Test;
9+
10+
import static org.junit.jupiter.api.Assertions.*;
11+
12+
class ContainerTest extends UITestBase {
13+
14+
@Test
15+
void testScrollableFlagsRespectBorderLayout() {
16+
Container container = new Container(new BorderLayout());
17+
18+
container.setScrollableX(true);
19+
container.setScrollableY(true);
20+
21+
assertFalse(container.scrollableXFlag(), "BorderLayout containers cannot scroll horizontally");
22+
assertFalse(container.scrollableYFlag(), "BorderLayout containers cannot scroll vertically");
23+
}
24+
25+
@Test
26+
void testSetScrollableAppliesToBothAxes() {
27+
Container container = new Container(new FlowLayout());
28+
29+
container.setScrollable(true);
30+
assertTrue(container.scrollableXFlag());
31+
assertTrue(container.scrollableYFlag());
32+
33+
container.setScrollable(false);
34+
assertFalse(container.scrollableXFlag());
35+
assertFalse(container.scrollableYFlag());
36+
}
37+
38+
@Test
39+
void testIsScrollableXDependsOnScrollSize() {
40+
Container container = new Container(new FlowLayout());
41+
container.setScrollableX(true);
42+
container.setWidth(100);
43+
container.setHeight(50);
44+
45+
container.setScrollSize(new Dimension(150, 50));
46+
assertTrue(container.isScrollableX(), "Scroll width larger than component width should allow scrolling");
47+
48+
container.setScrollSize(new Dimension(80, 50));
49+
assertFalse(container.isScrollableX(), "Scroll width smaller than component width should disable scrolling");
50+
}
51+
52+
@Test
53+
void testEncloseInUsesLayoutConstraints() {
54+
Label north = new Label("north");
55+
Container container = Container.encloseIn(new BorderLayout(), north, BorderLayout.NORTH);
56+
57+
assertEquals(1, container.getComponentCount());
58+
assertSame(north, container.getComponentAt(0));
59+
assertTrue(container.getLayout() instanceof BorderLayout);
60+
BorderLayout layout = (BorderLayout) container.getLayout();
61+
assertEquals(BorderLayout.NORTH, layout.getComponentConstraint(north));
62+
}
63+
64+
@Test
65+
void testEncloseInAddsComponentArgumentsSequentially() {
66+
Label first = new Label("first");
67+
Label second = new Label("second");
68+
69+
Container container = Container.encloseIn(new FlowLayout(), first, second);
70+
71+
assertEquals(2, container.getComponentCount());
72+
assertSame(first, container.getComponentAt(0));
73+
assertSame(second, container.getComponentAt(1));
74+
}
75+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package com.codename1.ui;
2+
3+
import com.codename1.test.UITestBase;
4+
import com.codename1.ui.Font;
5+
import com.codename1.ui.plaf.Style;
6+
import org.junit.jupiter.api.AfterEach;
7+
import org.junit.jupiter.api.Test;
8+
9+
import static org.junit.jupiter.api.Assertions.*;
10+
import static org.mockito.ArgumentMatchers.anyString;
11+
import static org.mockito.ArgumentMatchers.eq;
12+
import static org.mockito.Mockito.clearInvocations;
13+
import static org.mockito.Mockito.never;
14+
import static org.mockito.Mockito.verify;
15+
import static org.mockito.Mockito.when;
16+
17+
class DisplayTest extends UITestBase {
18+
19+
@AfterEach
20+
void resetStatics() {
21+
Container.blockOverdraw = false;
22+
Component.revalidateOnStyleChange = true;
23+
}
24+
25+
@Test
26+
void testConvertToPixelsHandlesVariousUnits() {
27+
Display display = Display.getInstance();
28+
29+
assertEquals(Math.round(2f * Font.getDefaultFont().getHeight()), display.convertToPixels(2f, Style.UNIT_TYPE_REM));
30+
assertEquals(Math.round(25f / 100f * CN.getDisplayHeight()), display.convertToPixels(25f, Style.UNIT_TYPE_VH));
31+
assertEquals(Math.round(40f / 100f * CN.getDisplayWidth()), display.convertToPixels(40f, Style.UNIT_TYPE_VW));
32+
assertEquals(Math.round(10f / 100f * Math.min(CN.getDisplayWidth(), CN.getDisplayHeight())),
33+
display.convertToPixels(10f, Style.UNIT_TYPE_VMIN));
34+
assertEquals(Math.round(60f / 100f * Math.max(CN.getDisplayWidth(), CN.getDisplayHeight())),
35+
display.convertToPixels(60f, Style.UNIT_TYPE_VMAX));
36+
assertEquals(display.convertToPixels(2.5f), display.convertToPixels(2.5f, Style.UNIT_TYPE_DIPS));
37+
assertEquals(540, display.convertToPixels(50f, Style.UNIT_TYPE_SCREEN_PERCENTAGE, true));
38+
assertEquals(960, display.convertToPixels(50f, Style.UNIT_TYPE_SCREEN_PERCENTAGE, false));
39+
assertEquals(7, display.convertToPixels(7f, (byte) 99));
40+
}
41+
42+
@Test
43+
void testSetPropertyHandlesSpecialKeys() {
44+
Display display = Display.getInstance();
45+
46+
display.setProperty("AppArg", "launch");
47+
verify(implementation).setAppArg("launch");
48+
49+
display.setProperty("blockOverdraw", "ignored");
50+
assertTrue(Container.blockOverdraw);
51+
52+
display.setProperty("blockCopyPaste", "true");
53+
verify(implementation).blockCopyPaste(true);
54+
55+
display.setProperty("Component.revalidateOnStyleChange", "false");
56+
assertFalse(Component.revalidateOnStyleChange);
57+
58+
display.setProperty("Component.revalidateOnStyleChange", "TRUE");
59+
assertTrue(Component.revalidateOnStyleChange);
60+
61+
display.setProperty("platformHint.someFlag", "value");
62+
verify(implementation).setPlatformHint("platformHint.someFlag", "value");
63+
}
64+
65+
@Test
66+
void testLocalPropertiesOverrideImplementation() {
67+
Display display = Display.getInstance();
68+
69+
display.setProperty("customKey", "localValue");
70+
clearInvocations(implementation);
71+
72+
String value = display.getProperty("customKey", "fallback");
73+
assertEquals("localValue", value);
74+
verify(implementation, never()).getProperty(eq("customKey"), anyString());
75+
76+
display.setProperty("customKey", null);
77+
when(implementation.getProperty(eq("customKey"), anyString())).thenReturn("implValue");
78+
79+
String fallback = display.getProperty("customKey", "fallback");
80+
assertEquals("implValue", fallback);
81+
}
82+
83+
@Test
84+
void testGetPropertyHandlesAppArgAndComponentFlag() {
85+
Display display = Display.getInstance();
86+
when(implementation.getAppArg()).thenReturn("cmdline");
87+
88+
assertEquals("cmdline", display.getProperty("AppArg", "default"));
89+
90+
Component.revalidateOnStyleChange = false;
91+
assertEquals("false", display.getProperty("Component.revalidateOnStyleChange", "default"));
92+
}
93+
}

0 commit comments

Comments
 (0)