From 0dff52345373747d49490a55a6da9210c2f78f7b Mon Sep 17 00:00:00 2001
From: kledmundson <6842706+kledmundson@users.noreply.github.com>
Date: Fri, 4 Oct 2024 09:14:44 -0700
Subject: [PATCH] Noseam has been refactored to be callable. Makefile test has
 been converted to a gtest and removed. (#5600)

* Noseam has been refactored to be callable. Makefile test has been converted to a gtest and removed. Addresses #5599.

* Modifications to address gtest failures. Also added addtional input parameter error checking to ensure noseam exits prior to generation of temporary files. Finally modified gtests to remove the print.prt file if generated. Addresses #5599.
---
 CHANGELOG.md                                  |   1 +
 isis/src/base/apps/noseam/main.cpp            |  96 +-----
 isis/src/base/apps/noseam/noseam.cpp          | 149 ++++++++++
 isis/src/base/apps/noseam/noseam.h            |  20 ++
 isis/src/base/apps/noseam/noseam.xml          |   3 +
 isis/src/base/apps/noseam/tsts/Makefile       |   4 -
 .../base/apps/noseam/tsts/default/Makefile    |  10 -
 isis/tests/FunctionalTestsNoseam.cpp          | 279 ++++++++++++++++++
 8 files changed, 464 insertions(+), 98 deletions(-)
 create mode 100644 isis/src/base/apps/noseam/noseam.cpp
 create mode 100644 isis/src/base/apps/noseam/noseam.h
 delete mode 100644 isis/src/base/apps/noseam/tsts/Makefile
 delete mode 100644 isis/src/base/apps/noseam/tsts/default/Makefile
 create mode 100644 isis/tests/FunctionalTestsNoseam.cpp

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e3d555def1..efde84a228 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -46,6 +46,7 @@ release.
 - Added *.history to the ignore list in downloadIsisData
 
 ### Changed
+- Noseam has been refactored to be callable; old Makefile test has been removed and replaced by a gtest. Issue: [#5599](https://github.com/USGS-Astrogeology/ISIS3/issues/5599)
 - Explode has been refactored to be callable; old Makefile test has been removed and replaced by a gtest. Issue: [#5557](https://github.com/USGS-Astrogeology/ISIS3/issues/5557)
 - Isisminer has been refactored to be callable; old Makefile tests have been removed and replaced by gtests. Issue: [#5516](https://github.com/USGS-Astrogeology/ISIS3/issues/5516)
 - Algebra has been refactored to be callable; old Makefile tests have been removed and replaced by gtests. Issue: [#5594](https://github.com/USGS-Astrogeology/ISIS3/issues/5594)
diff --git a/isis/src/base/apps/noseam/main.cpp b/isis/src/base/apps/noseam/main.cpp
index 9dd2eb7514..1a6cf6c7dc 100644
--- a/isis/src/base/apps/noseam/main.cpp
+++ b/isis/src/base/apps/noseam/main.cpp
@@ -1,92 +1,20 @@
-#include "Isis.h"
-#include "Application.h"
-#include "FileList.h"
-#include "Cube.h"
-#include "Preference.h"
-#include "ProgramLauncher.h"
-
-#include <iostream>
-#include <fstream>
-
-using namespace std;
-using namespace Isis;
-
-void IsisMain() {
-
-  //Get user parameters
-  UserInterface &ui = Application::GetUserInterface();
-  FileList cubes;
-  cubes.read(ui.GetFileName("FROMLIST"));
+/** This is free and unencumbered software released into the public domain.
 
-  int samples = ui.GetInteger("SAMPLES");
-  int lines = ui.GetInteger("LINES");
-  QString match = ui.GetAsString("MATCHBANDBIN");
+The authors of ISIS do not claim copyright on the contents of this file.
+For more details about the LICENSE terms and the AUTHORS, you will
+find files of those names at the top level of this repository. **/
 
-  //Sets upt the pathName to be used for most application calls
-  FileName inFile = cubes[0];
+/* SPDX-License-Identifier: CC0-1.0 */
 
-  Pvl &pref = Preference::Preferences();
-  QString pathName = (QString)pref.findGroup("DataDirectory")["Temporary"] + "/";
-
-  /**
-   * Creates a mosaic from the original images.  It is placed here
-   * so that the failure MATCHBANDBIN causes does not leave
-   * highpasses cubes lying around!
-  */
-  QString parameters = "FROMLIST=" + ui.GetFileName("FROMLIST") +
-                      " MOSAIC=" + pathName + "OriginalMosaic.cub" +
-                      " MATCHBANDBIN=" + match;
-  ProgramLauncher::RunIsisProgram("automos", parameters);
-
-  //Creates the highpass cubes from the cubes FileList
-  std::ofstream highPassList;
-  highPassList.open("HighPassList.lis");
-  for(int i = 0; i < cubes.size(); i++) {
-    inFile = cubes[i];
-    QString outParam = pathName + inFile.baseName() + "_highpass.cub";
-    parameters = "FROM=" + inFile.expanded() +
-                 " TO=" + outParam
-                 + " SAMPLES=" + toString(samples) + " LINES=" + toString(lines);
-    ProgramLauncher::RunIsisProgram("highpass", parameters);
-    //Reads the just created highpass cube into a list file for automos
-    highPassList << outParam << endl;
-  }
-  highPassList.close();
-
-  //Makes a mosaic out of the highpass cube filelist
-  parameters = "FROMLIST=HighPassList.lis MOSAIC=" + pathName + "HighpassMosaic.cub"
-               + " MATCHBANDBIN=" + match;
-  ProgramLauncher::RunIsisProgram("automos", parameters);
-
-  //Does a lowpass on the original mosaic
-  parameters = "FROM=" + pathName + "OriginalMosaic.cub"
-               + " TO=" + pathName + "LowpassMosaic.cub"
-               + " SAMPLES=" + toString(samples) + " LINES=" + toString(lines);
-  ProgramLauncher::RunIsisProgram("lowpass", parameters);
+#include "Isis.h"
 
-  //Finally combines the highpass and lowpass mosaics
-  parameters = "FROM=" + pathName + "HighpassMosaic.cub" +
-               " FROM2=" + pathName + "LowpassMosaic.cub" +
-               " TO=" + ui.GetCubeName("TO") +
-               " OPERATOR= add";
-  ProgramLauncher::RunIsisProgram("algebra", parameters);
+#include "noseam.h"
 
-  //Will remove all of the temp files by default
-  if(ui.GetBoolean("REMOVETEMP")) {
-    QString file("HighPassList.lis");
-    remove(file.toLatin1().data());
-    file = pathName + "HighpassMosaic.cub";
-    remove(file.toLatin1().data());
-    file = pathName + "LowpassMosaic.cub";
-    remove(file.toLatin1().data());
-    file = pathName + "OriginalMosaic.cub";
-    remove(file.toLatin1().data());
+#include "Application.h"
 
-    for(int i = 0; i < cubes.size(); i++) {
-      inFile = cubes[i];
-      file = pathName + inFile.baseName() + "_highpass.cub";
-      remove(file.toLatin1().data());
-    }
-  }
+using namespace Isis;
 
+void IsisMain() {
+  UserInterface &ui = Application::GetUserInterface();
+  noseam(ui);
 }
diff --git a/isis/src/base/apps/noseam/noseam.cpp b/isis/src/base/apps/noseam/noseam.cpp
new file mode 100644
index 0000000000..aaa198a1b1
--- /dev/null
+++ b/isis/src/base/apps/noseam/noseam.cpp
@@ -0,0 +1,149 @@
+/** This is free and unencumbered software released into the public domain.
+
+The authors of ISIS do not claim copyright on the contents of this file.
+For more details about the LICENSE terms and the AUTHORS, you will
+find files of those names at the top level of this repository. **/
+
+/* SPDX-License-Identifier: CC0-1.0 */
+
+#include "noseam.h"
+
+#include <iostream>
+#include <fstream>
+
+//#include "automos.h"
+#include "FileList.h"
+#include "FileName.h"
+#include "Cube.h"
+#include "Preference.h"
+#include "ProgramLauncher.h"
+
+using namespace std;
+
+namespace Isis {
+
+  /**
+   * Noseam creates a mosaic from a list of input cubes using an
+   * algorithm that minimizes seams.
+   *
+   * @param ui UserInterface object containing parameters
+   */
+  void noseam(UserInterface &ui) {
+
+    // Get Filename with list of cubes to mosaic
+    FileName cubeListFileName(ui.GetFileName("FROMLIST"));
+    std::cout << "***going to run 2nd noseam method\n";
+    return noseam(cubeListFileName, ui);
+  }
+
+
+  /**
+   * Noseam creates a mosaic from a list of input cubes using an
+   * algorithm that minimizes seams.
+   *
+   * @param cubeListFileName Filename with list of cubes to mosaic
+   * @param ui UserInterface object containing parameters
+   */
+  void noseam(FileName &cubeListFileName, UserInterface &ui) {
+
+    // Boxcar samples and lines must be odd and 1 or greater
+    int samples;
+    if (ui.WasEntered("SAMPLES")) {
+      samples = ui.GetInteger("SAMPLES");
+      
+      if (samples < 1 || samples % 2 == 0) {
+        string msg = "Value for [SAMPLES] must be odd and greater or equal to 1.";
+        throw IException(IException::User, msg, _FILEINFO_);
+      }
+    }
+    else {
+      string msg = "Parameter [SAMPLES] must be entered.";
+      throw IException(IException::User, msg, _FILEINFO_);
+    }
+
+    int lines;
+    if (ui.WasEntered("LINES")) {
+      lines = ui.GetInteger("LINES");
+
+      if (lines < 1 || lines % 2 == 0) {
+        string msg = "Value for [LINES] must be odd and greater or equal to 1.";
+        throw IException(IException::User, msg, _FILEINFO_);
+      }
+    }
+    else {
+      string msg = "Parameter [LINES] must be entered.";
+      throw IException(IException::User, msg, _FILEINFO_);      
+    }
+    // Get user parameters
+    FileList cubes;
+    cubes.read(cubeListFileName);
+
+    QString match = ui.GetAsString("MATCHBANDBIN");
+
+    // Sets up the pathName to be used for most application calls
+    FileName inFile = cubes[0];
+
+    QString pathName = FileName("$TEMPORARY/").expanded();
+
+    /**
+     * Creates a mosaic from the original images.  It is placed here
+     * so that the failure MATCHBANDBIN causes does not leave
+     * highpasses cubes lying around!
+    */
+    QString parameters = "FROMLIST=" + cubeListFileName.original() + 
+                        " MOSAIC=" + pathName + "OriginalMosaic.cub" +
+                        " MATCHBANDBIN=" + match;
+    ProgramLauncher::RunIsisProgram("automos", parameters);
+
+    // Creates the highpass cubes from the cubes FileList
+    ofstream highPassList;
+    highPassList.open("HighPassList.lis");
+    for(int i = 0; i < cubes.size(); i++) {
+      inFile = cubes[i];
+      QString outParam = pathName + inFile.baseName() + "_highpass.cub";
+      parameters = "FROM=" + inFile.expanded() +
+                   " TO=" + outParam
+                   + " SAMPLES=" + toString(samples) + " LINES=" + toString(lines);
+      ProgramLauncher::RunIsisProgram("highpass", parameters);
+      // Reads the just created highpass cube into a list file for automos
+      highPassList << outParam << endl;
+    }
+    highPassList.close();
+
+    // Makes a mosaic out of the highpass cube filelist
+    parameters = "FROMLIST=HighPassList.lis MOSAIC=" + pathName + "HighpassMosaic.cub"
+                 + " MATCHBANDBIN=" + match;
+    ProgramLauncher::RunIsisProgram("automos", parameters);
+
+    // Does a lowpass on the original mosaic
+    parameters = "FROM=" + pathName + "OriginalMosaic.cub"
+                 + " TO=" + pathName + "LowpassMosaic.cub"
+                 + " SAMPLES=" + toString(samples) + " LINES=" + toString(lines);
+    ProgramLauncher::RunIsisProgram("lowpass", parameters);
+
+    // Finally combines the highpass and lowpass mosaics
+    parameters = "FROM=" + pathName + "HighpassMosaic.cub" +
+                 " FROM2=" + pathName + "LowpassMosaic.cub" +
+                 " TO=" + ui.GetCubeName("TO") +
+                 " OPERATOR= add";
+    ProgramLauncher::RunIsisProgram("algebra", parameters);
+
+    // Will remove all of the temp files by default
+    if(ui.GetBoolean("REMOVETEMP")) {
+      QString file("HighPassList.lis");
+      remove(file.toLatin1().data());
+      file = pathName + "HighpassMosaic.cub";
+      remove(file.toLatin1().data());
+      file = pathName + "LowpassMosaic.cub";
+      remove(file.toLatin1().data());
+      file = pathName + "OriginalMosaic.cub";
+      remove(file.toLatin1().data());
+
+      for(int i = 0; i < cubes.size(); i++) {
+        inFile = cubes[i];
+        file = pathName + inFile.baseName() + "_highpass.cub";
+        remove(file.toLatin1().data());
+      }
+    }
+  }
+}
diff --git a/isis/src/base/apps/noseam/noseam.h b/isis/src/base/apps/noseam/noseam.h
new file mode 100644
index 0000000000..9c28183813
--- /dev/null
+++ b/isis/src/base/apps/noseam/noseam.h
@@ -0,0 +1,20 @@
+/** This is free and unencumbered software released into the public domain.
+
+The authors of ISIS do not claim copyright on the contents of this file.
+For more details about the LICENSE terms and the AUTHORS, you will
+find files of those names at the top level of this repository. **/
+
+/* SPDX-License-Identifier: CC0-1.0 */
+
+#ifndef noseam_h
+#define noseam_h
+
+#include "FileName.h"
+#include "UserInterface.h"
+
+namespace Isis{
+  extern void noseam(UserInterface &ui);
+  extern void noseam(FileName &cubeListFileName, UserInterface &ui);
+}
+
+#endif
diff --git a/isis/src/base/apps/noseam/noseam.xml b/isis/src/base/apps/noseam/noseam.xml
index 937559ef09..d6c50d53a8 100644
--- a/isis/src/base/apps/noseam/noseam.xml
+++ b/isis/src/base/apps/noseam/noseam.xml
@@ -41,6 +41,9 @@
       boxcar for the highpass and lowpass filters, have been condensed down to two 
       parameters, SAMPLES and LINES as the size of the boxcars must be the same. Fixes #258.
     </change>
+    <change name="Ken Edmundson" date="2024-8-25">
+      Converted noseam to callable app. Also converted Makefile test to gtest format.
+    </change>
   </history>
 
   <groups>
diff --git a/isis/src/base/apps/noseam/tsts/Makefile b/isis/src/base/apps/noseam/tsts/Makefile
deleted file mode 100644
index 46d84c74c2..0000000000
--- a/isis/src/base/apps/noseam/tsts/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-BLANKS = "%-6s"    
-LENGTH = "%-40s"
-
-include $(ISISROOT)/make/isismake.tststree
diff --git a/isis/src/base/apps/noseam/tsts/default/Makefile b/isis/src/base/apps/noseam/tsts/default/Makefile
deleted file mode 100644
index f25dbe9ea9..0000000000
--- a/isis/src/base/apps/noseam/tsts/default/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-APPNAME = noseam
-
-include $(ISISROOT)/make/isismake.tsts
-
-commands:
-	$(LS) $(INPUT)/* > $(OUTPUT)/cubes.lis;
-	$(APPNAME) FROMLIST=$(OUTPUT)/cubes.lis \
-	TO=$(OUTPUT)/result.cub \
-	SAMPLES=73 LINES=73 > /dev/null;
-	$(RM) $(OUTPUT)/cubes.lis;
diff --git a/isis/tests/FunctionalTestsNoseam.cpp b/isis/tests/FunctionalTestsNoseam.cpp
new file mode 100644
index 0000000000..a835c10b5b
--- /dev/null
+++ b/isis/tests/FunctionalTestsNoseam.cpp
@@ -0,0 +1,279 @@
+#include "noseam.h"
+
+#include "NetworkFixtures.h"
+#include "Pvl.h"
+#include "gmock/gmock.h"
+
+using namespace std;
+using namespace Isis;
+
+static QString APP_XML = FileName("$ISISROOT/bin/xml/noseam.xml").expanded();
+
+/**
+   * NoseamDefault Test using ThreeImageNetwork Fixture
+   * 
+   * INPUT: 1) FileName of cube list with cube1map, cube2map, cube3map
+   *           from ThreeImageNetwork Fixture
+   *        2) Boxcar dimensions
+   *           samples = 11
+   *           lines = 11
+   *        3) matchbandbin = yes (default)
+   *        4) removetemp = yes (default)
+   * 
+   * OUTPUT: noseamDefaultOut.cub
+  */
+TEST_F(ThreeImageNetwork, FunctionalTestNoseamDefault) {
+
+  // create list of input projected cube files
+  FileName cubeListFileName(tempDir.path() + "/cubes.lis");
+
+  ofstream of;
+  of.open((cubeListFileName.original()).toStdString());
+  of << cube1map->fileName() << "\n";
+  of << cube2map->fileName() << "\n";
+  of << cube3map->fileName() << "\n";
+  of.close();
+
+  // run noseam
+  QVector<QString> args = {"to=" + tempDir.path() + "/noseamDefaultOut.cub",
+                           "samples=11",
+                           "lines=11"
+                           };
+
+  UserInterface ui(APP_XML, args);
+
+  try {
+    noseam(cubeListFileName, ui);
+  }
+  catch (IException &e) {
+    FAIL() << e.toString().toStdString().c_str() << std::endl;
+  }
+ 
+  // validate output mosaic
+  Cube mosaic(tempDir.path() + "/noseamDefaultOut.cub");
+
+  PvlObject mosaicLabel = mosaic.label()->findObject("IsisCube");
+  PvlGroup dimensions = mosaicLabel.findObject("Core").findGroup("Dimensions");
+  PvlGroup pixels = mosaicLabel.findObject("Core").findGroup("Pixels");
+  PvlGroup mapping = mosaicLabel.findGroup("Mapping");
+
+  EXPECT_EQ(int(dimensions["Samples"]), 548);
+  EXPECT_EQ(int(dimensions["Lines"]), 487);
+  EXPECT_EQ(int(dimensions["Bands"]), 1);
+
+  EXPECT_EQ(pixels["Type"][0], "Real");
+  EXPECT_EQ(pixels["ByteOrder"][0], "Lsb");
+  EXPECT_EQ(double(pixels["Base"]), 0.0);
+  EXPECT_EQ(double(pixels["Multiplier"]), 1.0);
+
+  EXPECT_EQ(double(mapping["MinimumLatitude"]), 0.47920860194551);
+  EXPECT_EQ(double(mapping["MaximumLatitude"]), 3.3932951263901);
+  EXPECT_EQ(double(mapping["MinimumLongitude"]), -0.94830771139743);
+  EXPECT_EQ(double(mapping["MaximumLongitude"]), 1.4318179715731);
+
+  // remove print.prt file if it has been created
+  FileName printFile("print.prt");
+  if (printFile.fileExists()) {
+    remove("print.prt");
+  }
+}
+
+
+/**
+   * NoseamEvenBoxFilterSamples Test using ThreeImageNetwork Fixture
+   * 
+   * INPUT: 1) FileName of cube list with cube1map, cube2map, cube3map
+   *           from ThreeImageNetwork Fixture
+   *        2) Boxcar dimensions
+   *           samples = 12
+   *           lines = 11
+   *        3) matchbandbin = yes (default)
+   *        4) removetemp = yes (default)
+   * 
+   * THROWS: Value for [SAMPLES] must be odd and greater or equal to 1.
+  */
+TEST_F(ThreeImageNetwork, FunctionalTestNoseamEvenBoxFilterSamples) {
+  
+  // create list of input projected cube files
+  FileName cubeListFileName(tempDir.path() + "/cubes.lis");
+
+  // create list of input cube files
+  ofstream of;
+  of.open((cubeListFileName.original()).toStdString());
+  of << cube1map->fileName() << "\n";
+  of << cube2map->fileName() << "\n";
+  of << cube3map->fileName() << "\n";
+  of.close();
+
+  // run noseam
+  QVector<QString> args = {"to=" + tempDir.path() + "/result.cub",
+                           "samples=12",
+                           "lines=11"
+                           };
+
+  UserInterface ui(APP_XML, args);
+
+  try {
+    noseam(cubeListFileName, ui);
+    FAIL() << "Expected Exception for boxcar even sample input";
+  }
+  catch (IException &e) {
+    EXPECT_TRUE(e.toString().toLatin1().contains("[SAMPLES] must be odd"))
+      << e.toString().toStdString();
+  }
+
+  // remove print.prt file if it has been created
+  FileName printFile("print.prt");
+  if (printFile.fileExists()) {
+    remove("print.prt");
+  }
+}
+
+
+/**
+   * NoseamEvenBoxFilterLines Test using ThreeImageNetwork Fixture
+   * 
+   * INPUT: 1) FileName of cube list with cube1map, cube2map, cube3map
+   *           from ThreeImageNetwork Fixture
+   *        2) Boxcar dimensions
+   *           samples = 11
+   *           lines = 12
+   *        3) matchbandbin = yes (default)
+   *        4) removetemp = yes (default)
+   * 
+   * THROWS: Value for [LINES] must be odd and greater or equal to 1.
+  */
+TEST_F(ThreeImageNetwork, FunctionalTestNoseamEvenBoxFilterLines) {
+
+  // create list of input projected cube files
+  FileName cubeListFileName(tempDir.path() + "/cubes.lis");
+
+  // create list of input cube files
+  ofstream of;
+  of.open((cubeListFileName.original()).toStdString());
+  of << cube1map->fileName() << "\n";
+  of << cube2map->fileName() << "\n";
+  of << cube3map->fileName() << "\n";
+  of.close();
+
+  // run noseam
+  QVector<QString> args = {"to=" + tempDir.path() + "/result.cub",
+                           "samples=11",
+                           "lines=12"
+                           };
+
+  UserInterface ui(APP_XML, args);
+
+  try {
+    noseam(cubeListFileName, ui);
+    FAIL() << "Expected Exception for boxcar even line input";
+  }
+  catch (IException &e) {
+    EXPECT_TRUE(e.toString().toLatin1().contains("[LINES] must be odd"))
+      << e.toString().toStdString();
+  }
+
+  // remove print.prt file if it has been created
+  FileName printFile("print.prt");
+  if (printFile.fileExists()) {
+    remove("print.prt");
+  }
+}
+
+
+/**
+   * Noseam NoBoxFilterSamples Test using ThreeImageNetwork Fixture
+   * 
+   * INPUT: 1) FileName of cube list with cube1map, cube2map, cube3map
+   *           from ThreeImageNetwork Fixture
+   *        2) Boxcar dimensions
+   *           lines = 11
+   *        3) matchbandbin = yes (default)
+   *        4) removetemp = yes (default)
+   * 
+   * THROWS: Parameter [SAMPLES] must be entered.
+  */
+TEST_F(ThreeImageNetwork, FunctionalTestNoseamNoBoxFilterSamples) {
+
+  // create list of input projected cube files
+  FileName cubeListFileName(tempDir.path() + "/cubes.lis");
+
+  // create list of input cube files
+  ofstream of;
+  of.open((cubeListFileName.original()).toStdString());
+  of << cube1map->fileName() << "\n";
+  of << cube2map->fileName() << "\n";
+  of << cube3map->fileName() << "\n";
+  of.close();
+
+  // run noseam
+  QVector<QString> args = {"to=" + tempDir.path() + "/result.cub",
+                           "lines=11"
+                           };
+
+  UserInterface ui(APP_XML, args);
+
+  try {
+    noseam(cubeListFileName, ui);
+    FAIL() << "Expected Exception for no input for boxcar samples";
+  }
+  catch (IException &e) {
+    EXPECT_TRUE(e.toString().toLatin1().contains("[SAMPLES] must be entered"))
+      << e.toString().toStdString();
+  }
+
+  // remove print.prt file if it has been created
+  FileName printFile("print.prt");
+  if (printFile.fileExists()) {
+    remove("print.prt");
+  }
+}
+
+
+/**
+   * Noseam NoBoxFilterLines Test using ThreeImageNetwork Fixture
+   * 
+   * INPUT: 1) FileName of cube list with cube1map, cube2map, cube3map
+   *           from ThreeImageNetwork Fixture
+   *        2) Boxcar dimensions
+   *           samples = 11
+   *        3) matchbandbin = yes (default)
+   *        4) removetemp = yes (default)
+   * 
+   * THROWS: Parameter [LINES] must be entered.
+  */
+TEST_F(ThreeImageNetwork, FunctionalTestNoseamNoBoxFilterLines) {
+
+  // create list of input projected cube files
+  FileName cubeListFileName(tempDir.path() + "/cubes.lis");
+
+  // create list of input cube files
+  ofstream of;
+  of.open((cubeListFileName.original()).toStdString());
+  of << cube1map->fileName() << "\n";
+  of << cube2map->fileName() << "\n";
+  of << cube3map->fileName() << "\n";
+  of.close();
+
+  // run noseam
+  QVector<QString> args = {"to=" + tempDir.path() + "/result.cub",
+                           "samples=11"
+                           };
+
+  UserInterface ui(APP_XML, args);
+
+  try {
+    noseam(cubeListFileName, ui);
+    FAIL() << "Expected Exception for no input for boxcar lines";
+  }
+  catch (IException &e) {
+    EXPECT_TRUE(e.toString().toLatin1().contains("[LINES] must be entered"))
+      << e.toString().toStdString();
+  }
+
+  // determine if print.prt has been generated and if so, remove it
+  FileName printFile("print.prt");
+  if (printFile.fileExists()) {
+    remove("print.prt");
+  }
+}
-- 
GitLab