Move OutputCheck to its own header file
* So it can be used in tests for tageditor and other applications * Make it a header-only class so c++utilities does not depend on cppunit
This commit is contained in:
parent
5f14d55f25
commit
b4556c0481
|
@ -35,6 +35,7 @@ set(HEADER_FILES
|
||||||
misc/traits.h
|
misc/traits.h
|
||||||
tests/testutils.h
|
tests/testutils.h
|
||||||
tests/cppunit.h
|
tests/cppunit.h
|
||||||
|
tests/outputcheck.h
|
||||||
)
|
)
|
||||||
set(SRC_FILES
|
set(SRC_FILES
|
||||||
application/argumentparser.cpp
|
application/argumentparser.cpp
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "./outputcheck.h"
|
||||||
#include "./testutils.h"
|
#include "./testutils.h"
|
||||||
|
|
||||||
#include "../conversion/stringbuilder.h"
|
#include "../conversion/stringbuilder.h"
|
||||||
|
@ -21,81 +22,11 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ApplicationUtilities;
|
using namespace ApplicationUtilities;
|
||||||
using namespace ConversionUtilities;
|
using namespace ConversionUtilities;
|
||||||
|
using namespace TestUtilities;
|
||||||
using namespace TestUtilities::Literals;
|
using namespace TestUtilities::Literals;
|
||||||
|
|
||||||
using namespace CPPUNIT_NS;
|
using namespace CPPUNIT_NS;
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief The StandardOutputCheck class asserts whether the standard output written in the enclosing code block matches the expected output.
|
|
||||||
* \remarks Only works for output printed via std::cout.
|
|
||||||
* \todo Could be generalized and moved to testutils.h.
|
|
||||||
*/
|
|
||||||
class StandardOutputCheck {
|
|
||||||
public:
|
|
||||||
StandardOutputCheck(const string &expectedOutput);
|
|
||||||
StandardOutputCheck(string &&expectedOutput, string &&alternativeOutput);
|
|
||||||
StandardOutputCheck(function<void(const string &output)> &&customCheck);
|
|
||||||
~StandardOutputCheck();
|
|
||||||
|
|
||||||
private:
|
|
||||||
const function<void(const string &output)> m_customCheck;
|
|
||||||
const string m_expectedOutput;
|
|
||||||
const string m_alternativeOutput;
|
|
||||||
stringstream m_buffer;
|
|
||||||
streambuf *const m_regularCoutBuffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Redirects standard output to an internal buffer.
|
|
||||||
*/
|
|
||||||
StandardOutputCheck::StandardOutputCheck(const string &expectedOutput)
|
|
||||||
: m_expectedOutput(expectedOutput)
|
|
||||||
, m_buffer()
|
|
||||||
, m_regularCoutBuffer(cout.rdbuf(m_buffer.rdbuf()))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Redirects standard output to an internal buffer.
|
|
||||||
*/
|
|
||||||
StandardOutputCheck::StandardOutputCheck(string &&expectedOutput, string &&alternativeOutput)
|
|
||||||
: m_expectedOutput(expectedOutput)
|
|
||||||
, m_alternativeOutput(alternativeOutput)
|
|
||||||
, m_buffer()
|
|
||||||
, m_regularCoutBuffer(cout.rdbuf(m_buffer.rdbuf()))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Redirects standard output to an internal buffer.
|
|
||||||
*/
|
|
||||||
StandardOutputCheck::StandardOutputCheck(function<void(const string &)> &&customCheck)
|
|
||||||
: m_customCheck(customCheck)
|
|
||||||
, m_buffer()
|
|
||||||
, m_regularCoutBuffer(cout.rdbuf(m_buffer.rdbuf()))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Asserts the buffered standard output and restores the regular behaviour of std::cout.
|
|
||||||
*/
|
|
||||||
StandardOutputCheck::~StandardOutputCheck()
|
|
||||||
{
|
|
||||||
cout.rdbuf(m_regularCoutBuffer);
|
|
||||||
if (m_customCheck) {
|
|
||||||
m_customCheck(m_buffer.str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_alternativeOutput.empty()) {
|
|
||||||
CPPUNIT_ASSERT_EQUAL(m_expectedOutput, m_buffer.str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const string actualOutput(m_buffer.str());
|
|
||||||
if (m_expectedOutput != actualOutput && m_alternativeOutput != actualOutput) {
|
|
||||||
CPPUNIT_FAIL("Output is not either \"" % m_expectedOutput % "\" or \"" % m_alternativeOutput % "\". Got instead:\n" + actualOutput);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The ArgumentParserTests class tests the ArgumentParser and Argument classes.
|
* \brief The ArgumentParserTests class tests the ArgumentParser and Argument classes.
|
||||||
*/
|
*/
|
||||||
|
@ -518,7 +449,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv1[] = { "se" };
|
const char *const argv1[] = { "se" };
|
||||||
ArgumentReader reader(parser, argv1, argv1 + 1, true);
|
ArgumentReader reader(parser, argv1, argv1 + 1, true);
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=()\n");
|
const OutputCheck c("COMPREPLY=()\n");
|
||||||
reader.read();
|
reader.read();
|
||||||
parser.printBashCompletion(1, argv1, 0, reader);
|
parser.printBashCompletion(1, argv1, 0, reader);
|
||||||
}
|
}
|
||||||
|
@ -527,7 +458,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
getArg.setDenotesOperation(true);
|
getArg.setDenotesOperation(true);
|
||||||
setArg.setDenotesOperation(true);
|
setArg.setDenotesOperation(true);
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('set' )\n");
|
const OutputCheck c("COMPREPLY=('set' )\n");
|
||||||
reader.reset(argv1, argv1 + 1).read();
|
reader.reset(argv1, argv1 + 1).read();
|
||||||
parser.printBashCompletion(1, argv1, 0, reader);
|
parser.printBashCompletion(1, argv1, 0, reader);
|
||||||
}
|
}
|
||||||
|
@ -536,7 +467,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv2[] = { "set" };
|
const char *const argv2[] = { "set" };
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('set' )\n");
|
const OutputCheck c("COMPREPLY=('set' )\n");
|
||||||
reader.reset(argv2, argv2 + 1).read();
|
reader.reset(argv2, argv2 + 1).read();
|
||||||
parser.printBashCompletion(1, argv2, 0, reader);
|
parser.printBashCompletion(1, argv2, 0, reader);
|
||||||
}
|
}
|
||||||
|
@ -544,7 +475,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
// advance the cursor position -> the completion should propose the next argument
|
// advance the cursor position -> the completion should propose the next argument
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('--files' '--values' )\n");
|
const OutputCheck c("COMPREPLY=('--files' '--values' )\n");
|
||||||
reader.reset(argv2, argv2 + 1).read();
|
reader.reset(argv2, argv2 + 1).read();
|
||||||
parser.printBashCompletion(1, argv2, 1, reader);
|
parser.printBashCompletion(1, argv2, 1, reader);
|
||||||
}
|
}
|
||||||
|
@ -553,7 +484,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
filesArg.setDenotesOperation(true);
|
filesArg.setDenotesOperation(true);
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('files' '--values' )\n");
|
const OutputCheck c("COMPREPLY=('files' '--values' )\n");
|
||||||
reader.reset(argv2, argv2 + 1).read();
|
reader.reset(argv2, argv2 + 1).read();
|
||||||
parser.printBashCompletion(1, argv2, 1, reader);
|
parser.printBashCompletion(1, argv2, 1, reader);
|
||||||
}
|
}
|
||||||
|
@ -562,7 +493,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
filesArg.setDenotesOperation(false);
|
filesArg.setDenotesOperation(false);
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('display-file-info' 'get' 'set' '--help' )\n");
|
const OutputCheck c("COMPREPLY=('display-file-info' 'get' 'set' '--help' )\n");
|
||||||
reader.reset(nullptr, nullptr).read();
|
reader.reset(nullptr, nullptr).read();
|
||||||
parser.printBashCompletion(0, nullptr, 0, reader);
|
parser.printBashCompletion(0, nullptr, 0, reader);
|
||||||
}
|
}
|
||||||
|
@ -571,7 +502,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv3[] = { "get", "--fields" };
|
const char *const argv3[] = { "get", "--fields" };
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('title' 'album' 'artist' 'trackpos' '--files' )\n");
|
const OutputCheck c("COMPREPLY=('title' 'album' 'artist' 'trackpos' '--files' )\n");
|
||||||
reader.reset(argv3, argv3 + 2).read();
|
reader.reset(argv3, argv3 + 2).read();
|
||||||
parser.printBashCompletion(2, argv3, 2, reader);
|
parser.printBashCompletion(2, argv3, 2, reader);
|
||||||
}
|
}
|
||||||
|
@ -580,7 +511,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv4[] = { "set", "--values", "a" };
|
const char *const argv4[] = { "set", "--values", "a" };
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('album=' 'artist=' ); compopt -o nospace\n");
|
const OutputCheck c("COMPREPLY=('album=' 'artist=' ); compopt -o nospace\n");
|
||||||
reader.reset(argv4, argv4 + 3).read();
|
reader.reset(argv4, argv4 + 3).read();
|
||||||
parser.printBashCompletion(3, argv4, 2, reader);
|
parser.printBashCompletion(3, argv4, 2, reader);
|
||||||
}
|
}
|
||||||
|
@ -588,7 +519,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
// pre-defined values for implicit argument
|
// pre-defined values for implicit argument
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('title' 'album' 'artist' 'trackpos' '--fields' '--files' )\n");
|
const OutputCheck c("COMPREPLY=('title' 'album' 'artist' 'trackpos' '--fields' '--files' )\n");
|
||||||
reader.reset(argv3, argv3 + 1).read();
|
reader.reset(argv3, argv3 + 1).read();
|
||||||
parser.printBashCompletion(1, argv3, 2, reader);
|
parser.printBashCompletion(1, argv3, 2, reader);
|
||||||
}
|
}
|
||||||
|
@ -602,8 +533,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv5[] = { "get", "--files", iniFilePath.c_str() };
|
const char *const argv5[] = { "get", "--files", iniFilePath.c_str() };
|
||||||
{
|
{
|
||||||
// order for file names is not specified
|
// order for file names is not specified
|
||||||
const StandardOutputCheck c(
|
const OutputCheck c("COMPREPLY=('" % mkvFilePath % " '\"'\"'with quote'\"'\"'.mkv' '" % iniFilePath + ".ini' ); compopt -o filenames\n",
|
||||||
"COMPREPLY=('" % mkvFilePath % " '\"'\"'with quote'\"'\"'.mkv' '" % iniFilePath + ".ini' ); compopt -o filenames\n",
|
|
||||||
"COMPREPLY=('" % iniFilePath % ".ini' '" % mkvFilePath + " '\"'\"'with quote'\"'\"'.mkv' ); compopt -o filenames\n");
|
"COMPREPLY=('" % iniFilePath % ".ini' '" % mkvFilePath + " '\"'\"'with quote'\"'\"'.mkv' ); compopt -o filenames\n");
|
||||||
reader.reset(argv5, argv5 + 3).read();
|
reader.reset(argv5, argv5 + 3).read();
|
||||||
parser.printBashCompletion(3, argv5, 2, reader);
|
parser.printBashCompletion(3, argv5, 2, reader);
|
||||||
|
@ -613,7 +543,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv6[] = { "set", "--" };
|
const char *const argv6[] = { "set", "--" };
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('--files' '--values' )\n");
|
const OutputCheck c("COMPREPLY=('--files' '--values' )\n");
|
||||||
reader.reset(argv6, argv6 + 2).read();
|
reader.reset(argv6, argv6 + 2).read();
|
||||||
parser.printBashCompletion(2, argv6, 1, reader);
|
parser.printBashCompletion(2, argv6, 1, reader);
|
||||||
}
|
}
|
||||||
|
@ -622,7 +552,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv7[] = { "-i", "--sub", "--" };
|
const char *const argv7[] = { "-i", "--sub", "--" };
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('--files' '--nested-sub' '--verbose' )\n");
|
const OutputCheck c("COMPREPLY=('--files' '--nested-sub' '--verbose' )\n");
|
||||||
reader.reset(argv7, argv7 + 3).read();
|
reader.reset(argv7, argv7 + 3).read();
|
||||||
parser.printBashCompletion(3, argv7, 2, reader);
|
parser.printBashCompletion(3, argv7, 2, reader);
|
||||||
}
|
}
|
||||||
|
@ -631,7 +561,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv8[] = { "set", "--values", "t" };
|
const char *const argv8[] = { "set", "--values", "t" };
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('title=' 'trackpos=' ); compopt -o nospace\n");
|
const OutputCheck c("COMPREPLY=('title=' 'trackpos=' ); compopt -o nospace\n");
|
||||||
reader.reset(argv8, argv8 + 3).read();
|
reader.reset(argv8, argv8 + 3).read();
|
||||||
parser.printBashCompletion(3, argv8, 2, reader);
|
parser.printBashCompletion(3, argv8, 2, reader);
|
||||||
}
|
}
|
||||||
|
@ -640,13 +570,13 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv9[] = { "-gf" };
|
const char *const argv9[] = { "-gf" };
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('-gf' )\n");
|
const OutputCheck c("COMPREPLY=('-gf' )\n");
|
||||||
reader.reset(argv9, argv9 + 1).read();
|
reader.reset(argv9, argv9 + 1).read();
|
||||||
parser.printBashCompletion(1, argv9, 0, reader);
|
parser.printBashCompletion(1, argv9, 0, reader);
|
||||||
}
|
}
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c([](const string &actualOutput) { CPPUNIT_ASSERT_EQUAL(0_st, actualOutput.find("COMPREPLY=('--fields' ")); });
|
const OutputCheck c([](const string &actualOutput) { CPPUNIT_ASSERT_EQUAL(0_st, actualOutput.find("COMPREPLY=('--fields' ")); });
|
||||||
reader.reset(argv9, argv9 + 1).read();
|
reader.reset(argv9, argv9 + 1).read();
|
||||||
parser.printBashCompletion(1, argv9, 1, reader);
|
parser.printBashCompletion(1, argv9, 1, reader);
|
||||||
}
|
}
|
||||||
|
@ -658,7 +588,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv10[] = { "/some/path/tageditor", "--bash-completion-for", "0" };
|
const char *const argv10[] = { "/some/path/tageditor", "--bash-completion-for", "0" };
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('display-file-info' 'get' 'set' '--help' )\n");
|
const OutputCheck c("COMPREPLY=('display-file-info' 'get' 'set' '--help' )\n");
|
||||||
parser.readArgs(3, argv10);
|
parser.readArgs(3, argv10);
|
||||||
}
|
}
|
||||||
CPPUNIT_ASSERT(!strcmp("/some/path/tageditor", parser.executable()));
|
CPPUNIT_ASSERT(!strcmp("/some/path/tageditor", parser.executable()));
|
||||||
|
@ -668,7 +598,7 @@ void ArgumentParserTests::testBashCompletion()
|
||||||
const char *const argv11[] = { "/some/path/tageditor", "--bash-completion-for", "ge" };
|
const char *const argv11[] = { "/some/path/tageditor", "--bash-completion-for", "ge" };
|
||||||
parser.resetArgs();
|
parser.resetArgs();
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("COMPREPLY=('get' )\n");
|
const OutputCheck c("COMPREPLY=('get' )\n");
|
||||||
parser.readArgs(3, argv11);
|
parser.readArgs(3, argv11);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -711,31 +641,31 @@ void ArgumentParserTests::testHelp()
|
||||||
// parse args and assert output
|
// parse args and assert output
|
||||||
const char *const argv[] = { "app", "-h" };
|
const char *const argv[] = { "app", "-h" };
|
||||||
{
|
{
|
||||||
const StandardOutputCheck c("\e[1m" APP_NAME ", version " APP_VERSION "\n"
|
const OutputCheck c("\e[1m" APP_NAME ", version " APP_VERSION "\n"
|
||||||
"\e[0mLinked against: somelib, some other lib\n"
|
"\e[0mLinked against: somelib, some other lib\n"
|
||||||
"\n\e[0m"
|
"\n\e[0m"
|
||||||
"Available arguments:\n"
|
"Available arguments:\n"
|
||||||
"\e[1m--help, -h\e[0m\n"
|
"\e[1m--help, -h\e[0m\n"
|
||||||
" shows this information\n"
|
" shows this information\n"
|
||||||
" particularities: mandatory\n"
|
" particularities: mandatory\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\e[1mverbose, -v\e[0m\n"
|
"\e[1mverbose, -v\e[0m\n"
|
||||||
" be verbose\n"
|
" be verbose\n"
|
||||||
" example: actually not an operation\n"
|
" example: actually not an operation\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\e[1m--files, -f\e[0m\n"
|
"\e[1m--files, -f\e[0m\n"
|
||||||
" specifies the path of the file(s) to be opened\n"
|
" specifies the path of the file(s) to be opened\n"
|
||||||
" \e[1m--sub\e[0m\n"
|
" \e[1m--sub\e[0m\n"
|
||||||
" sub arg\n"
|
" sub arg\n"
|
||||||
" particularities: mandatory if parent argument is present\n"
|
" particularities: mandatory if parent argument is present\n"
|
||||||
" \e[1m--nested-sub\e[0m [value1] [value2] ...\n"
|
" \e[1m--nested-sub\e[0m [value1] [value2] ...\n"
|
||||||
" nested sub arg\n"
|
" nested sub arg\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\e[1m--env\e[0m [file] [value 2]\n"
|
"\e[1m--env\e[0m [file] [value 2]\n"
|
||||||
" env\n"
|
" env\n"
|
||||||
" default environment variable: FILES\n"
|
" default environment variable: FILES\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Project website: " APP_URL "\n");
|
"Project website: " APP_URL "\n");
|
||||||
parser.parseArgs(2, argv);
|
parser.parseArgs(2, argv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
#ifndef TESTUTILS_OUTPUTCHECK_H
|
||||||
|
#define TESTUTILS_OUTPUTCHECK_H
|
||||||
|
|
||||||
|
#include "../conversion/stringbuilder.h"
|
||||||
|
|
||||||
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace TestUtilities {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The StandardOutputCheck class asserts whether the (standard) output written in the enclosing code block
|
||||||
|
* matches the expected output.
|
||||||
|
*/
|
||||||
|
class OutputCheck {
|
||||||
|
public:
|
||||||
|
OutputCheck(const std::string &expectedOutput, std::ostream &os = std::cout);
|
||||||
|
OutputCheck(std::string &&expectedOutput, std::string &&alternativeOutput, std::ostream &os = std::cout);
|
||||||
|
OutputCheck(std::function<void(const std::string &output)> &&customCheck, std::ostream &os = std::cout);
|
||||||
|
~OutputCheck();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::ostream &m_os;
|
||||||
|
const std::function<void(const std::string &output)> m_customCheck;
|
||||||
|
const std::string m_expectedOutput;
|
||||||
|
const std::string m_alternativeOutput;
|
||||||
|
std::stringstream m_buffer;
|
||||||
|
std::streambuf *const m_regularOutputBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Redirects standard output to an internal buffer.
|
||||||
|
*/
|
||||||
|
inline OutputCheck::OutputCheck(const std::string &expectedOutput, std::ostream &os)
|
||||||
|
: m_os(os)
|
||||||
|
, m_expectedOutput(expectedOutput)
|
||||||
|
, m_buffer()
|
||||||
|
, m_regularOutputBuffer(os.rdbuf(m_buffer.rdbuf()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Redirects standard output to an internal buffer.
|
||||||
|
*/
|
||||||
|
inline OutputCheck::OutputCheck(std::string &&expectedOutput, std::string &&alternativeOutput, std::ostream &os)
|
||||||
|
: m_os(os)
|
||||||
|
, m_expectedOutput(expectedOutput)
|
||||||
|
, m_alternativeOutput(alternativeOutput)
|
||||||
|
, m_buffer()
|
||||||
|
, m_regularOutputBuffer(os.rdbuf(m_buffer.rdbuf()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Redirects standard output to an internal buffer.
|
||||||
|
*/
|
||||||
|
inline OutputCheck::OutputCheck(std::function<void(const std::string &)> &&customCheck, std::ostream &os)
|
||||||
|
: m_os(os)
|
||||||
|
, m_customCheck(customCheck)
|
||||||
|
, m_buffer()
|
||||||
|
, m_regularOutputBuffer(os.rdbuf(m_buffer.rdbuf()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Asserts the buffered standard output and restores the regular behaviour of std::cout.
|
||||||
|
*/
|
||||||
|
inline OutputCheck::~OutputCheck()
|
||||||
|
{
|
||||||
|
m_os.rdbuf(m_regularOutputBuffer);
|
||||||
|
if (m_customCheck) {
|
||||||
|
m_customCheck(m_buffer.str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_alternativeOutput.empty()) {
|
||||||
|
CPPUNIT_ASSERT_EQUAL(m_expectedOutput, m_buffer.str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const std::string actualOutput(m_buffer.str());
|
||||||
|
if (m_expectedOutput != actualOutput && m_alternativeOutput != actualOutput) {
|
||||||
|
using namespace ConversionUtilities;
|
||||||
|
CPPUNIT_FAIL("Output is not either \"" % m_expectedOutput % "\" or \"" % m_alternativeOutput % "\". Got instead:\n" + actualOutput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace TestUtilities
|
||||||
|
|
||||||
|
#endif // TESTUTILS_OUTPUTCHECK_H
|
Loading…
Reference in New Issue