Merge release-4-6 (commit 'Ic142a690')
[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 "cmdlinetest.h"
52
53 namespace
54 {
55
56 /********************************************************************
57  * MockModule
58  */
59
60 /*! \internal \brief
61  * Mock implementation of gmx::CommandLineModuleInterface.
62  *
63  * \ingroup module_commandline
64  */
65 class MockModule : public gmx::CommandLineModuleInterface
66 {
67     public:
68         //! Creates a mock module with the given name and description.
69         MockModule(const char *name, const char *description);
70
71         virtual const char *name() const { return name_; }
72         virtual const char *shortDescription() const { return descr_; }
73
74         MOCK_METHOD2(run, int(int argc, char *argv[]));
75
76     private:
77         const char             *name_;
78         const char             *descr_;
79 };
80
81 MockModule::MockModule(const char *name, const char *description)
82     : name_(name), descr_(description)
83 {
84 }
85
86 /********************************************************************
87  * Test fixture for the tests
88  */
89
90 class CommandLineModuleManagerTest : public ::testing::Test
91 {
92     public:
93         void initManager(const gmx::test::CommandLine &args);
94         MockModule &addModule(const char *name, const char *description);
95
96         gmx::CommandLineModuleManager &manager() { return *manager_; }
97
98     private:
99         boost::scoped_ptr<gmx::ProgramInfo>              programInfo_;
100         boost::scoped_ptr<gmx::CommandLineModuleManager> manager_;
101 };
102
103 void CommandLineModuleManagerTest::initManager(const gmx::test::CommandLine &args)
104 {
105     manager_.reset();
106     programInfo_.reset(new gmx::ProgramInfo("g_test", args.argc(), args.argv()));
107     manager_.reset(new gmx::CommandLineModuleManager(*programInfo_));
108 }
109
110 MockModule &
111 CommandLineModuleManagerTest::addModule(const char *name, const char *description)
112 {
113     MockModule *module = new MockModule(name, description);
114     manager().addModule(gmx::CommandLineModulePointer(module));
115     return *module;
116 }
117
118 /********************************************************************
119  * Actual tests
120  */
121
122 TEST_F(CommandLineModuleManagerTest, RunsModule)
123 {
124     const char *const cmdline[] = {
125         "g_test", "module", "-flag", "yes"
126     };
127     gmx::test::CommandLine args(cmdline);
128     initManager(args);
129     MockModule &mod1 = addModule("module", "First module");
130     addModule("other", "Second module");
131     using ::testing::_;
132     using ::testing::Args;
133     using ::testing::ElementsAreArray;
134     EXPECT_CALL(mod1, run(_, _))
135         .With(Args<1, 0>(ElementsAreArray(args.argv() + 1, args.argc() - 1)));
136     int rc = 0;
137     ASSERT_NO_THROW(rc = manager().run(args.argc(), args.argv()));
138     ASSERT_EQ(0, rc);
139 }
140
141 TEST_F(CommandLineModuleManagerTest, RunsModuleBasedOnBinaryName)
142 {
143     const char *const cmdline[] = {
144         "g_module", "-flag", "yes"
145     };
146     gmx::test::CommandLine args(cmdline);
147     initManager(args);
148     MockModule &mod1 = addModule("module", "First module");
149     addModule("other", "Second module");
150     using ::testing::_;
151     using ::testing::Args;
152     using ::testing::ElementsAreArray;
153     EXPECT_CALL(mod1, run(_, _))
154         .With(Args<1, 0>(ElementsAreArray(args.argv(), args.argc())));
155     int rc = 0;
156     ASSERT_NO_THROW(rc = manager().run(args.argc(), args.argv()));
157     ASSERT_EQ(0, rc);
158 }
159
160 TEST_F(CommandLineModuleManagerTest, RunsModuleBasedOnBinaryNameWithPathAndSuffix)
161 {
162     const char *const cmdline[] = {
163         "/usr/local/gromacs/bin/g_module" GMX_BINARY_SUFFIX ".exe", "-flag", "yes"
164     };
165     gmx::test::CommandLine args(cmdline);
166     initManager(args);
167     MockModule &mod1 = addModule("module", "First module");
168     addModule("other", "Second module");
169     using ::testing::_;
170     using ::testing::Args;
171     using ::testing::ElementsAreArray;
172     EXPECT_CALL(mod1, run(_, _))
173         .With(Args<1, 0>(ElementsAreArray(args.argv(), args.argc())));
174     int rc = 0;
175     ASSERT_NO_THROW(rc = manager().run(args.argc(), args.argv()));
176     ASSERT_EQ(0, rc);
177 }
178
179 TEST_F(CommandLineModuleManagerTest, HandlesConflictingBinaryAndModuleNames)
180 {
181     const char *const cmdline[] = {
182         "g_test", "test", "-flag", "yes"
183     };
184     gmx::test::CommandLine args(cmdline);
185     initManager(args);
186     MockModule &mod1 = addModule("test", "Test module");
187     addModule("other", "Second module");
188     using ::testing::_;
189     using ::testing::Args;
190     using ::testing::ElementsAreArray;
191     EXPECT_CALL(mod1, run(_, _))
192         .With(Args<1, 0>(ElementsAreArray(args.argv() + 1, args.argc() - 1)));
193     int rc = 0;
194     ASSERT_NO_THROW(rc = manager().run(args.argc(), args.argv()));
195     ASSERT_EQ(0, rc);
196 }
197
198 } // namespace