Skip to content

Commit 7d9676f

Browse files
authored
Add comprehensive tests for Label feature coverage (#4126)
* Add feature coverage tests for label behavior * Fix LabelFeatureTest import * Adjust autosize label test to use native font * Relax autosize label test width check * Relax autosize label test width check
1 parent 3735a2a commit 7d9676f

File tree

1 file changed

+250
-0
lines changed

1 file changed

+250
-0
lines changed
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
package com.codename1.ui;
2+
3+
import com.codename1.cloud.BindTarget;
4+
import com.codename1.junit.FormTest;
5+
import com.codename1.junit.UITestBase;
6+
import com.codename1.testing.TestCodenameOneImplementation;
7+
import com.codename1.ui.TextSelection.Span;
8+
import com.codename1.ui.TextSelection.TextSelectionSupport;
9+
import com.codename1.ui.geom.Dimension;
10+
import com.codename1.ui.plaf.Style;
11+
import com.codename1.ui.plaf.UIManager;
12+
13+
import java.util.Arrays;
14+
import java.util.Hashtable;
15+
16+
import static org.junit.jupiter.api.Assertions.*;
17+
18+
class LabelFeatureTest extends UITestBase {
19+
20+
@FormTest
21+
void testLegacyRendererModeRespected() {
22+
Form form = Display.getInstance().getCurrent();
23+
form.removeAll();
24+
25+
Style labelStyle = UIManager.getInstance().getComponentStyle("Label");
26+
Image legacyIcon = FontImage.createMaterial(FontImage.MATERIAL_HOME, labelStyle);
27+
Image standardIcon = Image.createImage(12, 12);
28+
29+
Label label = new Label("Legacy", legacyIcon);
30+
form.add(label);
31+
form.revalidate();
32+
33+
assertTrue(label.isLegacyRenderer(), "FontImage based icon should trigger legacy renderer mode");
34+
35+
label.setLegacyRenderer(false);
36+
assertFalse(label.isLegacyRenderer());
37+
38+
label.setIcon(standardIcon);
39+
assertFalse(label.isLegacyRenderer(), "Mutable RGB image should not force legacy renderer");
40+
41+
label.setIcon(legacyIcon);
42+
assertTrue(label.isLegacyRenderer(), "Switching back to a FontImage should restore legacy renderer");
43+
}
44+
45+
@FormTest
46+
void testAutoSizeModeAdjustsFontWithinBounds() {
47+
Form form = Display.getInstance().getCurrent();
48+
form.removeAll();
49+
50+
Display display = Display.getInstance();
51+
Label label = new Label("Autosize verification text that should stretch");
52+
53+
Font baseFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_LARGE);
54+
Font oversizedFont = baseFont.derive(display.convertToPixels(12f), baseFont.getStyle());
55+
label.getAllStyles().setFont(oversizedFont);
56+
57+
int preferredWidth = display.convertToPixels(20f);
58+
label.setPreferredSize(new Dimension(preferredWidth, display.convertToPixels(8f)));
59+
label.setAutoSizeMode(true);
60+
label.setMinAutoSize(2f);
61+
label.setMaxAutoSize(30f);
62+
label.getAllStyles().setPadding(0, 0, 0, 0);
63+
64+
float initialSize = label.getUnselectedStyle().getFont().getPixelSize();
65+
66+
form.add(label);
67+
form.revalidate();
68+
69+
Font resizedFont = label.getUnselectedStyle().getFont();
70+
float resizedSize = resizedFont.getPixelSize();
71+
72+
assertTrue(resizedSize >= display.convertToPixels(label.getMinAutoSize()), "Autosize should respect minimum size");
73+
assertTrue(resizedSize <= display.convertToPixels(label.getMaxAutoSize()), "Autosize should respect maximum size");
74+
assertTrue(resizedSize < initialSize, "Font size should shrink to satisfy autosize constraints");
75+
76+
int availableWidth = label.getWidth();
77+
assertTrue(label.getPreferredW() <= availableWidth, "Autosized preferred width should not exceed component width");
78+
assertTrue(label.isAutoSizeMode());
79+
}
80+
81+
@FormTest
82+
void testTextSelectionLifecycleAndSpanExtraction() {
83+
TestCodenameOneImplementation impl = implementation;
84+
impl.resetTextSelectionTracking();
85+
86+
Form form = Display.getInstance().getCurrent();
87+
form.removeAll();
88+
89+
Label label = new Label("Codename One text selection test");
90+
label.setTextSelectionEnabled(true);
91+
form.add(label);
92+
form.revalidate();
93+
94+
TextSelection selection = form.getTextSelection();
95+
selection.setEnabled(true);
96+
97+
assertEquals(1, impl.getInitializeTextSelectionCount(), "Initialization should be delegated to implementation");
98+
assertEquals(Component.TEXT_CURSOR, label.getCursor());
99+
100+
Component selectionRoot = TextSelection.findSelectionRoot(label);
101+
int relativeX = label.getAbsoluteX() - selectionRoot.getAbsoluteX() + label.getWidth() / 2;
102+
int relativeY = label.getAbsoluteY() - selectionRoot.getAbsoluteY() + label.getHeight() / 2;
103+
104+
TextSelectionSupport support = label.getTextSelectionSupport();
105+
Span span = support.triggerSelectionAt(selection, relativeX, relativeY);
106+
assertNotNull(span, "Triggering selection should return a span");
107+
108+
String selected = support.getTextForSpan(selection, span).trim();
109+
assertFalse(selected.isEmpty());
110+
111+
selection.setEnabled(false);
112+
assertEquals(1, impl.getDeinitializeTextSelectionCount(), "Disabling selection should deinitialize implementation");
113+
}
114+
115+
@FormTest
116+
void testIconUiidIsAppliedFromTheme() {
117+
Image icon = Image.createImage(10, 10);
118+
Object mask = icon.createMask();
119+
Hashtable theme = new Hashtable();
120+
theme.put("Label.derive", "Label");
121+
theme.put("LabelIcon.derive", "Label");
122+
theme.put("@customMask", mask);
123+
UIManager.getInstance().setThemeProps(theme);
124+
125+
Form form = Display.getInstance().getCurrent();
126+
form.removeAll();
127+
128+
Label label = new Label("Icon UIID");
129+
label.setIcon(icon);
130+
form.add(label);
131+
form.revalidate();
132+
133+
Component iconStyle = label.getIconStyleComponent();
134+
assertNotNull(iconStyle);
135+
assertEquals("LabelIcon", iconStyle.getUIID());
136+
}
137+
138+
@FormTest
139+
void testPropertyBindingForText() {
140+
Label label = new Label("Initial");
141+
142+
assertArrayEquals(new String[]{"text"}, label.getBindablePropertyNames());
143+
assertTrue(Arrays.asList(label.getBindablePropertyTypes()).contains(String.class));
144+
145+
BindTarget target = new BindTarget() {
146+
@Override
147+
public void propertyChanged(Component source, String propertyName, Object oldValue, Object newValue) {
148+
// Property binding notifications for labels are deprecated, but listeners should be accepted.
149+
}
150+
};
151+
152+
label.bindProperty("text", target);
153+
label.setText("Updated");
154+
assertEquals("Updated", label.getBoundPropertyValue("text"));
155+
label.unbindProperty("text", target);
156+
157+
label.setBoundPropertyValue("text", "Bound");
158+
assertEquals("Bound", label.getText());
159+
assertEquals("Bound", label.getBoundPropertyValue("text"));
160+
}
161+
162+
@FormTest
163+
void testIconMaskingCachesMaskedImage() {
164+
Form form = Display.getInstance().getCurrent();
165+
form.removeAll();
166+
167+
Image icon = Image.createImage(8, 8);
168+
Object mask = icon.createMask();
169+
170+
Label label = new Label("Masked", icon);
171+
label.setMask(mask);
172+
form.add(label);
173+
form.revalidate();
174+
175+
Image masked = label.getMaskedIcon();
176+
assertNotNull(masked);
177+
assertNotSame(icon, masked);
178+
assertSame(masked, label.getMaskedIcon(), "Masked icon should be cached");
179+
180+
label.setMaskName("custom");
181+
assertEquals("custom", label.getMaskName());
182+
}
183+
184+
@FormTest
185+
void testTickerLifecycleAndShiftUpdates() {
186+
Form form = Display.getInstance().getCurrent();
187+
form.removeAll();
188+
189+
Label label = new Label("Ticker requires narrow width");
190+
label.setPreferredSize(new Dimension(60, 40));
191+
form.add(label);
192+
form.revalidate();
193+
194+
assertTrue(label.shouldTickerStart(), "Ticker should start when text is wider than available");
195+
196+
label.startTicker(5, true);
197+
assertTrue(label.isTickerRunning());
198+
199+
label.stopTicker();
200+
assertFalse(label.isTickerRunning());
201+
202+
label.setTickerEnabled(false);
203+
label.startTicker(5, true);
204+
assertFalse(label.isTickerRunning(), "Disabled ticker should not start");
205+
}
206+
207+
@FormTest
208+
void testInvalidVerticalAlignmentThrows() {
209+
Label label = new Label();
210+
assertThrows(IllegalArgumentException.class, () -> label.setVerticalAlignment(999));
211+
}
212+
213+
@FormTest
214+
void testBaselineAlignmentCalculations() {
215+
Form form = Display.getInstance().getCurrent();
216+
form.removeAll();
217+
218+
Label label = new Label("Baseline");
219+
label.getAllStyles().setPadding(4, 6, 2, 2);
220+
label.setPreferredSize(new Dimension(120, 60));
221+
label.setVerticalAlignment(Component.BASELINE);
222+
form.add(label);
223+
form.revalidate();
224+
225+
int width = label.getWidth();
226+
int height = label.getHeight();
227+
Style style = label.getStyle();
228+
Font font = style.getFont();
229+
int expected = style.getPaddingTop() + (height - style.getVerticalPadding() - font.getHeight()) / 2 + font.getAscent();
230+
assertEquals(Component.BASELINE, label.getVerticalAlignment());
231+
assertEquals(expected, label.getBaseline(width, height));
232+
}
233+
234+
@FormTest
235+
void testSetFontIconAssignsFontImage() {
236+
Form form = Display.getInstance().getCurrent();
237+
form.removeAll();
238+
239+
Label label = new Label();
240+
Font font = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
241+
label.setFontIcon(font, 'A', 6f);
242+
243+
assertEquals('A', label.getFontIcon());
244+
assertEquals(6f, label.getFontIconSize(), 0.001f);
245+
assertSame(font, label.getIconFont());
246+
assertNotNull(label.getIcon());
247+
assertTrue(label.getIcon() instanceof FontImage);
248+
}
249+
}
250+

0 commit comments

Comments
 (0)