Change naming convention for C++ interfaces
[alexxy/gromacs.git] / src / gromacs / analysisdata / tests / mock_datamodule.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2011,2012,2013,2014,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  * Implements classes in mock_datamodule.h.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \ingroup module_analysisdata
41  */
42 #include "gmxpre.h"
43
44 #include "mock_datamodule.h"
45
46 #include <gmock/gmock.h>
47 #include <gtest/gtest.h>
48
49 #include "gromacs/analysisdata/analysisdata.h"
50 #include "gromacs/analysisdata/dataframe.h"
51 #include "gromacs/utility/gmxassert.h"
52 #include "gromacs/utility/stringutil.h"
53
54 #include "gromacs/analysisdata/tests/datatest.h"
55 #include "testutils/refdata.h"
56 #include "testutils/testasserts.h"
57
58 namespace gmx
59 {
60 namespace test
61 {
62
63 /********************************************************************
64  * MockAnalysisDataModule::Impl
65  */
66
67 /*! \internal \brief
68  * Private implementation class for gmx::test::MockAnalysisDataModule.
69  *
70  * \ingroup module_analysisdata
71  */
72 class MockAnalysisDataModule::Impl
73 {
74     public:
75         //! Initializes a mock object with the given flags.
76         explicit Impl(int flags);
77
78         /*! \brief
79          * Callback used to initialize reference data checks
80          *
81          * Called in response to dataStarted().
82          * Records the source data for later use (for access to data properties).
83          */
84         void startReferenceData(AbstractAnalysisData *data);
85         /*! \brief
86          * Callback used to check frame start against reference data.
87          *
88          * Called to check parameters and order of calls to frameStarted().
89          * In addition to reference data checks, this method checks statically
90          * that the new frame matches \a frameIndex_.
91          */
92         void startReferenceFrame(const AnalysisDataFrameHeader &header);
93         /*! \brief
94          * Callback used to check frame points against reference data.
95          *
96          * Called to check parameters and order of calls to pointsAdded().
97          */
98         void checkReferencePoints(const AnalysisDataPointSetRef &points);
99         /*! \brief
100          * Callback used to check frame finish against reference data.
101          *
102          * Called to check parameters and order of calls to frameFinished().
103          */
104         void finishReferenceFrame(const AnalysisDataFrameHeader &header);
105         /*! \brief
106          * Callback used to check serial frame finish with reference data.
107          *
108          * Called to check parameters and order of calls to
109          * frameFinishedSerial().
110          * \a frameIndex_ is incremented here.
111          */
112         void finishReferenceFrameSerial(int frameIndex);
113
114         /*! \brief
115          * Reference data checker to use for checking frames.
116          *
117          * Must be non-NULL if startReferenceFrame() is called.
118          */
119         boost::scoped_ptr<TestReferenceChecker>  rootChecker_;
120         /*! \brief
121          * Reference data checker to use to check the current frame.
122          *
123          * Non-NULL between startReferenceFrame() and finishReferenceFrame()
124          * calls.
125          */
126         boost::scoped_ptr<TestReferenceChecker>  frameChecker_;
127         //! Source data.
128         const AbstractAnalysisData              *source_;
129         //! Flags that will be returned by the mock module.
130         int                                      flags_;
131         //! Index of the current/next frame.
132         int                                      frameIndex_;
133 };
134
135 namespace
136 {
137
138 /*! \internal \brief
139  * Checks a single AnalysisDataValue.
140  *
141  * \ingroup module_analysisdata
142  */
143 void checkReferenceDataPoint(TestReferenceChecker    *checker,
144                              const AnalysisDataValue &value)
145 {
146     TestReferenceChecker compound(checker->checkCompound("DataValue", NULL));
147     compound.checkReal(value.value(), "Value");
148     if (compound.checkPresent(value.hasError(), "Error"))
149     {
150         compound.checkReal(value.error(), "Error");
151     }
152     if (compound.checkPresent(!value.isPresent(), "Present"))
153     {
154         compound.checkBoolean(value.isPresent(), "Present");
155     }
156 }
157
158 }       // namespace
159
160 MockAnalysisDataModule::Impl::Impl(int flags)
161     : source_(NULL), flags_(flags), frameIndex_(0)
162 {
163 }
164
165
166 void
167 MockAnalysisDataModule::Impl::startReferenceData(AbstractAnalysisData *data)
168 {
169     source_ = data;
170 }
171
172
173 void
174 MockAnalysisDataModule::Impl::startReferenceFrame(
175         const AnalysisDataFrameHeader &header)
176 {
177     GMX_RELEASE_ASSERT(rootChecker_.get() != NULL,
178                        "Root checker not set, but reference data used");
179     EXPECT_TRUE(frameChecker_.get() == NULL);
180     EXPECT_EQ(frameIndex_, header.index());
181     frameChecker_.reset(new TestReferenceChecker(
182                                 rootChecker_->checkCompound("DataFrame",
183                                                             formatString("Frame%d", frameIndex_).c_str())));
184     frameChecker_->checkReal(header.x(), "X");
185 }
186
187
188 void
189 MockAnalysisDataModule::Impl::checkReferencePoints(
190         const AnalysisDataPointSetRef &points)
191 {
192     EXPECT_TRUE(frameChecker_.get() != NULL);
193     if (frameChecker_.get() != NULL)
194     {
195         TestReferenceChecker checker(
196                 frameChecker_->checkCompound("DataValues", NULL));
197         checker.checkInteger(points.columnCount(), "Count");
198         if (checker.checkPresent(source_->dataSetCount() > 1, "DataSet"))
199         {
200             checker.checkInteger(points.dataSetIndex(), "DataSet");
201         }
202         const int  sourceColumnCount = source_->columnCount(points.dataSetIndex());
203         const bool bAllColumns       = (points.firstColumn() == 0
204                                         && points.columnCount() == sourceColumnCount);
205         if (checker.checkPresent(!bAllColumns, "FirstColumn"))
206         {
207             checker.checkInteger(points.firstColumn(), "FirstColumn");
208             checker.checkInteger(points.lastColumn(),  "LastColumn");
209         }
210
211         AnalysisDataValuesRef::const_iterator value;
212         for (value = points.values().begin(); value != points.values().end(); ++value)
213         {
214             checkReferenceDataPoint(&checker, *value);
215         }
216     }
217 }
218
219
220 void
221 MockAnalysisDataModule::Impl::finishReferenceFrame(
222         const AnalysisDataFrameHeader &header)
223 {
224     EXPECT_TRUE(frameChecker_.get() != NULL);
225     EXPECT_EQ(frameIndex_, header.index());
226     frameChecker_.reset();
227 }
228
229
230 void
231 MockAnalysisDataModule::Impl::finishReferenceFrameSerial(int frameIndex)
232 {
233     EXPECT_TRUE(frameChecker_.get() == NULL);
234     EXPECT_EQ(frameIndex_, frameIndex);
235     ++frameIndex_;
236 }
237
238
239 /********************************************************************
240  * MockAnalysisDataModule
241  */
242
243 namespace
244 {
245
246 /*! \brief
247  * Helper function for checking the data frame header against static data.
248  *
249  * \param[in] header    Frame header to check.
250  * \param[in] refFrame  Data to check against.
251  */
252 void checkHeader(const AnalysisDataFrameHeader    &header,
253                  const AnalysisDataTestInputFrame &refFrame)
254 {
255     EXPECT_EQ(refFrame.index(), header.index());
256     EXPECT_FLOAT_EQ(refFrame.x(), header.x());
257     EXPECT_FLOAT_EQ(refFrame.dx(), header.dx());
258 }
259
260 /*! \brief
261  * Helper function for checking a point set against static data.
262  *
263  * \param[in] points       Point set to check.
264  * \param[in] refPoints    Data to check against.
265  * \param[in] columnOffset Offset of first column of \p points in \p refPoints.
266  */
267 void checkPoints(const AnalysisDataPointSetRef       &points,
268                  const AnalysisDataTestInputPointSet &refPoints,
269                  int                                  columnOffset)
270 {
271     for (int i = 0; i < points.columnCount(); ++i)
272     {
273         const int column = points.firstColumn() - refPoints.firstColumn() + i + columnOffset;
274         EXPECT_FLOAT_EQ(refPoints.y(column),
275                         points.y(i))
276         << "  Column: " << i+1 << " / " << points.columnCount()
277         << " (+" << points.firstColumn() << ")\n"
278         << "Ref. col: " << column+1 << " / " << refPoints.size()
279         << " (+" << refPoints.firstColumn() << ", offs " << columnOffset << ")";
280     }
281 }
282
283 /*! \brief
284  * Helper function for checking a full frame against static data.
285  *
286  * \param[in] frame     Frame to check.
287  * \param[in] refFrame  Data to check against.
288  */
289 void checkFrame(const AnalysisDataFrameRef       &frame,
290                 const AnalysisDataTestInputFrame &refFrame)
291 {
292     checkHeader(frame.header(), refFrame);
293     ASSERT_EQ(refFrame.pointSetCount(), frame.pointSetCount());
294     for (int i = 0; i < frame.pointSetCount(); ++i)
295     {
296         const AnalysisDataPointSetRef       &points    = frame.pointSet(i);
297         const AnalysisDataTestInputPointSet &refPoints = refFrame.pointSet(i);
298         EXPECT_EQ(refPoints.firstColumn(), points.firstColumn());
299         checkPoints(points, refPoints, 0);
300     }
301 }
302
303 /*! \brief
304  * Functor for checking data frame header against static test input data.
305  *
306  * This functor is designed to be invoked as a handled for
307  * IAnalysisDataModule::frameStarted().
308  */
309 class StaticDataFrameHeaderChecker
310 {
311     public:
312         /*! \brief
313          * Constructs a checker against a given input data frame.
314          *
315          * \param[in] frame Frame to check against.
316          *
317          * \p frame must exist for the lifetime of this object.
318          */
319         StaticDataFrameHeaderChecker(const AnalysisDataTestInputFrame *frame)
320             : frame_(frame)
321         {
322         }
323
324         //! Function call operator for the functor.
325         void operator()(const AnalysisDataFrameHeader &header) const
326         {
327             SCOPED_TRACE(formatString("Frame %d", frame_->index()));
328             checkHeader(header, *frame_);
329         }
330
331     private:
332         const AnalysisDataTestInputFrame *frame_;
333 };
334
335 /*! \brief
336  * Functor for checking data frame points against static test input data.
337  *
338  * This functor is designed to be invoked as a handled for
339  * IAnalysisDataModule::pointsAdded().
340  */
341 class StaticDataPointsChecker
342 {
343     public:
344         /*! \brief
345          * Constructs a checker against a given input data frame and point set.
346          *
347          * \param[in] frame    Frame to check against.
348          * \param[in] points   Point set in \p frame to check against.
349          * \param[in] firstcol Expected first column.
350          * \param[in] n        Expected number of columns.
351          *
352          * \p firstcol and \p n are used to create a checker that only expects
353          * to be called for a subset of columns.
354          * \p frame and \p points must exist for the lifetime of this object.
355          */
356         StaticDataPointsChecker(const AnalysisDataTestInputFrame *frame,
357                                 const AnalysisDataTestInputPointSet *points,
358                                 int firstcol, int n)
359             : frame_(frame), points_(points), firstcol_(firstcol), n_(n)
360         {
361         }
362
363         //! Function call operator for the functor.
364         void operator()(const AnalysisDataPointSetRef &points) const
365         {
366             SCOPED_TRACE(formatString("Frame %d, point set %d",
367                                       frame_->index(), points_->index()));
368             EXPECT_EQ(points_->dataSetIndex(), points.dataSetIndex());
369             const int expectedFirstColumn
370                 = std::max(0, points_->firstColumn() - firstcol_);
371             const int expectedLastColumn
372                 = std::min(n_ - 1, points_->lastColumn() - firstcol_);
373             EXPECT_EQ(expectedFirstColumn, points.firstColumn());
374             EXPECT_EQ(expectedLastColumn,  points.lastColumn());
375             checkHeader(points.header(), *frame_);
376             checkPoints(points, *points_, firstcol_);
377         }
378
379     private:
380         const AnalysisDataTestInputFrame    *frame_;
381         const AnalysisDataTestInputPointSet *points_;
382         int                                  firstcol_;
383         int                                  n_;
384 };
385
386 /*! \brief
387  * Functor for requesting data storage.
388  *
389  * This functor is designed to be invoked as a handled for
390  * IAnalysisDataModule::dataStarted().
391  */
392 class DataStorageRequester
393 {
394     public:
395         /*! \brief
396          * Constructs a functor that requests the given amount of storage.
397          *
398          * \param[in] count  Number of frames of storage to request, or
399          *      -1 for all frames.
400          *
401          * \see AbstractAnalysisData::requestStorage()
402          */
403         explicit DataStorageRequester(int count) : count_(count) {}
404
405         //! Function call operator for the functor.
406         void operator()(AbstractAnalysisData *data) const
407         {
408             EXPECT_TRUE(data->requestStorage(count_));
409         }
410
411     private:
412         int                     count_;
413 };
414
415 /*! \brief
416  * Functor for checking data frame points and storage against static test input
417  * data.
418  *
419  * This functor is designed to be invoked as a handled for
420  * IAnalysisDataModule::pointsAdded().
421  */
422 class StaticDataPointsStorageChecker
423 {
424     public:
425         /*! \brief
426          * Constructs a checker for a given frame.
427          *
428          * \param[in] source     Data object that is being checked.
429          * \param[in] data       Test input data to check against.
430          * \param[in] frameIndex Frame index for which this functor expects
431          *      to be called.
432          * \param[in] pointSetIndex Point set for which this functor expects
433          *      to be called.
434          * \param[in] storageCount How many past frames should be checked for
435          *      storage (-1 = check all frames).
436          *
437          * This checker works as StaticDataPointsChecker, but additionally
438          * checks that previous frames can be accessed using access methods
439          * in AbstractAnalysisData and that correct data is returned.
440          *
441          * \p source and \p data must exist for the lifetime of this object.
442          */
443         StaticDataPointsStorageChecker(AbstractAnalysisData        *source,
444                                        const AnalysisDataTestInput *data,
445                                        int frameIndex, int pointSetIndex,
446                                        int storageCount)
447             : source_(source), data_(data),
448               frameIndex_(frameIndex), pointSetIndex_(pointSetIndex),
449               storageCount_(storageCount)
450         {
451         }
452
453         //! Function call operator for the functor.
454         void operator()(const AnalysisDataPointSetRef &points) const
455         {
456             SCOPED_TRACE(formatString("Frame %d", frameIndex_));
457             const AnalysisDataTestInputFrame    &refFrame  = data_->frame(frameIndex_);
458             const AnalysisDataTestInputPointSet &refPoints = refFrame.pointSet(pointSetIndex_);
459             EXPECT_EQ(refPoints.firstColumn(), points.firstColumn());
460             EXPECT_EQ(refPoints.size(), points.columnCount());
461             checkHeader(points.header(), refFrame);
462             checkPoints(points, refPoints, 0);
463             for (int past = 1;
464                  (storageCount_ < 0 || past <= storageCount_) && past <= frameIndex_;
465                  ++past)
466             {
467                 int   index = frameIndex_ - past;
468                 SCOPED_TRACE(formatString("Checking storage of frame %d", index));
469                 ASSERT_NO_THROW_GMX({
470                                         AnalysisDataFrameRef frame = source_->getDataFrame(index);
471                                         ASSERT_TRUE(frame.isValid());
472                                         checkFrame(frame, data_->frame(index));
473                                     });
474             }
475         }
476
477     private:
478         AbstractAnalysisData        *source_;
479         const AnalysisDataTestInput *data_;
480         int                          frameIndex_;
481         int                          pointSetIndex_;
482         int                          storageCount_;
483 };
484
485 /*! \brief
486  * Sets the mock object expectation to mimick AnalysisDataModuleSerial.
487  *
488  * Makes MockAnalysisDataModule::parallelDataStarted() behave as if the mock
489  * object was an AnalysisDataModuleSerial object: forward the call to
490  * MockAnalysisDataModule::dataStarted() and return false.
491  */
492 void setSerialExpectationForParallelDataStarted(MockAnalysisDataModule *mock)
493 {
494     using ::testing::_;
495     using ::testing::AtMost;
496     using ::testing::DoAll;
497     using ::testing::Invoke;
498     using ::testing::Return;
499     using ::testing::WithArg;
500     EXPECT_CALL(*mock, parallelDataStarted(_, _))
501         .Times(AtMost(1))
502         .WillOnce(DoAll(WithArg<0>(Invoke(mock, &MockAnalysisDataModule::dataStarted)),
503                         Return(false)));
504 }
505
506 }       // anonymous namespace
507
508
509 MockAnalysisDataModule::MockAnalysisDataModule(int flags)
510     : impl_(new Impl(flags))
511 {
512 }
513
514
515 MockAnalysisDataModule::~MockAnalysisDataModule()
516 {
517 }
518
519
520 int MockAnalysisDataModule::flags() const
521 {
522     return impl_->flags_;
523 }
524
525
526 void
527 MockAnalysisDataModule::setupStaticCheck(const AnalysisDataTestInput &data,
528                                          AbstractAnalysisData        *source,
529                                          bool                         bParallel)
530 {
531     impl_->flags_ |= efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets;
532
533     using ::testing::_;
534     using ::testing::Invoke;
535     using ::testing::Property;
536     using ::testing::Return;
537
538     if (bParallel)
539     {
540         ::testing::Expectation init =
541             EXPECT_CALL(*this, parallelDataStarted(source, _))
542                 .WillOnce(Return(true));
543         ::testing::ExpectationSet framesFinished;
544         ::testing::Expectation    prevFinish;
545         for (int row = 0; row < data.frameCount(); ++row)
546         {
547             ::testing::InSequence frameSequence;
548             const AnalysisDataTestInputFrame &frame = data.frame(row);
549             EXPECT_CALL(*this, frameStarted(Property(&AnalysisDataFrameHeader::index, row)))
550                 .After(init)
551                 .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
552             for (int ps = 0; ps < frame.pointSetCount(); ++ps)
553             {
554                 const AnalysisDataTestInputPointSet &points = frame.pointSet(ps);
555                 StaticDataPointsChecker              checker(&frame, &points, 0,
556                                                              data.columnCount(points.dataSetIndex()));
557                 EXPECT_CALL(*this, pointsAdded(Property(&AnalysisDataPointSetRef::frameIndex, row)))
558                     .WillOnce(Invoke(checker));
559             }
560             EXPECT_CALL(*this, frameFinished(Property(&AnalysisDataFrameHeader::index, row)))
561                 .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
562             ::testing::Expectation finish;
563             if (row > 0)
564             {
565                 finish = EXPECT_CALL(*this, frameFinishedSerial(row))
566                         .After(prevFinish);
567             }
568             else
569             {
570                 finish = EXPECT_CALL(*this, frameFinishedSerial(row));
571             }
572             framesFinished += finish;
573             prevFinish      = finish;
574         }
575         EXPECT_CALL(*this, dataFinished())
576             .After(framesFinished);
577     }
578     else
579     {
580         ::testing::InSequence dummy;
581         setSerialExpectationForParallelDataStarted(this);
582         EXPECT_CALL(*this, dataStarted(source));
583         for (int row = 0; row < data.frameCount(); ++row)
584         {
585             const AnalysisDataTestInputFrame &frame = data.frame(row);
586             EXPECT_CALL(*this, frameStarted(_))
587                 .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
588             for (int ps = 0; ps < frame.pointSetCount(); ++ps)
589             {
590                 const AnalysisDataTestInputPointSet &points = frame.pointSet(ps);
591                 StaticDataPointsChecker              checker(&frame, &points, 0,
592                                                              data.columnCount(points.dataSetIndex()));
593                 EXPECT_CALL(*this, pointsAdded(_)).WillOnce(Invoke(checker));
594             }
595             EXPECT_CALL(*this, frameFinished(_))
596                 .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
597             EXPECT_CALL(*this, frameFinishedSerial(row));
598         }
599         EXPECT_CALL(*this, dataFinished());
600     }
601 }
602
603
604 void
605 MockAnalysisDataModule::setupStaticColumnCheck(
606         const AnalysisDataTestInput &data,
607         int firstcol, int n, AbstractAnalysisData * /*source*/)
608 {
609     impl_->flags_ |= efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets;
610
611     ::testing::InSequence dummy;
612     using ::testing::_;
613     using ::testing::Invoke;
614
615     setSerialExpectationForParallelDataStarted(this);
616     EXPECT_CALL(*this, dataStarted(_));
617     for (int row = 0; row < data.frameCount(); ++row)
618     {
619         const AnalysisDataTestInputFrame &frame = data.frame(row);
620         EXPECT_CALL(*this, frameStarted(_))
621             .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
622         for (int ps = 0; ps < frame.pointSetCount(); ++ps)
623         {
624             const AnalysisDataTestInputPointSet &points = frame.pointSet(ps);
625             if (points.lastColumn() >= firstcol
626                 && points.firstColumn() <= firstcol + n - 1)
627             {
628                 EXPECT_CALL(*this, pointsAdded(_))
629                     .WillOnce(Invoke(StaticDataPointsChecker(&frame, &points, firstcol, n)));
630             }
631         }
632         EXPECT_CALL(*this, frameFinished(_))
633             .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
634         EXPECT_CALL(*this, frameFinishedSerial(row));
635     }
636     EXPECT_CALL(*this, dataFinished());
637 }
638
639
640 void
641 MockAnalysisDataModule::setupStaticStorageCheck(
642         const AnalysisDataTestInput &data,
643         int storageCount, AbstractAnalysisData *source)
644 {
645     GMX_RELEASE_ASSERT(data.isMultipoint() == source->isMultipoint(),
646                        "Mismatching multipoint properties");
647     impl_->flags_ |= efAllowMulticolumn | efAllowMultipoint | efAllowMultipleDataSets;
648
649     ::testing::InSequence dummy;
650     using ::testing::_;
651     using ::testing::Invoke;
652
653     setSerialExpectationForParallelDataStarted(this);
654     EXPECT_CALL(*this, dataStarted(source))
655         .WillOnce(Invoke(DataStorageRequester(storageCount)));
656     for (int row = 0; row < data.frameCount(); ++row)
657     {
658         const AnalysisDataTestInputFrame &frame = data.frame(row);
659         EXPECT_CALL(*this, frameStarted(_))
660             .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
661         for (int pointSet = 0; pointSet < frame.pointSetCount(); ++pointSet)
662         {
663             StaticDataPointsStorageChecker checker(source, &data, row, pointSet,
664                                                    storageCount);
665             EXPECT_CALL(*this, pointsAdded(_)).WillOnce(Invoke(checker));
666         }
667         EXPECT_CALL(*this, frameFinished(_))
668             .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
669         EXPECT_CALL(*this, frameFinishedSerial(row));
670     }
671     EXPECT_CALL(*this, dataFinished());
672 }
673
674
675 void
676 MockAnalysisDataModule::setupReferenceCheck(const TestReferenceChecker &checker,
677                                             AbstractAnalysisData       *source)
678 {
679     impl_->flags_ |= efAllowMulticolumn | efAllowMultipoint | efAllowMissing
680         | efAllowMultipleDataSets;
681
682     impl_->rootChecker_.reset(new TestReferenceChecker(checker));
683     // Google Mock does not support checking the order fully, because
684     // the number of frames is not known.
685     // Order of the frameStarted(), pointsAdded() and frameFinished()
686     // calls is checked using Google Test assertions in the invoked methods.
687     using ::testing::_;
688     using ::testing::AnyNumber;
689     using ::testing::Expectation;
690     using ::testing::Invoke;
691
692     setSerialExpectationForParallelDataStarted(this);
693     Expectation dataStart = EXPECT_CALL(*this, dataStarted(source))
694             .WillOnce(Invoke(impl_.get(), &Impl::startReferenceData));
695     Expectation frameStart = EXPECT_CALL(*this, frameStarted(_))
696             .After(dataStart)
697             .WillRepeatedly(Invoke(impl_.get(), &Impl::startReferenceFrame));
698     Expectation pointsAdd = EXPECT_CALL(*this, pointsAdded(_))
699             .After(dataStart)
700             .WillRepeatedly(Invoke(impl_.get(), &Impl::checkReferencePoints));
701     Expectation frameFinish = EXPECT_CALL(*this, frameFinished(_))
702             .After(dataStart)
703             .WillRepeatedly(Invoke(impl_.get(), &Impl::finishReferenceFrame));
704     Expectation frameFinishSerial = EXPECT_CALL(*this, frameFinishedSerial(_))
705             .After(dataStart)
706             .WillRepeatedly(Invoke(impl_.get(), &Impl::finishReferenceFrameSerial));
707     EXPECT_CALL(*this, dataFinished())
708         .After(frameStart, pointsAdd, frameFinish, frameFinishSerial);
709 }
710
711 } // namespace test
712 } // namespace gmx