Apply clang-format-11
[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,2016,2019,2020,2021, 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 gmx
56 {
57 namespace test
58 {
59 namespace
60 {
61
62 class InteractiveSession
63 {
64 public:
65     explicit InteractiveSession(ReferenceDataMode mode) :
66         data_(mode), helper_(data_.rootChecker()), nextInputLine_(0)
67     {
68     }
69
70     void addOutput(const char* output) { events_.emplace_back(WriteOutput, output); }
71     void addInputLine(const char* inputLine) { inputLines_.push_back(inputLine); }
72     void addReadInput() { events_.emplace_back(ReadInput, ""); }
73     void addInput(const char* inputLine)
74     {
75         addInputLine(inputLine);
76         addReadInput();
77     }
78     void addInputNoNewline(const char* inputLine)
79     {
80         addInputLine(inputLine);
81         helper_.setLastNewline(false);
82         events_.emplace_back(ReadInputNoNewline, "");
83     }
84
85     void run()
86     {
87         gmx::TextInputStream&  input  = helper_.inputStream();
88         gmx::TextOutputStream& output = helper_.outputStream();
89         helper_.setInputLines(inputLines_);
90         std::vector<Event>::const_iterator event;
91         for (event = events_.begin(); event != events_.end(); ++event)
92         {
93             if (event->first == WriteOutput)
94             {
95                 output.write(event->second);
96             }
97             else
98             {
99                 std::string expectedLine;
100                 const bool  bInputRemaining = (nextInputLine_ < inputLines_.size());
101                 if (bInputRemaining)
102                 {
103                     expectedLine = inputLines_[nextInputLine_];
104                     if (event->first != ReadInputNoNewline)
105                     {
106                         expectedLine.append("\n");
107                     }
108                 }
109                 ++nextInputLine_;
110                 std::string line;
111                 EXPECT_EQ(bInputRemaining, input.readLine(&line));
112                 EXPECT_EQ(expectedLine, line);
113             }
114         }
115         helper_.checkSession();
116     }
117
118 private:
119     enum EventType
120     {
121         ReadInput,
122         ReadInputNoNewline,
123         WriteOutput
124     };
125     // The latter is the output string.
126     typedef std::pair<EventType, const char*> Event;
127
128     TestReferenceData        data_;
129     InteractiveTestHelper    helper_;
130     std::vector<const char*> inputLines_;
131     size_t                   nextInputLine_;
132     std::vector<Event>       events_;
133 };
134
135 TEST(InteractiveTestHelperTest, ChecksSimpleSession)
136 {
137     {
138         InteractiveSession session(ReferenceDataMode::UpdateAll);
139         session.addOutput("First line\n");
140         session.addOutput("> ");
141         session.addInput("input");
142         session.addOutput("Second line\n");
143         session.addOutput("> ");
144         session.addReadInput();
145         session.addOutput("\n");
146         session.addOutput(".\n");
147         session.run();
148     }
149     {
150         InteractiveSession session(ReferenceDataMode::Compare);
151         session.addOutput("First line\n");
152         session.addOutput("> ");
153         session.addInput("input");
154         session.addOutput("Second line\n");
155         session.addOutput("> ");
156         session.addReadInput();
157         session.addOutput("\n");
158         session.addOutput(".\n");
159         session.run();
160     }
161 }
162
163 TEST(InteractiveTestHelperTest, ChecksSessionWithoutLastNewline)
164 {
165     {
166         InteractiveSession session(ReferenceDataMode::UpdateAll);
167         session.addOutput("First line\n");
168         session.addOutput("> ");
169         session.addInput("input");
170         session.addOutput("Second line\n");
171         session.addOutput("> ");
172         session.addInputNoNewline("input2");
173         session.addOutput("\n");
174         session.addOutput(".\n");
175         session.run();
176     }
177     {
178         InteractiveSession session(ReferenceDataMode::Compare);
179         session.addOutput("First line\n");
180         session.addOutput("> ");
181         session.addInput("input");
182         session.addOutput("Second line\n");
183         session.addOutput("> ");
184         session.addInputNoNewline("input2");
185         session.addOutput("\n");
186         session.addOutput(".\n");
187         session.run();
188     }
189 }
190
191 TEST(InteractiveTestHelperTest, ChecksSessionWithMissingOutput)
192 {
193     {
194         InteractiveSession session(ReferenceDataMode::UpdateAll);
195         session.addOutput("First line\n> ");
196         session.addInput("input");
197         session.addInput("input2");
198         session.addOutput("Second line\n> ");
199         session.addReadInput();
200         session.addOutput("\n.\n");
201         session.run();
202     }
203     {
204         InteractiveSession session(ReferenceDataMode::Compare);
205         session.addOutput("First line\n> ");
206         session.addInput("input");
207         session.addInput("input2");
208         session.addOutput("Second line\n> ");
209         session.addReadInput();
210         session.addOutput("\n.\n");
211         session.run();
212     }
213 }
214
215 TEST(InteractiveTestHelperTest, ChecksSessionWithEquivalentOutput)
216 {
217     {
218         InteractiveSession session(ReferenceDataMode::UpdateAll);
219         session.addOutput("First line\n");
220         session.addOutput("> ");
221         session.addInput("input");
222         session.addOutput("Second line\n> ");
223         session.addReadInput();
224         session.addOutput("\n");
225         session.addOutput(".\n");
226         session.run();
227     }
228     {
229         InteractiveSession session(ReferenceDataMode::Compare);
230         session.addOutput("First line\n> ");
231         session.addInput("input");
232         session.addOutput("Second line\n");
233         session.addOutput("> ");
234         session.addReadInput();
235         session.addOutput("\n.\n");
236         session.run();
237     }
238 }
239
240 TEST(InteractiveTestHelperTest, DetectsIncorrectOutput)
241 {
242     {
243         InteractiveSession session(ReferenceDataMode::UpdateAll);
244         session.addOutput("First line\n> ");
245         session.addInput("input");
246         session.addOutput("Second line\n> ");
247         session.addReadInput();
248         session.addOutput("\n.\n");
249         session.run();
250     }
251     {
252         InteractiveSession session(ReferenceDataMode::Compare);
253         session.addOutput("First line\n> ");
254         session.addInput("input");
255         session.addOutput("Incorrect line\n> ");
256         session.addReadInput();
257         session.addOutput("\n.\n");
258         EXPECT_NONFATAL_FAILURE(session.run(), "");
259     }
260 }
261
262 TEST(InteractiveTestHelperTest, DetectsMissingOutput)
263 {
264     {
265         InteractiveSession session(ReferenceDataMode::UpdateAll);
266         session.addOutput("First line\n> ");
267         session.addInput("input");
268         session.addOutput("Second line\n> ");
269         session.addInput("input2");
270         session.addOutput("Third line\n> ");
271         session.addReadInput();
272         session.addOutput("\n.\n");
273         session.run();
274     }
275     {
276         InteractiveSession session(ReferenceDataMode::Compare);
277         session.addOutput("First line\n> ");
278         session.addInput("input");
279         session.addInput("input2");
280         session.addOutput("Third line\n> ");
281         session.addReadInput();
282         session.addOutput("\n.\n");
283         EXPECT_NONFATAL_FAILURE(session.run(), "");
284     }
285 }
286
287 TEST(InteractiveTestHelperTest, DetectsMissingFinalOutput)
288 {
289     {
290         InteractiveSession session(ReferenceDataMode::UpdateAll);
291         session.addOutput("First line\n> ");
292         session.addInput("input");
293         session.addOutput("Second line\n> ");
294         session.addReadInput();
295         session.addOutput("\n.\n");
296         session.run();
297     }
298     {
299         InteractiveSession session(ReferenceDataMode::Compare);
300         session.addOutput("First line\n> ");
301         session.addInput("input");
302         session.addOutput("Second line\n> ");
303         session.addReadInput();
304         EXPECT_NONFATAL_FAILURE(session.run(), "");
305     }
306 }
307
308 TEST(InteractiveTestHelperTest, DetectsExtraOutput)
309 {
310     {
311         InteractiveSession session(ReferenceDataMode::UpdateAll);
312         session.addOutput("First line\n> ");
313         session.addInput("input");
314         session.addInput("input2");
315         session.addOutput("More output\n> ");
316         session.addReadInput();
317         session.addOutput("\n.\n");
318         session.run();
319     }
320     {
321         InteractiveSession session(ReferenceDataMode::Compare);
322         session.addOutput("First line\n> ");
323         session.addInput("input");
324         session.addOutput("Extra output\n> ");
325         session.addInput("input2");
326         session.addOutput("More output\n> ");
327         session.addReadInput();
328         session.addOutput("\n.\n");
329         EXPECT_NONFATAL_FAILURE(session.run(), "");
330     }
331 }
332
333 TEST(InteractiveTestHelperTest, DetectsMissingInput)
334 {
335     {
336         InteractiveSession session(ReferenceDataMode::UpdateAll);
337         session.addInput("input");
338         session.addInput("input2");
339         session.addReadInput();
340         session.run();
341     }
342     {
343         InteractiveSession session(ReferenceDataMode::Compare);
344         session.addInputLine("input");
345         session.addInputLine("input2");
346         session.addReadInput();
347         session.addReadInput();
348         EXPECT_NONFATAL_FAILURE(session.run(), "");
349     }
350 }
351
352 TEST(InteractiveTestHelperTest, DetectsExtraInput)
353 {
354     {
355         InteractiveSession session(ReferenceDataMode::UpdateAll);
356         session.addInput("input");
357         session.addInput("input2");
358         session.addReadInput();
359         session.run();
360     }
361     {
362         InteractiveSession session(ReferenceDataMode::Compare);
363         session.addInputLine("input");
364         session.addInputLine("input2");
365         session.addReadInput();
366         session.addReadInput();
367         session.addReadInput();
368         session.addReadInput();
369         EXPECT_NONFATAL_FAILURE(session.run(), "");
370     }
371 }
372
373 } // namespace
374 } // namespace test
375 } // namespace gmx