<xsl:value-of select="."/>
</xsl:template>
+<xsl:template match="OutputFiles">
+ <xsl:if test="*/*">
+ <h2>Output Files</h2>
+ <xsl:apply-templates />
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="OutputFiles/File">
+ <xsl:if test="*">
+ <h3><xsl:value-of select="@Name"/></h3>
+ <xsl:apply-templates />
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="OutputFiles/File/String[@Name='Contents']">
+ <pre>
+ <xsl:value-of select="substring(.,2)"/>
+ </pre>
+</xsl:template>
+
<xsl:template match="InteractiveSession">
<pre>
<xsl:for-each select="*">
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "testutils/cmdlinetest.h"
#include "testutils/refdata.h"
+#include "testutils/textblockmatchers.h"
namespace
{
using gmx::test::CommandLine;
+using gmx::test::ExactTextMatch;
class InsertMoleculesTest : public gmx::test::CommandLineTestBase
{
public:
InsertMoleculesTest()
{
- setOutputFile("-o", "out.gro");
+ setOutputFile("-o", "out.gro", ExactTextMatch());
}
void runTest(const CommandLine &args)
<ReferenceData>
<String Name="CommandLine">insert-molecules -box 4 -nmol 5</String>
<OutputFiles Name="Files">
- <String Name="-o"><![CDATA[
+ <File Name="-o">
+ <String Name="Contents"><![CDATA[
test two-residue molecule for insertion
10
1X X1 1 3.071 2.691 0.351
10Y Y1 10 3.845 1.125 0.921
4.00000 4.00000 4.00000
]]></String>
+ </File>
</OutputFiles>
</ReferenceData>
<ReferenceData>
<String Name="CommandLine">insert-molecules -box 4 -nmol 2</String>
<OutputFiles Name="Files">
- <String Name="-o"><![CDATA[
+ <File Name="-o">
+ <String Name="Contents"><![CDATA[
Test system for solvate/insert-molecules
10
1MeOH Me1 1 1.970 1.460 1.209
4X X2 10 3.910 3.371 4.028
4.00000 4.00000 4.00000
]]></String>
+ </File>
</OutputFiles>
</ReferenceData>
<ReferenceData>
<String Name="CommandLine">insert-molecules -nmol 1</String>
<OutputFiles Name="Files">
- <String Name="-o"><![CDATA[
+ <File Name="-o">
+ <String Name="Contents"><![CDATA[
Test system for solvate/insert-molecules
8
1MeOH Me1 1 1.970 1.460 1.209
4Y Y1 8 2.335 1.954 0.173
3.01000 3.01000 3.01000
]]></String>
+ </File>
</OutputFiles>
</ReferenceData>
<ReferenceData>
<String Name="CommandLine">insert-molecules -box 4</String>
<OutputFiles Name="Files">
- <String Name="-o"><![CDATA[
+ <File Name="-o">
+ <String Name="Contents"><![CDATA[
test molecule for insertion at origin
6
1X X1 1 0.000 0.000 0.000
3X X2 6 1.893 1.048 1.933
4.00000 4.00000 4.00000
]]></String>
+ </File>
</OutputFiles>
</ReferenceData>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "testutils/cmdlinetest.h"
#include "testutils/testfilemanager.h"
+#include "testutils/textblockmatchers.h"
namespace
{
using gmx::test::CommandLine;
+using gmx::test::NoTextMatch;
class SolvateTest : public gmx::test::CommandLineTestBase
{
public:
SolvateTest()
{
- setOutputFile("-o", "out.gro");
+ setOutputFile("-o", "out.gro", NoTextMatch());
}
void runTest(const CommandLine &args)
<xsl:value-of select="."/>
</xsl:template>
+<xsl:template match="OutputFiles">
+ <xsl:if test="*/*">
+ <h2>Output Files</h2>
+ <xsl:apply-templates />
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="OutputFiles/File">
+ <xsl:if test="*">
+ <h3><xsl:value-of select="@Name"/></h3>
+ <xsl:apply-templates />
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="OutputFiles/File/String[@Name='Contents']">
+ <pre>
+ <xsl:value-of select="substring(.,2)"/>
+ </pre>
+</xsl:template>
+
<xsl:template match="InteractiveSession">
<pre>
<xsl:for-each select="*">
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "testutils/cmdlinetest.h"
#include "testutils/testasserts.h"
+#include "testutils/textblockmatchers.h"
#include "moduletest.h"
{
using gmx::test::CommandLine;
+using gmx::test::NoTextMatch;
/********************************************************************
* Tests for gmx::analysismodules::PairDistance.
"-sel", "resindex 3", "-selgrouping", "none"
};
setTopology("simple.gro");
- setOutputFileNoTest("-o", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
runTest(CommandLine(cmdline));
}
"-cutoff", "1.5"
};
setTopology("simple.gro");
- setOutputFileNoTest("-o", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
runTest(CommandLine(cmdline));
}
"-cutoff", "1.5"
};
setTopology("simple.gro");
- setOutputFileNoTest("-o", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
runTest(CommandLine(cmdline));
}
"-type", "max"
};
setTopology("simple.gro");
- setOutputFileNoTest("-o", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
runTest(CommandLine(cmdline));
}
"-cutoff", "1.5", "-type", "max"
};
setTopology("simple.gro");
- setOutputFileNoTest("-o", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
runTest(CommandLine(cmdline));
}
"-cutoff", "2.5"
};
setTopology("simple.gro");
- setOutputFileNoTest("-o", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
runTest(CommandLine(cmdline));
}
"-cutoff", "3.5", "-type", "max"
};
setTopology("simple.gro");
- setOutputFileNoTest("-o", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
runTest(CommandLine(cmdline));
}
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "testutils/cmdlinetest.h"
#include "testutils/testasserts.h"
+#include "testutils/textblockmatchers.h"
#include "moduletest.h"
{
using gmx::test::CommandLine;
+using gmx::test::NoTextMatch;
/********************************************************************
* Tests for gmx::analysismodules::Rdf.
"-sel", "name OW", "not name OW"
};
setTopology("spc216.gro");
- setOutputFileNoTest("-o", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
excludeDataset("pairdist");
runTest(CommandLine(cmdline));
}
"-sel", "name OW", "not name OW"
};
setTopology("spc216.gro");
- setOutputFileNoTest("-o", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
excludeDataset("pairdist");
runTest(CommandLine(cmdline));
}
"-sel", "name OW", "not name OW"
};
setTopology("spc216.gro");
- setOutputFileNoTest("-o", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
excludeDataset("pairdist");
// TODO: Consider if it is possible to get a more reproducible result
// and/or a stricter tolerance (e.g., by checking that the sum of
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ <File Name="-or"/>
+ <File Name="-oa"/>
+ <File Name="-tv"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ <File Name="-or"/>
+ <File Name="-oa"/>
+ </OutputFiles>
</ReferenceData>
</DataFrame>
</AnalysisData>
</OutputData>
+ <OutputFiles Name="Files">
+ <File Name="-o"/>
+ <File Name="-or"/>
+ <File Name="-oa"/>
+ </OutputFiles>
</ReferenceData>
</AnalysisData>
</OutputData>
<OutputFiles Name="Files">
- <String Name="-q"><![CDATA[
+ <File Name="-o"/>
+ <File Name="-q">
+ <String Name="Contents"><![CDATA[
TITLE Connolly Dot Surface Generated by gmx sasa
REMARK THIS IS A SIMULATION BOX
CRYST1 59.062 68.451 30.517 90.00 90.00 90.00 P 1 1
TER
ENDMDL
]]></String>
+ </File>
</OutputFiles>
</ReferenceData>
</AnalysisData>
</OutputData>
<OutputFiles Name="Files">
- <String Name="-oi"><![CDATA[
+ <File Name="-oi">
+ <String Name="Contents"><![CDATA[
0.000 8 1 2 5 6 9 10 13 14 6 1 2 3 7 8 9
0.000 8 1 3 4 7 8 9 12 13 6 1 2 3 7 8 9
]]></String>
- <String Name="-on"><![CDATA[
+ </File>
+ <File Name="-on">
+ <String Name="Contents"><![CDATA[
[ y_<_2.5_f0_t0.000 ]
1 2 5 6 9 10 13 14
[ y_<_2.5_f1_t0.000 ]
1 3 4 7 8 9 12 13
]]></String>
+ </File>
</OutputFiles>
</ReferenceData>
</AnalysisData>
</OutputData>
<OutputFiles Name="Files">
- <String Name="-ofpdb"><![CDATA[
+ <File Name="-ofpdb">
+ <String Name="Contents"><![CDATA[
TITLE frame t= 0.000
REMARK THIS IS A SIMULATION BOX
CRYST1 100.000 100.000 100.000 90.00 90.00 90.00 P 1 1
TER
ENDMDL
]]></String>
+ </File>
</OutputFiles>
</ReferenceData>
</AnalysisData>
</OutputData>
<OutputFiles Name="Files">
- <String Name="-ofpdb"><![CDATA[
+ <File Name="-ofpdb">
+ <String Name="Contents"><![CDATA[
TITLE frame t= 0.000
REMARK THIS IS A SIMULATION BOX
CRYST1 100.000 100.000 100.000 90.00 90.00 90.00 P 1 1
TER
ENDMDL
]]></String>
+ </File>
</OutputFiles>
</ReferenceData>
</AnalysisData>
</OutputData>
<OutputFiles Name="Files">
- <String Name="-ofpdb"><![CDATA[
+ <File Name="-ofpdb">
+ <String Name="Contents"><![CDATA[
TITLE frame t= 0.000
REMARK THIS IS A SIMULATION BOX
CRYST1 100.000 100.000 100.000 90.00 90.00 90.00 P 1 1
TER
ENDMDL
]]></String>
+ </File>
</OutputFiles>
</ReferenceData>
</AnalysisData>
</OutputData>
<OutputFiles Name="Files">
- <String Name="-ofpdb"><![CDATA[
+ <File Name="-ofpdb">
+ <String Name="Contents"><![CDATA[
TITLE frame t= 0.000
REMARK THIS IS A SIMULATION BOX
CRYST1 100.000 100.000 100.000 90.00 90.00 90.00 P 1 1
TER
ENDMDL
]]></String>
+ </File>
</OutputFiles>
</ReferenceData>
<xsl:value-of select="."/>
</xsl:template>
+<xsl:template match="OutputFiles">
+ <xsl:if test="*/*">
+ <h2>Output Files</h2>
+ <xsl:apply-templates />
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="OutputFiles/File">
+ <xsl:if test="*">
+ <h3><xsl:value-of select="@Name"/></h3>
+ <xsl:apply-templates />
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="OutputFiles/File/String[@Name='Contents']">
+ <pre>
+ <xsl:value-of select="substring(.,2)"/>
+ </pre>
+</xsl:template>
+
<xsl:template match="InteractiveSession">
<pre>
<xsl:for-each select="*">
<xsl:apply-imports />
</xsl:template>
-<xsl:template match="OutputFiles">
- <h2>Output Files</h2>
- <xsl:for-each select="*">
- <h3><xsl:value-of select="@Name"/></h3>
- <pre>
- <xsl:value-of select="."/>
- </pre>
- </xsl:for-each>
-</xsl:template>
-
</xsl:stylesheet>
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2014, by the GROMACS development team, led by
+ * Copyright (c) 2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include "testutils/cmdlinetest.h"
#include "testutils/testasserts.h"
+#include "testutils/textblockmatchers.h"
#include "moduletest.h"
{
using gmx::test::CommandLine;
+using gmx::test::ExactTextMatch;
+using gmx::test::NoTextMatch;
/********************************************************************
* Tests for gmx::analysismodules::Sasa.
"-output", "name N CA C O H"
};
setTopology("lysozyme.gro");
- setOutputFileNoTest("-o", "xvg");
- setOutputFileNoTest("-or", "xvg");
- setOutputFileNoTest("-oa", "xvg");
- setOutputFileNoTest("-tv", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
+ setOutputFile("-or", ".xvg", NoTextMatch());
+ setOutputFile("-oa", ".xvg", NoTextMatch());
+ setOutputFile("-tv", ".xvg", NoTextMatch());
excludeDataset("dgsolv");
setDatasetTolerance("area", gmx::test::ulpTolerance(8));
setDatasetTolerance("volume", gmx::test::ulpTolerance(8));
"-surface", "atomnr 1"
};
setTopology("lysozyme.gro");
- setOutputFileNoTest("-o", "xvg");
- setOutputFile("-q", "connolly.pdb");
+ setOutputFile("-o", ".xvg", NoTextMatch());
+ setOutputFile("-q", "connolly.pdb", ExactTextMatch());
includeDataset("area");
runTest(CommandLine(cmdline));
}
"-output", "y > 1.5"
};
setTopology("lysozyme.gro");
- setOutputFileNoTest("-o", "xvg");
- setOutputFileNoTest("-or", "xvg");
- setOutputFileNoTest("-oa", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
+ setOutputFile("-or", ".xvg", NoTextMatch());
+ setOutputFile("-oa", ".xvg", NoTextMatch());
excludeDataset("volume");
excludeDataset("dgsolv");
setDatasetTolerance("area", gmx::test::ulpTolerance(8));
"-output", "y > 1.5 and z > 0"
};
setTopology("lysozyme.gro");
- setOutputFileNoTest("-o", "xvg");
- setOutputFileNoTest("-or", "xvg");
- setOutputFileNoTest("-oa", "xvg");
+ setOutputFile("-o", ".xvg", NoTextMatch());
+ setOutputFile("-or", ".xvg", NoTextMatch());
+ setOutputFile("-oa", ".xvg", NoTextMatch());
excludeDataset("volume");
excludeDataset("dgsolv");
setDatasetTolerance("area", gmx::test::ulpTolerance(8));
/*
* This file is part of the GROMACS molecular simulation package.
*
- * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by
+ * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
* Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
* and including many others, as listed in the AUTHORS file in the
* top-level source directory and at http://www.gromacs.org.
#include <gtest/gtest.h>
#include "testutils/cmdlinetest.h"
+#include "testutils/textblockmatchers.h"
#include "moduletest.h"
{
using gmx::test::CommandLine;
+using gmx::test::ExactTextMatch;
/********************************************************************
* Tests for gmx::analysismodules::Select.
};
setTopology("simple.gro");
setTrajectory("simple.gro");
- setOutputFile("-oi", "index.dat");
- setOutputFile("-on", "index.ndx");
+ setOutputFile("-oi", "index.dat", ExactTextMatch());
+ setOutputFile("-on", "index.ndx", ExactTextMatch());
excludeDataset("cfrac");
runTest(CommandLine(cmdline));
}
setTopology("simple.gro");
setTrajectory("simple.gro");
includeDataset("occupancy");
- setOutputFile("-ofpdb", "occupancy.pdb");
+ setOutputFile("-ofpdb", "occupancy.pdb", ExactTextMatch());
runTest(CommandLine(cmdline));
}
setTopology("simple.pdb");
setTrajectory("simple.gro");
includeDataset("occupancy");
- setOutputFile("-ofpdb", "occupancy.pdb");
+ setOutputFile("-ofpdb", "occupancy.pdb", ExactTextMatch());
runTest(CommandLine(cmdline));
}
setTopology("simple.pdb");
setTrajectory("simple.gro");
includeDataset("occupancy");
- setOutputFile("-ofpdb", "occupancy.pdb");
+ setOutputFile("-ofpdb", "occupancy.pdb", ExactTextMatch());
runTest(CommandLine(cmdline));
}
setTopology("simple.pdb");
setTrajectory("simple.gro");
includeDataset("occupancy");
- setOutputFile("-ofpdb", "occupancy.pdb");
+ setOutputFile("-ofpdb", "occupancy.pdb", ExactTextMatch());
runTest(CommandLine(cmdline));
}
// static
std::string TextReader::readFileToString(const char *filename)
{
- std::string result;
TextReader reader(filename);
- std::string line;
- while (reader.readLine(&line))
- {
- result.append(line);
- }
+ std::string result(reader.readAll());
reader.close();
return result;
}
return true;
}
+std::string TextReader::readAll()
+{
+ std::string result;
+ std::string line;
+ while (readLine(&line))
+ {
+ result.append(line);
+ }
+ return result;
+}
+
void TextReader::close()
{
impl_->stream_->close();
*/
bool readLineTrimmed(std::string *line);
+ /*! \brief
+ * Reads all remaining lines from the stream as a single string.
+ *
+ * \returns Full contents of the stream (from the current point to
+ * the end).
+ */
+ std::string readAll();
+
/*! \brief
* Closes the underlying stream.
*/
testfileredirector.cpp
testinit.cpp
testoptions.cpp
+ textblockmatchers.cpp
xvgtest.cpp)
add_library(testutils STATIC ${UNITTEST_TARGET_OPTIONS} ${TESTUTILS_SOURCES})
#include "testutils/refdata.h"
#include "testutils/testfilemanager.h"
-#include "testutils/xvgtest.h"
+#include "testutils/textblockmatchers.h"
namespace gmx
{
public:
struct OutputFileInfo
{
- OutputFileInfo(const char *option, const std::string &path)
- : option(option), path(path)
+ OutputFileInfo(const char *option, const std::string &path,
+ TextBlockMatcherPointer matcher)
+ : option(option), path(path), matcher(move(matcher))
+ {
+ }
+ OutputFileInfo(OutputFileInfo &&other)
+ : option(std::move(other.option)), path(std::move(other.path)),
+ matcher(std::move(other.matcher))
{
- xvg = endsWith(path, ".xvg");
}
- std::string option;
- std::string path;
- bool xvg;
+ std::string option;
+ std::string path;
+ TextBlockMatcherPointer matcher;
};
typedef std::vector<OutputFileInfo> OutputFileList;
}
void CommandLineTestHelper::setOutputFile(
- CommandLine *args, const char *option, const char *filename)
+ CommandLine *args, const char *option, const char *filename,
+ const ITextBlockMatcherSettings &matcher)
{
- std::string fullFilename = impl_->fileManager_.getTemporaryFilePath(filename);
- args->addOption(option, fullFilename);
- impl_->outputFiles_.push_back(Impl::OutputFileInfo(option, fullFilename));
-}
-
-void CommandLineTestHelper::setOutputFileNoTest(
- CommandLine *args, const char *option, const char *extension)
-{
- std::string fullFilename = impl_->fileManager_.getTemporaryFilePath(
- formatString("%d.%s", args->argc(), extension));
+ std::string suffix(filename);
+ if (startsWith(filename, "."))
+ {
+ suffix = formatString("%d.%s", args->argc(), filename);
+ }
+ std::string fullFilename = impl_->fileManager_.getTemporaryFilePath(suffix);
args->addOption(option, fullFilename);
+ impl_->outputFiles_.push_back(
+ Impl::OutputFileInfo(option, fullFilename, matcher.createMatcher()));
}
void CommandLineTestHelper::checkOutputFiles(TestReferenceChecker checker) const
outfile != impl_->outputFiles_.end();
++outfile)
{
- if (outfile->xvg)
- {
- TestReferenceChecker testChecker = checker.checkCompound("File",
- outfile->option.c_str());
- TextInputFile sis(outfile->path);
- checkXvgFile(&sis, &testChecker);
- }
- else
- {
- std::string output = TextReader::readFileToString(outfile->path);
- outputChecker.checkStringBlock(output, outfile->option.c_str());
- }
+ TestReferenceChecker fileChecker(
+ outputChecker.checkCompound("File", outfile->option.c_str()));
+ TextInputFile stream(outfile->path);
+ outfile->matcher->checkStream(&stream, &fileChecker);
+ stream.close();
}
}
}
}
void CommandLineTestBase::setOutputFile(
- const char *option, const char *filename)
-{
- impl_->helper_.setOutputFile(&impl_->cmdline_, option, filename);
-}
-
-void CommandLineTestBase::setOutputFileNoTest(
- const char *option, const char *extension)
+ const char *option, const char *filename,
+ const ITextBlockMatcherSettings &matcher)
{
- impl_->helper_.setOutputFileNoTest(&impl_->cmdline_, option, extension);
+ impl_->helper_.setOutputFile(&impl_->cmdline_, option, filename, matcher);
}
CommandLine &CommandLineTestBase::commandLine()
namespace test
{
+class ITextBlockMatcherSettings;
class TestFileManager;
class TestReferenceChecker;
*
* 1. Adding input files to a CommandLine instance by generating them from a
* string provided in the test (setInputFileContents()).
- * 2. Adding output files to a CommandLine instance (setOutputFile() and
- * setOutputFileNoTest()).
+ * 2. Adding output files to a CommandLine instance (setOutputFile()).
* 3. Checking the contents of some of the output files using
* TestReferenceData (setOutputFile() and checkOutputFiles()).
* 4. Static methods for easily executing command-line modules
* \param[in,out] args CommandLine to which to add the option.
* \param[in] option Option to set.
* \param[in] filename Name of the output file.
+ * \param[in] matcher Specifies how the contents of the file are
+ * tested.
*
- * This method:
+ * This method does the following:
* - Adds \p option to \p args to point a temporary file name
* constructed from \p filename.
* - Makes checkOutputFiles() to check the contents of the file
- * against reference data.
+ * against reference data, using \p matcher.
* - Marks the temporary file for removal at test teardown.
*
* \p filename is given to TestTemporaryFileManager to make a unique
- * filename for the temporary file, but is not otherwise used.
- *
+ * filename for the temporary file.
+ * If \p filename starts with a dot, a unique number is prefixed (such
+ * that it is possible to create multiple files with the same extension
+ * by just specifying the extension for every call of setOutputFile()).
+ *
+ * If the output file is needed to trigger some computation, or is
+ * unconditionally produced by the code under test, but the contents
+ * are not interesting for the test, use NoTextMatch as the matcher.
*/
void setOutputFile(CommandLine *args, const char *option,
- const char *filename);
- /*! \brief
- * Sets an output file parameter.
- *
- * \param[in,out] args CommandLine to which to add the option.
- * \param[in] option Option to set.
- * \param[in] extension Extension for the file to create.
- *
- * This method:
- * - Adds \p option to \p args to point to a temporary file name with
- * extension \p extension.
- * - Marks the temporary file for removal at test teardown.
- *
- * This method provides the mechanism to set output files that are
- * required to trigger computation of values that are required for
- * the test. The contents of the output file are not tested.
- *
- * Another use case is to mark files that are unconditionally produced
- * by the code under test, but do not need to be tested. This method
- * makes the test code aware of those files such that it can remove
- * them at the end of the test.
- */
- void setOutputFileNoTest(CommandLine *args, const char *option,
- const char *extension);
+ const char *filename,
+ const ITextBlockMatcherSettings &matcher);
/*! \brief
* Checks output files added with setOutputFile() against reference
*
* \see CommandLineTestHelper::setOutputFile()
*/
- void setOutputFile(const char *option, const char *filename);
- /*! \brief
- * Sets an output file parameter.
- *
- * \see CommandLineTestHelper::setOutputFileNoTest()
- */
- void setOutputFileNoTest(const char *option, const char *extension);
+ void setOutputFile(const char *option, const char *filename,
+ const ITextBlockMatcherSettings &matcher);
/*! \brief
* Returns the internal CommandLine object used to construct the
<xsl:value-of select="."/>
</xsl:template>
+<xsl:template match="OutputFiles">
+ <xsl:if test="*/*">
+ <h2>Output Files</h2>
+ <xsl:apply-templates />
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="OutputFiles/File">
+ <xsl:if test="*">
+ <h3><xsl:value-of select="@Name"/></h3>
+ <xsl:apply-templates />
+ </xsl:if>
+</xsl:template>
+
+<xsl:template match="OutputFiles/File/String[@Name='Contents']">
+ <pre>
+ <xsl:value-of select="substring(.,2)"/>
+ </pre>
+</xsl:template>
+
<xsl:template match="InteractiveSession">
<pre>
<xsl:for-each select="*">
}
-void TestReferenceChecker::checkStringBlock(const std::string &value,
- const char *id)
+void TestReferenceChecker::checkTextBlock(const std::string &value,
+ const char *id)
{
EXPECT_PLAIN(impl_->processItem(Impl::cStringNodeName, id,
ExactStringBlockChecker(value)));
* formatted output, and attempts to make the output XML such that it
* is easier to edit by hand to set the desired output formatting.
*/
- void checkStringBlock(const std::string &value, const char *id);
+ void checkTextBlock(const std::string &value, const char *id);
//! Check a single integer value.
void checkInteger(int value, const char *id);
//! Check a single int64 value.
}
else
{
- checker->checkStringBlock(text, id);
+ checker->checkTextBlock(text, id);
}
}
{
TestReferenceData data(gmx::test::erefdataUpdateAll);
TestReferenceChecker checker(data.rootChecker());
- checker.checkStringBlock("Line1\nLine2\n", "block");
+ checker.checkTextBlock("Line1\nLine2\n", "block");
checker.checkString("Test", "string");
}
{
TestReferenceData data(gmx::test::erefdataCompare);
TestReferenceChecker checker(data.rootChecker());
- checker.checkStringBlock("Line1\nLine2\n", "block");
+ checker.checkTextBlock("Line1\nLine2\n", "block");
checker.checkString("Line1\nLine2\n", "block");
- checker.checkStringBlock("Test", "string");
+ checker.checkTextBlock("Test", "string");
}
}
TestReferenceChecker checker(data.rootChecker());
checker.checkString("\"<'>\n \r &\\/;", "string");
// \r is not handled correctly
- checker.checkStringBlock("\"<'>\n ]]> &\\/;", "stringblock");
+ checker.checkTextBlock("\"<'>\n ]]> &\\/;", "stringblock");
}
{
TestReferenceData data(gmx::test::erefdataCompare);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("\"<'>\n \r &\\/;", "string");
- checker.checkStringBlock("\"<'>\n ]]> &\\/;", "stringblock");
+ checker.checkTextBlock("\"<'>\n ]]> &\\/;", "stringblock");
}
}
TestReferenceChecker checker(data.rootChecker());
checker.checkString("Test", "string");
EXPECT_NONFATAL_FAILURE(checker.checkString("Test2", "string"), "");
- checker.checkStringBlock("TestString", "stringblock");
- EXPECT_NONFATAL_FAILURE(checker.checkStringBlock("TestString2", "stringblock"), "");
+ checker.checkTextBlock("TestString", "stringblock");
+ EXPECT_NONFATAL_FAILURE(checker.checkTextBlock("TestString2", "stringblock"), "");
}
{
TestReferenceData data(gmx::test::erefdataCompare);
TestReferenceChecker checker(data.rootChecker());
checker.checkString("Test", "string");
EXPECT_NONFATAL_FAILURE(checker.checkString("Test2", "string"), "");
- checker.checkStringBlock("TestString", "stringblock");
- EXPECT_NONFATAL_FAILURE(checker.checkStringBlock("TestString2", "stringblock"), "");
+ checker.checkTextBlock("TestString", "stringblock");
+ EXPECT_NONFATAL_FAILURE(checker.checkTextBlock("TestString2", "stringblock"), "");
}
}
namespace
{
+
+using gmx::test::checkXvgFile;
+using gmx::test::XvgMatchSettings;
+
//! Input testing data - an inline xvg file.
const char * const input[] = {
"0 2905.86 -410.199",
gmx::test::TestReferenceChecker checker(data.rootChecker());
// Convert char array to a stream and add it to the checker
gmx::StringInputStream sis(input);
- gmx::test::checkXvgFile(&sis, &checker);
+ checkXvgFile(&sis, &checker, XvgMatchSettings());
}
{
// Now read it back
gmx::test::TestReferenceChecker checker(data.rootChecker());
// Convert char array to a stream and add it to the checker
gmx::StringInputStream sis(input);
- gmx::test::checkXvgFile(&sis, &checker);
+ checkXvgFile(&sis, &checker, XvgMatchSettings());
}
}
gmx::test::TestReferenceChecker checker(data.rootChecker());
// Convert char array to a stream and add it to the checker
gmx::StringInputStream sis(input);
- gmx::test::checkXvgFile(&sis, &checker);
+ checkXvgFile(&sis, &checker, XvgMatchSettings());
}
{
const char * const input[] = {
gmx::test::TestReferenceData data(gmx::test::erefdataCompare);
gmx::test::TestReferenceChecker checker(data.rootChecker());
gmx::StringInputStream sis(input);
- EXPECT_NONFATAL_FAILURE(gmx::test::checkXvgFile(&sis, &checker), "absent");
+ EXPECT_NONFATAL_FAILURE(checkXvgFile(&sis, &checker, XvgMatchSettings()), "absent");
}
}
gmx::test::TestReferenceChecker checker(data.rootChecker());
// Convert char array to a stream and add it to the checker
gmx::StringInputStream sis(input);
- gmx::test::checkXvgFile(&sis, &checker);
+ checkXvgFile(&sis, &checker, XvgMatchSettings());
}
{
const char * const input[] = {
gmx::test::TestReferenceData data(gmx::test::erefdataCompare);
gmx::test::TestReferenceChecker checker(data.rootChecker());
gmx::StringInputStream sis(input);
- EXPECT_NONFATAL_FAILURE(gmx::test::checkXvgFile(&sis, &checker), "Row6");
+ EXPECT_NONFATAL_FAILURE(checkXvgFile(&sis, &checker, XvgMatchSettings()), "Row6");
}
}
gmx::test::TestReferenceChecker checker(data.rootChecker());
// Convert char array to a stream and add it to the checker
gmx::StringInputStream sis(input);
- gmx::test::checkXvgFile(&sis, &checker);
+ checkXvgFile(&sis, &checker, XvgMatchSettings());
}
{
const char * const input[] = {
gmx::test::TestReferenceData data(gmx::test::erefdataCompare);
gmx::test::TestReferenceChecker checker(data.rootChecker());
gmx::StringInputStream sis(input);
- EXPECT_NONFATAL_FAILURE(gmx::test::checkXvgFile(&sis, &checker), "-411");
+ EXPECT_NONFATAL_FAILURE(checkXvgFile(&sis, &checker, XvgMatchSettings()), "-411");
}
}
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * Implements classes from textblockmatchers.h.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \ingroup module_testutils
+ */
+#include "gmxpre.h"
+
+#include "textblockmatchers.h"
+
+#include "gromacs/utility/textreader.h"
+
+#include "testutils/refdata.h"
+
+namespace gmx
+{
+namespace test
+{
+
+namespace
+{
+
+class ExactTextMatcher : public ITextBlockMatcher
+{
+ public:
+ virtual void checkStream(TextInputStream *stream,
+ TestReferenceChecker *checker)
+ {
+ TextReader reader(stream);
+ checker->checkTextBlock(reader.readAll(), "Contents");
+ }
+};
+
+class NoTextMatcher : public ITextBlockMatcher
+{
+ public:
+ virtual void checkStream(TextInputStream * /*stream*/,
+ TestReferenceChecker * /*checker*/)
+ {
+ }
+};
+
+} // namespace
+
+ITextBlockMatcher::~ITextBlockMatcher()
+{
+}
+
+ITextBlockMatcherSettings::~ITextBlockMatcherSettings()
+{
+}
+
+TextBlockMatcherPointer ExactTextMatch::createMatcher() const
+{
+ return TextBlockMatcherPointer(new ExactTextMatcher());
+}
+
+TextBlockMatcherPointer NoTextMatch::createMatcher() const
+{
+ return TextBlockMatcherPointer(new NoTextMatcher());
+}
+
+} // namespace test
+} // namespace gmx
--- /dev/null
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2015, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * GROMACS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \libinternal \file
+ * \brief
+ * Declares utility classes for testing multi-line strings against reference data.
+ *
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
+ * \inlibraryapi
+ * \ingroup module_testutils
+ */
+#ifndef GMX_TESTUTILS_TEXTBLOCKMATCHERS_H
+#define GMX_TESTUTILS_TEXTBLOCKMATCHERS_H
+
+#include <memory>
+#include <string>
+
+namespace gmx
+{
+
+class TextInputStream;
+
+namespace test
+{
+
+class TestReferenceChecker;
+
+/*! \libinternal \brief
+ * Represents a text matcher, matching text stream contents against reference
+ * data.
+ *
+ * Typical pattern of declaring such matchers is to
+ * - Create a factory that implements ITextBlockMatcherSettings,
+ * - Make that factory provide any necessary parameters that the matcher needs,
+ * using a "named parameter" idiom (see XvgMatch for an example), and
+ * - Make the factory create and return an instance of an internal
+ * implementation class that implements ITextBlockMatcher and provides
+ * the actual matching logic.
+ *
+ * Any method that then wants to accept a matcher can accept a
+ * ITextBlockMatcherSettings.
+ *
+ * \inlibraryapi
+ * \ingroup module_testutils
+ */
+class ITextBlockMatcher
+{
+ public:
+ virtual ~ITextBlockMatcher();
+
+ /*! \brief
+ * Matches contents of a stream against reference data.
+ *
+ * \param stream Stream to match.
+ * \param checker Checker to use for matching.
+ *
+ * The method can change the state of the provided checker (e.g., by
+ * changing the default tolerance).
+ * The caller is responsible of providing a checker where such state
+ * changes do not matter.
+ */
+ virtual void checkStream(TextInputStream *stream,
+ TestReferenceChecker *checker) = 0;
+};
+
+//! Smart pointer for managing a ITextBlockMatcher.
+typedef std::unique_ptr<ITextBlockMatcher> TextBlockMatcherPointer;
+
+/*! \libinternal \brief
+ * Represents a factory for creating a text matcher.
+ *
+ * See derived classes for available matchers. Each derived class represents
+ * one type of matcher (see ITextBlockMatcher), and provides any methods
+ * necessary to pass parameters to such a matcher. Methods that accept a
+ * matcher can then take in this interface, and call createMatcher() to use the
+ * matcher that the caller of the method specifies.
+ *
+ * \inlibraryapi
+ * \ingroup module_testutils
+ */
+class ITextBlockMatcherSettings
+{
+ public:
+ //! Factory method that constructs the matcher after parameters are set.
+ virtual TextBlockMatcherPointer createMatcher() const = 0;
+
+ protected:
+ virtual ~ITextBlockMatcherSettings();
+};
+
+/*! \libinternal \brief
+ * Use an exact text match (the contents should be exactly equal).
+ *
+ * \inlibraryapi
+ * \ingroup module_testutils
+ */
+class ExactTextMatch : public ITextBlockMatcherSettings
+{
+ public:
+ virtual TextBlockMatcherPointer createMatcher() const;
+};
+
+/*! \libinternal \brief
+ * Do not match the text (the contents are ignored).
+ *
+ * \inlibraryapi
+ * \ingroup module_testutils
+ */
+class NoTextMatch : public ITextBlockMatcherSettings
+{
+ public:
+ virtual TextBlockMatcherPointer createMatcher() const;
+};
+
+} // namespace test
+} // namespace gmx
+
+#endif
* Implements routine to check the content of xvg files.
*
* \author David van der Spoel <david.vanderspoel@icm.uu.se>
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
* \ingroup module_testutils
*/
#include "gmxpre.h"
#include "testutils/refdata.h"
#include "testutils/testasserts.h"
+#include "testutils/textblockmatchers.h"
namespace gmx
{
-
namespace test
{
-void checkXvgFile(TextInputStream *input,
- TestReferenceChecker *checker)
+namespace
+{
+
+class XvgMatcher : public ITextBlockMatcher
{
+ public:
+ explicit XvgMatcher(const XvgMatchSettings &settings)
+ : settings_(settings)
+ {
+ }
+
+ virtual void checkStream(TextInputStream *stream,
+ TestReferenceChecker *checker)
+ {
+ checkXvgFile(stream, checker, settings_);
+ }
+
+ private:
+ XvgMatchSettings settings_;
+};
+
+} // namespace
+
+void checkXvgFile(TextInputStream *input,
+ TestReferenceChecker *checker,
+ const XvgMatchSettings &settings)
+{
+ TestReferenceChecker dataChecker(checker->checkCompound("XvgData", "Data"));
+ dataChecker.setDefaultTolerance(settings.tolerance);
+
std::string line;
int nrow = 0;
row.push_back(dval);
}
std::string buf = formatString("Row%d", nrow++);
- checker->checkSequence(row.begin(), row.end(), buf.c_str());
+ dataChecker.checkSequence(row.begin(), row.end(), buf.c_str());
}
}
std::string buf = formatString("Row%d", nrow++);
- checker->checkPresent(false, buf.c_str());
+ dataChecker.checkPresent(false, buf.c_str());
}
-} // namespace test
+TextBlockMatcherPointer XvgMatch::createMatcher() const
+{
+ return TextBlockMatcherPointer(new XvgMatcher(settings_));
+}
+} // namespace test
} // namespace gmx
* Declares function to add the content of an xvg file to a checker.
*
* \author David van der Spoel <david.vanderspoel@icm.uu.se>
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
* \inlibraryapi
* \ingroup module_testutils
*/
#include <string>
+#include "testutils/testasserts.h"
+#include "testutils/textblockmatchers.h"
+
namespace gmx
{
class TestReferenceChecker;
+struct XvgMatchSettings
+{
+ XvgMatchSettings() : tolerance(defaultRealTolerance()) {}
+
+ FloatingPointTolerance tolerance;
+};
+
/*! \brief
* Adds content of xvg file to TestReferenceChecker object.
*
* \param[in] input Object returning the lines of the file/data
* one by one.
* \param[in,out] checker The checker object.
+ * \param[in] settings Settings to use for matching.
+ */
+void checkXvgFile(TextInputStream *input,
+ TestReferenceChecker *checker,
+ const XvgMatchSettings &settings);
+
+/*! \libinternal \brief
+ * Match the contents as an xvg file.
+ *
+ * \see checkXvgFile()
+ *
+ * \inlibraryapi
+ * \ingroup module_testutils
*/
-void checkXvgFile(TextInputStream *input,
- TestReferenceChecker *checker);
+class XvgMatch : public ITextBlockMatcherSettings
+{
+ public:
+ //! Sets the tolerance for matching data point values.
+ XvgMatch &tolerance(const FloatingPointTolerance &tolerance)
+ {
+ settings_.tolerance = tolerance;
+ return *this;
+ }
+
+ virtual TextBlockMatcherPointer createMatcher() const;
+ private:
+ XvgMatchSettings settings_;
+};
} // namespace test