This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new eadd814257 disabled buttons for unit tests and code hardening, fixes
#6406 (#6407)
eadd814257 is described below
commit eadd814257a93a2a93b5345da1d28358992c4306
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Fri Jan 16 11:32:36 2026 +0100
disabled buttons for unit tests and code hardening, fixes #6406 (#6407)
cleanup dialog a bit
---
.../apache/hop/testing/gui/TestingGuiPlugin.java | 100 +++++++++++++++++++--
.../xp/UpdateUnitTestButtonsExtensionPoint.java | 53 +++++++++++
.../hop/ui/testing/PipelineUnitTestEditor.java | 55 ++++++------
.../hop/ui/core/gui/GuiCompositeWidgets.java | 15 +++-
.../apache/hop/ui/core/gui/GuiToolbarWidgets.java | 4 +
5 files changed, 191 insertions(+), 36 deletions(-)
diff --git
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/gui/TestingGuiPlugin.java
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/gui/TestingGuiPlugin.java
index d4efed5fc9..4ba0658774 100644
---
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/gui/TestingGuiPlugin.java
+++
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/gui/TestingGuiPlugin.java
@@ -112,6 +112,8 @@ public class TestingGuiPlugin {
private static TestingGuiPlugin instance = null;
+ private static final ILogChannel log = LogChannel.GENERAL;
+
public TestingGuiPlugin() {
// Do nothing
}
@@ -871,6 +873,9 @@ public class TestingGuiPlugin {
// Update the GUI
//
pipelineGraph.updateGui();
+
+ // Enable/disable buttons based on selection
+ enableUnitTestButtons();
} catch (Exception e) {
new ErrorDialog(
hopGui.getShell(),
@@ -892,7 +897,30 @@ public class TestingGuiPlugin {
if (pipelineMeta == null) {
return;
}
- PipelineUnitTest unitTest = getCurrentUnitTest(pipelineMeta);
+ Combo combo = getUnitTestsCombo();
+ if (combo == null) {
+ return;
+ }
+ if (StringUtils.isEmpty(combo.getText())) {
+ return;
+ }
+
+ String unitTestName = combo.getText();
+
+ // Load the unit test to verify it exists
+ PipelineUnitTest unitTest = null;
+ try {
+ IHopMetadataSerializer<PipelineUnitTest> testSerializer =
+ hopGui.getMetadataProvider().getSerializer(PipelineUnitTest.class);
+ unitTest = testSerializer.load(unitTestName);
+ } catch (Exception e) {
+ log.logError("Error loading unit test: " + unitTestName, e);
+ return;
+ }
+
+ if (unitTest == null || Utils.isEmpty(unitTest.getName())) {
+ return;
+ }
MetadataManager<PipelineUnitTest> manager =
new MetadataManager<>(
@@ -900,12 +928,25 @@ public class TestingGuiPlugin {
hopGui.getMetadataProvider(),
PipelineUnitTest.class,
hopGui.getShell());
- if (unitTest != null
- && !Utils.isEmpty(unitTest.getName())
- && manager.editMetadata(unitTest.getName())) {
+ if (manager.editMetadata(unitTest.getName())) {
// Activate the test
refreshUnitTestsList();
- selectUnitTest(pipelineMeta, unitTest);
+
+ // Reload the unit test and select it
+ try {
+ IHopMetadataSerializer<PipelineUnitTest> testSerializer =
+ hopGui.getMetadataProvider().getSerializer(PipelineUnitTest.class);
+ PipelineUnitTest reloadedTest = testSerializer.load(unitTestName);
+ if (reloadedTest != null) {
+ selectUnitTest(pipelineMeta, reloadedTest);
+ }
+ } catch (Exception e) {
+ // Log but don't fail
+ log.logError("Error reloading unit test after edit", e);
+ }
+
+ // Enable/disable buttons based on selection
+ enableUnitTestButtons();
}
}
@@ -939,6 +980,9 @@ public class TestingGuiPlugin {
// Activate the test
refreshUnitTestsList();
selectUnitTest(pipelineMeta, test);
+
+ // Enable/disable buttons based on selection
+ enableUnitTestButtons();
}
}
@@ -995,6 +1039,9 @@ public class TestingGuiPlugin {
testSerializer.delete(pipelineUnitTest.getName());
refreshUnitTestsList();
+
+ // Enable/disable buttons based on selection
+ enableUnitTestButtons();
} catch (Exception e) {
new ErrorDialog(
hopGui.getShell(),
@@ -1017,12 +1064,52 @@ public class TestingGuiPlugin {
return null;
}
+ /**
+ * Enable or disable the unit test buttons (Edit, Detach, Delete) based on
whether a unit test is
+ * selected.
+ */
+ public void enableUnitTestButtons() {
+ HopGuiPipelineGraph pipelineGraph = HopGui.getActivePipelineGraph();
+ if (pipelineGraph == null) {
+ return;
+ }
+
+ // Check if toolbar widgets are available
+ if (pipelineGraph.getToolBarWidgets() == null) {
+ return;
+ }
+
+ Combo combo = getUnitTestsCombo();
+ boolean hasSelection = combo != null &&
!StringUtils.isEmpty(combo.getText());
+
+ if (log.isDebug()) {
+ log.logDebug(
+ "Enabling unit test buttons: hasSelection="
+ + hasSelection
+ + ", comboText="
+ + (combo != null ? combo.getText() : "null"));
+ }
+
+ pipelineGraph
+ .getToolBarWidgets()
+ .enableToolbarItem(ID_TOOLBAR_ITEM_UNIT_TEST_EDIT, hasSelection);
+ pipelineGraph
+ .getToolBarWidgets()
+ .enableToolbarItem(ID_TOOLBAR_ITEM_UNIT_TEST_DETACH, hasSelection);
+ pipelineGraph
+ .getToolBarWidgets()
+ .enableToolbarItem(ID_TOOLBAR_ITEM_UNIT_TESTS_DELETE, hasSelection);
+ }
+
public static void refreshUnitTestsList() {
HopGuiPipelineGraph pipelineGraph = HopGui.getActivePipelineGraph();
if (pipelineGraph == null) {
return;
}
pipelineGraph.getToolBarWidgets().refreshComboItemList(ID_TOOLBAR_UNIT_TESTS_COMBO);
+
+ // Update button states after refresh
+ getInstance().enableUnitTestButtons();
}
public static void selectUnitTestInList(String name) {
@@ -1178,6 +1265,9 @@ public class TestingGuiPlugin {
// Update the pipeline graph
hopGui.getActiveFileTypeHandler().updateGui();
}
+
+ // Enable/disable buttons based on selection
+ enableUnitTestButtons();
} catch (Exception e) {
new ErrorDialog(
hopGui.getShell(),
diff --git
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/UpdateUnitTestButtonsExtensionPoint.java
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/UpdateUnitTestButtonsExtensionPoint.java
new file mode 100644
index 0000000000..e3a5f63bbb
--- /dev/null
+++
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/UpdateUnitTestButtonsExtensionPoint.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hop.testing.xp;
+
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.extension.ExtensionPoint;
+import org.apache.hop.core.extension.IExtensionPoint;
+import org.apache.hop.core.logging.ILogChannel;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.testing.gui.TestingGuiPlugin;
+import org.apache.hop.ui.hopgui.HopGui;
+import org.apache.hop.ui.hopgui.file.pipeline.HopGuiPipelineGraph;
+import org.eclipse.swt.widgets.Display;
+
+@ExtensionPoint(
+ extensionPointId = "HopGuiPipelineGraphUpdateGui",
+ id = "UpdateUnitTestButtonsUpdateGuiExtensionPoint",
+ description = "Enable/disable unit test toolbar buttons based on whether a
test is selected")
+/**
+ * This extension point is called whenever the pipeline graph GUI is updated.
It ensures the unit
+ * test toolbar buttons (Edit, Detach, Delete) are enabled or disabled based
on whether a unit test
+ * is currently selected.
+ */
+public class UpdateUnitTestButtonsExtensionPoint implements
IExtensionPoint<HopGuiPipelineGraph> {
+
+ @Override
+ public void callExtensionPoint(
+ ILogChannel log, IVariables variables, HopGuiPipelineGraph pipelineGraph)
+ throws HopException {
+
+ // Update the unit test button states
+ // Use asyncExec to ensure this runs after any async combo population
+ Display display = HopGui.getInstance().getDisplay();
+ if (display != null && !display.isDisposed()) {
+ display.asyncExec(() ->
TestingGuiPlugin.getInstance().enableUnitTestButtons());
+ }
+ }
+}
diff --git
a/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestEditor.java
b/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestEditor.java
index a74b0f1177..efafe5c003 100644
---
a/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestEditor.java
+++
b/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestEditor.java
@@ -99,7 +99,7 @@ public class PipelineUnitTestEditor extends
MetadataEditor<PipelineUnitTest> {
wName = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
PropsUi.setLook(wName);
FormData fdName = new FormData();
- fdName.top = new FormAttachment(wlName, 0, SWT.CENTER);
+ fdName.top = new FormAttachment(0, margin);
fdName.left = new FormAttachment(middle, 0);
fdName.right = new FormAttachment(100, 0);
wName.setLayoutData(fdName);
@@ -118,7 +118,7 @@ public class PipelineUnitTestEditor extends
MetadataEditor<PipelineUnitTest> {
wDescription = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
PropsUi.setLook(wDescription);
FormData fdDescription = new FormData();
- fdDescription.top = new FormAttachment(wlDescription, 0, SWT.CENTER);
+ fdDescription.top = new FormAttachment(lastControl, margin);
fdDescription.left = new FormAttachment(middle, 0);
fdDescription.right = new FormAttachment(100, 0);
wDescription.setLayoutData(fdDescription);
@@ -137,7 +137,7 @@ public class PipelineUnitTestEditor extends
MetadataEditor<PipelineUnitTest> {
wTestType = new Combo(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
PropsUi.setLook(wTestType);
FormData fdTestType = new FormData();
- fdTestType.top = new FormAttachment(wlTestType, 0, SWT.CENTER);
+ fdTestType.top = new FormAttachment(lastControl, margin);
fdTestType.left = new FormAttachment(middle, 0);
fdTestType.right = new FormAttachment(100, 0);
wTestType.setLayoutData(fdTestType);
@@ -153,25 +153,25 @@ public class PipelineUnitTestEditor extends
MetadataEditor<PipelineUnitTest> {
FormData fdlPipelineFilename = new FormData();
fdlPipelineFilename.top = new FormAttachment(lastControl, margin);
fdlPipelineFilename.left = new FormAttachment(0, 0);
- fdlPipelineFilename.right = new FormAttachment(middle, 0);
+ fdlPipelineFilename.right = new FormAttachment(middle, -margin);
wlPipelineFilename.setLayoutData(fdlPipelineFilename);
Button wbPipelineFilename = new Button(parent, SWT.PUSH);
PropsUi.setLook(wbPipelineFilename);
wbPipelineFilename.setText(BaseMessages.getString(PKG,
"PipelineUnitTestDialog.Button.Browse"));
FormData fdbPipelineFilename = new FormData();
- fdbPipelineFilename.right = new FormAttachment(99, 0);
- fdbPipelineFilename.top = new FormAttachment(wlPipelineFilename, 0,
SWT.CENTER);
+ fdbPipelineFilename.right = new FormAttachment(100, 0);
+ fdbPipelineFilename.top = new FormAttachment(lastControl, margin);
wbPipelineFilename.setLayoutData(fdbPipelineFilename);
wbPipelineFilename.addListener(SWT.Selection,
this::browsePipelineFilename);
wPipelineFilename = new Text(parent, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
PropsUi.setLook(wPipelineFilename);
FormData fdPipelineFilename = new FormData();
- fdPipelineFilename.top = new FormAttachment(wlPipelineFilename, 0,
SWT.CENTER);
- fdPipelineFilename.left = new FormAttachment(middle, margin);
+ fdPipelineFilename.top = new FormAttachment(lastControl, margin);
+ fdPipelineFilename.left = new FormAttachment(middle, 0);
fdPipelineFilename.right = new FormAttachment(wbPipelineFilename, -margin);
wPipelineFilename.setLayoutData(fdPipelineFilename);
- lastControl = wPipelineFilename;
+ lastControl = wbPipelineFilename;
// The optional filename of the test result...
//
@@ -186,7 +186,7 @@ public class PipelineUnitTestEditor extends
MetadataEditor<PipelineUnitTest> {
wFilename = new TextVar(manager.getVariables(), parent, SWT.SINGLE |
SWT.LEFT | SWT.BORDER);
PropsUi.setLook(wFilename);
FormData fdFilename = new FormData();
- fdFilename.top = new FormAttachment(wlFilename, 0, SWT.CENTER);
+ fdFilename.top = new FormAttachment(lastControl, margin);
fdFilename.left = new FormAttachment(middle, 0);
fdFilename.right = new FormAttachment(100, 0);
wFilename.setLayoutData(fdFilename);
@@ -200,28 +200,28 @@ public class PipelineUnitTestEditor extends
MetadataEditor<PipelineUnitTest> {
FormData fdlBasePath = new FormData();
fdlBasePath.top = new FormAttachment(lastControl, margin);
fdlBasePath.left = new FormAttachment(0, 0);
- fdlBasePath.right = new FormAttachment(middle, 0);
+ fdlBasePath.right = new FormAttachment(middle, -margin);
wlBasePath.setLayoutData(fdlBasePath);
Button wbBasePath = new Button(parent, SWT.PUSH);
PropsUi.setLook(wbBasePath);
wbBasePath.setText(BaseMessages.getString(PKG,
"PipelineUnitTestDialog.Button.Browse"));
FormData fdbBasePath = new FormData();
- fdbBasePath.right = new FormAttachment(99, 0);
- fdbBasePath.top = new FormAttachment(wlBasePath, 0, SWT.CENTER);
+ fdbBasePath.right = new FormAttachment(100, 0);
+ fdbBasePath.top = new FormAttachment(lastControl, margin);
wbBasePath.setLayoutData(fdbBasePath);
wbBasePath.addListener(SWT.Selection, this::browseTestPathDir);
wBasePath = new TextVar(manager.getVariables(), parent, SWT.SINGLE |
SWT.LEFT | SWT.BORDER);
PropsUi.setLook(wBasePath);
FormData fdBasePath = new FormData();
- fdBasePath.top = new FormAttachment(wbBasePath, 0, SWT.CENTER);
- fdBasePath.left = new FormAttachment(middle, margin);
+ fdBasePath.top = new FormAttachment(lastControl, margin);
+ fdBasePath.left = new FormAttachment(middle, 0);
fdBasePath.right = new FormAttachment(wbBasePath, -margin);
wBasePath.setLayoutData(fdBasePath);
- lastControl = wBasePath;
+ lastControl = wbBasePath;
- // The base path for relative test path resolution
+ // Auto-open checkbox
//
Label wlAutoOpen = new Label(parent, SWT.RIGHT);
PropsUi.setLook(wlAutoOpen);
@@ -236,21 +236,20 @@ public class PipelineUnitTestEditor extends
MetadataEditor<PipelineUnitTest> {
FormData fdAutoOpen = new FormData();
fdAutoOpen.top = new FormAttachment(wlAutoOpen, 0, SWT.CENTER);
fdAutoOpen.left = new FormAttachment(middle, 0);
- fdAutoOpen.right = new FormAttachment(100, 0);
wAutoOpen.setLayoutData(fdAutoOpen);
lastControl = wAutoOpen;
// The list of database replacements in the unit test pipeline
//
- Label wlFieldMapping = new Label(parent, SWT.NONE);
- wlFieldMapping.setText(
+ Label wlDbReplacements = new Label(parent, SWT.NONE);
+ wlDbReplacements.setText(
BaseMessages.getString(PKG,
"PipelineUnitTestDialog.DbReplacements.Label"));
- PropsUi.setLook(wlFieldMapping);
- FormData fdlUpIns = new FormData();
- fdlUpIns.left = new FormAttachment(0, 0);
- fdlUpIns.top = new FormAttachment(lastControl, 3 * margin);
- wlFieldMapping.setLayoutData(fdlUpIns);
- lastControl = wlFieldMapping;
+ PropsUi.setLook(wlDbReplacements);
+ FormData fdlDbReplacements = new FormData();
+ fdlDbReplacements.left = new FormAttachment(0, 0);
+ fdlDbReplacements.top = new FormAttachment(lastControl, 2 * margin);
+ wlDbReplacements.setLayoutData(fdlDbReplacements);
+ lastControl = wlDbReplacements;
// the database replacements
//
@@ -294,7 +293,7 @@ public class PipelineUnitTestEditor extends
MetadataEditor<PipelineUnitTest> {
fdDbReplacements.left = new FormAttachment(0, 0);
fdDbReplacements.top = new FormAttachment(lastControl, margin);
fdDbReplacements.right = new FormAttachment(100, 0);
- fdDbReplacements.bottom = new FormAttachment(lastControl, 250);
+ fdDbReplacements.bottom = new FormAttachment(50, -margin);
wDbReplacements.setLayoutData(fdDbReplacements);
lastControl = wDbReplacements;
@@ -304,7 +303,7 @@ public class PipelineUnitTestEditor extends
MetadataEditor<PipelineUnitTest> {
PropsUi.setLook(wlVariableValues);
FormData fdlVariableValues = new FormData();
fdlVariableValues.left = new FormAttachment(0, 0);
- fdlVariableValues.top = new FormAttachment(lastControl, margin);
+ fdlVariableValues.top = new FormAttachment(lastControl, 2 * margin);
wlVariableValues.setLayoutData(fdlVariableValues);
lastControl = wlVariableValues;
diff --git
a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java
b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java
index c0847937c8..5eb69fb899 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiCompositeWidgets.java
@@ -642,8 +642,12 @@ public class GuiCompositeWidgets {
// New layout: control goes on the right, aligned with the row below
the label
fdControl.top = new FormAttachment(label, PropsUi.getMargin() / 2);
} else {
- // Old layout: control aligned with label (center)
- fdControl.top = new FormAttachment(label, 0, SWT.CENTER);
+ // Old layout: control aligned with lastControl to maintain proper
vertical spacing
+ if (lastControl != null) {
+ fdControl.top = new FormAttachment(lastControl, PropsUi.getMargin());
+ } else {
+ fdControl.top = new FormAttachment(0, PropsUi.getMargin());
+ }
}
} else {
if (lastControl != null) {
@@ -681,7 +685,12 @@ public class GuiCompositeWidgets {
} else {
fdControl.right = new FormAttachment(rightControl, -5);
}
- fdControl.top = new FormAttachment(label, 0, SWT.CENTER);
+ // Attach to lastControl to create proper vertical spacing between
widgets
+ if (lastControl != null) {
+ fdControl.top = new FormAttachment(lastControl, PropsUi.getMargin());
+ } else {
+ fdControl.top = new FormAttachment(0, PropsUi.getMargin());
+ }
}
} else {
// No label
diff --git a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiToolbarWidgets.java
b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiToolbarWidgets.java
index b5bab5c11a..91b4bb24f4 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/gui/GuiToolbarWidgets.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/gui/GuiToolbarWidgets.java
@@ -453,6 +453,10 @@ public class GuiToolbarWidgets extends BaseGuiWidgets {
SvgLabelFacade.enable(toolItem, uniqueId, imageLabel, enabled);
}
}
+ // Also update the ToolItem state for consistency
+ if (enabled != toolItem.isEnabled()) {
+ toolItem.setEnabled(enabled);
+ }
} else {
if (enabled != toolItem.isEnabled()) {
toolItem.setEnabled(enabled);