/*
+ * This file is part of the GROMACS molecular simulation package.
*
- * This source code is part of
+ * Copyright (c) 2010,2011,2012,2013,2014, 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.
*
- * G R O M A C S
+ * 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.
*
- * GROningen MAchine for Chemical Simulations
+ * 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.
*
- * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
- * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
- * Copyright (c) 2001-2009, The GROMACS development team,
- * check out http://www.gromacs.org for more information.
-
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * 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, 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 www.gromacs.org.
+ * 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 papers on the package - you can find them in the top README file.
- *
- * For more info, check our website at http://www.gromacs.org
+ * the research papers on the package. Check out http://www.gromacs.org.
*/
/*! \internal \file
* \brief
* These tests check that methods in storage objects are called properly in all
* situations, and also that the OptionStorageTemplate class behaves properly.
*
- * \author Teemu Murtola <teemu.murtola@cbr.su.se>
+ * \author Teemu Murtola <teemu.murtola@gmail.com>
* \ingroup module_options
*/
-#include <vector>
+#include "gmxpre.h"
+
#include <string>
+#include <vector>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "gromacs/options/abstractoption.h"
#include "gromacs/options/options.h"
-#include "gromacs/options/optionstoragetemplate.h"
#include "gromacs/options/optionsassigner.h"
+#include "gromacs/options/optionstoragetemplate.h"
#include "gromacs/utility/exceptions.h"
+
+#include "testutils/testasserts.h"
#include "testutils/testexceptions.h"
namespace
{
class MockOption;
+class MockOptionStorage;
-/*! \internal \brief
+class MockOptionInfo : public gmx::OptionInfo
+{
+ public:
+ //! Creates an option info object for the given option.
+ explicit MockOptionInfo(MockOptionStorage *option);
+
+ MockOptionStorage &option();
+};
+
+/*! \brief
* Mock implementation of an option storage class for unit testing.
*
* Provides facilities for checking that correct methods are called, and for
// using MyBase::addValue;
// using MyBase::commitValues;
// "using" is correct but MSVC gives error C2248. Workaround:
+ //! \copydoc gmx::OptionStorageTemplate::markAsSet()
void markAsSet()
{
MyBase::markAsSet();
}
+ //! \copydoc gmx::OptionStorageTemplate::addValue()
void addValue(const std::string &value)
{
MyBase::addValue(value);
}
+ //! \copydoc gmx::OptionStorageTemplate::commitValues()
void commitValues()
{
MyBase::commitValues();
}
+ virtual gmx::OptionInfo &optionInfo() { return info_; }
// These are not used.
- virtual gmx::OptionInfo &optionInfo()
- {
- GMX_THROW(gmx::test::TestException("Not implemented"));
- }
- virtual const char *typeString() const { return "mock"; }
- virtual std::string formatSingleValue(const std::string &/*value*/) const
+ virtual std::string typeString() const { return "mock"; }
+ virtual std::string formatSingleValue(const std::string & /*value*/) const
{
return "";
}
MOCK_METHOD1(convertValue, void(const std::string &value));
MOCK_METHOD1(processSetValues, void(ValueList *values));
MOCK_METHOD0(processAll, void());
+
+ private:
+ MockOptionInfo info_;
};
/*! \internal \brief
class MockOption : public gmx::OptionTemplate<std::string, MockOption>
{
public:
+ //! OptionInfo subclass corresponding to this option type.
+ typedef MockOptionInfo InfoType;
+
//! Initializes an option with the given name.
explicit MockOption(const char *name)
- : MyBase(name), storagePtr_(NULL)
+ : MyBase(name)
{
}
- //! Sets an output pointer to give access to the created storage object.
- MyClass &storageObject(MockOptionStorage **storagePtr)
- { storagePtr_ = storagePtr; return me(); }
-
private:
- virtual gmx::AbstractOptionStoragePointer createStorage() const
+ virtual gmx::AbstractOptionStorage *createStorage(
+ const gmx::OptionManagerContainer & /*managers*/) const
{
- MockOptionStorage *storage = new MockOptionStorage(*this);
- if (storagePtr_ != NULL)
- {
- *storagePtr_ = storage;
- }
- return gmx::AbstractOptionStoragePointer(storage);
+ return new MockOptionStorage(*this);
}
-
- MockOptionStorage **storagePtr_;
};
MockOptionStorage::MockOptionStorage(const MockOption &settings)
- : MyBase(settings)
+ : MyBase(settings), info_(this)
{
using ::testing::_;
using ::testing::Invoke;
.WillByDefault(WithArg<0>(Invoke(this, &MockOptionStorage::addValue)));
}
+MockOptionInfo::MockOptionInfo(MockOptionStorage *option)
+ : gmx::OptionInfo(option)
+{
+}
+
+MockOptionStorage &MockOptionInfo::option()
+{
+ return static_cast<MockOptionStorage &>(gmx::OptionInfo::option());
+}
+
/*
* Tests that finish() can set a required option even if the user has not
* provided it.
{
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
- MockOptionStorage *mock = NULL;
- ASSERT_NO_THROW(options.addOption(
- MockOption("name").storageObject(&mock).required()
- .storeVector(&values)));
- ASSERT_TRUE(mock != NULL);
+ MockOptionInfo *info = options.addOption(
+ MockOption("name").required().storeVector(&values));
+ MockOptionStorage *mock = &info->option();
{
::testing::InSequence dummy;
using ::testing::DoAll;
}
gmx::OptionsAssigner assigner(&options);
- EXPECT_NO_THROW(assigner.start());
- EXPECT_NO_THROW(assigner.finish());
- EXPECT_NO_THROW(options.finish());
+ EXPECT_NO_THROW_GMX(assigner.start());
+ EXPECT_NO_THROW_GMX(assigner.finish());
+ EXPECT_NO_THROW_GMX(options.finish());
ASSERT_EQ(1U, values.size());
EXPECT_EQ("dummy", values[0]);
{
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
- MockOptionStorage *mock = NULL;
- ASSERT_NO_THROW(options.addOption(
- MockOption("name").storageObject(&mock)
- .storeVector(&values).multiValue()));
- ASSERT_TRUE(mock != NULL);
+ MockOptionInfo *info = options.addOption(
+ MockOption("name").storeVector(&values).multiValue());
+ MockOptionStorage *mock = &info->option();
{
::testing::InSequence dummy;
using ::testing::ElementsAre;
}
gmx::OptionsAssigner assigner(&options);
- EXPECT_NO_THROW(assigner.start());
- ASSERT_NO_THROW(assigner.startOption("name"));
- EXPECT_NO_THROW(assigner.appendValue("a"));
- EXPECT_NO_THROW(assigner.appendValue("b"));
- EXPECT_NO_THROW(assigner.appendValue("c"));
- EXPECT_NO_THROW(assigner.finishOption());
- EXPECT_NO_THROW(assigner.finish());
- EXPECT_NO_THROW(options.finish());
+ EXPECT_NO_THROW_GMX(assigner.start());
+ ASSERT_NO_THROW_GMX(assigner.startOption("name"));
+ EXPECT_NO_THROW_GMX(assigner.appendValue("a"));
+ EXPECT_NO_THROW_GMX(assigner.appendValue("b"));
+ EXPECT_NO_THROW_GMX(assigner.appendValue("c"));
+ EXPECT_NO_THROW_GMX(assigner.finishOption());
+ EXPECT_NO_THROW_GMX(assigner.finish());
+ EXPECT_NO_THROW_GMX(options.finish());
ASSERT_EQ(2U, values.size());
EXPECT_EQ("a", values[0]);
{
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
- MockOptionStorage *mock = NULL;
- ASSERT_NO_THROW(options.addOption(
- MockOption("name").storageObject(&mock)
- .storeVector(&values).multiValue()));
- ASSERT_TRUE(mock != NULL);
+ MockOptionInfo *info = options.addOption(
+ MockOption("name").storeVector(&values).multiValue());
+ MockOptionStorage *mock = &info->option();
{
::testing::InSequence dummy;
using ::testing::DoAll;
}
gmx::OptionsAssigner assigner(&options);
- EXPECT_NO_THROW(assigner.start());
- ASSERT_NO_THROW(assigner.startOption("name"));
- EXPECT_NO_THROW(assigner.appendValue("a"));
- EXPECT_NO_THROW(assigner.appendValue("b"));
- EXPECT_NO_THROW(assigner.finishOption());
- EXPECT_NO_THROW(assigner.finish());
- EXPECT_NO_THROW(options.finish());
+ EXPECT_NO_THROW_GMX(assigner.start());
+ ASSERT_NO_THROW_GMX(assigner.startOption("name"));
+ EXPECT_NO_THROW_GMX(assigner.appendValue("a"));
+ EXPECT_NO_THROW_GMX(assigner.appendValue("b"));
+ EXPECT_NO_THROW_GMX(assigner.finishOption());
+ EXPECT_NO_THROW_GMX(assigner.finish());
+ EXPECT_NO_THROW_GMX(options.finish());
ASSERT_EQ(3U, values.size());
EXPECT_EQ("a", values[0]);
{
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
- MockOptionStorage *mock = NULL;
- ASSERT_NO_THROW(options.addOption(
- MockOption("name").storageObject(&mock)
- .storeVector(&values).valueCount(2)));
- ASSERT_TRUE(mock != NULL);
+ MockOptionInfo *info = options.addOption(
+ MockOption("name").storeVector(&values).valueCount(2));
+ MockOptionStorage *mock = &info->option();
{
::testing::InSequence dummy;
using ::testing::DoAll;
}
gmx::OptionsAssigner assigner(&options);
- EXPECT_NO_THROW(assigner.start());
- ASSERT_NO_THROW(assigner.startOption("name"));
- EXPECT_NO_THROW(assigner.appendValue("a"));
- EXPECT_THROW(assigner.appendValue("b"), gmx::InvalidInputError);
- EXPECT_NO_THROW(assigner.finishOption());
- EXPECT_NO_THROW(assigner.finish());
- EXPECT_NO_THROW(options.finish());
+ EXPECT_NO_THROW_GMX(assigner.start());
+ ASSERT_NO_THROW_GMX(assigner.startOption("name"));
+ EXPECT_NO_THROW_GMX(assigner.appendValue("a"));
+ EXPECT_THROW_GMX(assigner.appendValue("b"), gmx::InvalidInputError);
+ EXPECT_NO_THROW_GMX(assigner.finishOption());
+ EXPECT_NO_THROW_GMX(assigner.finish());
+ EXPECT_NO_THROW_GMX(options.finish());
ASSERT_TRUE(values.empty());
}
{
gmx::Options options(NULL, NULL);
std::vector<std::string> values;
- MockOptionStorage *mock = NULL;
- ASSERT_NO_THROW(options.addOption(
- MockOption("name").storageObject(&mock)
- .storeVector(&values).valueCount(0)));
- ASSERT_TRUE(mock != NULL);
+ MockOptionInfo *info = options.addOption(
+ MockOption("name").storeVector(&values).valueCount(0));
+ MockOptionStorage *mock = &info->option();
{
::testing::InSequence dummy;
using ::testing::DoAll;
}
gmx::OptionsAssigner assigner(&options);
- EXPECT_NO_THROW(assigner.start());
- EXPECT_NO_THROW(assigner.startOption("name"));
- EXPECT_NO_THROW(assigner.appendValue("a"));
- EXPECT_NO_THROW(assigner.finishOption());
- EXPECT_NO_THROW(assigner.finish());
- EXPECT_NO_THROW(options.finish());
+ EXPECT_NO_THROW_GMX(assigner.start());
+ EXPECT_NO_THROW_GMX(assigner.startOption("name"));
+ EXPECT_NO_THROW_GMX(assigner.appendValue("a"));
+ EXPECT_NO_THROW_GMX(assigner.finishOption());
+ EXPECT_NO_THROW_GMX(assigner.finish());
+ EXPECT_NO_THROW_GMX(options.finish());
ASSERT_EQ(0U, values.size());
}