Improve gmx::test::CommandLine.
[alexxy/gromacs.git] / src / gromacs / commandline / tests / cmdlinemodulemanager.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief
33  * Tests gmx::CommandLineModuleManager.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \ingroup module_commandline
37  */
38 // For GMX_BINARY_SUFFIX
39 #ifdef HAVE_CONFIG_H
40 #include "config.h"
41 #endif
42
43 #include <vector>
44
45 #include <gmock/gmock.h>
46
47 #include "gromacs/commandline/cmdlinemodule.h"
48 #include "gromacs/commandline/cmdlinemodulemanager.h"
49 #include "gromacs/utility/programinfo.h"
50
51 #include "testutils/cmdlinetest.h"
52
53 namespace
54 {
55
56 using gmx::test::CommandLine;
57
58 /********************************************************************
59  * MockModule
60  */
61
62 /*! \internal \brief
63  * Mock implementation of gmx::CommandLineModuleInterface.
64  *
65  * \ingroup module_commandline
66  */
67 class MockModule : public gmx::CommandLineModuleInterface
68 {
69     public:
70         //! Creates a mock module with the given name and description.
71         MockModule(const char *name, const char *description);
72
73         virtual const char *name() const { return name_; }
74         virtual const char *shortDescription() const { return descr_; }
75
76         MOCK_METHOD2(run, int(int argc, char *argv[]));
77
78     private:
79         const char             *name_;
80         const char             *descr_;
81 };
82
83 MockModule::MockModule(const char *name, const char *description)
84     : name_(name), descr_(description)
85 {
86 }
87
88 /********************************************************************
89  * Test fixture for the tests
90  */
91
92 class CommandLineModuleManagerTest : public ::testing::Test
93 {
94     public:
95         void initManager(const CommandLine &args);
96         MockModule &addModule(const char *name, const char *description);
97
98         gmx::CommandLineModuleManager &manager() { return *manager_; }
99
100     private:
101         boost::scoped_ptr<gmx::ProgramInfo>              programInfo_;
102         boost::scoped_ptr<gmx::CommandLineModuleManager> manager_;
103 };
104
105 void CommandLineModuleManagerTest::initManager(const CommandLine &args)
106 {
107     manager_.reset();
108     programInfo_.reset(new gmx::ProgramInfo("g_test", args.argc(), args.argv()));
109     manager_.reset(new gmx::CommandLineModuleManager(*programInfo_));
110 }
111
112 MockModule &
113 CommandLineModuleManagerTest::addModule(const char *name, const char *description)
114 {
115     MockModule *module = new MockModule(name, description);
116     manager().addModule(gmx::CommandLineModulePointer(module));
117     return *module;
118 }
119
120 /********************************************************************
121  * Actual tests
122  */
123
124 TEST_F(CommandLineModuleManagerTest, RunsModule)
125 {
126     const char *const cmdline[] = {
127         "g_test", "module", "-flag", "yes"
128     };
129     CommandLine args(CommandLine::create(cmdline));
130     initManager(args);
131     MockModule &mod1 = addModule("module", "First module");
132     addModule("other", "Second module");
133     using ::testing::_;
134     using ::testing::Args;
135     using ::testing::ElementsAreArray;
136     EXPECT_CALL(mod1, run(_, _))
137         .With(Args<1, 0>(ElementsAreArray(args.argv() + 1, args.argc() - 1)));
138     int rc = 0;
139     ASSERT_NO_THROW(rc = manager().run(args.argc(), args.argv()));
140     ASSERT_EQ(0, rc);
141 }
142
143 TEST_F(CommandLineModuleManagerTest, RunsModuleBasedOnBinaryName)
144 {
145     const char *const cmdline[] = {
146         "g_module", "-flag", "yes"
147     };
148     CommandLine args(CommandLine::create(cmdline));
149     initManager(args);
150     MockModule &mod1 = addModule("module", "First module");
151     addModule("other", "Second module");
152     using ::testing::_;
153     using ::testing::Args;
154     using ::testing::ElementsAreArray;
155     EXPECT_CALL(mod1, run(_, _))
156         .With(Args<1, 0>(ElementsAreArray(args.argv(), args.argc())));
157     int rc = 0;
158     ASSERT_NO_THROW(rc = manager().run(args.argc(), args.argv()));
159     ASSERT_EQ(0, rc);
160 }
161
162 TEST_F(CommandLineModuleManagerTest, RunsModuleBasedOnBinaryNameWithPathAndSuffix)
163 {
164     const char *const cmdline[] = {
165         "/usr/local/gromacs/bin/g_module" GMX_BINARY_SUFFIX ".exe", "-flag", "yes"
166     };
167     CommandLine args(CommandLine::create(cmdline));
168     initManager(args);
169     MockModule &mod1 = addModule("module", "First module");
170     addModule("other", "Second module");
171     using ::testing::_;
172     using ::testing::Args;
173     using ::testing::ElementsAreArray;
174     EXPECT_CALL(mod1, run(_, _))
175         .With(Args<1, 0>(ElementsAreArray(args.argv(), args.argc())));
176     int rc = 0;
177     ASSERT_NO_THROW(rc = manager().run(args.argc(), args.argv()));
178     ASSERT_EQ(0, rc);
179 }
180
181 TEST_F(CommandLineModuleManagerTest, HandlesConflictingBinaryAndModuleNames)
182 {
183     const char *const cmdline[] = {
184         "g_test", "test", "-flag", "yes"
185     };
186     CommandLine args(CommandLine::create(cmdline));
187     initManager(args);
188     MockModule &mod1 = addModule("test", "Test module");
189     addModule("other", "Second module");
190     using ::testing::_;
191     using ::testing::Args;
192     using ::testing::ElementsAreArray;
193     EXPECT_CALL(mod1, run(_, _))
194         .With(Args<1, 0>(ElementsAreArray(args.argv() + 1, args.argc() - 1)));
195     int rc = 0;
196     ASSERT_NO_THROW(rc = manager().run(args.argc(), args.argv()));
197     ASSERT_EQ(0, rc);
198 }
199
200 } // namespace