Tests for interactive selection input
[alexxy/gromacs.git] / src / testutils / tests / interactivetest.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2015, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \internal \file
36  * \brief
37  * Self-tests for interactive test helpers.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \ingroup module_testutils
41  */
42 #include "gmxpre.h"
43
44 #include "testutils/interactivetest.h"
45
46 #include <vector>
47
48 #include <gtest/gtest.h>
49 #include <gtest/gtest-spi.h>
50
51 #include "gromacs/utility/textstream.h"
52
53 #include "testutils/refdata.h"
54
55 namespace
56 {
57
58 class InteractiveSession
59 {
60     public:
61         InteractiveSession(gmx::test::ReferenceDataMode mode)
62             : data_(mode), helper_(data_.rootChecker()), nextInputLine_(0)
63         {
64         }
65
66         void addOutput(const char *output)
67         {
68             events_.push_back(Event(WriteOutput, output));
69         }
70         void addInputLine(const char *inputLine)
71         {
72             inputLines_.push_back(inputLine);
73         }
74         void addReadInput()
75         {
76             events_.push_back(Event(ReadInput, ""));
77         }
78         void addInput(const char *inputLine)
79         {
80             addInputLine(inputLine);
81             addReadInput();
82         }
83         void addInputNoNewline(const char *inputLine)
84         {
85             addInputLine(inputLine);
86             helper_.setLastNewline(false);
87             events_.push_back(Event(ReadInputNoNewline, ""));
88         }
89
90         void run()
91         {
92             gmx::TextInputStream              &input  = helper_.inputStream();
93             gmx::TextOutputStream             &output = helper_.outputStream();
94             helper_.setInputLines(inputLines_);
95             std::vector<Event>::const_iterator event;
96             for (event = events_.begin(); event != events_.end(); ++event)
97             {
98                 if (event->first == WriteOutput)
99                 {
100                     output.write(event->second);
101                 }
102                 else
103                 {
104                     std::string expectedLine;
105                     const bool  bInputRemaining = (nextInputLine_ < inputLines_.size());
106                     if (bInputRemaining)
107                     {
108                         expectedLine = inputLines_[nextInputLine_];
109                         if (event->first != ReadInputNoNewline)
110                         {
111                             expectedLine.append("\n");
112                         }
113                     }
114                     ++nextInputLine_;
115                     std::string line;
116                     EXPECT_EQ(bInputRemaining, input.readLine(&line));
117                     EXPECT_EQ(expectedLine, line);
118                 }
119             }
120             helper_.checkSession();
121         }
122
123     private:
124         enum EventType
125         {
126             ReadInput,
127             ReadInputNoNewline,
128             WriteOutput
129         };
130         // The latter is the output string.
131         typedef std::pair<EventType, const char *> Event;
132
133         gmx::test::TestReferenceData     data_;
134         gmx::test::InteractiveTestHelper helper_;
135         std::vector<const char *>        inputLines_;
136         size_t                           nextInputLine_;
137         std::vector<Event>               events_;
138 };
139
140 TEST(InteractiveTestHelperTest, ChecksSimpleSession)
141 {
142     {
143         InteractiveSession session(gmx::test::erefdataUpdateAll);
144         session.addOutput("First line\n");
145         session.addOutput("> ");
146         session.addInput("input");
147         session.addOutput("Second line\n");
148         session.addOutput("> ");
149         session.addReadInput();
150         session.addOutput("\n");
151         session.addOutput(".\n");
152         session.run();
153     }
154     {
155         InteractiveSession session(gmx::test::erefdataCompare);
156         session.addOutput("First line\n");
157         session.addOutput("> ");
158         session.addInput("input");
159         session.addOutput("Second line\n");
160         session.addOutput("> ");
161         session.addReadInput();
162         session.addOutput("\n");
163         session.addOutput(".\n");
164         session.run();
165     }
166 }
167
168 TEST(InteractiveTestHelperTest, ChecksSessionWithoutLastNewline)
169 {
170     {
171         InteractiveSession session(gmx::test::erefdataUpdateAll);
172         session.addOutput("First line\n");
173         session.addOutput("> ");
174         session.addInput("input");
175         session.addOutput("Second line\n");
176         session.addOutput("> ");
177         session.addInputNoNewline("input2");
178         session.addOutput("\n");
179         session.addOutput(".\n");
180         session.run();
181     }
182     {
183         InteractiveSession session(gmx::test::erefdataCompare);
184         session.addOutput("First line\n");
185         session.addOutput("> ");
186         session.addInput("input");
187         session.addOutput("Second line\n");
188         session.addOutput("> ");
189         session.addInputNoNewline("input2");
190         session.addOutput("\n");
191         session.addOutput(".\n");
192         session.run();
193     }
194 }
195
196 TEST(InteractiveTestHelperTest, ChecksSessionWithMissingOutput)
197 {
198     {
199         InteractiveSession session(gmx::test::erefdataUpdateAll);
200         session.addOutput("First line\n> ");
201         session.addInput("input");
202         session.addInput("input2");
203         session.addOutput("Second line\n> ");
204         session.addReadInput();
205         session.addOutput("\n.\n");
206         session.run();
207     }
208     {
209         InteractiveSession session(gmx::test::erefdataCompare);
210         session.addOutput("First line\n> ");
211         session.addInput("input");
212         session.addInput("input2");
213         session.addOutput("Second line\n> ");
214         session.addReadInput();
215         session.addOutput("\n.\n");
216         session.run();
217     }
218 }
219
220 TEST(InteractiveTestHelperTest, ChecksSessionWithEquivalentOutput)
221 {
222     {
223         InteractiveSession session(gmx::test::erefdataUpdateAll);
224         session.addOutput("First line\n");
225         session.addOutput("> ");
226         session.addInput("input");
227         session.addOutput("Second line\n> ");
228         session.addReadInput();
229         session.addOutput("\n");
230         session.addOutput(".\n");
231         session.run();
232     }
233     {
234         InteractiveSession session(gmx::test::erefdataCompare);
235         session.addOutput("First line\n> ");
236         session.addInput("input");
237         session.addOutput("Second line\n");
238         session.addOutput("> ");
239         session.addReadInput();
240         session.addOutput("\n.\n");
241         session.run();
242     }
243 }
244
245 TEST(InteractiveTestHelperTest, DetectsIncorrectOutput)
246 {
247     {
248         InteractiveSession session(gmx::test::erefdataUpdateAll);
249         session.addOutput("First line\n> ");
250         session.addInput("input");
251         session.addOutput("Second line\n> ");
252         session.addReadInput();
253         session.addOutput("\n.\n");
254         session.run();
255     }
256     {
257         InteractiveSession session(gmx::test::erefdataCompare);
258         session.addOutput("First line\n> ");
259         session.addInput("input");
260         session.addOutput("Incorrect line\n> ");
261         session.addReadInput();
262         session.addOutput("\n.\n");
263         EXPECT_NONFATAL_FAILURE(session.run(), "");
264     }
265 }
266
267 TEST(InteractiveTestHelperTest, DetectsMissingOutput)
268 {
269     {
270         InteractiveSession session(gmx::test::erefdataUpdateAll);
271         session.addOutput("First line\n> ");
272         session.addInput("input");
273         session.addOutput("Second line\n> ");
274         session.addInput("input2");
275         session.addOutput("Third line\n> ");
276         session.addReadInput();
277         session.addOutput("\n.\n");
278         session.run();
279     }
280     {
281         InteractiveSession session(gmx::test::erefdataCompare);
282         session.addOutput("First line\n> ");
283         session.addInput("input");
284         session.addInput("input2");
285         session.addOutput("Third line\n> ");
286         session.addReadInput();
287         session.addOutput("\n.\n");
288         EXPECT_NONFATAL_FAILURE(session.run(), "");
289     }
290 }
291
292 TEST(InteractiveTestHelperTest, DetectsMissingFinalOutput)
293 {
294     {
295         InteractiveSession session(gmx::test::erefdataUpdateAll);
296         session.addOutput("First line\n> ");
297         session.addInput("input");
298         session.addOutput("Second line\n> ");
299         session.addReadInput();
300         session.addOutput("\n.\n");
301         session.run();
302     }
303     {
304         InteractiveSession session(gmx::test::erefdataCompare);
305         session.addOutput("First line\n> ");
306         session.addInput("input");
307         session.addOutput("Second line\n> ");
308         session.addReadInput();
309         EXPECT_NONFATAL_FAILURE(session.run(), "");
310     }
311 }
312
313 TEST(InteractiveTestHelperTest, DetectsExtraOutput)
314 {
315     {
316         InteractiveSession session(gmx::test::erefdataUpdateAll);
317         session.addOutput("First line\n> ");
318         session.addInput("input");
319         session.addInput("input2");
320         session.addOutput("More output\n> ");
321         session.addReadInput();
322         session.addOutput("\n.\n");
323         session.run();
324     }
325     {
326         InteractiveSession session(gmx::test::erefdataCompare);
327         session.addOutput("First line\n> ");
328         session.addInput("input");
329         session.addOutput("Extra output\n> ");
330         session.addInput("input2");
331         session.addOutput("More output\n> ");
332         session.addReadInput();
333         session.addOutput("\n.\n");
334         EXPECT_NONFATAL_FAILURE(session.run(), "");
335     }
336 }
337
338 TEST(InteractiveTestHelperTest, DetectsMissingInput)
339 {
340     {
341         InteractiveSession session(gmx::test::erefdataUpdateAll);
342         session.addInput("input");
343         session.addInput("input2");
344         session.addReadInput();
345         session.run();
346     }
347     {
348         InteractiveSession session(gmx::test::erefdataCompare);
349         session.addInputLine("input");
350         session.addInputLine("input2");
351         session.addReadInput();
352         session.addReadInput();
353         EXPECT_NONFATAL_FAILURE(session.run(), "");
354     }
355 }
356
357 TEST(InteractiveTestHelperTest, DetectsExtraInput)
358 {
359     {
360         InteractiveSession session(gmx::test::erefdataUpdateAll);
361         session.addInput("input");
362         session.addInput("input2");
363         session.addReadInput();
364         session.run();
365     }
366     {
367         InteractiveSession session(gmx::test::erefdataCompare);
368         session.addInputLine("input");
369         session.addInputLine("input2");
370         session.addReadInput();
371         session.addReadInput();
372         session.addReadInput();
373         session.addReadInput();
374         EXPECT_NONFATAL_FAILURE(session.run(), "");
375     }
376 }
377
378 } // namespace