Skip to content

Commit 4c058ff

Browse files
authored
Add extensive unit tests for core UI components (#4042)
* Add extensive UI component unit tests * Adjust label shift test expectations * Adjust label mask persistence test
1 parent 6c2447b commit 4c058ff

File tree

5 files changed

+402
-0
lines changed

5 files changed

+402
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.codename1.ui;
2+
3+
import com.codename1.test.UITestBase;
4+
import com.codename1.ui.events.ActionEvent;
5+
import com.codename1.ui.events.ActionListener;
6+
import org.junit.jupiter.api.Test;
7+
8+
import java.lang.reflect.Method;
9+
import java.util.concurrent.atomic.AtomicInteger;
10+
11+
import static org.junit.jupiter.api.Assertions.*;
12+
import static org.mockito.Mockito.when;
13+
14+
class ButtonTest extends UITestBase {
15+
16+
@Test
17+
void testSetCommandBindsCommandAndFiresAction() throws Exception {
18+
when(implementation.isBuiltinSoundsEnabled()).thenReturn(false);
19+
AtomicInteger actionCount = new AtomicInteger();
20+
Command cmd = new Command("Go") {
21+
@Override
22+
public void actionPerformed(ActionEvent evt) {
23+
actionCount.incrementAndGet();
24+
}
25+
};
26+
27+
Button button = new Button();
28+
button.setCommand(cmd);
29+
30+
assertEquals("Go", button.getText());
31+
assertSame(cmd, button.getCommand());
32+
assertTrue(button.getListeners().contains(cmd));
33+
34+
Method fire = Button.class.getDeclaredMethod("fireActionEvent", int.class, int.class);
35+
fire.setAccessible(true);
36+
fire.invoke(button, 10, 20);
37+
38+
assertEquals(1, actionCount.get());
39+
}
40+
41+
@Test
42+
void testStateChangeListenerReceivesPressedAndReleasedEvents() {
43+
when(implementation.isBuiltinSoundsEnabled()).thenReturn(false);
44+
Button button = new Button();
45+
AtomicInteger stateChanges = new AtomicInteger();
46+
ActionListener listener = evt -> stateChanges.incrementAndGet();
47+
button.addStateChangeListener(listener);
48+
49+
button.pressed();
50+
assertEquals(Button.STATE_PRESSED, button.getState());
51+
button.released();
52+
assertEquals(Button.STATE_ROLLOVER, button.getState());
53+
button.setReleased();
54+
assertEquals(Button.STATE_DEFAULT, button.getState());
55+
56+
assertEquals(3, stateChanges.get());
57+
58+
button.removeStateChangeListener(listener);
59+
button.pressed();
60+
assertEquals(3, stateChanges.get());
61+
}
62+
63+
@Test
64+
void testBindStateMirrorsSourceStateUntilUnbound() {
65+
when(implementation.isBuiltinSoundsEnabled()).thenReturn(false);
66+
Button source = new Button();
67+
Button follower = new Button();
68+
follower.bindStateTo(source);
69+
70+
source.pressed();
71+
assertEquals(Button.STATE_PRESSED, follower.getState());
72+
73+
source.setReleased();
74+
assertEquals(Button.STATE_DEFAULT, follower.getState());
75+
76+
follower.unbindStateFrom(source);
77+
source.pressed();
78+
assertEquals(Button.STATE_DEFAULT, follower.getState());
79+
}
80+
81+
@Test
82+
void testRippleDefaultAppliesToNewButtons() {
83+
boolean original = Button.isButtonRippleEffectDefault();
84+
try {
85+
Button.setButtonRippleEffectDefault(true);
86+
Button ripple = new Button();
87+
assertTrue(ripple.isRippleEffect());
88+
89+
Button.setButtonRippleEffectDefault(false);
90+
Button noRipple = new Button();
91+
assertFalse(noRipple.isRippleEffect());
92+
} finally {
93+
Button.setButtonRippleEffectDefault(original);
94+
}
95+
}
96+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.codename1.ui;
2+
3+
import com.codename1.test.UITestBase;
4+
import com.codename1.ui.events.ActionListener;
5+
import com.codename1.ui.plaf.UIManager;
6+
import org.junit.jupiter.api.Test;
7+
8+
import java.util.Hashtable;
9+
import java.util.concurrent.atomic.AtomicInteger;
10+
11+
import static org.junit.jupiter.api.Assertions.*;
12+
import static org.mockito.Mockito.when;
13+
14+
class CheckBoxTest extends UITestBase {
15+
16+
@Test
17+
void testCreateToggleProducesToggleUiid() {
18+
CheckBox checkBox = CheckBox.createToggle("value");
19+
assertTrue(checkBox.isToggle());
20+
assertEquals("ToggleButton", checkBox.getUIID());
21+
}
22+
23+
@Test
24+
void testSelectionChangeNotifiesListenersAndBinding() {
25+
CheckBox checkBox = new CheckBox("Accept");
26+
AtomicInteger changes = new AtomicInteger();
27+
ActionListener listener = evt -> changes.incrementAndGet();
28+
checkBox.addChangeListener(listener);
29+
30+
checkBox.setSelected(true);
31+
checkBox.setSelected(true);
32+
checkBox.setSelected(false);
33+
34+
assertEquals(2, changes.get());
35+
checkBox.removeChangeListeners(listener);
36+
37+
checkBox.setBoundPropertyValue("selected", Boolean.TRUE);
38+
assertTrue(checkBox.isSelected());
39+
assertEquals(Boolean.TRUE, checkBox.getBoundPropertyValue("selected"));
40+
}
41+
42+
@Test
43+
void testReleasedTogglesSelection() {
44+
when(implementation.isBuiltinSoundsEnabled()).thenReturn(false);
45+
CheckBox checkBox = new CheckBox("Notify");
46+
assertFalse(checkBox.isSelected());
47+
48+
checkBox.released(0, 0);
49+
assertTrue(checkBox.isSelected());
50+
51+
checkBox.released(0, 0);
52+
assertFalse(checkBox.isSelected());
53+
}
54+
55+
@Test
56+
void testThemeConstantControlsOppositeSide() {
57+
Hashtable<String, Object> theme = new Hashtable<String, Object>();
58+
theme.put("@checkBoxOppositeSideBool", "true");
59+
UIManager.getInstance().setThemeProps(theme);
60+
61+
CheckBox checkBox = new CheckBox("Align");
62+
checkBox.refreshTheme(false);
63+
64+
assertTrue(checkBox.isOppositeSide());
65+
}
66+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package com.codename1.ui;
2+
3+
import com.codename1.test.UITestBase;
4+
import com.codename1.ui.Component;
5+
import com.codename1.ui.Image;
6+
import com.codename1.ui.list.DefaultListCellRenderer;
7+
import com.codename1.ui.list.DefaultListModel;
8+
import com.codename1.ui.list.ListModel;
9+
import com.codename1.ui.plaf.UIManager;
10+
import org.junit.jupiter.api.Test;
11+
12+
import java.util.Hashtable;
13+
14+
import static org.junit.jupiter.api.Assertions.*;
15+
16+
class ComboBoxTest extends UITestBase {
17+
18+
@Test
19+
void testDefaultRendererUiidsAreApplied() {
20+
ComboBox<String> comboBox = new ComboBox<String>("A", "B");
21+
assertEquals("ComboBox", comboBox.getUIID());
22+
23+
DefaultListCellRenderer renderer = (DefaultListCellRenderer) comboBox.getRenderer();
24+
assertEquals("ComboBoxItem", renderer.getUIID());
25+
Component focus = renderer.getListFocusComponent(comboBox);
26+
assertNotNull(focus);
27+
assertEquals("ComboBoxFocus", focus.getUIID());
28+
}
29+
30+
@Test
31+
void testSetUiidPropagatesToRendererComponents() {
32+
ComboBox<String> comboBox = new ComboBox<String>("One", "Two");
33+
comboBox.setUIID("MyCombo");
34+
35+
DefaultListCellRenderer renderer = (DefaultListCellRenderer) comboBox.getRenderer();
36+
assertEquals("MyComboItem", renderer.getUIID());
37+
Component focus = renderer.getListFocusComponent(comboBox);
38+
assertNotNull(focus);
39+
assertEquals("MyComboFocus", focus.getUIID());
40+
}
41+
42+
@Test
43+
void testStaticDefaultsImpactNewInstances() {
44+
boolean originalInclude = ComboBox.isDefaultIncludeSelectCancel();
45+
boolean originalSpinner = ComboBox.isDefaultActAsSpinnerDialog();
46+
try {
47+
ComboBox.setDefaultIncludeSelectCancel(false);
48+
ComboBox.setDefaultActAsSpinnerDialog(true);
49+
50+
ComboBox<String> comboBox = new ComboBox<String>();
51+
assertFalse(comboBox.isIncludeSelectCancel());
52+
assertTrue(comboBox.isActAsSpinnerDialog());
53+
} finally {
54+
ComboBox.setDefaultIncludeSelectCancel(originalInclude);
55+
ComboBox.setDefaultActAsSpinnerDialog(originalSpinner);
56+
}
57+
}
58+
59+
@Test
60+
void testCreatePopupListUsesPopupUiidsWhenThemeRequests() {
61+
Hashtable<String, Object> theme = new Hashtable<String, Object>();
62+
theme.put("@otherPopupRendererBool", "true");
63+
UIManager.getInstance().setThemeProps(theme);
64+
65+
ExposedComboBox<String> comboBox = new ExposedComboBox<String>(new DefaultListModel<String>("X", "Y"));
66+
com.codename1.ui.List<String> popupList = comboBox.createPopupListPublic();
67+
68+
assertEquals("ComboBoxList", popupList.getUIID());
69+
DefaultListCellRenderer renderer = (DefaultListCellRenderer) popupList.getRenderer();
70+
assertEquals("PopupItem", renderer.getUIID());
71+
assertEquals("PopupFocus", renderer.getListFocusComponent(popupList).getUIID());
72+
}
73+
74+
@Test
75+
void testMutableFlagsCanBeAdjustedPerInstance() {
76+
ComboBox<String> comboBox = new ComboBox<String>();
77+
comboBox.setIncludeSelectCancel(false);
78+
comboBox.setActAsSpinnerDialog(true);
79+
comboBox.setComboBoxImage(Image.createImage(5, 5));
80+
81+
assertFalse(comboBox.isIncludeSelectCancel());
82+
assertTrue(comboBox.isActAsSpinnerDialog());
83+
assertNotNull(comboBox.getComboBoxImage());
84+
}
85+
86+
private static class ExposedComboBox<T> extends ComboBox<T> {
87+
ExposedComboBox(ListModel<T> model) {
88+
super(model);
89+
}
90+
91+
com.codename1.ui.List<T> createPopupListPublic() {
92+
return super.createPopupList();
93+
}
94+
}
95+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.codename1.ui;
2+
3+
import com.codename1.test.UITestBase;
4+
import com.codename1.ui.plaf.UIManager;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.util.HashMap;
8+
import java.util.Map;
9+
10+
import static org.junit.jupiter.api.Assertions.*;
11+
12+
class LabelTest extends UITestBase {
13+
14+
@Test
15+
void testTextPositionValidation() {
16+
Label label = new Label();
17+
label.setTextPosition(Label.RIGHT);
18+
assertThrows(IllegalArgumentException.class, () -> label.setTextPosition(999));
19+
}
20+
21+
@Test
22+
void testBadgeConfigurationCreatesStyleComponent() {
23+
Label label = new Label();
24+
assertNull(label.getBadgeStyleComponent());
25+
26+
label.setBadgeText("9");
27+
label.setBadgeUIID("CustomBadge");
28+
29+
assertEquals("9", label.getBadgeText());
30+
assertNotNull(label.getBadgeStyleComponent());
31+
assertEquals("CustomBadge", label.getBadgeStyleComponent().getUIID());
32+
}
33+
34+
@Test
35+
void testLocalizationCanBeDisabledPerLabel() {
36+
Map<String, String> bundle = new HashMap<String, String>();
37+
bundle.put("key", "Localized");
38+
UIManager.getInstance().setBundle(bundle);
39+
40+
Label localized = new Label();
41+
localized.setText("key");
42+
assertEquals("Localized", localized.getText());
43+
44+
Label raw = new Label();
45+
raw.setShouldLocalize(false);
46+
raw.setText("key");
47+
assertEquals("key", raw.getText());
48+
}
49+
50+
@Test
51+
void testMaskGapAndShiftSettingsPersist() {
52+
Label label = new Label();
53+
Object mask = new Object();
54+
label.setMaskName("rounded");
55+
label.setGap(7);
56+
label.setEndsWith3Points(false);
57+
label.setShiftMillimeters(5);
58+
assertEquals(5, label.getShiftMillimeters());
59+
60+
label.setShiftMillimeters(2.5f);
61+
label.setShowEvenIfBlank(true);
62+
63+
assertEquals("rounded", label.getMaskName());
64+
assertNull(label.getMask());
65+
66+
label.setMask(mask);
67+
68+
assertSame(mask, label.getMask());
69+
assertEquals("rounded", label.getMaskName());
70+
assertEquals(7, label.getGap());
71+
assertFalse(label.isEndsWith3Points());
72+
assertEquals(3, label.getShiftMillimeters());
73+
assertEquals(2.5f, label.getShiftMillimetersF(), 0.0001f);
74+
assertTrue(label.isShowEvenIfBlank());
75+
}
76+
}

0 commit comments

Comments
 (0)