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 ff741727ee Fix for issue #7355 (#7357)
ff741727ee is described below
commit ff741727ee47f73bc23432638e5b7d0cfc838116
Author: Matt Casters <[email protected]>
AuthorDate: Mon Jun 29 15:07:33 2026 +0200
Fix for issue #7355 (#7357)
---
.../main/java/org/apache/hop/testing/DataSet.java | 4 +
.../org/apache/hop/testing/DataSetCsvUtil.java | 12 +-
.../testing/actions/runtests/RunPipelineTests.java | 20 +++
.../hop/testing/xp/AutoOpenTestExtensionPoint.java | 14 ++
.../testing/xp/LocationMouseUpExtensionPoint.java | 61 +++++++
.../testing/PipelineUnitTestSetLocationDialog.java | 199 ++++++++++++++++++++-
.../ui/testing/messages/messages_en_US.properties | 11 ++
.../hop/ui/core/dialog/CheckResultDialog.java | 12 +-
8 files changed, 320 insertions(+), 13 deletions(-)
diff --git
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/DataSet.java
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/DataSet.java
index d6032005a3..6f87743c56 100644
--- a/plugins/misc/testing/src/main/java/org/apache/hop/testing/DataSet.java
+++ b/plugins/misc/testing/src/main/java/org/apache/hop/testing/DataSet.java
@@ -141,6 +141,10 @@ public class DataSet extends HopMetadataBase implements
Cloneable, IHopMetadata
IRowMeta rowMeta = new RowMeta();
for (PipelineUnitTestFieldMapping fieldMapping :
location.getFieldMappings()) {
IValueMeta valueMeta =
setRowMeta.searchValueMeta(fieldMapping.getDataSetFieldName());
+ if (valueMeta == null) {
+ valueMeta =
+ new
org.apache.hop.core.row.value.ValueMetaString(fieldMapping.getDataSetFieldName());
+ }
rowMeta.addValueMeta(valueMeta);
}
return rowMeta;
diff --git
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/DataSetCsvUtil.java
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/DataSetCsvUtil.java
index dee52d8cf6..07cf152302 100644
---
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/DataSetCsvUtil.java
+++
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/DataSetCsvUtil.java
@@ -170,10 +170,14 @@ public class DataSetCsvUtil {
for (int i = 0; i < dataSetFieldIndexes.length; i++) {
int index = dataSetFieldIndexes[i];
- IValueMeta valueMeta = setRowMeta.getValueMeta(index);
- constantValueMeta.setConversionMetadata(valueMeta);
- String value = csvRecord.get(index);
- row[i] = valueMeta.convertData(constantValueMeta, value);
+ if (index >= 0 && index < setRowMeta.size() && index <
csvRecord.size()) {
+ IValueMeta valueMeta = setRowMeta.getValueMeta(index);
+ constantValueMeta.setConversionMetadata(valueMeta);
+ String value = csvRecord.get(index);
+ row[i] = valueMeta.convertData(constantValueMeta, value);
+ } else {
+ row[i] = null;
+ }
}
rows.add(row);
}
diff --git
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/actions/runtests/RunPipelineTests.java
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/actions/runtests/RunPipelineTests.java
index dadb9436f1..078f3af85c 100644
---
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/actions/runtests/RunPipelineTests.java
+++
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/actions/runtests/RunPipelineTests.java
@@ -167,6 +167,26 @@ public class RunPipelineTests extends ActionBase
implements IAction, Cloneable {
if (test == null) {
throw new HopException("Unit test '" + testName + "' could not be
found");
}
+
+ variables.setVariable(
+ org.apache.hop.testing.util.DataSetConst.VAR_UNIT_TEST_NAME,
test.getName());
+ try {
+ if
("GUI".equalsIgnoreCase(org.apache.hop.core.Const.getHopPlatformRuntime())) {
+ Class<?> hopGuiClass =
Class.forName("org.apache.hop.ui.hopgui.HopGui");
+ Object hopGuiInstance =
hopGuiClass.getMethod("getInstance").invoke(null);
+ if (hopGuiInstance != null) {
+ IVariables guiVariables =
+ (IVariables)
hopGuiClass.getMethod("getVariables").invoke(hopGuiInstance);
+ if (guiVariables != null) {
+ guiVariables.setVariable(
+ org.apache.hop.testing.util.DataSetConst.VAR_UNIT_TEST_NAME,
test.getName());
+ }
+ }
+ }
+ } catch (Throwable e) {
+ // Ignore
+ }
+
return UnitTestUtil.loadTestPipeline(test, metadataProvider, variables);
}
diff --git
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/AutoOpenTestExtensionPoint.java
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/AutoOpenTestExtensionPoint.java
index a92d519c5c..a660bd5d24 100644
---
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/AutoOpenTestExtensionPoint.java
+++
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/AutoOpenTestExtensionPoint.java
@@ -55,6 +55,20 @@ public class AutoOpenTestExtensionPoint implements
IExtensionPoint<PipelineMeta>
TestingGuiPlugin.findPipelineUnitTest(
variables, pipelineMeta, hopGui.getMetadataProvider());
+ // See if a specific unit test was requested
+ //
+ String unitTestName =
+
variables.getVariable(org.apache.hop.testing.util.DataSetConst.VAR_UNIT_TEST_NAME);
+ if (unitTestName != null && !unitTestName.isEmpty()) {
+ for (PipelineUnitTest test : tests) {
+ if (unitTestName.equalsIgnoreCase(test.getName())) {
+ TestingGuiPlugin.selectUnitTest(pipelineMeta, test);
+
variables.setVariable(org.apache.hop.testing.util.DataSetConst.VAR_UNIT_TEST_NAME,
null);
+ return;
+ }
+ }
+ }
+
// See which ones are auto opening...
//
List<PipelineUnitTest> openTests = new ArrayList<>();
diff --git
a/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/LocationMouseUpExtensionPoint.java
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/LocationMouseUpExtensionPoint.java
new file mode 100644
index 0000000000..c94253ed19
--- /dev/null
+++
b/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/LocationMouseUpExtensionPoint.java
@@ -0,0 +1,61 @@
+/*
+ * 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.gui.AreaOwner;
+import org.apache.hop.core.gui.Point;
+import org.apache.hop.core.logging.ILogChannel;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.pipeline.PipelineMeta;
+import org.apache.hop.testing.gui.TestingGuiPlugin;
+import org.apache.hop.testing.util.DataSetConst;
+import org.apache.hop.ui.hopgui.file.pipeline.HopGuiPipelineGraph;
+import
org.apache.hop.ui.hopgui.file.pipeline.extension.HopGuiPipelineGraphExtension;
+
+@ExtensionPoint(
+ extensionPointId = "PipelineGraphMouseUp",
+ id = "LocationMouseUpExtensionPoint",
+ description = "Prevent showing context menu when clicking on a data set")
+public class LocationMouseUpExtensionPoint
+ implements IExtensionPoint<HopGuiPipelineGraphExtension> {
+
+ @Override
+ public void callExtensionPoint(
+ ILogChannel log, IVariables variables, HopGuiPipelineGraphExtension
pipelineGraphExtension)
+ throws HopException {
+ HopGuiPipelineGraph pipelineGraph =
pipelineGraphExtension.getPipelineGraph();
+ PipelineMeta pipelineMeta = pipelineGraph.getPipelineMeta();
+
+ if (TestingGuiPlugin.getCurrentUnitTest(pipelineMeta) == null) {
+ return;
+ }
+
+ Point point = pipelineGraphExtension.getPoint();
+ AreaOwner areaOwner = pipelineGraph.getVisibleAreaOwner(point.x, point.y);
+ if (areaOwner != null && areaOwner.getAreaType() != null) {
+ if (DataSetConst.AREA_DRAWN_INPUT_DATA_SET.equals(areaOwner.getParent())
+ ||
DataSetConst.AREA_DRAWN_GOLDEN_DATA_SET.equals(areaOwner.getParent())
+ ||
DataSetConst.AREA_DRAWN_GOLDEN_DATA_RESULT.equals(areaOwner.getParent())) {
+ pipelineGraphExtension.setPreventingDefault(true);
+ }
+ }
+ }
+}
diff --git
a/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestSetLocationDialog.java
b/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestSetLocationDialog.java
index 644c881af6..dc22e044d9 100644
---
a/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestSetLocationDialog.java
+++
b/plugins/misc/testing/src/main/java/org/apache/hop/ui/testing/PipelineUnitTestSetLocationDialog.java
@@ -21,7 +21,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.core.CheckResult;
import org.apache.hop.core.Const;
+import org.apache.hop.core.ICheckResult;
import org.apache.hop.core.SourceToTargetMapping;
import org.apache.hop.core.exception.HopException;
import org.apache.hop.core.row.IRowMeta;
@@ -34,6 +36,7 @@ import org.apache.hop.testing.PipelineUnitTestFieldMapping;
import org.apache.hop.testing.PipelineUnitTestSetLocation;
import org.apache.hop.ui.core.PropsUi;
import org.apache.hop.ui.core.dialog.BaseDialog;
+import org.apache.hop.ui.core.dialog.CheckResultDialog;
import org.apache.hop.ui.core.dialog.EnterMappingDialog;
import org.apache.hop.ui.core.dialog.ErrorDialog;
import org.apache.hop.ui.core.gui.GuiResource;
@@ -190,11 +193,15 @@ public class PipelineUnitTestSetLocationDialog extends
Dialog {
wGetSortFields.setText(
BaseMessages.getString(PKG,
"PipelineUnitTestSetLocationDialog.GetSortFields.Button"));
wGetSortFields.addListener(SWT.Selection, e -> getSortFields());
+ Button wValidate = new Button(shell, SWT.PUSH);
+ wValidate.setText(
+ BaseMessages.getString(PKG,
"PipelineUnitTestSetLocationDialog.Validate.Button"));
+ wValidate.addListener(SWT.Selection, e -> validate());
Button wCancel = new Button(shell, SWT.PUSH);
wCancel.setText(BaseMessages.getString(PKG, "System.Button.Cancel"));
wCancel.addListener(SWT.Selection, e -> cancel());
BaseTransformDialog.positionBottomButtons(
- shell, new Button[] {wOk, wMapFields, wGetSortFields, wCancel},
margin, null);
+ shell, new Button[] {wOk, wMapFields, wGetSortFields, wValidate,
wCancel}, margin, null);
// the field mapping grid in between on the left
//
@@ -428,6 +435,196 @@ public class PipelineUnitTestSetLocationDialog extends
Dialog {
}
}
+ protected void validate() {
+ List<ICheckResult> remarks = new ArrayList<>();
+
+ String transformName = wTransformName.getText();
+ String datasetName = wDataset.getText();
+
+ if (StringUtils.isEmpty(datasetName)) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ BaseMessages.getString(
+ PKG,
"PipelineUnitTestSetLocationDialog.Validate.Result.DatasetNotSelected"),
+ null));
+ }
+ if (StringUtils.isEmpty(transformName)) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ BaseMessages.getString(
+ PKG,
"PipelineUnitTestSetLocationDialog.Validate.Result.TransformNotSelected"),
+ null));
+ }
+
+ DataSet dataSet = null;
+ if (StringUtils.isNotEmpty(datasetName)) {
+ try {
+ dataSet = findDataSet(datasetName);
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_OK,
+ "Dataset '" + datasetName + "' exists in metadata.",
+ null));
+ } catch (Exception e) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ BaseMessages.getString(
+ PKG,
+
"PipelineUnitTestSetLocationDialog.Validate.Result.DatasetNotExist",
+ datasetName),
+ null));
+ }
+ }
+
+ // Check fields of the transform if selected
+ IRowMeta transformRowMeta = null;
+ if (StringUtils.isNotEmpty(transformName)) {
+ transformRowMeta = transformFieldsMap.get(transformName);
+ if (transformRowMeta == null) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ "Unable to find fields for transform " + transformName,
+ null));
+ }
+ }
+
+ IRowMeta setRowMeta = null;
+ if (dataSet != null) {
+ try {
+ setRowMeta = dataSet.getSetRowMeta();
+ } catch (Exception e) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ "Error reading fields metadata for dataset '"
+ + datasetName
+ + "': "
+ + e.getMessage(),
+ null));
+ }
+ }
+
+ // Verify field mappings
+ PipelineUnitTestSetLocation loc = new PipelineUnitTestSetLocation();
+ getInfo(loc);
+
+ if (loc.getFieldMappings().isEmpty()) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_WARNING,
+ BaseMessages.getString(
+ PKG,
"PipelineUnitTestSetLocationDialog.Validate.Result.FieldMappingEmpty"),
+ null));
+ } else {
+ for (PipelineUnitTestFieldMapping mapping : loc.getFieldMappings()) {
+ String tField = mapping.getTransformFieldName();
+ String dField = mapping.getDataSetFieldName();
+
+ if (transformRowMeta != null && StringUtils.isNotEmpty(tField)) {
+ if (transformRowMeta.indexOfValue(tField) < 0) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ BaseMessages.getString(
+ PKG,
+
"PipelineUnitTestSetLocationDialog.Validate.Result.TransformFieldNotExist",
+ tField,
+ transformName),
+ null));
+ }
+ }
+ if (setRowMeta != null && StringUtils.isNotEmpty(dField)) {
+ if (setRowMeta.indexOfValue(dField) < 0) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ BaseMessages.getString(
+ PKG,
+
"PipelineUnitTestSetLocationDialog.Validate.Result.DatasetFieldNotExist",
+ dField,
+ datasetName),
+ null));
+ }
+ }
+ }
+ }
+
+ // Verify sort field order mappings
+ if (setRowMeta != null) {
+ for (String sortField : loc.getFieldOrder()) {
+ if (StringUtils.isNotEmpty(sortField) &&
setRowMeta.indexOfValue(sortField) < 0) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ BaseMessages.getString(
+ PKG,
+
"PipelineUnitTestSetLocationDialog.Validate.Result.SortFieldNotExist",
+ sortField,
+ datasetName),
+ null));
+ }
+ }
+ }
+
+ // Verify CSV file exists and can read rows
+ if (dataSet != null) {
+ String filename = dataSet.getActualDataSetFilename(variables);
+ try {
+ org.apache.commons.vfs2.FileObject file =
+ org.apache.hop.core.vfs.HopVfs.getFileObject(filename);
+ if (!file.exists()) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ BaseMessages.getString(
+ PKG,
+
"PipelineUnitTestSetLocationDialog.Validate.Result.CsvNotExist",
+ filename),
+ null));
+ } else {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_OK, "CSV file '" + filename + "'
exists.", null));
+ try {
+ List<Object[]> rows =
+ dataSet.getAllRows(variables,
org.apache.hop.core.logging.LogChannel.UI);
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_OK,
+ BaseMessages.getString(
+ PKG,
+
"PipelineUnitTestSetLocationDialog.Validate.Result.Success",
+ String.valueOf(rows.size())),
+ null));
+ } catch (Exception e) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ BaseMessages.getString(
+ PKG,
+
"PipelineUnitTestSetLocationDialog.Validate.Result.CsvReadError",
+ e.getMessage()),
+ null));
+ }
+ }
+ } catch (Exception e) {
+ remarks.add(
+ new CheckResult(
+ ICheckResult.TYPE_RESULT_ERROR,
+ "Error resolving CSV file path: " + e.getMessage(),
+ null));
+ }
+ }
+
+ // Show CheckResultDialog
+ CheckResultDialog checkResultDialog = new CheckResultDialog(shell,
remarks);
+ checkResultDialog.open();
+ }
+
public void ok() {
getInfo(location);
ok = true;
diff --git
a/plugins/misc/testing/src/main/resources/org/apache/hop/ui/testing/messages/messages_en_US.properties
b/plugins/misc/testing/src/main/resources/org/apache/hop/ui/testing/messages/messages_en_US.properties
index bd0fde2762..31bdb3eae8 100644
---
a/plugins/misc/testing/src/main/resources/org/apache/hop/ui/testing/messages/messages_en_US.properties
+++
b/plugins/misc/testing/src/main/resources/org/apache/hop/ui/testing/messages/messages_en_US.properties
@@ -61,3 +61,14 @@ PipelineUnitTestSetLocationDialog.GetSortFields.Button=Get
sort fields
PipelineUnitTestSetLocationDialog.MapFields.Button=Map fields
PipelineUnitTestSetLocationDialog.Shell.Title=Dataset Location
PipelineUnitTestSetLocationDialog.TransformName.Label=Transform
+PipelineUnitTestSetLocationDialog.Validate.Button=Validate
+PipelineUnitTestSetLocationDialog.Validate.Result.DatasetNotSelected=Please
select a dataset to validate.
+PipelineUnitTestSetLocationDialog.Validate.Result.TransformNotSelected=Please
select a transform to validate.
+PipelineUnitTestSetLocationDialog.Validate.Result.DatasetNotExist=Dataset
''{0}'' does not exist.
+PipelineUnitTestSetLocationDialog.Validate.Result.CsvNotExist=CSV file ''{0}''
does not exist on disk.
+PipelineUnitTestSetLocationDialog.Validate.Result.CsvReadError=Error reading
CSV rows: {0}
+PipelineUnitTestSetLocationDialog.Validate.Result.FieldMappingEmpty=Field
mappings are empty.
+PipelineUnitTestSetLocationDialog.Validate.Result.TransformFieldNotExist=Transform
field ''{0}'' does not exist in transform ''{1}''.
+PipelineUnitTestSetLocationDialog.Validate.Result.DatasetFieldNotExist=Dataset
field ''{0}'' does not exist in dataset ''{1}''.
+PipelineUnitTestSetLocationDialog.Validate.Result.SortFieldNotExist=Sort field
''{0}'' does not exist in dataset ''{1}''.
+PipelineUnitTestSetLocationDialog.Validate.Result.Success=Dataset location
configuration is valid. {0} rows read successfully.
diff --git
a/ui/src/main/java/org/apache/hop/ui/core/dialog/CheckResultDialog.java
b/ui/src/main/java/org/apache/hop/ui/core/dialog/CheckResultDialog.java
index e5762cb994..728b5a3f32 100644
--- a/ui/src/main/java/org/apache/hop/ui/core/dialog/CheckResultDialog.java
+++ b/ui/src/main/java/org/apache/hop/ui/core/dialog/CheckResultDialog.java
@@ -65,7 +65,6 @@ public class CheckResultDialog extends Dialog {
private final PropsUi props;
private Color red;
- private Color green;
private Color yellow;
private boolean showSuccessfulResults = false;
@@ -84,7 +83,6 @@ public class CheckResultDialog extends Dialog {
Display display = parent.getDisplay();
red = display.getSystemColor(SWT.COLOR_RED);
- green = display.getSystemColor(SWT.COLOR_GREEN);
yellow = display.getSystemColor(SWT.COLOR_YELLOW);
shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX);
@@ -219,22 +217,20 @@ public class CheckResultDialog extends Dialog {
ti.setText(2, cr.getType() + " - " + cr.getTypeDesc());
ti.setText(3, cr.getText());
- Color col = ti.getBackground();
+ Color col = null;
switch (cr.getType()) {
- case ICheckResult.TYPE_RESULT_OK:
- col = green;
- break;
case ICheckResult.TYPE_RESULT_ERROR:
col = red;
break;
case ICheckResult.TYPE_RESULT_WARNING:
col = yellow;
break;
- case ICheckResult.TYPE_RESULT_COMMENT:
default:
break;
}
- ti.setBackground(col);
+ if (col != null) {
+ ti.setBackground(col);
+ }
}
}