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 f516646ee7 Improve YamlInput component spacing, add unit tests, and 
fix Sonar issues (#6965)
f516646ee7 is described below

commit f516646ee77740d15c508340fde6669e6cea3524
Author: Lance <[email protected]>
AuthorDate: Mon Apr 6 20:36:35 2026 +0800

    Improve YamlInput component spacing, add unit tests, and fix Sonar issues 
(#6965)
---
 .../transforms/datasets/golden-yaml-input.csv      |   3 +-
 .../pipeline/transforms/yamlinput/YamlInput.java   | 165 +++----
 .../transforms/yamlinput/YamlInputData.java        |  13 +-
 .../transforms/yamlinput/YamlInputDialog.java      | 286 ++++++------
 .../transforms/yamlinput/YamlInputField.java       |   7 +-
 .../transforms/yamlinput/YamlInputMeta.java        |   3 +-
 .../pipeline/transforms/yamlinput/YamlReader.java  | 513 ++++++++++-----------
 .../yamlinput/messages/messages_en_US.properties   |   2 +-
 .../transforms/yamlinput/YamlInputDataTests.java   |  51 ++
 .../transforms/yamlinput/YamlInputFieldTests.java  | 119 +++++
 .../transforms/yamlinput/YamlInputMetaTest.java    | 218 +++++++++
 .../transforms/yamlinput/YamlInputTests.java       | 296 ++++++++++++
 .../transforms/yamlinput/YamlReaderTests.java      | 230 +++++++++
 13 files changed, 1363 insertions(+), 543 deletions(-)

diff --git a/integration-tests/transforms/datasets/golden-yaml-input.csv 
b/integration-tests/transforms/datasets/golden-yaml-input.csv
index cd156b7622..6a7bac4601 100644
--- a/integration-tests/transforms/datasets/golden-yaml-input.csv
+++ b/integration-tests/transforms/datasets/golden-yaml-input.csv
@@ -1,3 +1,2 @@
 
organisation,acronym,project,javaFileCount,awesome,used-apache-projects,statistics
-The Apache Software Foundation,The ASF,Apache Hop,4447,Y,"[Spark, Flink, Beam, 
Commons, VFS]
-","{number-of-libs:  1159,number-of-messages-bundles:  
13025,integration-test-projects:  {count:  39,pipelines:  1032,workflows:  
498}}"
+The Apache Software Foundation,The ASF,Apache Hop,4447,Y,"[Spark, Flink, Beam, 
Commons, VFS]","{number-of-libs:  1159,number-of-messages-bundles:  
13025,integration-test-projects:  {count:  39,pipelines:  1032,workflows:  
498}}"
diff --git 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInput.java
 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInput.java
index 34179a1978..6b48d39a89 100644
--- 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInput.java
+++ 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInput.java
@@ -53,9 +53,9 @@ public class YamlInput extends BaseTransform<YamlInputMeta, 
YamlInputData> {
   }
 
   private void handleMissingFiles() throws HopException {
-    List<FileObject> nonExistantFiles = data.files.getNonExistentFiles();
-    if (!nonExistantFiles.isEmpty()) {
-      String message = 
FileInputList.getRequiredFilesDescription(nonExistantFiles);
+    List<FileObject> nonExistentFiles = data.files.getNonExistentFiles();
+    if (!nonExistentFiles.isEmpty()) {
+      String message = 
FileInputList.getRequiredFilesDescription(nonExistentFiles);
       logError(
           BaseMessages.getString(PKG, "YamlInput.Log.RequiredFilesTitle"),
           BaseMessages.getString(PKG, "YamlInput.Log.RequiredFiles", message));
@@ -78,9 +78,10 @@ public class YamlInput extends BaseTransform<YamlInputMeta, 
YamlInputData> {
 
   private boolean readNextString() {
     try {
-      data.readrow = getRow(); // Grab another row ...
+      // Grab another row ...
+      data.readRow = getRow();
 
-      if (data.readrow == null) {
+      if (data.readRow == null) {
         // finished processing!
         if (isDetailed()) {
           logDetailed(BaseMessages.getString(PKG, 
"YamlInput.Log.FinishedProcessing"));
@@ -116,14 +117,13 @@ public class YamlInput extends 
BaseTransform<YamlInputMeta, YamlInputData> {
       }
 
       // get field value
-      String fieldvalue = getInputRowMeta().getString(data.readrow, 
data.indexOfYamlField);
-
+      String fieldValue = getInputRowMeta().getString(data.readRow, 
data.indexOfYamlField);
       getLinesInput();
 
       if (isDetailed()) {
         logDetailed(
             BaseMessages.getString(
-                PKG, "YamlInput.Log.YAMLStream", meta.getYamlField(), 
fieldvalue));
+                PKG, "YamlInput.Log.YAMLStream", meta.getYamlField(), 
fieldValue));
       }
 
       if (meta.isSourceFile()) {
@@ -131,15 +131,14 @@ public class YamlInput extends 
BaseTransform<YamlInputMeta, YamlInputData> {
         // source is a file.
 
         data.yaml = new YamlReader();
-        data.yaml.loadFile(HopVfs.getFileObject(fieldvalue, variables));
+        data.yaml.loadFile(HopVfs.getFileObject(fieldValue, variables));
         dataVolumeIn =
             (dataVolumeIn != null ? dataVolumeIn : 0L) + 
data.yaml.getBytesReadFromFile();
 
-        addFileToResultFilesname(data.yaml.getFile());
-
+        addFileToResultFilesName(data.yaml.getFile());
       } else {
         data.yaml = new YamlReader();
-        data.yaml.loadString(fieldvalue);
+        data.yaml.loadString(fieldValue);
       }
     } catch (Exception e) {
       logError(BaseMessages.getString(PKG, "YamlInput.Log.UnexpectedError", 
e.toString()));
@@ -151,7 +150,7 @@ public class YamlInput extends BaseTransform<YamlInputMeta, 
YamlInputData> {
     return false;
   }
 
-  private void addFileToResultFilesname(FileObject file) {
+  private void addFileToResultFilesName(FileObject file) {
     if (meta.isAddingResultFile()) {
       // Add this to the result file names...
       ResultFile resultFile =
@@ -164,7 +163,7 @@ public class YamlInput extends BaseTransform<YamlInputMeta, 
YamlInputData> {
 
   private boolean openNextFile() {
     try {
-      if (data.filenr >= data.files.nrOfFiles()) {
+      if (data.fileIndex >= data.files.nrOfFiles()) {
         // finished processing!
         if (isDetailed()) {
           logDetailed(BaseMessages.getString(PKG, 
"YamlInput.Log.FinishedProcessing"));
@@ -172,10 +171,10 @@ public class YamlInput extends 
BaseTransform<YamlInputMeta, YamlInputData> {
         return false;
       }
       // Get file to process from list
-      data.file = data.files.getFile(data.filenr);
+      data.file = data.files.getFile(data.fileIndex);
 
       // Move file pointer ahead!
-      data.filenr++;
+      data.fileIndex++;
 
       if (meta.isIgnoringEmptyFile() && data.file.getContent().getSize() == 0) 
{
         if (isBasic()) {
@@ -198,7 +197,7 @@ public class YamlInput extends BaseTransform<YamlInputMeta, 
YamlInputData> {
         dataVolumeIn =
             (dataVolumeIn != null ? dataVolumeIn : 0L) + 
data.yaml.getBytesReadFromFile();
 
-        addFileToResultFilesname(data.file);
+        addFileToResultFilesName(data.file);
 
         if (isDetailed()) {
           logDetailed(
@@ -210,7 +209,7 @@ public class YamlInput extends BaseTransform<YamlInputMeta, 
YamlInputData> {
           BaseMessages.getString(
               PKG,
               "YamlInput.Log.UnableToOpenFile",
-              "" + data.filenr,
+              "" + data.fileIndex,
               data.file.toString(),
               e.toString()));
       stopAll();
@@ -243,24 +242,25 @@ public class YamlInput extends 
BaseTransform<YamlInputMeta, YamlInputData> {
     }
     // Grab a row
     Object[] r = getOneRow();
-
-    if (r == null) {
-      setOutputDone(); // signal end to receiver(s)
-      return false; // end of data or error.
+    if (Utils.isEmpty(r)) {
+      // signal end to receiver(s)
+      setOutputDone();
+      // end of data or error.
+      return false;
     }
 
     if (isRowLevel()) {
       logRowlevel(
           BaseMessages.getString(PKG, "YamlInput.Log.ReadRow", 
data.outputRowMeta.getString(r)));
     }
-
     incrementLinesOutput();
 
-    data.rownr++;
+    data.rowIndex++;
     Object[] rowCopy = data.outputRowMeta.cloneRow(r);
-    putRow(data.outputRowMeta, rowCopy); // copy row to output rowset(s)
+    // copy row to output rowset(s)
+    putRow(data.outputRowMeta, rowCopy);
 
-    if (meta.getRowLimit() > 0 && data.rownr > meta.getRowLimit()) {
+    if (meta.getRowLimit() > 0 && data.rowIndex > meta.getRowLimit()) {
       // limit has been reached: stop now.
       setOutputDone();
       return false;
@@ -269,71 +269,52 @@ public class YamlInput extends 
BaseTransform<YamlInputMeta, YamlInputData> {
   }
 
   private Object[] getOneRow() throws HopException {
-    Object[] row = null;
-    boolean rowAvailable = false;
-    boolean fileOpened = false;
     if (!meta.isInFields()) {
-      while (data.file == null || !fileOpened && !rowAvailable) {
-        if (data.file != null) {
-          // We have opened a file
-          // read one row
-          row = getRowData();
-
-          if (row == null) {
-            // No row extracted
-            // let's see for the next file
-            if (!openNextFile()) {
-              return null;
-            }
-            fileOpened = true;
-          } else {
-            // We had extracted one row
-            rowAvailable = true;
-          }
-        } else {
-          // First time we get there
-          // we have to open a new file
-          if (!openNextFile()) {
-            return null;
-          }
-          fileOpened = true;
-        }
+      return getOneRowFromFileMode();
+    }
+
+    return getOneRowFromFieldMode();
+  }
+
+  private Object[] getOneRowFromFileMode() throws HopException {
+    while (true) {
+      if (data.file == null && !openNextFile()) {
+        return new Object[0];
       }
-    } else {
-      while (data.readrow == null || (data.readrow != null && !fileOpened && 
!rowAvailable)) {
-        if (data.readrow != null) {
-          // We have red the incoming Yaml value
-          // let's get one row
-          row = getRowData();
-          if (row == null) {
-            // No row.. reader next row
-            if (readNextString()) {
-              return null;
-            }
-            fileOpened = true;
-          } else {
-            // We have returned one row
-            rowAvailable = true;
-          }
-        } else {
-          // First time we get there
-          // We have to parse incoming Yaml value
-          if (readNextString()) {
-            return null;
-          }
-          fileOpened = true;
-        }
-        if (data.readrow == null) {
-          return null;
-        }
+
+      if (data.file == null) {
+        continue;
+      }
+
+      Object[] row = getRowData();
+      if (row != null && row.length > 0) {
+        return row;
       }
-    }
 
-    if (!rowAvailable) {
-      row = getRowData();
+      if (!openNextFile()) {
+        return new Object[0];
+      }
     }
+  }
+
+  private Object[] getOneRowFromFieldMode() throws HopException {
+    while (true) {
+      if (data.readRow == null) {
+        if (readNextString()) {
+          return new Object[0];
+        }
+        continue;
+      }
+
+      Object[] row = getRowData();
+      if (row != null && row.length > 0) {
+        return row;
+      }
 
-    return row;
+      if (readNextString()) {
+        return new Object[0];
+      }
+    }
   }
 
   private Object[] getRowData() throws HopException {
@@ -343,13 +324,13 @@ public class YamlInput extends 
BaseTransform<YamlInputMeta, YamlInputData> {
     try {
       // Create new row...
       outputRowData = data.yaml.getRow(data.rowMeta);
-      if (outputRowData == null) {
-        return null;
+      if (outputRowData == null || outputRowData.length == 0) {
+        return new Object[0];
       }
 
-      if (data.readrow != null) {
+      if (data.readRow != null) {
         outputRowData =
-            RowDataUtil.addRowData(data.readrow, data.totalPreviousFields, 
outputRowData);
+            RowDataUtil.addRowData(data.readRow, data.totalPreviousFields, 
outputRowData);
       } else {
         outputRowData = RowDataUtil.resizeArray(outputRowData, 
data.totalOutStreamFields);
       }
@@ -362,9 +343,8 @@ public class YamlInput extends BaseTransform<YamlInputMeta, 
YamlInputData> {
       }
       // See if we need to add the row number to the row...
       if (meta.isIncludeRowNumber() && 
!Utils.isEmpty(meta.getRowNumberField())) {
-        outputRowData[rowIndex++] = data.rownr;
+        outputRowData[rowIndex] = data.rowIndex;
       }
-
     } catch (Exception e) {
       boolean sendToErrorRow = false;
       String errorMessage = null;
@@ -390,9 +370,8 @@ public class YamlInput extends BaseTransform<YamlInputMeta, 
YamlInputData> {
 
   @Override
   public boolean init() {
-
     if (super.init()) {
-      data.rownr = 1L;
+      data.rowIndex = 1L;
       data.nrInputFields = meta.getInputFields().size();
 
       data.rowMeta = new RowMeta();
diff --git 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputData.java
 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputData.java
index 41eb050e75..0b53fbad96 100644
--- 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputData.java
+++ 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputData.java
@@ -21,14 +21,13 @@ import org.apache.commons.vfs2.FileObject;
 import org.apache.hop.core.fileinput.FileInputList;
 import org.apache.hop.core.row.IRowMeta;
 import org.apache.hop.pipeline.transform.BaseTransformData;
-import org.apache.hop.pipeline.transform.ITransformData;
 
 @SuppressWarnings("java:S1104")
-public class YamlInputData extends BaseTransformData implements ITransformData 
{
+public class YamlInputData extends BaseTransformData {
   public IRowMeta outputRowMeta;
 
   public int nrInputFields;
-  public Object[] readrow;
+  public Object[] readRow;
   public int totalPreviousFields;
   public int totalOutFields;
   public int totalOutStreamFields;
@@ -37,9 +36,9 @@ public class YamlInputData extends BaseTransformData 
implements ITransformData {
   public FileInputList files;
 
   public FileObject file;
-  public int filenr;
+  public int fileIndex;
 
-  public long rownr;
+  public long rowIndex;
   public int indexOfYamlField;
 
   public YamlReader yaml;
@@ -49,10 +48,10 @@ public class YamlInputData extends BaseTransformData 
implements ITransformData {
   public YamlInputData() {
     super();
 
-    this.filenr = 0;
+    this.fileIndex = 0;
     this.indexOfYamlField = -1;
     this.nrInputFields = -1;
-    this.readrow = null;
+    this.readRow = null;
     this.totalPreviousFields = 0;
     this.file = null;
     this.totalOutFields = 0;
diff --git 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDialog.java
 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDialog.java
index 6ab30addf7..8dbf1b40fb 100644
--- 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDialog.java
+++ 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDialog.java
@@ -17,7 +17,6 @@
 
 package org.apache.hop.pipeline.transforms.yamlinput;
 
-import java.util.ArrayList;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.Props;
 import org.apache.hop.core.exception.HopException;
@@ -74,21 +73,22 @@ public class YamlInputDialog extends BaseTransformDialog {
   public static final String 
CONST_YAML_INPUT_DIALOG_ERROR_PARSING_DATA_DIALOG_MESSAGE =
       "YamlInputDialog.ErrorParsingData.DialogMessage";
 
-  private static final String YES = "Y";
-
-  public static final String[] NO_YES_DEC =
+  protected static final String[] NO_YES_DEC =
       new String[] {
         BaseMessages.getString(PKG, "System.Combo.No"),
         BaseMessages.getString(PKG, "System.Combo.Yes")
       };
-  public static final String[] RequiredFilesCode = new String[] {"N", "Y"};
 
   private Label wlFilename;
   private Label wlYamlIsAFile;
-  private Button wbbFilename; // Browse: add file or directory
-  private Button wbdFilename; // Delete
-  private Button wbeFilename; // Edit
-  private Button wbaFilename; // Add or change
+  // Browse: add file or directory
+  private Button wbbFilename;
+  // Delete
+  private Button wbdFilename;
+  // Edit
+  private Button wbeFilename;
+  // Add or change
+  private Button wbaFilename;
   private TextVar wFilename;
 
   private Label wlFilenameList;
@@ -111,10 +111,10 @@ public class YamlInputDialog extends BaseTransformDialog {
   private Label wlInclFilenameField;
   private TextVar wInclFilenameField;
   private Label wlAddResult;
-  private Button wInclRownum;
+  private Button wInclRowNum;
 
-  private Label wlInclRownumField;
-  private TextVar wInclRownumField;
+  private Label wlInclRowNumField;
+  private TextVar wInclRowNumField;
 
   private Label wlLimit;
   private Text wLimit;
@@ -129,12 +129,7 @@ public class YamlInputDialog extends BaseTransformDialog {
   private Label wlDoNotFailIfNoFile;
   private Button wDoNotFailIfNoFile;
 
-  private YamlInputMeta input;
-
-  public static final int[] dateLengths = new int[] {23, 19, 14, 10, 10, 10, 
10, 8, 8, 8, 8, 6, 6};
-
-  ArrayList<String> listpath = new ArrayList<>();
-  String precNodeName = null;
+  private final YamlInputMeta input;
 
   public YamlInputDialog(
       Shell parent, IVariables variables, YamlInputMeta transformMeta, 
PipelineMeta pipelineMeta) {
@@ -178,29 +173,27 @@ public class YamlInputDialog extends BaseTransformDialog {
     PropsUi.setLook(wOutputField);
     wOutputField.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.wOutputField.Label"));
 
-    FormLayout outputfieldgroupLayout = new FormLayout();
-    outputfieldgroupLayout.marginWidth = 10;
-    outputfieldgroupLayout.marginHeight = 10;
-    wOutputField.setLayout(outputfieldgroupLayout);
+    FormLayout outPutFieldGroupLayout = new FormLayout();
+    outPutFieldGroupLayout.marginWidth = 10;
+    outPutFieldGroupLayout.marginHeight = 10;
+    wOutputField.setLayout(outPutFieldGroupLayout);
 
-    // Is XML string defined in a Field
+    // Source is defined in a field
     Label wlXmlStreamField = new Label(wOutputField, SWT.RIGHT);
     wlXmlStreamField.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.wlXmlStreamField.Label"));
     PropsUi.setLook(wlXmlStreamField);
     FormData fdlXMLStreamField = new FormData();
-    fdlXMLStreamField.left = new FormAttachment(0, -margin);
-    fdlXMLStreamField.top = new FormAttachment(0, margin);
-    fdlXMLStreamField.right = new FormAttachment(middle, -margin);
+    fdlXMLStreamField.left = new FormAttachment(0, 0);
+    fdlXMLStreamField.right = new FormAttachment(middle, 0);
     wlXmlStreamField.setLayoutData(fdlXMLStreamField);
     wYAMLStreamField = new Button(wOutputField, SWT.CHECK);
     PropsUi.setLook(wYAMLStreamField);
     wYAMLStreamField.setToolTipText(
         BaseMessages.getString(PKG, 
"YamlInputDialog.wYAMLStreamField.Tooltip"));
     FormData fdYAMLStreamField = new FormData();
-    fdYAMLStreamField.left = new FormAttachment(middle, -margin);
-    fdYAMLStreamField.top = new FormAttachment(wlXmlStreamField, 0, 
SWT.CENTER);
+    fdYAMLStreamField.left = new FormAttachment(wlXmlStreamField, margin);
     wYAMLStreamField.setLayoutData(fdYAMLStreamField);
-    SelectionAdapter lsyamlstream =
+    SelectionAdapter lsYamlStream =
         new SelectionAdapter() {
           @Override
           public void widgetSelected(SelectionEvent arg0) {
@@ -208,25 +201,25 @@ public class YamlInputDialog extends BaseTransformDialog {
             input.setChanged();
           }
         };
-    wYAMLStreamField.addSelectionListener(lsyamlstream);
+    wYAMLStreamField.addSelectionListener(lsYamlStream);
 
-    // Is XML source is a file?
+    // Source is a filename
     wlYamlIsAFile = new Label(wOutputField, SWT.RIGHT);
     wlYamlIsAFile.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.XMLIsAFile.Label"));
     PropsUi.setLook(wlYamlIsAFile);
     FormData fdlXMLIsAFile = new FormData();
-    fdlXMLIsAFile.left = new FormAttachment(0, -margin);
-    fdlXMLIsAFile.top = new FormAttachment(wYAMLStreamField, margin);
-    fdlXMLIsAFile.right = new FormAttachment(middle, -margin);
+    fdlXMLIsAFile.left = new FormAttachment(0, 0);
+    fdlXMLIsAFile.top = new FormAttachment(wlXmlStreamField, margin);
+    fdlXMLIsAFile.right = new FormAttachment(middle, 0);
     wlYamlIsAFile.setLayoutData(fdlXMLIsAFile);
     wYAMLIsAFile = new Button(wOutputField, SWT.CHECK);
     PropsUi.setLook(wYAMLIsAFile);
     wYAMLIsAFile.setToolTipText(BaseMessages.getString(PKG, 
"YamlInputDialog.XMLIsAFile.Tooltip"));
     FormData fdYAMLIsAFile = new FormData();
-    fdYAMLIsAFile.left = new FormAttachment(middle, -margin);
-    fdYAMLIsAFile.top = new FormAttachment(wlYamlIsAFile, 0, SWT.CENTER);
+    fdYAMLIsAFile.left = new FormAttachment(wlYamlIsAFile, margin);
+    fdYAMLIsAFile.top = new FormAttachment(wYAMLStreamField, margin);
     wYAMLIsAFile.setLayoutData(fdYAMLIsAFile);
-    SelectionAdapter lsyamlisafile =
+    SelectionAdapter lsYamlIsFile =
         new SelectionAdapter() {
           @Override
           public void widgetSelected(SelectionEvent arg0) {
@@ -234,16 +227,16 @@ public class YamlInputDialog extends BaseTransformDialog {
             enableFileSettings();
           }
         };
-    wYAMLIsAFile.addSelectionListener(lsyamlisafile);
+    wYAMLIsAFile.addSelectionListener(lsYamlIsFile);
 
-    // If XML string defined in a Field
+    // Get source from a field
     wlYamlField = new Label(wOutputField, SWT.RIGHT);
     wlYamlField.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.wlYamlField.Label"));
     PropsUi.setLook(wlYamlField);
     FormData fdlXMLField = new FormData();
-    fdlXMLField.left = new FormAttachment(0, -margin);
-    fdlXMLField.top = new FormAttachment(wYAMLIsAFile, margin);
-    fdlXMLField.right = new FormAttachment(middle, -margin);
+    fdlXMLField.left = new FormAttachment(0, 0);
+    fdlXMLField.top = new FormAttachment(wlYamlIsAFile, margin);
+    fdlXMLField.right = new FormAttachment(middle, 0);
     wlYamlField.setLayoutData(fdlXMLField);
 
     wYAMLLField = new CCombo(wOutputField, SWT.BORDER | SWT.READ_ONLY);
@@ -251,9 +244,9 @@ public class YamlInputDialog extends BaseTransformDialog {
     PropsUi.setLook(wYAMLLField);
     wYAMLLField.addModifyListener(lsMod);
     FormData fdXMLField = new FormData();
-    fdXMLField.left = new FormAttachment(middle, -margin);
+    fdXMLField.left = new FormAttachment(wlYamlField, margin);
     fdXMLField.top = new FormAttachment(wYAMLIsAFile, margin);
-    fdXMLField.right = new FormAttachment(100, -margin);
+    fdXMLField.right = new FormAttachment(100, 0);
     wYAMLLField.setLayoutData(fdXMLField);
     wYAMLLField.addFocusListener(
         new FocusListener() {
@@ -376,40 +369,40 @@ public class YamlInputDialog extends BaseTransformDialog {
     fdbShowFiles.bottom = new FormAttachment(100, 0);
     wbShowFiles.setLayoutData(fdbShowFiles);
 
-    ColumnInfo[] colinfo = new ColumnInfo[4];
-    colinfo[0] =
+    ColumnInfo[] colInfo = new ColumnInfo[4];
+    colInfo[0] =
         new ColumnInfo(
             BaseMessages.getString(PKG, 
"YamlInputDialog.Files.Filename.Column"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
-    colinfo[1] =
+    colInfo[1] =
         new ColumnInfo(
             BaseMessages.getString(PKG, 
"YamlInputDialog.Files.Wildcard.Column"),
             ColumnInfo.COLUMN_TYPE_TEXT,
             false);
 
-    colinfo[0].setUsingVariables(true);
-    colinfo[1].setUsingVariables(true);
-    colinfo[1].setToolTip(BaseMessages.getString(PKG, 
"YamlInputDialog.Files.Wildcard.Tooltip"));
-    colinfo[2] =
+    colInfo[0].setUsingVariables(true);
+    colInfo[1].setUsingVariables(true);
+    colInfo[1].setToolTip(BaseMessages.getString(PKG, 
"YamlInputDialog.Files.Wildcard.Tooltip"));
+    colInfo[2] =
         new ColumnInfo(
             BaseMessages.getString(PKG, "YamlInputDialog.Required.Column"),
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             NO_YES_DEC);
-    colinfo[2].setToolTip(BaseMessages.getString(PKG, 
"YamlInputDialog.Required.Tooltip"));
-    colinfo[3] =
+    colInfo[2].setToolTip(BaseMessages.getString(PKG, 
"YamlInputDialog.Required.Tooltip"));
+    colInfo[3] =
         new ColumnInfo(
             BaseMessages.getString(PKG, 
"YamlInputDialog.IncludeSubDirs.Column"),
             ColumnInfo.COLUMN_TYPE_CCOMBO,
             NO_YES_DEC);
-    colinfo[3].setToolTip(BaseMessages.getString(PKG, 
"YamlInputDialog.IncludeSubDirs.Tooltip"));
+    colInfo[3].setToolTip(BaseMessages.getString(PKG, 
"YamlInputDialog.IncludeSubDirs.Tooltip"));
 
     wFilenameList =
         new TableView(
             variables,
             wFileComp,
             SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER,
-            colinfo,
+            colInfo,
             2,
             lsMod,
             props);
@@ -458,10 +451,10 @@ public class YamlInputDialog extends BaseTransformDialog {
     PropsUi.setLook(wXmlConf);
     wXmlConf.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.wXmlConf.Label"));
 
-    FormLayout xmlConfgroupLayout = new FormLayout();
-    xmlConfgroupLayout.marginWidth = 10;
-    xmlConfgroupLayout.marginHeight = 10;
-    wXmlConf.setLayout(xmlConfgroupLayout);
+    FormLayout xmlConfGroupLayout = new FormLayout();
+    xmlConfGroupLayout.marginWidth = 10;
+    xmlConfGroupLayout.marginHeight = 10;
+    wXmlConf.setLayout(xmlConfGroupLayout);
 
     // Ignore Empty File
     wlIgnoreEmptyFile = new Label(wXmlConf, SWT.RIGHT);
@@ -469,7 +462,6 @@ public class YamlInputDialog extends BaseTransformDialog {
     PropsUi.setLook(wlIgnoreEmptyFile);
     FormData fdlIgnoreEmptyFile = new FormData();
     fdlIgnoreEmptyFile.left = new FormAttachment(0, 0);
-    fdlIgnoreEmptyFile.top = new FormAttachment(0, margin);
     fdlIgnoreEmptyFile.right = new FormAttachment(middle, -margin);
     wlIgnoreEmptyFile.setLayoutData(fdlIgnoreEmptyFile);
     wIgnoreEmptyFile = new Button(wXmlConf, SWT.CHECK);
@@ -478,7 +470,6 @@ public class YamlInputDialog extends BaseTransformDialog {
         BaseMessages.getString(PKG, 
"YamlInputDialog.IgnoreEmptyFile.Tooltip"));
     FormData fdIgnoreEmptyFile = new FormData();
     fdIgnoreEmptyFile.left = new FormAttachment(middle, 0);
-    fdIgnoreEmptyFile.top = new FormAttachment(wlIgnoreEmptyFile, 0, 
SWT.CENTER);
     wIgnoreEmptyFile.setLayoutData(fdIgnoreEmptyFile);
     wIgnoreEmptyFile.addSelectionListener(new 
ComponentSelectionListener(input));
 
@@ -538,17 +529,16 @@ public class YamlInputDialog extends BaseTransformDialog {
     wAdditionalFields.setText(
         BaseMessages.getString(PKG, 
"YamlInputDialog.wAdditionalFields.Label"));
 
-    FormLayout additionalFieldsgroupLayout = new FormLayout();
-    additionalFieldsgroupLayout.marginWidth = 10;
-    additionalFieldsgroupLayout.marginHeight = 10;
-    wAdditionalFields.setLayout(additionalFieldsgroupLayout);
+    FormLayout additionalFieldsGroupLayout = new FormLayout();
+    additionalFieldsGroupLayout.marginWidth = 10;
+    additionalFieldsGroupLayout.marginHeight = 10;
+    wAdditionalFields.setLayout(additionalFieldsGroupLayout);
 
     wlInclFilename = new Label(wAdditionalFields, SWT.RIGHT);
     wlInclFilename.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.InclFilename.Label"));
     PropsUi.setLook(wlInclFilename);
     FormData fdlInclFilename = new FormData();
     fdlInclFilename.left = new FormAttachment(0, 0);
-    fdlInclFilename.top = new FormAttachment(wXmlConf, 4 * margin);
     fdlInclFilename.right = new FormAttachment(middle, -margin);
     wlInclFilename.setLayoutData(fdlInclFilename);
     wInclFilename = new Button(wAdditionalFields, SWT.CHECK);
@@ -557,7 +547,6 @@ public class YamlInputDialog extends BaseTransformDialog {
         BaseMessages.getString(PKG, "YamlInputDialog.InclFilename.Tooltip"));
     FormData fdInclFilename = new FormData();
     fdInclFilename.left = new FormAttachment(middle, 0);
-    fdInclFilename.top = new FormAttachment(wlInclFilename, 0, SWT.CENTER);
     wInclFilename.setLayoutData(fdInclFilename);
     wInclFilename.addSelectionListener(new ComponentSelectionListener(input));
 
@@ -567,7 +556,6 @@ public class YamlInputDialog extends BaseTransformDialog {
     PropsUi.setLook(wlInclFilenameField);
     FormData fdlInclFilenameField = new FormData();
     fdlInclFilenameField.left = new FormAttachment(wInclFilename, margin);
-    fdlInclFilenameField.top = new FormAttachment(wLimit, 4 * margin);
     wlInclFilenameField.setLayoutData(fdlInclFilenameField);
     wInclFilenameField =
         new TextVar(variables, wAdditionalFields, SWT.SINGLE | SWT.LEFT | 
SWT.BORDER);
@@ -575,43 +563,42 @@ public class YamlInputDialog extends BaseTransformDialog {
     wInclFilenameField.addModifyListener(lsMod);
     FormData fdInclFilenameField = new FormData();
     fdInclFilenameField.left = new FormAttachment(wlInclFilenameField, margin);
-    fdInclFilenameField.top = new FormAttachment(wLimit, 4 * margin);
     fdInclFilenameField.right = new FormAttachment(100, 0);
     wInclFilenameField.setLayoutData(fdInclFilenameField);
 
-    Label wlInclRownum = new Label(wAdditionalFields, SWT.RIGHT);
-    wlInclRownum.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.InclRownum.Label"));
-    PropsUi.setLook(wlInclRownum);
-    FormData fdlInclRownum = new FormData();
-    fdlInclRownum.left = new FormAttachment(0, 0);
-    fdlInclRownum.top = new FormAttachment(wInclFilenameField, margin);
-    fdlInclRownum.right = new FormAttachment(middle, -margin);
-    wlInclRownum.setLayoutData(fdlInclRownum);
-    wInclRownum = new Button(wAdditionalFields, SWT.CHECK);
-    PropsUi.setLook(wInclRownum);
-    wInclRownum.setToolTipText(BaseMessages.getString(PKG, 
"YamlInputDialog.InclRownum.Tooltip"));
-    FormData fdRownum = new FormData();
-    fdRownum.left = new FormAttachment(middle, 0);
-    fdRownum.top = new FormAttachment(wlInclRownum, 0, SWT.CENTER);
-    wInclRownum.setLayoutData(fdRownum);
-    wInclRownum.addSelectionListener(new ComponentSelectionListener(input));
-
-    wlInclRownumField = new Label(wAdditionalFields, SWT.RIGHT);
-    wlInclRownumField.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.InclRownumField.Label"));
-    PropsUi.setLook(wlInclRownumField);
-    FormData fdlInclRownumField = new FormData();
-    fdlInclRownumField.left = new FormAttachment(wInclRownum, margin);
-    fdlInclRownumField.top = new FormAttachment(wInclFilenameField, margin);
-    wlInclRownumField.setLayoutData(fdlInclRownumField);
-    wInclRownumField =
+    Label wlInclRowNum = new Label(wAdditionalFields, SWT.RIGHT);
+    wlInclRowNum.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.InclRownum.Label"));
+    PropsUi.setLook(wlInclRowNum);
+    FormData fdlInclRowNum = new FormData();
+    fdlInclRowNum.left = new FormAttachment(0, 0);
+    fdlInclRowNum.top = new FormAttachment(wInclFilenameField, margin);
+    fdlInclRowNum.right = new FormAttachment(middle, -margin);
+    wlInclRowNum.setLayoutData(fdlInclRowNum);
+    wInclRowNum = new Button(wAdditionalFields, SWT.CHECK);
+    PropsUi.setLook(wInclRowNum);
+    wInclRowNum.setToolTipText(BaseMessages.getString(PKG, 
"YamlInputDialog.InclRownum.Tooltip"));
+    FormData fdRowNum = new FormData();
+    fdRowNum.left = new FormAttachment(middle, 0);
+    fdRowNum.top = new FormAttachment(wlInclRowNum, 0, SWT.CENTER);
+    wInclRowNum.setLayoutData(fdRowNum);
+    wInclRowNum.addSelectionListener(new ComponentSelectionListener(input));
+
+    wlInclRowNumField = new Label(wAdditionalFields, SWT.RIGHT);
+    wlInclRowNumField.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.InclRownumField.Label"));
+    PropsUi.setLook(wlInclRowNumField);
+    FormData fdlInclRowNumField = new FormData();
+    fdlInclRowNumField.left = new FormAttachment(wInclRowNum, margin);
+    fdlInclRowNumField.top = new FormAttachment(wInclFilenameField, margin);
+    wlInclRowNumField.setLayoutData(fdlInclRowNumField);
+    wInclRowNumField =
         new TextVar(variables, wAdditionalFields, SWT.SINGLE | SWT.LEFT | 
SWT.BORDER);
-    PropsUi.setLook(wInclRownumField);
-    wInclRownumField.addModifyListener(lsMod);
-    FormData fdInclRownumField = new FormData();
-    fdInclRownumField.left = new FormAttachment(wlInclRownumField, margin);
-    fdInclRownumField.top = new FormAttachment(wInclFilenameField, margin);
-    fdInclRownumField.right = new FormAttachment(100, 0);
-    wInclRownumField.setLayoutData(fdInclRownumField);
+    PropsUi.setLook(wInclRowNumField);
+    wInclRowNumField.addModifyListener(lsMod);
+    FormData fdInclRowNumField = new FormData();
+    fdInclRowNumField.left = new FormAttachment(wlInclRowNumField, margin);
+    fdInclRowNumField.top = new FormAttachment(wInclFilenameField, margin);
+    fdInclRowNumField.right = new FormAttachment(100, 0);
+    wInclRowNumField.setLayoutData(fdInclRowNumField);
 
     FormData fdAdditionalFields = new FormData();
     fdAdditionalFields.left = new FormAttachment(0, margin);
@@ -631,17 +618,16 @@ public class YamlInputDialog extends BaseTransformDialog {
     PropsUi.setLook(wAddFileResult);
     wAddFileResult.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.wAddFileResult.Label"));
 
-    FormLayout addFileResultgroupLayout = new FormLayout();
-    addFileResultgroupLayout.marginWidth = 10;
-    addFileResultgroupLayout.marginHeight = 10;
-    wAddFileResult.setLayout(addFileResultgroupLayout);
+    FormLayout addFileResultGroupLayout = new FormLayout();
+    addFileResultGroupLayout.marginWidth = 10;
+    addFileResultGroupLayout.marginHeight = 10;
+    wAddFileResult.setLayout(addFileResultGroupLayout);
 
     wlAddResult = new Label(wAddFileResult, SWT.RIGHT);
     wlAddResult.setText(BaseMessages.getString(PKG, 
"YamlInputDialog.AddResult.Label"));
     PropsUi.setLook(wlAddResult);
     FormData fdlAddResult = new FormData();
     fdlAddResult.left = new FormAttachment(0, 0);
-    fdlAddResult.top = new FormAttachment(wAdditionalFields, margin);
     fdlAddResult.right = new FormAttachment(middle, -margin);
     wlAddResult.setLayoutData(fdlAddResult);
     wAddResult = new Button(wAddFileResult, SWT.CHECK);
@@ -649,7 +635,6 @@ public class YamlInputDialog extends BaseTransformDialog {
     wAddResult.setToolTipText(BaseMessages.getString(PKG, 
"YamlInputDialog.AddResult.Tooltip"));
     FormData fdAddResult = new FormData();
     fdAddResult.left = new FormAttachment(middle, 0);
-    fdAddResult.top = new FormAttachment(wlAddResult, 0, SWT.CENTER);
     wAddResult.setLayoutData(fdAddResult);
     wAddResult.addSelectionListener(new ComponentSelectionListener(input));
 
@@ -700,7 +685,7 @@ public class YamlInputDialog extends BaseTransformDialog {
 
     final int FieldsRows = input.getInputFields().size();
 
-    ColumnInfo[] colinf =
+    ColumnInfo[] colInf =
         new ColumnInfo[] {
           new ColumnInfo(
               BaseMessages.getString(PKG, 
"YamlInputDialog.FieldsTable.Name.Column"),
@@ -742,15 +727,15 @@ public class YamlInputDialog extends BaseTransformDialog {
           new ColumnInfo(
               BaseMessages.getString(PKG, 
"YamlInputDialog.FieldsTable.TrimType.Column"),
               ColumnInfo.COLUMN_TYPE_CCOMBO,
-              YamlInputField.trimTypeDesc,
+              YamlInputField.TRIM_TYPE_DESC,
               true)
         };
 
-    colinf[0].setUsingVariables(true);
-    colinf[0].setToolTip(
+    colInf[0].setUsingVariables(true);
+    colInf[0].setToolTip(
         BaseMessages.getString(PKG, 
"YamlInputDialog.FieldsTable.Name.Column.Tooltip"));
-    colinf[1].setUsingVariables(true);
-    colinf[1].setToolTip(
+    colInf[1].setUsingVariables(true);
+    colInf[1].setToolTip(
         BaseMessages.getString(PKG, 
"YamlInputDialog.FieldsTable.XPath.Column.Tooltip"));
 
     wFields =
@@ -758,7 +743,7 @@ public class YamlInputDialog extends BaseTransformDialog {
             variables,
             wFieldsComp,
             SWT.FULL_SELECTION | SWT.MULTI,
-            colinf,
+            colInf,
             FieldsRows,
             lsMod,
             props);
@@ -795,7 +780,7 @@ public class YamlInputDialog extends BaseTransformDialog {
         new SelectionAdapter() {
           @Override
           public void widgetSelected(SelectionEvent arg0) {
-            wFilenameList.add(new String[] {wFilename.getText(), 
wFilemask.getText()});
+            wFilenameList.add(wFilename.getText(), wFilemask.getText());
             wFilename.setText("");
             wFilemask.setText("");
             wFilenameList.removeEmptyRows();
@@ -841,9 +826,9 @@ public class YamlInputDialog extends BaseTransformDialog {
           @Override
           public void widgetSelected(SelectionEvent e) {
             try {
-              YamlInputMeta tfii = new YamlInputMeta();
-              getInfo(tfii);
-              FileInputList fileInputList = tfii.getFiles(variables);
+              YamlInputMeta im = new YamlInputMeta();
+              getInfo(im);
+              FileInputList fileInputList = im.getFiles(variables);
               String[] files = fileInputList.getFileStrings();
               if (files != null && files.length > 0) {
                 EnterSelectionDialog esd =
@@ -884,11 +869,11 @@ public class YamlInputDialog extends BaseTransformDialog {
         });
 
     // Enable/disable the right fields to allow a row number to be added to 
each row...
-    wInclRownum.addSelectionListener(
+    wInclRowNum.addSelectionListener(
         new SelectionAdapter() {
           @Override
           public void widgetSelected(SelectionEvent e) {
-            setIncludeRownum();
+            setIncludeRowNum();
           }
         });
 
@@ -896,29 +881,24 @@ public class YamlInputDialog extends BaseTransformDialog {
     wFilename.addModifyListener(e -> 
wFilename.setToolTipText(wFilename.getText()));
 
     // Listen to the Browse... button
-    if (wbbFilename != null) {
-      // Listen to the browse button next to the file name
-      //
-      wbbFilename.addListener(
-          SWT.Selection,
-          e ->
-              BaseDialog.presentFileDialog(
-                  shell,
-                  wFilename,
-                  variables,
-                  new String[] {"*.yaml;*.YAML;*.yml;*.YML", "*"},
-                  new String[] {
-                    "Yaml files", BaseMessages.getString(PKG, 
"System.FileType.AllFiles")
-                  },
-                  true));
-    }
-
+    wbbFilename.addListener(
+        SWT.Selection,
+        e ->
+            BaseDialog.presentFileDialog(
+                shell,
+                wFilename,
+                variables,
+                new String[] {"*.yaml;*.YAML;*.yml;*.YML", "*"},
+                new String[] {
+                  "Yaml files", BaseMessages.getString(PKG, 
"System.FileType.AllFiles")
+                },
+                true));
     wTabFolder.setSelection(0);
 
     getData(input);
     activateStreamField();
     setIncludeFilename();
-    setIncludeRownum();
+    setIncludeRowNum();
     input.setChanged(changed);
     wFields.optWidth(true);
 
@@ -931,7 +911,6 @@ public class YamlInputDialog extends BaseTransformDialog {
 
   private void setXMLStreamField() {
     try {
-
       wYAMLLField.removeAll();
 
       IRowMeta r = pipelineMeta.getPrevTransformFields(variables, 
transformName);
@@ -1049,9 +1028,9 @@ public class YamlInputDialog extends BaseTransformDialog {
     wInclFilenameField.setEnabled(wInclFilename.getSelection());
   }
 
-  public void setIncludeRownum() {
-    wlInclRownumField.setEnabled(wInclRownum.getSelection());
-    wInclRownumField.setEnabled(wInclRownum.getSelection());
+  public void setIncludeRowNum() {
+    wlInclRowNumField.setEnabled(wInclRowNum.getSelection());
+    wInclRowNumField.setEnabled(wInclRowNum.getSelection());
   }
 
   /**
@@ -1071,7 +1050,7 @@ public class YamlInputDialog extends BaseTransformDialog {
     wFilenameList.optimizeTableView();
 
     wInclFilename.setSelection(in.isIncludeFilename());
-    wInclRownum.setSelection(in.isIncludeRowNumber());
+    wInclRowNum.setSelection(in.isIncludeRowNumber());
     wAddResult.setSelection(in.isAddingResultFile());
     wIgnoreEmptyFile.setSelection(in.isIgnoringEmptyFile());
     wDoNotFailIfNoFile.setSelection(in.isDoNotFailIfNoFile());
@@ -1079,7 +1058,7 @@ public class YamlInputDialog extends BaseTransformDialog {
     wYAMLIsAFile.setSelection(in.isSourceFile());
     wYAMLLField.setText(Const.NVL(in.getYamlField(), ""));
     wInclFilenameField.setText(Const.NVL(in.getFilenameField(), ""));
-    wInclRownumField.setText(Const.NVL(in.getRowNumberField(), ""));
+    wInclRowNumField.setText(Const.NVL(in.getRowNumberField(), ""));
     wLimit.setText("" + in.getRowLimit());
 
     if (isDebug()) {
@@ -1089,8 +1068,8 @@ public class YamlInputDialog extends BaseTransformDialog {
       YamlInputField field = in.getInputFields().get(i);
       TableItem item = wFields.table.getItem(i);
       String length = "" + field.getLength();
-      String prec = "" + field.getPrecision();
-      String decim = field.getDecimalSymbol();
+      String precision = "" + field.getPrecision();
+      String decimalSymbol = field.getDecimalSymbol();
 
       item.setText(1, Const.NVL(field.getName(), ""));
       item.setText(2, Const.NVL(field.getPath(), ""));
@@ -1099,12 +1078,12 @@ public class YamlInputDialog extends 
BaseTransformDialog {
       if (!"-1".equals(length)) {
         item.setText(5, length);
       }
-      if (!"-1".equals(prec)) {
-        item.setText(6, prec);
+      if (!"-1".equals(precision)) {
+        item.setText(6, precision);
       }
       item.setText(7, Const.NVL(field.getCurrencySymbol(), ""));
-      if (decim != null) {
-        item.setText(8, decim);
+      if (decimalSymbol != null) {
+        item.setText(8, decimalSymbol);
       }
       item.setText(9, Const.NVL(field.getGroupSymbol(), ""));
       item.setText(10, Const.NVL(field.getTrimTypeDesc(), ""));
@@ -1132,15 +1111,16 @@ public class YamlInputDialog extends 
BaseTransformDialog {
   }
 
   private void getInfo(YamlInputMeta in) {
-    transformName = wTransformName.getText(); // return value
+    // return value
+    transformName = wTransformName.getText();
 
     // copy info to TextFileInputMeta class (input)
     in.setRowLimit(Const.toLong(wLimit.getText(), 0L));
     in.setFilenameField(wInclFilenameField.getText());
-    in.setRowNumberField(wInclRownumField.getText());
+    in.setRowNumberField(wInclRowNumField.getText());
     in.setAddingResultFile(wAddResult.getSelection());
     in.setIncludeFilename(wInclFilename.getSelection());
-    in.setIncludeRowNumber(wInclRownum.getSelection());
+    in.setIncludeRowNumber(wInclRowNum.getSelection());
     in.setIgnoringEmptyFile(wIgnoreEmptyFile.getSelection());
     in.setDoNotFailIfNoFile(wDoNotFailIfNoFile.getSelection());
 
diff --git 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputField.java
 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputField.java
index c54827563b..0d694120cb 100644
--- 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputField.java
+++ 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputField.java
@@ -39,15 +39,12 @@ public class YamlInputField implements Cloneable {
   public static final int TYPE_TRIM_RIGHT = 2;
   public static final int TYPE_TRIM_BOTH = 3;
 
-  public static final String[] trimTypeCode = {"none", "left", "right", 
"both"};
-
-  public static final String[] trimTypeDesc = {
+  protected static final String[] TRIM_TYPE_DESC = {
     BaseMessages.getString(PKG, "YamlInputField.TrimType.None"),
     BaseMessages.getString(PKG, "YamlInputField.TrimType.Left"),
     BaseMessages.getString(PKG, "YamlInputField.TrimType.Right"),
     BaseMessages.getString(PKG, "YamlInputField.TrimType.Both")
   };
-  public static final String CONST_SPACES = "        ";
 
   @HopMetadataProperty(key = "name")
   private String name;
@@ -100,7 +97,7 @@ public class YamlInputField implements Cloneable {
 
   public YamlInputField(YamlInputField f) {
     this();
-    this.name = name;
+    this.name = f.name;
     this.path = f.path;
     this.type = f.type;
     this.length = f.length;
diff --git 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMeta.java
 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMeta.java
index 0c02b3923b..5ff1826815 100644
--- 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMeta.java
+++ 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMeta.java
@@ -245,7 +245,8 @@ public class YamlInputMeta extends 
BaseTransformMeta<YamlInput, YamlInputData> {
       inputFile.setFileMask(file.getFileMask());
       inputFile.setIncludeSubFolders(file.isIncludingSubFolders());
       inputFile.setFileRequired(file.isFileRequired());
-      inputFile.setExcludeFileMask(null); // Not provided in this transform
+      // Not provided in this transform
+      inputFile.setExcludeFileMask(null);
       inputFiles.add(inputFile);
     }
     return FileInputList.createFileList(variables, inputFiles, null);
diff --git 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlReader.java
 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlReader.java
index 310e4c9c3e..d0acefd6da 100644
--- 
a/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlReader.java
+++ 
b/plugins/transforms/yamlinput/src/main/java/org/apache/hop/pipeline/transforms/yamlinput/YamlReader.java
@@ -17,18 +17,18 @@
 
 package org.apache.hop.pipeline.transforms.yamlinput;
 
-import java.io.InputStream;
+import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.sql.Timestamp;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.vfs2.FileObject;
 import org.apache.hop.core.Const;
-import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.exception.HopPluginException;
 import org.apache.hop.core.io.CountingInputStream;
 import org.apache.hop.core.row.IRowMeta;
@@ -37,7 +37,6 @@ import org.apache.hop.core.row.RowMeta;
 import org.apache.hop.core.row.value.ValueMetaFactory;
 import org.apache.hop.core.row.value.ValueMetaNone;
 import org.apache.hop.core.util.Utils;
-import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.core.vfs.HopVfs;
 import org.yaml.snakeyaml.Yaml;
 
@@ -46,36 +45,31 @@ import org.yaml.snakeyaml.Yaml;
  * streams.
  */
 public class YamlReader {
-
   private static final String DEFAULT_LIST_VALUE_NAME = "Value";
 
-  private String filename;
   private String string;
-  private FileObject file;
+  @Getter private FileObject file;
 
   // document
   // Store all documents available
   private List<Object> documents;
   // Store current document
-  private Object document;
+  @Getter private Object document;
   // Store document iterator
-  private Iterator<Object> documenti;
+  private Iterator<Object> documentIt;
 
   // object current inside a document
   // In case we use a list
   private Object dataList;
   // Store object iterator
-  private Iterator<Object> dataListi;
-
+  private Iterator<Object> dataListIt;
   private boolean useMap;
-
-  private Yaml yaml;
+  @Getter private Yaml yaml;
 
   /** Bytes read from the last loaded file (for data volume tracking). */
-  private long bytesReadFromFile;
+  @Getter private long bytesReadFromFile;
 
   public YamlReader() {
-    this.filename = null;
     this.string = null;
     this.file = null;
     this.documents = new ArrayList<>();
@@ -86,44 +80,17 @@ public class YamlReader {
 
   public void loadFile(FileObject file) throws Exception {
     this.file = file;
-    this.filename = HopVfs.getFilename(file);
-
-    InputStream is = null;
-    try {
-      is = HopVfs.getInputStream(getFile());
-      CountingInputStream countingStream = new CountingInputStream(is);
-      is = countingStream;
 
+    try (CountingInputStream is = new 
CountingInputStream(HopVfs.getInputStream(getFile()))) {
       for (Object data : getYaml().loadAll(is)) {
         documents.add(data);
         this.useMap = (data instanceof Map);
       }
-      bytesReadFromFile = countingStream.getCount();
-      this.documenti = documents.iterator();
-
-    } finally {
-      if (is != null) {
-        is.close();
-      }
+      bytesReadFromFile = is.getCount();
+      this.documentIt = documents.iterator();
     }
   }
 
-  /** Returns bytes read from the last file loaded via {@link 
#loadFile(FileObject)}. */
-  public long getBytesReadFromFile() {
-    return bytesReadFromFile;
-  }
-
-  public void loadFile(String filename, IVariables variables) throws Exception 
{
-    this.filename = filename;
-    this.file = HopVfs.getFileObject(filename, variables);
-
-    loadFile(this.file);
-  }
-
-  private Yaml getYaml() {
-    return this.yaml;
-  }
-
   public void loadString(String string) {
     this.string = string;
     bytesReadFromFile = 0;
@@ -131,298 +98,152 @@ public class YamlReader {
       documents.add(data);
       this.useMap = (data instanceof Map);
     }
-    this.documenti = documents.iterator();
+    this.documentIt = documents.iterator();
   }
 
   public boolean isMapUsed() {
     return this.useMap;
   }
 
-  public Object[] getRow(IRowMeta rowMeta) throws HopException {
-
-    Object[] retval = null;
-
-    if (getDocument() != null) {
-      if (isMapUsed()) {
-        Map<Object, Object> map = (Map<Object, Object>) getDocument();
-        retval = new Object[rowMeta.size()];
-        for (int i = 0; i < rowMeta.size(); i++) {
-          IValueMeta valueMeta = rowMeta.getValueMeta(i);
-          Object o = null;
-          if (Utils.isEmpty(valueMeta.getName())) {
-            o = getDocument().toString();
-          } else {
-            o = map.get(valueMeta.getName());
-          }
-          retval[i] = getValue(o, valueMeta);
-        }
-
-        // We have done with this document
-        finishDocument();
-      } else {
-        if (dataList != null) {
-
-          List<Object> list = (List<Object>) getDocument();
-          if (list.size() == 1) {
-            Iterator<Object> it = list.iterator();
-            Object value = it.next();
-            Map<Object, Object> map = (Map<Object, Object>) value;
-            retval = new Object[rowMeta.size()];
-            for (int i = 0; i < rowMeta.size(); i++) {
-              IValueMeta valueMeta = rowMeta.getValueMeta(i);
-              Object o = null;
-              if (Utils.isEmpty(valueMeta.getName())) {
-                o = getDocument().toString();
-              } else {
-                o = map.get(valueMeta.getName());
-              }
-              retval[i] = getValue(o, valueMeta);
-            }
-          } else {
-
-            IValueMeta valueMeta = rowMeta.getValueMeta(0);
-            retval = new Object[1];
-
-            retval[0] = getValue(dataList, valueMeta);
-          }
-          dataList = null;
-        } else {
-          // We are using List
-          if (dataListi.hasNext()) {
-            dataList = dataListi.next();
-          } else {
-            // We have done with this document
-            finishDocument();
-          }
-        }
-      }
-    } else {
-      // See if we have another document
+  /** get row */
+  public Object[] getRow(IRowMeta rowMeta) {
+    if (document == null) {
       getNextDocument();
     }
 
-    if (retval == null && !isfinishedDocument()) {
+    if (document == null) {
+      return new Object[0];
+    }
+
+    Object[] row = fetchRow(rowMeta);
+    if (row.length == 0 && !isFinishedDocument()) {
       return getRow(rowMeta);
     }
-    return retval;
+    return row;
   }
 
-  private Object getValue(Object value, IValueMeta valueMeta) {
+  private Object[] fetchRow(IRowMeta rowMeta) {
+    if (isMapUsed()) {
+      return processMapRow(rowMeta, (Map<?, ?>) document);
+    }
 
-    if (value == null) {
-      return null;
+    return processListRow(rowMeta);
+  }
+
+  private Object[] handleCurrentListValue(IRowMeta rowMeta) {
+    List<?> list = (List<?>) document;
+
+    if (list.size() == 1 && list.getFirst() instanceof Map<?, ?> map) {
+      return processMapRow(rowMeta, map);
     }
-    Object o = null;
 
-    if (value instanceof List) {
-      value = getYaml().dump(value);
+    IValueMeta valueMeta = rowMeta.getValueMeta(0);
+    return new Object[] {getValue(dataList, valueMeta)};
+  }
+
+  private Object[] processListRow(IRowMeta rowMeta) {
+    if (dataList == null) {
+      return advanceListIterator();
     }
 
-    switch (valueMeta.getType()) {
-      case IValueMeta.TYPE_INTEGER:
-        if (value instanceof Integer integerValue) {
-          o = Long.valueOf(integerValue);
-        } else if (value instanceof BigInteger bigIntegerValue) {
-          o = bigIntegerValue.longValue();
-        } else if (value instanceof Long longValue) {
-          o = Long.valueOf(longValue);
-        } else {
-          o = Long.valueOf(value.toString());
-        }
-        break;
-      case IValueMeta.TYPE_NUMBER:
-        if (value instanceof Integer integerValue) {
-          o = Double.valueOf(integerValue);
-        } else if (value instanceof BigInteger bigIntegerValue) {
-          o = bigIntegerValue.doubleValue();
-        } else if (value instanceof Long longValue) {
-          o = Double.valueOf(longValue);
-        } else if (value instanceof Double) {
-          o = value;
-        } else {
-          o = Double.valueOf((String) value);
-        }
-        break;
-      case IValueMeta.TYPE_BIGNUMBER:
-        if (value instanceof Integer integerValue) {
-          o = new BigDecimal(integerValue);
-        } else if (value instanceof BigInteger bigIntegerValue) {
-          o = new BigDecimal(bigIntegerValue);
-        } else if (value instanceof Long longValue) {
-          o = new BigDecimal(longValue);
-        } else if (value instanceof Double doubleValue) {
-          o = BigDecimal.valueOf(doubleValue);
-        }
-        break;
-      case IValueMeta.TYPE_BOOLEAN:
-        o = value;
-        break;
-      case IValueMeta.TYPE_DATE:
-        o = value;
-        break;
-      case IValueMeta.TYPE_BINARY:
-        o = value;
-        break;
-      default:
-        String s = setMap(value);
-
-        // Do trimming
-        switch (valueMeta.getTrimType()) {
-          case YamlInputField.TYPE_TRIM_LEFT:
-            s = Const.ltrim(s);
-            break;
-          case YamlInputField.TYPE_TRIM_RIGHT:
-            s = Const.rtrim(s);
-            break;
-          case YamlInputField.TYPE_TRIM_BOTH:
-            s = Const.trim(s);
-            break;
-          default:
-            break;
-        }
-        o = s;
+    Object[] row = handleCurrentListValue(rowMeta);
+    dataList = null;
+    return row;
+  }
 
-        break;
+  private Object[] processMapRow(IRowMeta rowMeta, Map<?, ?> map) {
+    Object[] row = new Object[rowMeta.size()];
+
+    for (int i = 0; i < rowMeta.size(); i++) {
+      IValueMeta valueMeta = rowMeta.getValueMeta(i);
+
+      Object value =
+          Utils.isEmpty(valueMeta.getName()) ? document.toString() : 
map.get(valueMeta.getName());
+
+      row[i] = getValue(value, valueMeta);
+    }
+
+    finishDocument();
+    return row;
+  }
+
+  private Object[] advanceListIterator() {
+    if (!dataListIt.hasNext()) {
+      finishDocument();
+      return new Object[0];
     }
-    return o;
+
+    dataList = dataListIt.next();
+    return new Object[0];
   }
 
   private void getNextDocument() {
     // See if we have another document
-    if (this.documenti.hasNext()) {
+    if (this.documentIt.hasNext()) {
       // We have another document
-      this.document = this.documenti.next();
+      this.document = this.documentIt.next();
       if (!isMapUsed()) {
+        @SuppressWarnings("unchecked")
         List<Object> list = (List<Object>) getDocument();
-        dataListi = list.iterator();
+        dataListIt = list.iterator();
       }
     }
   }
 
   private String setMap(Object value) {
-    String result = value.toString();
+    StringBuilder result = new StringBuilder(value.toString());
     if (value instanceof Map) {
-
+      @SuppressWarnings("unchecked")
       Map<Object, Object> map = (Map<Object, Object>) value;
-      Iterator it = map.entrySet().iterator();
+      Iterator<Map.Entry<Object, Object>> it = map.entrySet().iterator();
 
       int nr = 0;
       while (it.hasNext()) {
-        Map.Entry pairs = (Map.Entry) it.next();
+        Map.Entry<Object, Object> pairs = it.next();
         String res = pairs.getKey().toString() + ":  " + 
setMap(pairs.getValue());
         if (nr == 0) {
-          result = "{" + res;
+          result = new StringBuilder("{" + res);
         } else {
-          result += "," + res;
+          result.append(",").append(res);
         }
         nr++;
       }
       if (nr > 0) {
-        result += "}";
-      }
-    }
-    return result;
-  }
-
-  public RowMeta getFields() {
-    RowMeta rowMeta = new RowMeta();
-
-    Iterator<Object> ito = documents.iterator();
-    while (ito.hasNext()) {
-      Object data = ito.next();
-      if (data instanceof Map) {
-        // First check if we deals with a map
-
-        Map<Object, Object> map = (Map<Object, Object>) data;
-        Iterator it = map.entrySet().iterator();
-        while (it.hasNext()) {
-          Map.Entry pairs = (Map.Entry) it.next();
-          String valueName = pairs.getKey().toString();
-          IValueMeta valueMeta;
-          try {
-            valueMeta = ValueMetaFactory.createValueMeta(valueName, 
getType(pairs.getValue()));
-          } catch (HopPluginException e) {
-            valueMeta = new ValueMetaNone(valueName);
-          }
-          rowMeta.addValueMeta(valueMeta);
-        }
-      } else if (data instanceof List) {
-
-        rowMeta = new RowMeta();
-        // Maybe we deals with List
-        List<Object> list = (List<Object>) data;
-        Iterator<Object> it = list.iterator();
-        Object value = it.next();
-
-        if (list.size() == 1) {
-          Map<Object, Object> map = (Map<Object, Object>) value;
-          Iterator its = map.entrySet().iterator();
-          while (its.hasNext()) {
-            Map.Entry pairs = (Map.Entry) its.next();
-            String valueName = pairs.getKey().toString();
-            IValueMeta valueMeta;
-            try {
-              valueMeta = ValueMetaFactory.createValueMeta(valueName, 
getType(pairs.getValue()));
-            } catch (HopPluginException e) {
-              valueMeta = new ValueMetaNone(valueName);
-            }
-            rowMeta.addValueMeta(valueMeta);
-          }
-        } else {
-          IValueMeta valueMeta;
-          try {
-            valueMeta = 
ValueMetaFactory.createValueMeta(DEFAULT_LIST_VALUE_NAME, getType(value));
-          } catch (HopPluginException e) {
-            valueMeta = new ValueMetaNone(DEFAULT_LIST_VALUE_NAME);
-          }
-          rowMeta.addValueMeta(valueMeta);
-        }
+        result.append("}");
       }
     }
-
-    return rowMeta;
+    return result.toString();
   }
 
   private int getType(Object value) {
-
-    if (value instanceof Integer) {
-      return IValueMeta.TYPE_INTEGER;
-    }
-    if (value instanceof Double) {
-      return IValueMeta.TYPE_NUMBER;
-    } else if (value instanceof Long) {
-      return IValueMeta.TYPE_INTEGER;
-    } else if (value instanceof Date) {
-      return IValueMeta.TYPE_DATE;
-    } else if (value instanceof java.sql.Date) {
-      return IValueMeta.TYPE_DATE;
-    } else if (value instanceof Timestamp) {
-      return IValueMeta.TYPE_DATE;
-    } else if (value instanceof Boolean) {
-      return IValueMeta.TYPE_BOOLEAN;
-    } else if (value instanceof BigInteger) {
-      return IValueMeta.TYPE_BIGNUMBER;
-    } else if (value instanceof BigDecimal) {
-      return IValueMeta.TYPE_BIGNUMBER;
-    } else if (value instanceof Byte) {
-      return IValueMeta.TYPE_BINARY;
+    if (value == null) {
+      return IValueMeta.TYPE_STRING;
     }
-    return IValueMeta.TYPE_STRING;
-  }
 
-  private Object getDocument() {
-    return this.document;
+    return switch (value) {
+      case Integer ignored -> IValueMeta.TYPE_INTEGER;
+      case Long ignored -> IValueMeta.TYPE_INTEGER;
+      case Double ignored -> IValueMeta.TYPE_NUMBER;
+      case Boolean ignored -> IValueMeta.TYPE_BOOLEAN;
+      case BigInteger ignored -> IValueMeta.TYPE_BIGNUMBER;
+      case BigDecimal ignored -> IValueMeta.TYPE_BIGNUMBER;
+      case Byte ignored -> IValueMeta.TYPE_BINARY;
+      case Timestamp ignored -> IValueMeta.TYPE_DATE;
+      case java.sql.Date ignored -> IValueMeta.TYPE_DATE;
+      case java.util.Date ignored -> IValueMeta.TYPE_DATE;
+      default -> IValueMeta.TYPE_STRING;
+    };
   }
 
   private void finishDocument() {
     this.document = null;
   }
 
-  private boolean isfinishedDocument() {
+  private boolean isFinishedDocument() {
     return (this.document == null);
   }
 
-  public void close() throws Exception {
+  public void close() throws IOException {
     if (file != null) {
       file.close();
     }
@@ -430,11 +251,141 @@ public class YamlReader {
     this.yaml = null;
   }
 
-  public FileObject getFile() {
-    return this.file;
-  }
-
   public String getStringValue() {
     return this.string;
   }
+
+  /** get value */
+  private Object getValue(Object value, IValueMeta valueMeta) {
+    if (value == null) {
+      return null;
+    }
+
+    Object normalizedValue = normalizeList(value);
+
+    return switch (valueMeta.getType()) {
+      case IValueMeta.TYPE_INTEGER -> convertToInteger(normalizedValue);
+      case IValueMeta.TYPE_NUMBER -> convertToDouble(normalizedValue);
+      case IValueMeta.TYPE_BIGNUMBER -> convertToBigDecimal(normalizedValue);
+      case IValueMeta.TYPE_BOOLEAN, IValueMeta.TYPE_DATE, 
IValueMeta.TYPE_BINARY -> normalizedValue;
+      default -> convertToString(normalizedValue, valueMeta);
+    };
+  }
+
+  private Object normalizeList(Object value) {
+    if (value instanceof List) {
+      String dumped = getYaml().dump(value);
+      if (StringUtils.isEmpty(dumped)) {
+        return dumped;
+      }
+
+      return stripTrailingLineBreaks(dumped);
+    }
+    return value;
+  }
+
+  /** SnakeYAML {@code dump} ends the stream with a line break; strip it for 
cell values. */
+  private static String stripTrailingLineBreaks(String s) {
+    int end = s.length();
+    while (end > 0) {
+      char c = s.charAt(end - 1);
+      if (c != '\n' && c != '\r') {
+        break;
+      }
+      end--;
+    }
+    return s.substring(0, end);
+  }
+
+  /** object -> long */
+  private Long convertToInteger(Object value) {
+    return switch (value) {
+      case Integer i -> i.longValue();
+      case BigInteger bi -> bi.longValue();
+      case Long l -> l;
+      default -> Long.valueOf(value.toString());
+    };
+  }
+
+  /** object -> double */
+  private Double convertToDouble(Object value) {
+    return switch (value) {
+      case Integer i -> i.doubleValue();
+      case BigInteger bi -> bi.doubleValue();
+      case Long l -> l.doubleValue();
+      case Double d -> d;
+      default -> Double.valueOf(value.toString());
+    };
+  }
+
+  private BigDecimal convertToBigDecimal(Object value) {
+    return switch (value) {
+      case Integer i -> new BigDecimal(i);
+      case BigInteger bi -> new BigDecimal(bi);
+      case Long l -> BigDecimal.valueOf(l);
+      case Double d -> BigDecimal.valueOf(d);
+      default -> null;
+    };
+  }
+
+  private String convertToString(Object value, IValueMeta valueMeta) {
+    String s = setMap(value);
+    return applyTrim(s, valueMeta);
+  }
+
+  private String applyTrim(String s, IValueMeta valueMeta) {
+    return switch (valueMeta.getTrimType()) {
+      case YamlInputField.TYPE_TRIM_LEFT -> Const.ltrim(s);
+      case YamlInputField.TYPE_TRIM_RIGHT -> Const.rtrim(s);
+      case YamlInputField.TYPE_TRIM_BOTH -> Const.trim(s);
+      default -> s;
+    };
+  }
+
+  /** get fields. */
+  public RowMeta getFields() {
+    RowMeta rowMeta = new RowMeta();
+
+    for (Object data : documents) {
+      if (data instanceof Map<?, ?> map) {
+        appendFromMap(rowMeta, map);
+      } else if (data instanceof List<?> list) {
+        appendFromList(rowMeta, list);
+      }
+    }
+
+    return rowMeta;
+  }
+
+  private void appendFromList(RowMeta rowMeta, List<?> list) {
+    if (list.isEmpty()) {
+      return;
+    }
+
+    Object first = list.getFirst();
+    if (list.size() == 1 && first instanceof Map<?, ?> map) {
+      appendFromMap(rowMeta, map);
+    } else {
+      addField(rowMeta, DEFAULT_LIST_VALUE_NAME, first);
+    }
+  }
+
+  private void appendFromMap(RowMeta rowMeta, Map<?, ?> map) {
+    for (Map.Entry<?, ?> entry : map.entrySet()) {
+      addField(rowMeta, entry.getKey(), entry.getValue());
+    }
+  }
+
+  private void addField(RowMeta rowMeta, Object key, Object value) {
+    String fieldName = String.valueOf(key);
+
+    IValueMeta valueMeta;
+    try {
+      valueMeta = ValueMetaFactory.createValueMeta(fieldName, getType(value));
+    } catch (HopPluginException e) {
+      valueMeta = new ValueMetaNone(fieldName);
+    }
+
+    rowMeta.addValueMeta(valueMeta);
+  }
 }
diff --git 
a/plugins/transforms/yamlinput/src/main/resources/org/apache/hop/pipeline/transforms/yamlinput/messages/messages_en_US.properties
 
b/plugins/transforms/yamlinput/src/main/resources/org/apache/hop/pipeline/transforms/yamlinput/messages/messages_en_US.properties
index 7f90292da5..94f75a3266 100644
--- 
a/plugins/transforms/yamlinput/src/main/resources/org/apache/hop/pipeline/transforms/yamlinput/messages/messages_en_US.properties
+++ 
b/plugins/transforms/yamlinput/src/main/resources/org/apache/hop/pipeline/transforms/yamlinput/messages/messages_en_US.properties
@@ -70,7 +70,7 @@ YamlInputDialog.FilenameAdd.Tooltip=Add this entry to the 
list of files & direct
 YamlInputDialog.FilenameBrowse.Button=&Browse
 YamlInputDialog.FilenameEdit.Button=&Edit
 YamlInputDialog.FilenameEdit.Tooltip=Edit the selected file and remove from 
the list.
-YamlInputDialog.FilenameList.Label=Selected files\: 
+YamlInputDialog.FilenameList.Label=Selected files
 YamlInputDialog.FilenameRemove.Button=&Delete
 YamlInputDialog.FilenameRemove.Tooltip=Delete the selected entries from the 
list of files.
 YamlInputDialog.Files.Filename.Column=File/Directory
diff --git 
a/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDataTests.java
 
b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDataTests.java
new file mode 100644
index 0000000000..35a407e2ac
--- /dev/null
+++ 
b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputDataTests.java
@@ -0,0 +1,51 @@
+/*
+ * 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.pipeline.transforms.yamlinput;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import org.junit.jupiter.api.Test;
+
+/** Unit test for {@link YamlInputData} */
+class YamlInputDataTests {
+
+  @Test
+  void testDefaultConstructor() {
+    YamlInputData data = new YamlInputData();
+    assertNotNull(data);
+
+    assertEquals(0, data.fileIndex);
+    assertEquals(-1, data.indexOfYamlField);
+    assertEquals(-1, data.nrInputFields);
+    assertEquals(0, data.totalPreviousFields);
+    assertEquals(0, data.totalOutFields);
+    assertEquals(0, data.totalOutStreamFields);
+
+    assertEquals(0L, data.rowIndex);
+
+    assertNull(data.file);
+    assertNull(data.readRow);
+    assertNull(data.yaml);
+
+    assertNull(data.files);
+    assertNull(data.outputRowMeta);
+    assertNull(data.rowMeta);
+  }
+}
diff --git 
a/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputFieldTests.java
 
b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputFieldTests.java
new file mode 100644
index 0000000000..9e96de5fab
--- /dev/null
+++ 
b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputFieldTests.java
@@ -0,0 +1,119 @@
+/*
+ * 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.pipeline.transforms.yamlinput;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+
+import org.apache.hop.core.row.IValueMeta;
+import org.junit.jupiter.api.Test;
+
+/** Unit test for {@link YamlInputField} */
+class YamlInputFieldTests {
+
+  @Test
+  void testDefaultConstructor() {
+    YamlInputField field = new YamlInputField();
+
+    assertEquals("", field.getName());
+    assertEquals("", field.getPath());
+    assertEquals(-1, field.getLength());
+    assertEquals(-1, field.getPrecision());
+    assertEquals("", field.getFormat());
+    assertEquals("", field.getGroupSymbol());
+    assertEquals("", field.getDecimalSymbol());
+    assertEquals("", field.getCurrencySymbol());
+
+    assertEquals(IValueMeta.TYPE_STRING, field.getType());
+    assertEquals(YamlInputField.TYPE_TRIM_NONE, field.getTrimType());
+  }
+
+  @Test
+  void testConstructorWithName() {
+    YamlInputField field = new YamlInputField("testField");
+
+    assertEquals("testField", field.getName());
+  }
+
+  @Test
+  void testCopyConstructor() {
+    YamlInputField original = new YamlInputField("name");
+    original.setPath("$.data.name");
+    original.setType(IValueMeta.TYPE_INTEGER);
+    original.setLength(10);
+    original.setFormat("###");
+    original.setTrimType(YamlInputField.TYPE_TRIM_BOTH);
+    original.setPrecision(2);
+    original.setCurrencySymbol("$");
+    original.setDecimalSymbol(".");
+    original.setGroupSymbol(",");
+
+    YamlInputField copy = new YamlInputField(original);
+
+    assertEquals(original.getName(), copy.getName());
+    assertEquals(original.getPath(), copy.getPath());
+    assertEquals(original.getType(), copy.getType());
+    assertEquals(original.getLength(), copy.getLength());
+    assertEquals(original.getFormat(), copy.getFormat());
+    assertEquals(original.getTrimType(), copy.getTrimType());
+    assertEquals(original.getPrecision(), copy.getPrecision());
+    assertEquals(original.getCurrencySymbol(), copy.getCurrencySymbol());
+    assertEquals(original.getDecimalSymbol(), copy.getDecimalSymbol());
+    assertEquals(original.getGroupSymbol(), copy.getGroupSymbol());
+  }
+
+  @Test
+  void testClone() {
+    YamlInputField original = new YamlInputField("cloneField");
+    original.setPath("$.path");
+
+    YamlInputField cloned = (YamlInputField) original.clone();
+
+    assertNotSame(original, cloned);
+    assertEquals(original.getName(), cloned.getName());
+    assertEquals(original.getPath(), cloned.getPath());
+  }
+
+  @Test
+  void testTrimTypeDesc() {
+    YamlInputField field = new YamlInputField();
+    field.setTrimType(YamlInputField.TYPE_TRIM_BOTH);
+
+    String desc = field.getTrimTypeDesc();
+    assertNotNull(desc);
+  }
+
+  @Test
+  void testStaticTrimTypeMethods() {
+    String desc = 
YamlInputField.getTrimTypeDesc(YamlInputField.TYPE_TRIM_LEFT);
+    assertNotNull(desc);
+
+    int type = YamlInputField.getTrimTypeByDesc(desc);
+    assertEquals(YamlInputField.TYPE_TRIM_LEFT, type);
+  }
+
+  @Test
+  void testGetTypeDesc() {
+    YamlInputField field = new YamlInputField();
+    field.setType(IValueMeta.TYPE_INTEGER);
+
+    String desc = field.getTypeDesc();
+    assertNotNull(desc);
+  }
+}
diff --git 
a/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMetaTest.java
 
b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMetaTest.java
index 42360c4236..d71a68e1fd 100644
--- 
a/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMetaTest.java
+++ 
b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputMetaTest.java
@@ -17,10 +17,22 @@
 package org.apache.hop.pipeline.transforms.yamlinput;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.hop.core.ICheckResult;
+import org.apache.hop.core.fileinput.FileInputList;
 import org.apache.hop.core.plugins.PluginRegistry;
+import org.apache.hop.core.row.IRowMeta;
 import org.apache.hop.core.row.IValueMeta;
+import org.apache.hop.core.row.RowMeta;
 import org.apache.hop.core.row.value.ValueMetaDate;
 import org.apache.hop.core.row.value.ValueMetaInteger;
 import org.apache.hop.core.row.value.ValueMetaJson;
@@ -28,11 +40,18 @@ import org.apache.hop.core.row.value.ValueMetaNumber;
 import org.apache.hop.core.row.value.ValueMetaPlugin;
 import org.apache.hop.core.row.value.ValueMetaPluginType;
 import org.apache.hop.core.row.value.ValueMetaString;
+import org.apache.hop.core.variables.Variables;
+import org.apache.hop.core.xml.XmlHandler;
+import org.apache.hop.pipeline.transform.TransformMeta;
 import org.apache.hop.pipeline.transform.TransformSerializationTestUtil;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.w3c.dom.Node;
 
+/** Unit test for {@link YamlInputMeta} */
 class YamlInputMetaTest {
+
   @BeforeEach
   void beforeEach() throws Exception {
     PluginRegistry registry = PluginRegistry.getInstance();
@@ -80,6 +99,10 @@ class YamlInputMetaTest {
     assertTrue(file.isFileRequired());
     assertTrue(file.isIncludingSubFolders());
 
+    testSerializationRoundTrip_1(meta);
+  }
+
+  private void testSerializationRoundTrip_1(YamlInputMeta meta) {
     assertEquals(3, meta.getInputFields().size());
     YamlInputField field = meta.getInputFields().getFirst();
     assertEquals("field1", field.getName());
@@ -103,4 +126,199 @@ class YamlInputMetaTest {
     assertEquals(2, field.getPrecision());
     assertEquals(IValueMeta.TRIM_TYPE_BOTH, field.getTrimType());
   }
+
+  @Test
+  void testDefaultConstructor() {
+    YamlInputMeta meta = new YamlInputMeta();
+
+    assertNotNull(meta.getYamlFiles());
+    assertNotNull(meta.getInputFields());
+
+    assertTrue(meta.getYamlFiles().isEmpty());
+    assertTrue(meta.getInputFields().isEmpty());
+
+    assertEquals("", meta.getFilenameField());
+    assertEquals("", meta.getRowNumberField());
+    assertEquals("", meta.getYamlField());
+    assertEquals(0, meta.getRowLimit());
+
+    assertTrue(meta.isDoNotFailIfNoFile());
+  }
+
+  @Test
+  void testCloneDeepCopy() {
+    YamlInputMeta meta = new YamlInputMeta();
+
+    YamlInputMeta.YamlFile file = new YamlInputMeta.YamlFile();
+    file.setFilename("test.yaml");
+    meta.getYamlFiles().add(file);
+
+    YamlInputField field = new YamlInputField("name");
+    meta.getInputFields().add(field);
+
+    YamlInputMeta clone = meta.clone();
+
+    assertNotSame(meta, clone);
+
+    assertNotSame(meta.getYamlFiles(), clone.getYamlFiles());
+    assertNotSame(meta.getInputFields(), clone.getInputFields());
+
+    assertNotSame(meta.getYamlFiles().getFirst(), 
clone.getYamlFiles().getFirst());
+    assertNotSame(meta.getInputFields().getFirst(), 
clone.getInputFields().getFirst());
+  }
+
+  @Test
+  void testGetFields_basic() throws Exception {
+    YamlInputMeta meta = new YamlInputMeta();
+
+    YamlInputField field = new YamlInputField("id");
+    field.setType(IValueMeta.TYPE_INTEGER);
+    field.setLength(10);
+    field.setPrecision(0);
+
+    meta.getInputFields().add(field);
+
+    IRowMeta rowMeta = new RowMeta();
+    Variables vars = new Variables();
+
+    meta.getFields(rowMeta, "testTransform", null, null, vars, null);
+
+    assertEquals(1, rowMeta.size());
+
+    IValueMeta v = rowMeta.getValueMeta(0);
+    assertEquals("id", v.getName());
+    assertEquals(IValueMeta.TYPE_INTEGER, v.getType());
+    assertEquals(10, v.getLength());
+  }
+
+  @Test
+  void testGetFields_withExtraFields() throws Exception {
+    YamlInputMeta meta = new YamlInputMeta();
+
+    meta.setIncludeFilename(true);
+    meta.setFilenameField("filename");
+
+    meta.setIncludeRowNumber(true);
+    meta.setRowNumberField("rowNum");
+
+    IRowMeta rowMeta = new RowMeta();
+    Variables vars = new Variables();
+
+    meta.getFields(rowMeta, "t", null, null, vars, null);
+
+    assertEquals(2, rowMeta.size());
+    assertEquals("filename", rowMeta.getValueMeta(0).getName());
+    assertEquals("rowNum", rowMeta.getValueMeta(1).getName());
+  }
+
+  @Test
+  void testGetFiles(@TempDir Path tempDir) throws IOException {
+    YamlInputMeta meta = new YamlInputMeta();
+
+    Path tempFile = tempDir.resolve("test.yaml");
+    Files.createFile(tempFile);
+
+    YamlInputMeta.YamlFile file = new YamlInputMeta.YamlFile();
+    file.setFilename(tempFile.toString());
+    file.setFileMask(".*yaml");
+
+    meta.getYamlFiles().add(file);
+
+    Variables vars = new Variables();
+    FileInputList list = meta.getFiles(vars);
+
+    assertNotNull(list);
+    assertFalse(list.getFiles().isEmpty());
+  }
+
+  @Test
+  void testCheck_noInput() {
+    YamlInputMeta meta = new YamlInputMeta();
+    List<ICheckResult> remarks = new ArrayList<>();
+
+    meta.check(
+        remarks,
+        null,
+        new TransformMeta(),
+        null,
+        new String[] {},
+        null,
+        null,
+        new Variables(),
+        null);
+
+    assertFalse(remarks.isEmpty());
+  }
+
+  @Test
+  void testCheck_noFields() {
+    YamlInputMeta meta = new YamlInputMeta();
+    List<ICheckResult> remarks = new ArrayList<>();
+
+    meta.check(
+        remarks,
+        null,
+        new TransformMeta(),
+        null,
+        new String[] {"input"},
+        null,
+        null,
+        new Variables(),
+        null);
+
+    assertTrue(remarks.stream().anyMatch(r -> r.getType() == 
ICheckResult.TYPE_RESULT_ERROR));
+  }
+
+  @Test
+  void testCheck_inFieldsMode_ok() {
+    YamlInputMeta meta = new YamlInputMeta();
+    meta.setInFields(true);
+    meta.setYamlField("yaml");
+
+    meta.getInputFields().add(new YamlInputField("name"));
+
+    List<ICheckResult> remarks = new ArrayList<>();
+
+    meta.check(
+        remarks,
+        null,
+        new TransformMeta(),
+        null,
+        new String[] {"input"},
+        null,
+        null,
+        new Variables(),
+        null);
+
+    assertTrue(remarks.stream().anyMatch(r -> r.getType() == 
ICheckResult.TYPE_RESULT_OK));
+  }
+
+  @Test
+  void testConvertLegacyXml(@TempDir Path tempDir) throws Exception {
+    Path tempFile = tempDir.resolve("test.yaml");
+    Files.createFile(tempFile);
+
+    String xml =
+        String.format(
+            """
+                               <file>
+                                     <name>%s</name>
+                                     <filemask>.*\\.yaml</filemask>
+                                     <file_required>Y</file_required>
+                                     <include_subfolders>Y</include_subfolders>
+                                 </file>
+                               """,
+            tempFile);
+    Node node = XmlHandler.loadXmlString(xml);
+
+    YamlInputMeta meta = new YamlInputMeta();
+    meta.convertLegacyXml(node);
+
+    assertEquals(1, meta.getYamlFiles().size());
+
+    YamlInputMeta.YamlFile file = meta.getYamlFiles().getFirst();
+    assertEquals(tempFile.toString(), file.getFilename());
+    assertTrue(file.isFileRequired());
+    assertTrue(file.isIncludingSubFolders());
+  }
 }
diff --git 
a/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputTests.java
 
b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputTests.java
new file mode 100644
index 0000000000..21877c167c
--- /dev/null
+++ 
b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlInputTests.java
@@ -0,0 +1,296 @@
+/*
+ * 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.pipeline.transforms.yamlinput;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import java.io.FileWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.commons.lang3.reflect.MethodUtils;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.fileinput.FileInputList;
+import org.apache.hop.core.logging.ILoggingObject;
+import org.apache.hop.core.row.IRowMeta;
+import org.apache.hop.core.row.IValueMeta;
+import org.apache.hop.core.row.RowMeta;
+import org.apache.hop.core.variables.IVariables;
+import org.apache.hop.core.vfs.HopVfs;
+import org.apache.hop.pipeline.Pipeline;
+import org.apache.hop.pipeline.PipelineMeta;
+import org.apache.hop.pipeline.transforms.mock.TransformMockHelper;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+/** Unit test for {@link YamlInput} */
+class YamlInputTests {
+  private TransformMockHelper<YamlInputMeta, YamlInputData> helper;
+  @TempDir private Path tempDir;
+  @Mock private IVariables variables;
+
+  @BeforeEach
+  void setup() throws Exception {
+    HopEnvironment.init();
+
+    helper = new TransformMockHelper<>("Yaml_test", YamlInputMeta.class, 
YamlInputData.class);
+    Mockito.doReturn(helper.iLogChannel)
+        .when(helper.logChannelFactory)
+        .create(any(), any(ILoggingObject.class));
+
+    when(helper.pipeline.isRunning()).thenReturn(true);
+  }
+
+  @Test
+  void testInit_shouldBuildRowMeta() {
+    YamlInputField field = new YamlInputField();
+    field.setPath("user.name");
+    field.setType(IValueMeta.TYPE_STRING);
+    field.setTrimType(YamlInputField.TYPE_TRIM_BOTH);
+
+    YamlInputMeta meta = helper.iTransformMeta;
+    YamlInputData data = helper.iTransformData;
+    PipelineMeta plMeta = helper.pipelineMeta;
+    Pipeline pipeline = helper.pipeline;
+    YamlInput input = new YamlInput(helper.transformMeta, meta, data, 0, 
plMeta, pipeline);
+
+    when(meta.getInputFields()).thenReturn(List.of(field));
+
+    boolean result = input.init();
+    assertTrue(result);
+
+    assertNotNull(input.getData().rowMeta);
+    assertEquals(1, input.getData().nrInputFields);
+  }
+
+  @Test
+  void testHandleMissingFiles_shouldThrowException() {
+    FileObject mockFile = mock(FileObject.class);
+    FileInputList fileList = mock(FileInputList.class);
+
+    when(fileList.getNonExistentFiles()).thenReturn(List.of(mockFile));
+
+    YamlInputMeta meta = helper.iTransformMeta;
+    YamlInputData data = helper.iTransformData;
+    PipelineMeta plMeta = helper.pipelineMeta;
+    Pipeline pipeline = helper.pipeline;
+    data.files = fileList;
+    YamlInput transform = new YamlInput(helper.transformMeta, meta, data, 0, 
plMeta, pipeline);
+
+    InvocationTargetException ex =
+        assertThrows(
+            InvocationTargetException.class,
+            () -> MethodUtils.invokeMethod(transform, true, 
"handleMissingFiles"));
+
+    Throwable exception = ex.getTargetException();
+    assertInstanceOf(HopException.class, exception);
+  }
+
+  @Test
+  void testGetRowData_shouldMergeYamlAndInputRow() throws Exception {
+    YamlInputMeta meta = helper.iTransformMeta;
+    YamlInputData data = helper.iTransformData;
+    PipelineMeta plMeta = helper.pipelineMeta;
+    Pipeline pipeline = helper.pipeline;
+    YamlInput transform = new YamlInput(helper.transformMeta, meta, data, 0, 
plMeta, pipeline);
+
+    // mock yaml reader
+    YamlReader yamlReader = mock(YamlReader.class);
+    Object[] yamlRow = new Object[] {"alice", 18};
+
+    data.yaml = yamlReader;
+    data.rowMeta = new RowMeta();
+    data.totalPreviousFields = 1;
+    data.totalOutStreamFields = 3;
+    data.totalOutFields = 1;
+
+    data.readRow = new Object[] {"file1.yml"};
+    when(yamlReader.getRow(any())).thenReturn(yamlRow);
+
+    Object[] result = (Object[]) MethodUtils.invokeMethod(transform, true, 
"getRowData");
+
+    assertNotNull(result);
+    assertEquals("file1.yml", result[0]);
+    assertEquals("alice", result[1]);
+    assertEquals(18, result[2]);
+  }
+
+  @Test
+  void testOpenNextFile_shouldAdvanceIndex() throws Exception {
+    YamlInputMeta meta = helper.iTransformMeta;
+    YamlInputData data = helper.iTransformData;
+    PipelineMeta plMeta = helper.pipelineMeta;
+    Pipeline pipeline = helper.pipeline;
+    YamlInput transform = new YamlInput(helper.transformMeta, meta, data, 0, 
plMeta, pipeline);
+
+    Path tempFile = tempDir.resolve("test.yaml");
+    try (FileWriter writer = new FileWriter(tempFile.toFile())) {
+      writer.write("""
+                                       name: Alice
+                                       age: 30
+                                       """);
+    }
+
+    data.fileIndex = 0;
+
+    data.files = mock(FileInputList.class);
+    when(data.files.nrOfFiles()).thenReturn(1);
+    
when(data.files.getFile(0)).thenReturn(HopVfs.getFileObject(tempFile.toString()));
+
+    boolean result = (boolean) MethodUtils.invokeMethod(transform, true, 
"openNextFile");
+    assertTrue(result);
+    assertEquals(1, data.fileIndex);
+    assertNotNull(data.yaml);
+  }
+
+  /**
+   * {@link YamlInput#processRow()} in file mode: reads a YAML map, emits one 
row via {@code
+   * putRow}, then returns false when no more rows.
+   */
+  @Test
+  void testProcessRow_fileMode_emitsOneRowThenFinishes() throws Exception {
+    Path tempFile = tempDir.resolve("processRow-one.yaml");
+    Files.writeString(tempFile, """
+                                               name: Alice
+                                               age: 30
+                                               """);
+
+    YamlInputMeta meta = new YamlInputMeta();
+    meta.setInFields(false);
+    meta.setDoNotFailIfNoFile(true);
+    YamlInputField fName = new YamlInputField();
+    fName.setName("name");
+    fName.setPath("name");
+    fName.setType(IValueMeta.TYPE_STRING);
+    YamlInputField fAge = new YamlInputField();
+    fAge.setName("age");
+    fAge.setPath("age");
+    fAge.setType(IValueMeta.TYPE_INTEGER);
+    meta.getInputFields().add(fName);
+    meta.getInputFields().add(fAge);
+    YamlInputMeta.YamlFile yf = new YamlInputMeta.YamlFile();
+    yf.setFilename(tempFile.toAbsolutePath().toString());
+    yf.setFileMask(".*\\.ya?ml");
+    yf.setFileRequired(false);
+    meta.getYamlFiles().add(yf);
+
+    YamlInputData data = new YamlInputData();
+    YamlInput transform =
+        new YamlInput(helper.transformMeta, meta, data, 0, 
helper.pipelineMeta, helper.pipeline);
+    transform = spy(transform);
+
+    List<Object[]> written = new ArrayList<>();
+    doAnswer(
+            invocation -> {
+              Object[] row = invocation.getArgument(1);
+              written.add(Arrays.copyOf(row, row.length));
+              return null;
+            })
+        .when(transform)
+        .putRow(any(IRowMeta.class), any());
+
+    assertTrue(transform.init());
+    assertTrue(transform.processRow(), "first processRow should emit a row");
+    assertFalse(transform.processRow(), "second processRow should end (no more 
rows)");
+    assertEquals(1, written.size());
+    assertEquals("Alice", written.getFirst()[0]);
+    assertEquals(30L, ((Number) written.getFirst()[1]).longValue());
+  }
+
+  /**
+   * Row limit stops {@link YamlInput#processRow()} after the configured 
number of output rows
+   * (single-document map still yields only one row when limit is 1).
+   */
+  @Test
+  void testProcessRow_rowLimit_stopsAfterOneRow() throws Exception {
+    Path tempFile = tempDir.resolve("processRow-limit.yaml");
+    Files.writeString(tempFile, """
+                                               name: Bob
+                                               age: 40
+                                               """);
+
+    YamlInputMeta meta = new YamlInputMeta();
+    meta.setInFields(false);
+    meta.setDoNotFailIfNoFile(true);
+    meta.setRowLimit(1);
+    YamlInputField fName = new YamlInputField();
+    fName.setName("name");
+    fName.setPath("name");
+    fName.setType(IValueMeta.TYPE_STRING);
+    YamlInputField fAge = new YamlInputField();
+    fAge.setName("age");
+    fAge.setPath("age");
+    fAge.setType(IValueMeta.TYPE_INTEGER);
+    meta.getInputFields().add(fName);
+    meta.getInputFields().add(fAge);
+    YamlInputMeta.YamlFile yf = new YamlInputMeta.YamlFile();
+    yf.setFilename(tempFile.toAbsolutePath().toString());
+    yf.setFileMask(".*\\.ya?ml");
+    yf.setFileRequired(false);
+    meta.getYamlFiles().add(yf);
+
+    YamlInputData data = new YamlInputData();
+    YamlInput transform =
+        spy(
+            new YamlInput(
+                helper.transformMeta, meta, data, 0, helper.pipelineMeta, 
helper.pipeline));
+
+    List<Object[]> written = new ArrayList<>();
+    doAnswer(
+            invocation -> {
+              Object[] row = invocation.getArgument(1);
+              written.add(Arrays.copyOf(row, row.length));
+              return null;
+            })
+        .when(transform)
+        .putRow(any(IRowMeta.class), any());
+
+    assertTrue(transform.init());
+    assertFalse(
+        transform.processRow(),
+        "one row is emitted then processRow returns false when row limit is 
exceeded");
+    assertFalse(transform.processRow(), "no further rows after end of YAML");
+    assertEquals(1, written.size());
+    assertEquals("Bob", written.getFirst()[0]);
+    assertEquals(40L, ((Number) written.getFirst()[1]).longValue());
+  }
+
+  @AfterEach
+  void tearDown() {
+    helper.cleanUp();
+  }
+}
diff --git 
a/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlReaderTests.java
 
b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlReaderTests.java
new file mode 100644
index 0000000000..b105f9f7be
--- /dev/null
+++ 
b/plugins/transforms/yamlinput/src/test/java/org/apache/hop/pipeline/transforms/yamlinput/YamlReaderTests.java
@@ -0,0 +1,230 @@
+/*
+ * 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.pipeline.transforms.yamlinput;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.FileWriter;
+import java.nio.file.Path;
+import java.util.Date;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.hop.core.HopEnvironment;
+import org.apache.hop.core.exception.HopException;
+import org.apache.hop.core.row.IValueMeta;
+import org.apache.hop.core.row.RowMeta;
+import org.apache.hop.core.vfs.HopVfs;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+/** Unit test for {@link YamlReader} */
+class YamlReaderTests {
+  private YamlReader reader;
+
+  @BeforeEach
+  void setUp() {
+    reader = new YamlReader();
+  }
+
+  @BeforeAll
+  static void init() {
+    try {
+      HopEnvironment.init();
+    } catch (HopException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @Test
+  void testLoadString_MapStructure() {
+    String yaml = """
+                               name: John
+                               age: 30
+                               active: true
+                               """;
+
+    reader.loadString(yaml);
+
+    RowMeta rowMeta = reader.getFields();
+    assertEquals(3, rowMeta.size());
+
+    Object[] row = reader.getRow(rowMeta);
+
+    assertNotNull(row);
+    assertEquals("John", row[0]);
+    // Integer -> Long
+    assertEquals(30L, row[1]);
+    assertEquals(true, row[2]);
+  }
+
+  @Test
+  void testLoadString_ListOfMap() {
+    String yaml = """
+                               - name: Alice
+                                 age: 25
+                                 createTime: 2026-03-04 12:03:01
+                               """;
+
+    reader.loadString(yaml);
+
+    RowMeta rowMeta = reader.getFields();
+    Object[] row = reader.getRow(rowMeta);
+
+    assertNotNull(row);
+    assertEquals("Alice", row[0]);
+    assertEquals(25L, row[1]);
+    assertInstanceOf(Date.class, row[2]);
+  }
+
+  @Test
+  void testLoadString_ListMultipleValues() {
+    String yaml = """
+                               - 1
+                               - 2
+                               - 3
+                               """;
+
+    reader.loadString(yaml);
+
+    RowMeta rowMeta = reader.getFields();
+    // DEFAULT_LIST_VALUE_NAME
+    assertEquals(1, rowMeta.size());
+
+    Object[] row1 = reader.getRow(rowMeta);
+    Object[] row2 = reader.getRow(rowMeta);
+    Object[] row3 = reader.getRow(rowMeta);
+
+    assertEquals(1L, row1[0]);
+    assertEquals(2L, row2[0]);
+    assertEquals(3L, row3[0]);
+  }
+
+  @Test
+  void testMultipleDocuments() {
+    String yaml = """
+                               ---
+                               name: A
+                               ---
+                               name: B
+                               """;
+
+    reader.loadString(yaml);
+
+    RowMeta rowMeta = reader.getFields();
+    Object[] row1 = reader.getRow(rowMeta);
+    Object[] row2 = reader.getRow(rowMeta);
+
+    assertEquals("A", row1[0]);
+    assertEquals("B", row2[0]);
+  }
+
+  @Test
+  void testTypeConversion_Number() {
+    String yaml = """
+                               value: 12.5
+                               """;
+
+    reader.loadString(yaml);
+
+    RowMeta rowMeta = reader.getFields();
+    Object[] row = reader.getRow(rowMeta);
+
+    assertInstanceOf(Double.class, row[0]);
+    assertEquals(12.5, (Double) row[0]);
+  }
+
+  @Test
+  void testNestedMapToString() {
+    String yaml = """
+                               person:
+                                 name: Tom
+                                 age: 20
+                               """;
+
+    reader.loadString(yaml);
+
+    RowMeta rowMeta = reader.getFields();
+    Object[] row = reader.getRow(rowMeta);
+
+    assertNotNull(row[0]);
+    assertTrue(row[0].toString().contains("name"));
+    assertTrue(row[0].toString().contains("age"));
+  }
+
+  @Test
+  void testEmptyYaml() {
+    reader.loadString("");
+
+    RowMeta rowMeta = reader.getFields();
+    Object[] row = reader.getRow(rowMeta);
+
+    assertEquals(0, row.length);
+  }
+
+  @Test
+  void testGetFields_TypeInference() {
+    String yaml =
+        """
+                               - intField: 1
+                                 longField: 2
+                                 doubleField: 1.5
+                                 boolField: true
+                                 bigIntField: 99999999999999999999
+                                 bigDecField: 9999999999999999999999999.55
+                                 byteField: 1
+                                 dateField: 2026-03-04T12:03:01
+                               """;
+
+    reader.loadString(yaml);
+
+    RowMeta rowMeta = reader.getFields();
+    assertEquals(IValueMeta.TYPE_INTEGER, rowMeta.getValueMeta(0).getType());
+    assertEquals(IValueMeta.TYPE_INTEGER, rowMeta.getValueMeta(1).getType());
+    assertEquals(IValueMeta.TYPE_NUMBER, rowMeta.getValueMeta(2).getType());
+    assertEquals(IValueMeta.TYPE_BOOLEAN, rowMeta.getValueMeta(3).getType());
+    assertEquals(IValueMeta.TYPE_BIGNUMBER, rowMeta.getValueMeta(4).getType());
+    assertEquals(IValueMeta.TYPE_NUMBER, rowMeta.getValueMeta(5).getType());
+    assertEquals(IValueMeta.TYPE_INTEGER, rowMeta.getValueMeta(6).getType());
+    assertEquals(IValueMeta.TYPE_DATE, rowMeta.getValueMeta(7).getType());
+  }
+
+  @Test
+  void testLoadFile_singleDocument_map(@TempDir Path tempDir) throws Exception 
{
+    Path tempFile = tempDir.resolve("test.yaml");
+    try (FileWriter writer = new FileWriter(tempFile.toFile())) {
+      writer.write("""
+                                       name: Alice
+                                       age: 30
+                                       """);
+    }
+
+    FileObject fileObject = HopVfs.getFileObject(tempFile.toString());
+    reader.loadFile(fileObject);
+
+    assertNotNull(reader.getYaml());
+    assertTrue(reader.isMapUsed());
+
+    RowMeta rowMeta = reader.getFields();
+    assertEquals(2, rowMeta.size());
+    assertTrue(reader.getBytesReadFromFile() > 0);
+  }
+}

Reply via email to