}
//! Creates an implementation class from a low-level context.
explicit Impl(const HelpWriterContext &writerContext)
- : writerContext_(writerContext), bHidden_(false)
+ : writerContext_(writerContext),
+ completionWriter_(NULL), bHidden_(false)
{
}
const CommandLineModuleInterface *moduleOverride_;
bool bHidden_;
+ File *outputOverride_;
+
GMX_DISALLOW_COPY_AND_ASSIGN(CommandLineHelpModuleImpl);
};
const CommandLineModuleGroupList &groups)
: rootTopic_(new RootHelpTopic), programContext_(programContext),
binaryName_(binaryName), modules_(modules), groups_(groups),
- context_(NULL), moduleOverride_(NULL), bHidden_(false)
+ context_(NULL), moduleOverride_(NULL), bHidden_(false),
+ outputOverride_(NULL)
{
}
impl_->moduleOverride_ = &module;
}
+void CommandLineHelpModule::setOutputRedirect(File *output)
+{
+ impl_->outputOverride_ = output;
+}
+
int CommandLineHelpModule::run(int argc, char *argv[])
{
// Add internal topics lazily here.
return 0;
}
+ File *outputFile = &File::standardOutput();
+ if (impl_->outputOverride_ != NULL)
+ {
+ outputFile = impl_->outputOverride_;
+ }
HelpLinks links(eHelpOutputFormat_Console);
initProgramLinks(&links, *impl_);
boost::scoped_ptr<CommandLineHelpContext> context(
- new CommandLineHelpContext(&File::standardOutput(),
+ new CommandLineHelpContext(outputFile,
eHelpOutputFormat_Console, &links));
context->setShowHidden(impl_->bHidden_);
if (impl_->moduleOverride_ != NULL)
{
class CommandLineHelpContext;
+class File;
class Options;
class ProgramContextInterface;
*/
void setModuleOverride(const CommandLineModuleInterface &module);
+ /*! \brief
+ * Sets a file to write help output to instead of default `stdout`.
+ *
+ * Used for unit testing; see
+ * CommandLineModuleManager::setOutputRedirect() for more details.
+ */
+ void setOutputRedirect(File *output);
+
virtual const char *name() const { return "help"; }
virtual const char *shortDescription() const
{
impl_->bQuiet_ = bQuiet;
}
+void CommandLineModuleManager::setOutputRedirect(File *output)
+{
+ impl_->ensureHelpModuleExists();
+ impl_->helpModule_->setOutputRedirect(output);
+}
+
void CommandLineModuleManager::setSingleModule(CommandLineModuleInterface *module)
{
impl_->singleModule_ = module;
class CommandLineModuleGroupData;
class CommandLineModuleInterface;
class CommandLineProgramContext;
+class File;
//! \addtogroup module_commandline
//! \{
*
* \param[in] bQuiet Whether the module manager should remain silent.
*
- * Normally, the module manager prints out some information to stderr
+ * Normally, the module manager prints out some information to `stderr`
* before it starts the module and after it finishes. This removes
* that output, which is useful in particular for unit tests so that
- * they don't spam stderr.
+ * they don't spam `stderr`.
*/
void setQuiet(bool bQuiet);
+ /*! \brief
+ * Redirects the output of the module manager to a file.
+ *
+ * \param[in] output File to write the output to.
+ *
+ * Normally, the module manager prints explicitly requested text such
+ * as help output to `stdout`, but this method can be used to redirect
+ * that output to a file. This is used for unit tests, either to keep
+ * them quiet or to verify that output. To keep implementation options
+ * open, behavior with `output == NULL` is undefined and should not be
+ * relied on. For tests, there should only be need to call this a
+ * single time, right after creating the manager.
+ */
+ void setOutputRedirect(File *output);
/*! \brief
* Makes the manager always run a single module.
#include "gromacs/commandline/cmdlinemodule.h"
#include "gromacs/commandline/cmdlinemodulemanager.h"
#include "gromacs/commandline/cmdlineprogramcontext.h"
+#include "gromacs/utility/file.h"
#include "gromacs/onlinehelp/tests/mock_helptopic.h"
#include "testutils/cmdlinetest.h"
#include "testutils/testasserts.h"
+#include "testutils/testfilemanager.h"
namespace
{
gmx::CommandLineModuleManager &manager() { return *manager_; }
+ void ignoreManagerOutput();
+
private:
boost::scoped_ptr<gmx::CommandLineProgramContext> programContext_;
boost::scoped_ptr<gmx::CommandLineModuleManager> manager_;
+ gmx::test::TestFileManager fileManager_;
+ boost::scoped_ptr<gmx::File> outputFile_;
};
void CommandLineModuleManagerTest::initManager(
return *topic;
}
+void CommandLineModuleManagerTest::ignoreManagerOutput()
+{
+ outputFile_.reset(
+ new gmx::File(fileManager_.getTemporaryFilePath("out.txt"), "w"));
+ manager().setOutputRedirect(outputFile_.get());
+}
+
/********************************************************************
* Actual tests
*/
+TEST_F(CommandLineModuleManagerTest, RunsGeneralHelp)
+{
+ const char *const cmdline[] = {
+ "test"
+ };
+ CommandLine args(cmdline);
+ initManager(args, "test");
+ ignoreManagerOutput();
+ addModule("module", "First module");
+ addModule("other", "Second module");
+ int rc = 0;
+ ASSERT_NO_THROW_GMX(rc = manager().run(args.argc(), args.argv()));
+ ASSERT_EQ(0, rc);
+}
+
TEST_F(CommandLineModuleManagerTest, RunsModule)
{
const char *const cmdline[] = {