Skip to content

Commit c4581e9

Browse files
committed
#436 more UI automated testing
1 parent a2e0ea5 commit c4581e9

File tree

4 files changed

+120
-11
lines changed

4 files changed

+120
-11
lines changed

.idea/runConfigurations/TcMenuDesigner_Single_Test.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tcMenuGenerator/src/main/java/com/thecoderscorner/menu/editorui/uimodel/UIRuntimeListMenuItem.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.List;
2727
import java.util.Optional;
2828
import java.util.function.BiConsumer;
29+
import java.util.stream.Collectors;
2930

3031
import static com.thecoderscorner.menu.domain.RuntimeListMenuItem.ListCreationMode;
3132

@@ -60,6 +61,15 @@ protected Optional<RuntimeListMenuItem> getChangedMenuItem() {
6061
errors.add(new FieldError(bundle.getString("menu.editor.enum.fmt.error"), "Choices"));
6162
}
6263

64+
if(creationModeCombo.getValue() != ListCreationMode.CUSTOM_RTCALL && localHandler.isLocalSupportEnabled()) {
65+
var itemsNotInResources = listView.getItems().stream()
66+
.filter(item -> item.startsWith("%") && !item.startsWith("%%") && item.length() > 1)
67+
.filter(item -> localHandler.getLocalSpecificEntry(item.substring(1)) == null)
68+
.collect(Collectors.joining(", "));
69+
errors.add(new FieldError(bundle.getString("menu.editor.core.locale.missing") + " " + itemsNotInResources,
70+
"List values", false));
71+
}
72+
6373
builder.withInitialRows(initialRowsSpinner.getValue());
6474
builder.withCreationMode(creationModeCombo.getValue());
6575
var item = builder.menuItem();
@@ -70,6 +80,7 @@ protected Optional<RuntimeListMenuItem> getChangedMenuItem() {
7080
protected int internalInitPanel(GridPane pane, int idx) {
7181
idx++;
7282
initialRowsSpinner = new Spinner<>(0, 255, getMenuItem().getInitialRows());
83+
initialRowsSpinner.setId("initialRowsSpinner");
7384
initialRowsSpinner.valueProperty().addListener((observable, oldValue, newValue) -> callChangeConsumer());
7485
pane.add(new Label(bundle.getString("menu.editor.initial.rows")), 0, idx);
7586
pane.add(initialRowsSpinner, 1, idx);
@@ -110,8 +121,4 @@ private void listTypeHasChanged() {
110121
buttonsToAddRemove.removeButton().setDisable(listView.getSelectionModel().getSelectedIndex() == -1);
111122
} else buttonsToAddRemove.removeButton().setDisable(true);
112123
}
113-
114-
protected String getEnumEntryKey(int i) {
115-
return String.format("menu.%d.list.%d", getMenuItem().getId(), i);
116-
}
117124
}
Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,112 @@
11
package com.thecoderscorner.menu.editorint.uitests.uimenuitem;
22

3+
import com.thecoderscorner.menu.domain.RuntimeListMenuItem;
4+
import com.thecoderscorner.menu.domain.RuntimeListMenuItemBuilder;
5+
import com.thecoderscorner.menu.domain.util.MenuItemHelper;
36
import com.thecoderscorner.menu.editorui.generator.core.VariableNameGenerator;
7+
import com.thecoderscorner.menu.persist.LocaleMappingHandler;
8+
import com.thecoderscorner.menu.persist.PropertiesLocaleEnabledHandler;
9+
import com.thecoderscorner.menu.persist.SafeBundleLoader;
410
import javafx.application.Platform;
11+
import javafx.scene.Node;
12+
import javafx.scene.control.Label;
13+
import javafx.scene.control.Spinner;
514
import javafx.stage.Stage;
615
import org.junit.jupiter.api.AfterEach;
716
import org.junit.jupiter.api.Test;
817
import org.junit.jupiter.api.extension.ExtendWith;
18+
import org.testfx.api.FxAssert;
19+
import org.testfx.api.FxRobot;
920
import org.testfx.framework.junit5.ApplicationExtension;
1021
import org.testfx.framework.junit5.Start;
22+
import org.testfx.matcher.control.ListViewMatchers;
1123

12-
import static org.junit.jupiter.api.Assertions.fail;
13-
import static org.mockito.ArgumentMatchers.any;
24+
import java.io.File;
25+
import java.io.IOException;
26+
import java.nio.file.Files;
27+
import java.nio.file.Path;
28+
import java.util.Comparator;
29+
import java.util.List;
30+
31+
import static org.assertj.core.api.Assertions.assertThat;
32+
import static org.testfx.api.FxAssert.verifyThat;
1433

1534
@ExtendWith(ApplicationExtension.class)
1635
public class UIRuntimeListMenuItemTest extends UIMenuItemTestBase {
36+
private Path tempPath;
37+
1738
@Start
18-
public void setup(Stage stage) {
39+
public void setup(Stage stage) throws IOException {
40+
tempPath = Files.createTempDirectory("i18ntest");
1941
init(stage);
2042
}
2143

2244
@AfterEach
23-
protected void closeWindow() {
45+
protected void closeWindow() throws IOException {
2446
Platform.runLater(() -> stage.close());
47+
Files.walk(tempPath)
48+
.sorted(Comparator.reverseOrder())
49+
.map(Path::toFile)
50+
.forEach(File::delete);
51+
}
52+
53+
@Test
54+
public void testListInCustomMode(FxRobot robot) throws Exception {
55+
VariableNameGenerator vng = new VariableNameGenerator(menuTree, false);
56+
var uiList = editorUI.createPanelForMenuItem(new RuntimeListMenuItemBuilder()
57+
.withExisting((RuntimeListMenuItem) menuTree.getMenuById(10).orElseThrow())
58+
.withInitialRows(10).withCreationMode(RuntimeListMenuItem.ListCreationMode.CUSTOM_RTCALL)
59+
.menuItem(), menuTree, vng, mockedConsumer);
60+
if(uiList.isEmpty()) throw new IllegalArgumentException("No menu item found");
61+
createMainPanel(uiList);
62+
63+
performAllCommonChecks(uiList.get().getMenuItem(), false, false);
64+
65+
verifyThat("#initialRowsSpinner", (Spinner<Integer> spinner) -> spinner.getValue() == 10);
2566
}
2667

2768
@Test
28-
public void testListCanConstruct() throws Exception {
69+
public void testListInArrayMode(FxRobot robot) throws Exception {
2970
VariableNameGenerator vng = new VariableNameGenerator(menuTree, false);
30-
var uiList = editorUI.createPanelForMenuItem(menuTree.getMenuById(10).get(), menuTree, vng, mockedConsumer);
71+
RuntimeListMenuItem menuItem = new RuntimeListMenuItemBuilder()
72+
.withExisting((RuntimeListMenuItem) menuTree.getMenuById(10).orElseThrow())
73+
.withInitialRows(10).withCreationMode(RuntimeListMenuItem.ListCreationMode.FLASH_ARRAY)
74+
.menuItem();
75+
MenuItemHelper.setMenuState(menuItem, List.of("%list1", "%list2"), menuTree);
76+
77+
var uiList = editorUI.createPanelForMenuItem(menuItem, menuTree, vng, mockedConsumer);
3178
if(uiList.isEmpty()) throw new IllegalArgumentException("No menu item found");
3279
createMainPanel(uiList);
3380

3481
performAllCommonChecks(uiList.get().getMenuItem(), false, false);
82+
verifyThat("#initialRowsSpinner", Node::isDisable);
83+
FxAssert.verifyThat("#enumList", ListViewMatchers.hasListCell("%list1"));
84+
FxAssert.verifyThat("#enumList", ListViewMatchers.hasListCell("%list2"));
85+
86+
robot.clickOn("#addEnumEntry");
87+
FxAssert.verifyThat("#enumList", ListViewMatchers.hasItems(3));
88+
FxAssert.verifyThat("#enumList", ListViewMatchers.hasListCell("ChangeMe"));
89+
90+
var item = menuTree.getMenuById(10).orElseThrow();
91+
assertThat((List<String>)MenuItemHelper.getValueFor(item, menuTree)).containsExactly("%list1", "%list2", "ChangeMe");
92+
93+
var errorText = "WARNING List values: no locale entry in bundle";
94+
verifyThat("#uiItemErrors", (Label l)-> l.getText().contains(errorText) && l.isVisible());
95+
verifyThat("#initialRowsSpinner", (Spinner<Integer> s)-> s.getValue() == 3);
96+
97+
}
98+
99+
@Override
100+
protected LocaleMappingHandler getTestLocaleHandler() {
101+
try {
102+
var coreFile = tempPath.resolve("temp.properties");
103+
Files.writeString(coreFile, """
104+
menu.item.name=hello world
105+
list1=abc
106+
""");
107+
return new PropertiesLocaleEnabledHandler(new SafeBundleLoader(tempPath, "temp"));
108+
} catch (IOException e) {
109+
throw new RuntimeException(e);
110+
}
35111
}
36112
}

tcMenuJavaApi/src/main/java/com/thecoderscorner/menu/domain/RuntimeListMenuItem.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,17 @@
66

77
package com.thecoderscorner.menu.domain;
88

9+
import com.thecoderscorner.menu.domain.state.MenuTree;
10+
import com.thecoderscorner.menu.domain.util.MenuItemHelper;
911
import com.thecoderscorner.menu.domain.util.MenuItemVisitor;
1012

13+
import java.util.List;
1114
import java.util.Objects;
1215

16+
/**
17+
* This class represents a runtime list menu item, which is a type of menu item that can contain a list of values.
18+
* It extends the MenuItem class and inherits its properties and methods.
19+
*/
1320
public class RuntimeListMenuItem extends MenuItem {
1421
public enum ListCreationMode {CUSTOM_RTCALL, RAM_ARRAY, FLASH_ARRAY }
1522
private final int initialRows;
@@ -58,8 +65,27 @@ public int hashCode() {
5865
return Objects.hash(getInitialRows(), getName(), getId(), getEepromAddress(), getFunctionName(), isReadOnly(), getVariableName(), getListCreationMode());
5966
}
6067

68+
/**
69+
* Used with MenuItemHelper's visit method, accepts a MenuItemVisitor and calls the appropriate visit method for a RuntimeListMenuItem.
70+
*
71+
* @param visitor The MenuItemVisitor to accept
72+
*/
6173
@Override
6274
public void accept(MenuItemVisitor visitor) {
6375
visitor.visit(this);
6476
}
77+
78+
79+
/**
80+
* Retrieves the list of items from a menu tree for a specific RuntimeListMenuItem. This is a helper to
81+
* get back the list of items stored in the tree state.
82+
*
83+
* @param menuTree the menu tree from which to retrieve the items
84+
* @return a list of items as strings
85+
*/
86+
@SuppressWarnings("unchecked")
87+
public List<String> getItemsFromTree(MenuTree menuTree) {
88+
return (List<String>) MenuItemHelper.getValueFor(this, menuTree);
89+
}
90+
6591
}

0 commit comments

Comments
 (0)