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);
+        }
       }
     }
 

Reply via email to