More flexible input data for analysisdata tests.
authorTeemu Murtola <teemu.murtola@gmail.com>
Sat, 8 Jun 2013 10:29:48 +0000 (13:29 +0300)
committerGerrit Code Review <gerrit@gerrit.gromacs.org>
Mon, 24 Jun 2013 05:11:41 +0000 (07:11 +0200)
Instead of somewhat inflexible parsing from a static real[] array,
construct the input data objects by explicit method calls to add frames
and point sets.  Convert the existing tests to construct the input data
this way.

Increase coverage of multipoint tests for AnalysisData by using
point sets that do not cover the full range of columns.
Improve test error messages and fix issues found while doing this.

Prerequisite for unit tests for #869 and #1010.

Change-Id: Idd0831d9bbf8e59b6edfab758cd53881133e1f3a

src/gromacs/analysisdata/dataframe.cpp
src/gromacs/analysisdata/tests/analysisdata.cpp
src/gromacs/analysisdata/tests/arraydata.cpp
src/gromacs/analysisdata/tests/average.cpp
src/gromacs/analysisdata/tests/histogram.cpp
src/testutils/datatest.cpp
src/testutils/datatest.h
src/testutils/mock_datamodule.cpp

index 5e5841dc15519eee25ce85f3ce910f2d7739256f..543ae428310b58d7e1ed349a335c9b028e9ef20c 100644 (file)
@@ -101,21 +101,21 @@ AnalysisDataPointSetRef::AnalysisDataPointSetRef(
         return;
     }
     AnalysisDataValuesRef::const_iterator begin = points.values().begin();
-    int newFirstColumn = firstColumn - points.firstColumn();
-    if (newFirstColumn > 0)
+    int pointsOffset = firstColumn - points.firstColumn();
+    if (pointsOffset > 0)
     {
         // Offset pointer if the first column is not the first in points.
-        begin         += newFirstColumn;
-        newFirstColumn = 0;
+        begin += pointsOffset;
     }
     else
     {
         // Take into account if first column is before the first in points.
-        columnCount -= -newFirstColumn;
+        firstColumn_ = -pointsOffset;
+        columnCount -= -pointsOffset;
     }
     // Decrease column count if there are not enough columns in points.
     AnalysisDataValuesRef::const_iterator end = begin + columnCount;
-    if (newFirstColumn + columnCount > points.columnCount())
+    if (pointsOffset + columnCount > points.columnCount())
     {
         end = points.values().end();
     }
index c9d3fe8e9f71cb500529bff5c30dcaa75c1fbb03..3e07571085c90dfb853a667951a0648b0383a6e6 100644 (file)
@@ -56,6 +56,7 @@
 #include "testutils/mock_datamodule.h"
 #include "testutils/testasserts.h"
 
+using gmx::test::AnalysisDataTestInput;
 using gmx::test::MockAnalysisDataModule;
 using gmx::test::MockAnalysisDataModulePointer;
 
@@ -129,13 +130,56 @@ TEST(AnalysisDataInitializationTest, ChecksMultiPointModules)
 //! Test fixture for gmx::AnalysisData.
 typedef gmx::test::AnalysisDataTestFixture AnalysisDataTest;
 
-using gmx::test::END_OF_FRAME;
-using gmx::test::MPSTOP;
-//! Input data for gmx::AnalysisData tests.
-const real inputdata[] = {
-    1.0,  0.0, 1.0, 2.0, END_OF_FRAME,
-    2.0,  1.0, 1.0, 1.0, END_OF_FRAME,
-    3.0,  2.0, 0.0, 0.0, END_OF_FRAME
+// Basic input data for gmx::AnalysisData tests.
+class SimpleInputData
+{
+    public:
+        static const AnalysisDataTestInput &get()
+        {
+            static SimpleInputData singleton;
+            return singleton.data_;
+        }
+
+        SimpleInputData() : data_(3, false)
+        {
+            data_.addFrameWithValues(1.0,  0.0, 1.0, 2.0);
+            data_.addFrameWithValues(2.0,  1.0, 1.0, 1.0);
+            data_.addFrameWithValues(3.0,  2.0, 0.0, 0.0);
+        }
+
+    private:
+        AnalysisDataTestInput  data_;
+};
+
+// Input data for multipoint gmx::AnalysisData tests.
+class MultipointInputData
+{
+    public:
+        static const AnalysisDataTestInput &get()
+        {
+            static MultipointInputData singleton;
+            return singleton.data_;
+        }
+
+        MultipointInputData() : data_(3, true)
+        {
+            using gmx::test::AnalysisDataTestInputFrame;
+            AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0);
+            frame1.addPointSetWithValues(0, 0.0, 1.0, 2.0);
+            frame1.addPointSetWithValues(0, 1.1, 2.1, 1.1);
+            frame1.addPointSetWithValues(0, 2.2, 1.2, 0.2);
+            AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0);
+            frame2.addPointSetWithValues(1, 1.0, 1.0);
+            frame2.addPointSetWithValues(0, 2.1, 1.1, 0.1);
+            frame2.addPointSetWithValues(2, 1.2);
+            AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0);
+            frame3.addPointSetWithValues(0, 2.0, 0.0, 0.0);
+            frame3.addPointSetWithValues(0, 3.1, 2.1);
+            frame3.addPointSetWithValues(1, 2.2, 1.2);
+        }
+
+    private:
+        AnalysisDataTestInput  data_;
 };
 
 /*
@@ -144,8 +188,8 @@ const real inputdata[] = {
  */
 TEST_F(AnalysisDataTest, CallsModuleCorrectly)
 {
-    gmx::test::AnalysisDataTestInput input(inputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data));
@@ -160,8 +204,8 @@ TEST_F(AnalysisDataTest, CallsModuleCorrectly)
  */
 TEST_F(AnalysisDataTest, CallsColumnModuleCorrectly)
 {
-    gmx::test::AnalysisDataTestInput input(inputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     ASSERT_NO_THROW_GMX(addStaticColumnCheckerModule(input, 0, 2, &data));
@@ -175,8 +219,8 @@ TEST_F(AnalysisDataTest, CallsColumnModuleCorrectly)
  */
 TEST_F(AnalysisDataTest, CallsModuleCorrectlyWithOutOfOrderFrames)
 {
-    gmx::test::AnalysisDataTestInput input(inputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data));
@@ -199,8 +243,8 @@ TEST_F(AnalysisDataTest, CallsModuleCorrectlyWithOutOfOrderFrames)
  */
 TEST_F(AnalysisDataTest, FullStorageWorks)
 {
-    gmx::test::AnalysisDataTestInput input(inputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     ASSERT_NO_THROW_GMX(addStaticStorageCheckerModule(input, -1, &data));
@@ -213,8 +257,8 @@ TEST_F(AnalysisDataTest, FullStorageWorks)
  */
 TEST_F(AnalysisDataTest, CanAddModuleAfterStoredData)
 {
-    gmx::test::AnalysisDataTestInput input(inputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
     ASSERT_TRUE(data.requestStorage(-1));
 
@@ -228,29 +272,22 @@ TEST_F(AnalysisDataTest, CanAddModuleAfterStoredData)
  */
 TEST_F(AnalysisDataTest, LimitedStorageWorks)
 {
-    gmx::test::AnalysisDataTestInput input(inputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     ASSERT_NO_THROW_GMX(addStaticStorageCheckerModule(input, 1, &data));
     ASSERT_NO_THROW_GMX(presentAllData(input, &data));
 }
 
-//! Input data for multipoint gmx::AnalysisData tests.
-const real multipointinputdata[] = {
-    1.0,  0.0, 1.0, 2.0, MPSTOP, 1.1, 2.1, 1.1, MPSTOP, 2.2, 1.2, 0.2, END_OF_FRAME,
-    2.0,  1.0, 1.0, 1.0, MPSTOP, 2.1, 1.1, 0.1, MPSTOP, 1.2, 0.2, 1.2, END_OF_FRAME,
-    3.0,  2.0, 0.0, 0.0, MPSTOP, 3.1, 2.1, 1.1, MPSTOP, 0.2, 2.2, 1.2, END_OF_FRAME
-};
-
 /*
  * Tests that multipoint data is forwarded correctly to modules using two
  * independent modules.
  */
 TEST_F(AnalysisDataTest, MultipointCallsModuleCorrectly)
 {
-    gmx::test::AnalysisDataTestInput input(multipointinputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = MultipointInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     ASSERT_NO_THROW_GMX(addStaticCheckerModule(input, &data));
@@ -265,8 +302,8 @@ TEST_F(AnalysisDataTest, MultipointCallsModuleCorrectly)
  */
 TEST_F(AnalysisDataTest, MultipointCallsColumnModuleCorrectly)
 {
-    gmx::test::AnalysisDataTestInput input(multipointinputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = MultipointInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     ASSERT_NO_THROW_GMX(addStaticColumnCheckerModule(input, 0, 2, &data));
index 8baf800b6443cbea7d12065973fdda5e61c14949..1e861432bf0ddd65ac6adb3cff99e801c3bdd627 100644 (file)
@@ -51,6 +51,8 @@
 #include "testutils/datatest.h"
 #include "testutils/testasserts.h"
 
+using gmx::test::AnalysisDataTestInput;
+
 namespace
 {
 
@@ -61,19 +63,32 @@ namespace
 //! Test fixture for gmx::AnalysisArrayData.
 typedef gmx::test::AnalysisDataTestFixture AnalysisArrayDataTest;
 
-using gmx::test::END_OF_FRAME;
-//! Input data for gmx::AnalysisArrayData tests.
-const real inputdata[] = {
-    1.0,  0.0, 1.0, 2.0, END_OF_FRAME,
-    2.0,  1.0, 1.0, 1.0, END_OF_FRAME,
-    3.0,  2.0, 0.0, 0.0, END_OF_FRAME,
-    4.0,  3.0, 2.0, 1.0, END_OF_FRAME
+// Input data for gmx::AnalysisArrayData tests.
+class SimpleInputData
+{
+    public:
+        static const AnalysisDataTestInput &get()
+        {
+            static SimpleInputData singleton;
+            return singleton.data_;
+        }
+
+        SimpleInputData() : data_(3, false)
+        {
+            data_.addFrameWithValues(1.0,  0.0, 1.0, 2.0);
+            data_.addFrameWithValues(2.0,  1.0, 1.0, 1.0);
+            data_.addFrameWithValues(3.0,  2.0, 0.0, 0.0);
+            data_.addFrameWithValues(4.0,  3.0, 2.0, 1.0);
+        }
+
+    private:
+        AnalysisDataTestInput  data_;
 };
 
 TEST_F(AnalysisArrayDataTest, CallsModuleCorrectly)
 {
-    gmx::test::AnalysisDataTestInput input(inputdata);
-    gmx::AnalysisArrayData           data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisArrayData       data;
     data.setXAxis(1.0, 1.0);
     setupArrayData(input, &data);
 
@@ -84,8 +99,8 @@ TEST_F(AnalysisArrayDataTest, CallsModuleCorrectly)
 
 TEST_F(AnalysisArrayDataTest, StorageWorks)
 {
-    gmx::test::AnalysisDataTestInput input(inputdata);
-    gmx::AnalysisArrayData           data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisArrayData       data;
     data.setXAxis(1.0, 1.0);
     setupArrayData(input, &data);
 
index 543562e60511996de9d12dac8d27bf7a79c908c0..e45d1c256f2fcc4406260c94fedd49833017883a 100644 (file)
 #include "testutils/datatest.h"
 #include "testutils/testasserts.h"
 
+using gmx::test::AnalysisDataTestInput;
+
 namespace
 {
 
-using gmx::test::END_OF_FRAME;
-using gmx::test::MPSTOP;
-//! Input data for gmx::AnalysisDataAverageModule tests.
-const real inputdata[] = {
-    1.0,  0.0, 1.0, 2.0, END_OF_FRAME,
-    2.0,  1.0, 1.0, 1.0, END_OF_FRAME,
-    3.0,  2.0, 0.0, 0.0, END_OF_FRAME
+// Simple input data for gmx::AnalysisDataAverageModule tests.
+class SimpleInputData
+{
+    public:
+        static const AnalysisDataTestInput &get()
+        {
+            static SimpleInputData singleton;
+            return singleton.data_;
+        }
+
+        SimpleInputData() : data_(3, false)
+        {
+            data_.addFrameWithValues(1.0,  0.0, 1.0, 2.0);
+            data_.addFrameWithValues(2.0,  1.0, 1.0, 1.0);
+            data_.addFrameWithValues(3.0,  2.0, 0.0, 0.0);
+        }
+
+    private:
+        AnalysisDataTestInput  data_;
 };
-//! Multipoint input data for gmx::AnalysisDataAverageModule tests.
-const real mpinputdata[] = {
-/* *INDENT-OFF* */
-    1.0,  0.0, 1.0, 2.0, MPSTOP,
-          1.0, 0.0, MPSTOP,
-          2.0, END_OF_FRAME,
-    2.0,  1.0, 1.0, MPSTOP,
-          2.0, END_OF_FRAME,
-    3.0,  2.0, 0.0, 0.0, END_OF_FRAME
-/* *INDENT-ON* */
+
+// Multipoint input data for gmx::AnalysisDataAverageModule tests.
+class MultipointInputData
+{
+    public:
+        static const AnalysisDataTestInput &get()
+        {
+            static MultipointInputData singleton;
+            return singleton.data_;
+        }
+
+        MultipointInputData() : data_(3, true)
+        {
+            using gmx::test::AnalysisDataTestInputFrame;
+            AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0);
+            frame1.addPointSetWithValues(0, 0.0, 1.0, 2.0);
+            frame1.addPointSetWithValues(0, 1.0, 0.0);
+            frame1.addPointSetWithValues(0, 2.0);
+            AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0);
+            frame2.addPointSetWithValues(0, 1.0, 1.0);
+            frame2.addPointSetWithValues(0, 2.0);
+            AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0);
+            frame3.addPointSetWithValues(0, 2.0, 0.0, 0.0);
+        }
+
+    private:
+        AnalysisDataTestInput  data_;
 };
 
 
@@ -87,8 +118,8 @@ typedef gmx::test::AnalysisDataTestFixture AverageModuleTest;
 
 TEST_F(AverageModuleTest, BasicTest)
 {
-    gmx::test::AnalysisDataTestInput      input(inputdata);
-    gmx::AnalysisData                     data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     gmx::AnalysisDataAverageModulePointer module(
@@ -103,8 +134,8 @@ TEST_F(AverageModuleTest, BasicTest)
 
 TEST_F(AverageModuleTest, HandlesMultipointData)
 {
-    gmx::test::AnalysisDataTestInput input(mpinputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = MultipointInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     gmx::AnalysisDataAverageModulePointer module(
@@ -119,8 +150,8 @@ TEST_F(AverageModuleTest, HandlesMultipointData)
 
 TEST_F(AverageModuleTest, CanCustomizeXAxis)
 {
-    gmx::test::AnalysisDataTestInput      input(inputdata);
-    gmx::AnalysisData                     data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     gmx::AnalysisDataAverageModulePointer module(new gmx::AnalysisDataAverageModule());
@@ -142,8 +173,8 @@ typedef gmx::test::AnalysisDataTestFixture FrameAverageModuleTest;
 
 TEST_F(FrameAverageModuleTest, BasicTest)
 {
-    gmx::test::AnalysisDataTestInput           input(inputdata);
-    gmx::AnalysisData                          data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     gmx::AnalysisDataFrameAverageModulePointer module(
index 07e77f87942429fef17060831e428035040343a4..7f9622ada81805ab1dd0c4849d45d3036e0a2943 100644 (file)
@@ -54,6 +54,8 @@
 #include "testutils/datatest.h"
 #include "testutils/testasserts.h"
 
+using gmx::test::AnalysisDataTestInput;
+
 namespace
 {
 
@@ -149,19 +151,41 @@ TEST(AnalysisHistogramSettingsTest, InitializesFromRangeWithRoundedRange)
 //! Test fixture for gmx::AnalysisDataSimpleHistogramModule.
 typedef gmx::test::AnalysisDataTestFixture SimpleHistogramModuleTest;
 
-using gmx::test::END_OF_FRAME;
-using gmx::test::MPSTOP;
-//! Input data for gmx::AnalysisDataSimpleHistogramModule tests.
-const real simpleinputdata[] = {
-    1.0,  0.7, MPSTOP, 1.1, MPSTOP, 2.3, MPSTOP, 2.9, END_OF_FRAME,
-    2.0,  1.3, MPSTOP, 2.2, END_OF_FRAME,
-    3.0,  3.3, MPSTOP, 1.2, MPSTOP, 1.3, END_OF_FRAME
+// Input data for gmx::AnalysisDataSimpleHistogramModule tests.
+class SimpleInputData
+{
+    public:
+        static const AnalysisDataTestInput &get()
+        {
+            static SimpleInputData singleton;
+            return singleton.data_;
+        }
+
+        SimpleInputData() : data_(1, true)
+        {
+            using gmx::test::AnalysisDataTestInputFrame;
+            AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0);
+            frame1.addPointSetWithValues(0, 0.7);
+            frame1.addPointSetWithValues(0, 1.1);
+            frame1.addPointSetWithValues(0, 2.3);
+            frame1.addPointSetWithValues(0, 2.9);
+            AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0);
+            frame2.addPointSetWithValues(0, 1.3);
+            frame2.addPointSetWithValues(0, 2.2);
+            AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0);
+            frame3.addPointSetWithValues(0, 3.3);
+            frame3.addPointSetWithValues(0, 1.2);
+            frame3.addPointSetWithValues(0, 1.3);
+        }
+
+    private:
+        AnalysisDataTestInput  data_;
 };
 
 TEST_F(SimpleHistogramModuleTest, ComputesCorrectly)
 {
-    gmx::test::AnalysisDataTestInput input(simpleinputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     gmx::AnalysisDataSimpleHistogramModulePointer module(
@@ -181,8 +205,8 @@ TEST_F(SimpleHistogramModuleTest, ComputesCorrectly)
 
 TEST_F(SimpleHistogramModuleTest, ComputesCorrectlyWithAll)
 {
-    gmx::test::AnalysisDataTestInput input(simpleinputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = SimpleInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     gmx::AnalysisDataSimpleHistogramModulePointer module(
@@ -207,17 +231,41 @@ TEST_F(SimpleHistogramModuleTest, ComputesCorrectlyWithAll)
 //! Test fixture for gmx::AnalysisDataWeightedHistogramModule.
 typedef gmx::test::AnalysisDataTestFixture WeightedHistogramModuleTest;
 
-//! Input data for both weighted histogram and bin average module tests.
-const real weightedinputdata[] = {
-    1.0,  0.7, 0.5, MPSTOP, 1.1, 1.0, MPSTOP, 2.3, 1.0, MPSTOP, 2.9, 2.0, END_OF_FRAME,
-    2.0,  1.3, 1.0, MPSTOP, 2.2, 3.0, END_OF_FRAME,
-    3.0,  3.3, 0.5, MPSTOP, 1.2, 2.0, MPSTOP, 1.3, 1.0, END_OF_FRAME
+// Input data for both weighted histogram and bin average module tests.
+class WeightedInputData
+{
+    public:
+        static const AnalysisDataTestInput &get()
+        {
+            static WeightedInputData singleton;
+            return singleton.data_;
+        }
+
+        WeightedInputData() : data_(2, true)
+        {
+            using gmx::test::AnalysisDataTestInputFrame;
+            AnalysisDataTestInputFrame &frame1 = data_.addFrame(1.0);
+            frame1.addPointSetWithValues(0, 0.7, 0.5);
+            frame1.addPointSetWithValues(0, 1.1, 1.0);
+            frame1.addPointSetWithValues(0, 2.3, 1.0);
+            frame1.addPointSetWithValues(0, 2.9, 2.0);
+            AnalysisDataTestInputFrame &frame2 = data_.addFrame(2.0);
+            frame2.addPointSetWithValues(0, 1.3, 1.0);
+            frame2.addPointSetWithValues(0, 2.2, 3.0);
+            AnalysisDataTestInputFrame &frame3 = data_.addFrame(3.0);
+            frame3.addPointSetWithValues(0, 3.3, 0.5);
+            frame3.addPointSetWithValues(0, 1.2, 2.0);
+            frame3.addPointSetWithValues(0, 1.3, 1.0);
+        }
+
+    private:
+        AnalysisDataTestInput  data_;
 };
 
 TEST_F(WeightedHistogramModuleTest, ComputesCorrectly)
 {
-    gmx::test::AnalysisDataTestInput input(weightedinputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = WeightedInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     gmx::AnalysisDataWeightedHistogramModulePointer module(
@@ -237,8 +285,8 @@ TEST_F(WeightedHistogramModuleTest, ComputesCorrectly)
 
 TEST_F(WeightedHistogramModuleTest, ComputesCorrectlyWithAll)
 {
-    gmx::test::AnalysisDataTestInput input(weightedinputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = WeightedInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     gmx::AnalysisDataWeightedHistogramModulePointer module(
@@ -265,8 +313,8 @@ typedef gmx::test::AnalysisDataTestFixture BinAverageModuleTest;
 
 TEST_F(BinAverageModuleTest, ComputesCorrectly)
 {
-    gmx::test::AnalysisDataTestInput input(weightedinputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = WeightedInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     gmx::AnalysisDataBinAverageModulePointer module(
@@ -283,8 +331,8 @@ TEST_F(BinAverageModuleTest, ComputesCorrectly)
 
 TEST_F(BinAverageModuleTest, ComputesCorrectlyWithAll)
 {
-    gmx::test::AnalysisDataTestInput input(weightedinputdata);
-    gmx::AnalysisData                data;
+    const AnalysisDataTestInput &input = WeightedInputData::get();
+    gmx::AnalysisData            data;
     ASSERT_NO_THROW_GMX(setupDataObject(input, &data));
 
     gmx::AnalysisDataBinAverageModulePointer module(
@@ -309,15 +357,29 @@ TEST_F(BinAverageModuleTest, ComputesCorrectlyWithAll)
 //! Test fixture for gmx::AbstractAverageHistogram.
 typedef gmx::test::AnalysisDataTestFixture AbstractAverageHistogramTest;
 
-//! Input data for gmx::AbstractAverageHistogram tests.
-const real averageinputdata[] = {
-    1.0, 2.0, 1.0, END_OF_FRAME,
-    1.5, 1.0, 1.0, END_OF_FRAME,
-    2.0, 3.0, 2.0, END_OF_FRAME,
-    2.5, 4.0, 2.0, END_OF_FRAME,
-    3.0, 2.0, 1.0, END_OF_FRAME,
-    3.5, 0.0, 3.0, END_OF_FRAME,
-    4.0, 1.0, 3.0, END_OF_FRAME
+// Input data for gmx::AbstractAverageHistogram tests.
+class AverageInputData
+{
+    public:
+        static const AnalysisDataTestInput &get()
+        {
+            static AverageInputData singleton;
+            return singleton.data_;
+        }
+
+        AverageInputData() : data_(2, false)
+        {
+            data_.addFrameWithValues(1.0,  2.0, 1.0);
+            data_.addFrameWithValues(1.5,  1.0, 1.0);
+            data_.addFrameWithValues(2.0,  3.0, 2.0);
+            data_.addFrameWithValues(2.5,  4.0, 2.0);
+            data_.addFrameWithValues(3.0,  2.0, 1.0);
+            data_.addFrameWithValues(3.5,  0.0, 3.0);
+            data_.addFrameWithValues(4.0,  1.0, 3.0);
+        }
+
+    private:
+        AnalysisDataTestInput  data_;
 };
 
 /*! \internal \brief
@@ -346,8 +408,8 @@ class MockAverageHistogram : public gmx::AbstractAverageHistogram
 
 TEST_F(AbstractAverageHistogramTest, ClonesCorrectly)
 {
-    gmx::test::AnalysisDataTestInput input(averageinputdata);
-    MockAverageHistogram             data(
+    const AnalysisDataTestInput &input = AverageInputData::get();
+    MockAverageHistogram         data(
             gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins());
     setupArrayData(input, &data);
 
@@ -364,8 +426,8 @@ TEST_F(AbstractAverageHistogramTest, ClonesCorrectly)
 
 TEST_F(AbstractAverageHistogramTest, ResamplesAtDoubleBinWidth)
 {
-    gmx::test::AnalysisDataTestInput input(averageinputdata);
-    MockAverageHistogram             data(
+    const AnalysisDataTestInput &input = AverageInputData::get();
+    MockAverageHistogram         data(
             gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins());
     setupArrayData(input, &data);
 
@@ -380,8 +442,8 @@ TEST_F(AbstractAverageHistogramTest, ResamplesAtDoubleBinWidth)
 
 TEST_F(AbstractAverageHistogramTest, ResamplesAtDoubleBinWidthWithIntegerBins)
 {
-    gmx::test::AnalysisDataTestInput input(averageinputdata);
-    MockAverageHistogram             data(
+    const AnalysisDataTestInput &input = AverageInputData::get();
+    MockAverageHistogram         data(
             gmx::histogramFromBins(1.0, input.frameCount(), 0.5).integerBins());
     setupArrayData(input, &data);
 
index 9b290a00062d5d089d3b2a66287ded711b46b4d6..d3ad9a9795bac5104c138da165180b3cc856b05f 100644 (file)
@@ -62,7 +62,9 @@ namespace test
  * AnalysisDataTestInputPointSet
  */
 
-AnalysisDataTestInputPointSet::AnalysisDataTestInputPointSet()
+AnalysisDataTestInputPointSet::AnalysisDataTestInputPointSet(
+        int index, int firstColumn)
+    : index_(index), firstColumn_(firstColumn)
 {
 }
 
@@ -76,54 +78,44 @@ AnalysisDataTestInputFrame::AnalysisDataTestInputFrame(int index, real x)
 {
 }
 
+AnalysisDataTestInputPointSet &
+AnalysisDataTestInputFrame::addPointSet(int firstColumn)
+{
+    pointSets_.push_back(AnalysisDataTestInputPointSet(pointSets_.size(), firstColumn));
+    return pointSets_.back();
+}
+
+void AnalysisDataTestInputFrame::addPointSetWithValues(int firstColumn, real y1)
+{
+    AnalysisDataTestInputPointSet &pointSet = addPointSet(firstColumn);
+    pointSet.addValue(y1);
+}
+
+void AnalysisDataTestInputFrame::addPointSetWithValues(int firstColumn, real y1,
+                                                       real y2)
+{
+    AnalysisDataTestInputPointSet &pointSet = addPointSet(firstColumn);
+    pointSet.addValue(y1);
+    pointSet.addValue(y2);
+}
+
+void AnalysisDataTestInputFrame::addPointSetWithValues(int firstColumn, real y1,
+                                                       real y2, real y3)
+{
+    AnalysisDataTestInputPointSet &pointSet = addPointSet(firstColumn);
+    pointSet.addValue(y1);
+    pointSet.addValue(y2);
+    pointSet.addValue(y3);
+}
+
 
 /********************************************************************
  * AnalysisDataTestInput
  */
 
-void AnalysisDataTestInput::initFromArray(const real *data, size_t count)
+AnalysisDataTestInput::AnalysisDataTestInput(int columnCount, bool bMultipoint)
+    : columnCount_(columnCount), bMultipoint_(bMultipoint)
 {
-    size_t columns = 0;
-
-    for (size_t i = 0; i < count; ++i)
-    {
-        if (data[i] == MPSTOP)
-        {
-            bMultipoint_ = true;
-            break;
-        }
-    }
-    for (size_t i = 0; i < count; )
-    {
-        frames_.push_back(AnalysisDataTestInputFrame(frames_.size(), data[i]));
-        AnalysisDataTestInputFrame &frame = frames_.back();
-        GMX_RELEASE_ASSERT(data[i] != END_OF_FRAME && data[i] != MPSTOP,
-                           "Empty data frame");
-        while (data[i] != END_OF_FRAME)
-        {
-            ++i;
-            frame.points_.push_back(AnalysisDataTestInputPointSet());
-            AnalysisDataTestInputPointSet &points = frame.points_.back();
-            while (data[i] != MPSTOP && data[i] != END_OF_FRAME)
-            {
-                GMX_RELEASE_ASSERT(i < count,
-                                   "Premature end of data");
-                points.y_.push_back(data[i]);
-                ++i;
-            }
-            size_t frameColumns = points.y_.size();
-            GMX_RELEASE_ASSERT(frameColumns > 0U, "Empty data point set");
-            GMX_RELEASE_ASSERT(!(!bMultipoint_ && columns > 0U && columns != frameColumns),
-                               "Different frames have different number of columns");
-            if (columns < frameColumns)
-            {
-                columns = frameColumns;
-            }
-        }
-        ++i;
-    }
-    GMX_RELEASE_ASSERT(!frames_.empty(), "Empty data");
-    columnCount_ = columns;
 }
 
 
@@ -140,6 +132,31 @@ const AnalysisDataTestInputFrame &AnalysisDataTestInput::frame(int index) const
 }
 
 
+AnalysisDataTestInputFrame &AnalysisDataTestInput::addFrame(real x)
+{
+    frames_.push_back(AnalysisDataTestInputFrame(frames_.size(), x));
+    return frames_.back();
+}
+
+void AnalysisDataTestInput::addFrameWithValues(real x, real y1)
+{
+    AnalysisDataTestInputFrame &frame = addFrame(x);
+    frame.addPointSetWithValues(0, y1);
+}
+
+void AnalysisDataTestInput::addFrameWithValues(real x, real y1, real y2)
+{
+    AnalysisDataTestInputFrame &frame = addFrame(x);
+    frame.addPointSetWithValues(0, y1, y2);
+}
+
+void AnalysisDataTestInput::addFrameWithValues(real x, real y1, real y2, real y3)
+{
+    AnalysisDataTestInputFrame &frame = addFrame(x);
+    frame.addPointSetWithValues(0, y1, y2, y3);
+}
+
+
 /********************************************************************
  * AnalysisDataTest
  */
@@ -178,10 +195,11 @@ void AnalysisDataTestFixture::presentDataFrame(const AnalysisDataTestInput &inpu
     handle.startFrame(row, frame.x(), frame.dx());
     for (int i = 0; i < frame.pointSetCount(); ++i)
     {
-        const AnalysisDataTestInputPointSet &points = frame.points(i);
+        const AnalysisDataTestInputPointSet &points = frame.pointSet(i);
         for (int j = 0; j < points.size(); ++j)
         {
-            handle.setPoint(j, points.y(j), points.dy(j), points.present(j));
+            handle.setPoint(j + points.firstColumn(),
+                            points.y(j), points.dy(j), points.present(j));
         }
         if (input.isMultipoint())
         {
index d637ad38ccd819cf50d892618014d83d2455c46e..0de86506f5dc755accb69d6995835279277fb7ec 100644 (file)
@@ -43,7 +43,6 @@
 #ifndef GMX_TESTUTILS_DATATEST_H
 #define GMX_TESTUTILS_DATATEST_H
 
-#include <limits>
 #include <vector>
 
 #include <gtest/gtest.h>
@@ -64,11 +63,6 @@ class AnalysisDataHandle;
 namespace test
 {
 
-//! Constant to use to signify end of one data frame for AnalysisDataTestInput.
-const real END_OF_FRAME = std::numeric_limits<real>::max();
-//! Constant to use to signify end of one multipoint set for AnalysisDataTestInput.
-const real MPSTOP = -std::numeric_limits<real>::max();
-
 /*! \libinternal \brief
  * Represents a single set of points in AnalysisDataTestInputFrame structure.
  *
@@ -83,6 +77,12 @@ const real MPSTOP = -std::numeric_limits<real>::max();
 class AnalysisDataTestInputPointSet
 {
     public:
+        //! Returns zero-based index of this point set in its frame.
+        int index() const { return index_; }
+        //! Returns zero-based index of the first column in this point set.
+        int firstColumn() const { return firstColumn_; }
+        //! Returns zero-based index of the last column in this point set.
+        int lastColumn() const { return firstColumn_ + size() - 1; }
         //! Returns the number of columns in the point set.
         int size() const { return y_.size(); }
         //! Returns the value in column \p i.
@@ -94,13 +94,19 @@ class AnalysisDataTestInputPointSet
         //! Returns a vector of values for all columns.
         const std::vector<real> &yvector() const { return y_; }
 
+        //! Appends a value to this point set.
+        void addValue(real y) { y_.push_back(y); }
+
     private:
         //! Creates an empty point set.
-        AnalysisDataTestInputPointSet();
+        AnalysisDataTestInputPointSet(int index, int firstColumn);
 
+        int                     index_;
+        int                     firstColumn_;
         std::vector<real>       y_;
 
-        friend class AnalysisDataTestInput;
+        //! For constructing new point sets.
+        friend class AnalysisDataTestInputFrame;
 };
 
 /*! \libinternal \brief
@@ -120,31 +126,41 @@ class AnalysisDataTestInputFrame
         real dx() const { return 0.0; }
 
         //! Number of individual point sets in the frame.
-        int pointSetCount() const { return points_.size(); }
+        int pointSetCount() const { return pointSets_.size(); }
         //! Returns a point set object for a given point set.
-        const AnalysisDataTestInputPointSet &points(int index = 0) const
+        const AnalysisDataTestInputPointSet &pointSet(int index) const
         {
-            GMX_ASSERT(index >= 0 && static_cast<size_t>(index) < points_.size(),
+            GMX_ASSERT(index >= 0 && static_cast<size_t>(index) < pointSets_.size(),
                        "Point set index out of range");
-            return points_[index];
+            return pointSets_[index];
         }
 
+        //! Appends an empty point set to this frame.
+        AnalysisDataTestInputPointSet &addPointSet(int firstColumn);
+        //! Adds a point set with given values to this frame.
+        void addPointSetWithValues(int firstColumn, real y1);
+        //! Adds a point set with given values to this frame.
+        void addPointSetWithValues(int firstColumn, real y1, real y2);
+        //! Adds a point set with given values to this frame.
+        void addPointSetWithValues(int firstColumn, real y1, real y2, real y3);
+
     private:
         //! Constructs a new frame object with the given values.
         AnalysisDataTestInputFrame(int index, real x);
 
         int                                         index_;
         real                                        x_;
-        std::vector<AnalysisDataTestInputPointSet>  points_;
+        std::vector<AnalysisDataTestInputPointSet>  pointSets_;
 
+        //! For constructing new frames.
         friend class AnalysisDataTestInput;
 };
 
 /*! \libinternal \brief
  * Represents static input data for AbstractAnalysisData tests.
  *
- * Used to construct structured test input data from a static array of reals,
- * and then typically used as input to methods in AnalysisDataTestFixture.
+ * Used to construct structured test input data for analysis data unit tests.
+ * Typically used as input to methods in AnalysisDataTestFixture.
  *
  * \see AnalysisDataTestFixture
  *
@@ -155,42 +171,33 @@ class AnalysisDataTestInput
 {
     public:
         /*! \brief
-         * Constructs data representation from a simple array.
+         * Constructs empty input data.
          *
-         * \tparam    count Number of elements in the array.
-         * \param[in] data  Array to construct data from.
-         *
-         * The input array should consist of a set of frames, separated by a
-         * END_OF_FRAME marker.  The first value for a frame is the X value,
-         * all following values are Y values.
-         * For multipoint data, one frame can contain several point sets,
-         * separated by MPSTOP markers.  There should be no MPSTOP marker after
-         * the last point set, only an END_OF_FRAME marker.  All point sets are
-         * assumed to start from column zero, but the sets may contain
-         * different number of columns.  For non-multipoint data, all frames
-         * must containt the same number of columns.
-         * The final element in the array should be an END_OF_FRAME.
+         * \param[in] columnCount  Number of columns in the data.
+         * \param[in] bMultipoint  Whether the data will be multipoint.
          */
-        template <size_t count>
-        explicit AnalysisDataTestInput(const real (&data)[count])
-            : columnCount_(0), bMultipoint_(false)
-        {
-            initFromArray(data, count);
-        }
+        AnalysisDataTestInput(int columnCount, bool bMultipoint);
         ~AnalysisDataTestInput();
 
-        //! Returns the number of frames in the input data.
-        int frameCount() const { return frames_.size(); }
-        //! Returns the number of columns in the input data.
-        int columnCount() const { return columnCount_; }
         //! Whether the input data is multipoint.
         bool isMultipoint() const { return bMultipoint_; }
+        //! Returns the number of columns in the input data.
+        int columnCount() const { return columnCount_; }
+        //! Returns the number of frames in the input data.
+        int frameCount() const { return frames_.size(); }
         //! Returns a frame object for the given input frame.
         const AnalysisDataTestInputFrame &frame(int index) const;
 
-    private:
-        void initFromArray(const real *data, size_t count);
+        //! Appends an empty frame to this data.
+        AnalysisDataTestInputFrame &addFrame(real x);
+        //! Adds a frame with a single point set and the given values.
+        void addFrameWithValues(real x, real y1);
+        //! Adds a frame with a single point set and the given values.
+        void addFrameWithValues(real x, real y1, real y2);
+        //! Adds a frame with a single point set and the given values.
+        void addFrameWithValues(real x, real y1, real y2, real y3);
 
+    private:
         int                                     columnCount_;
         bool                                    bMultipoint_;
         std::vector<AnalysisDataTestInputFrame> frames_;
@@ -221,13 +228,13 @@ class AnalysisDataTestInput
  *
  * presentAllData() and presentDataFrame() are provided to push data from an
  * AnalysisDataTestInput into an AnalysisData object.  In typical tests, most
- * checks are done during the these methods, by the added mock modules.
+ * checks are done during these methods, by the added mock modules.
  * setupArrayData() performs the same function for classes derived from
  * AbstractAnalysisArrayData.  In that case, the test should separately ensure
  * that AbstractAnalysisArrayData::valuesReady() gets called.
  *
  * \todo
- * Support for errors and for arbitrary multipoint data.
+ * Support for arbitrary AnalysisDataValues (errors and missing values).
  *
  * \see AnalysisDataTestInput
  *
@@ -397,10 +404,12 @@ void AnalysisDataTestFixture::setupArrayData(const AnalysisDataTestInput &input,
     {
         const AnalysisDataTestInputFrame    &frame = input.frame(row);
         EXPECT_FLOAT_EQ(frame.x(), data->xvalue(row));
-        const AnalysisDataTestInputPointSet &points = frame.points();
-        for (int column = 0; column < input.columnCount(); ++column)
+        GMX_RELEASE_ASSERT(frame.pointSetCount() == 1,
+                           "Multiple point sets not supported by array data");
+        const AnalysisDataTestInputPointSet &points = frame.pointSet(0);
+        for (int column = 0; column < points.size(); ++column)
         {
-            data->setValue(row, column, points.y(column));
+            data->setValue(row, column + points.firstColumn(), points.y(column));
         }
     }
 }
index c3c5d1c92d95a095ca7aa66972a566d12834c6ca..ea9f57cf97344eb0757c2e1afaec2522c1892b5b 100644 (file)
@@ -247,10 +247,13 @@ void checkPoints(const AnalysisDataPointSetRef       &points,
 {
     for (int i = 0; i < points.columnCount(); ++i)
     {
-        EXPECT_FLOAT_EQ(refPoints.y(points.firstColumn() + columnOffset + i),
+        const int column = points.firstColumn() - refPoints.firstColumn() + i + columnOffset;
+        EXPECT_FLOAT_EQ(refPoints.y(column),
                         points.y(i))
-        << "  Column: " << i << " (+" << points.firstColumn() << ") / "
-        << points.columnCount();
+        << "  Column: " << i+1 << " / " << points.columnCount()
+        << " (+" << points.firstColumn() << ")\n"
+        << "Ref. col: " << column+1 << " / " << refPoints.size()
+        << " (+" << refPoints.firstColumn() << ", offs " << columnOffset << ")";
     }
 }
 
@@ -264,7 +267,7 @@ void checkFrame(const AnalysisDataFrameRef       &frame,
                 const AnalysisDataTestInputFrame &refFrame)
 {
     checkHeader(frame.header(), refFrame);
-    checkPoints(frame.points(), refFrame.points(), 0);
+    checkPoints(frame.points(), refFrame.pointSet(0), 0);
 }
 
 /*! \internal \brief
@@ -330,9 +333,14 @@ class StaticDataPointsChecker
         //! Function call operator for the functor.
         void operator()(const AnalysisDataPointSetRef &points) const
         {
-            SCOPED_TRACE(formatString("Frame %d", frame_->index()));
-            EXPECT_EQ(0, points.firstColumn());
-            EXPECT_EQ(n_, points.columnCount());
+            SCOPED_TRACE(formatString("Frame %d, point set %d",
+                                      frame_->index(), points_->index()));
+            const int expectedFirstColumn
+                = std::max(0, points_->firstColumn() - firstcol_);
+            const int expectedLastColumn
+                = std::min(n_ - 1, points_->lastColumn() - firstcol_);
+            EXPECT_EQ(expectedFirstColumn, points.firstColumn());
+            EXPECT_EQ(expectedLastColumn,  points.lastColumn());
             checkHeader(points.header(), *frame_);
             checkPoints(points, *points_, firstcol_);
         }
@@ -411,10 +419,12 @@ class StaticDataPointsStorageChecker
         void operator()(const AnalysisDataPointSetRef &points) const
         {
             SCOPED_TRACE(formatString("Frame %d", frameIndex_));
-            EXPECT_EQ(0, points.firstColumn());
+            const AnalysisDataTestInputFrame    &refFrame  = data_->frame(frameIndex_);
+            const AnalysisDataTestInputPointSet &refPoints = refFrame.pointSet(0);
+            EXPECT_EQ(refPoints.firstColumn(), points.firstColumn());
             EXPECT_EQ(data_->columnCount(), points.columnCount());
-            checkHeader(points.header(), data_->frame(frameIndex_));
-            checkPoints(points, data_->frame(frameIndex_).points(), 0);
+            checkHeader(points.header(), refFrame);
+            checkPoints(points, refPoints, 0);
             for (int past = 1;
                  (storageCount_ < 0 || past <= storageCount_) && past <= frameIndex_;
                  ++past)
@@ -476,10 +486,10 @@ MockAnalysisDataModule::setupStaticCheck(const AnalysisDataTestInput &data,
             .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
         for (int ps = 0; ps < frame.pointSetCount(); ++ps)
         {
-            const AnalysisDataTestInputPointSet &points = frame.points(ps);
+            const AnalysisDataTestInputPointSet &points = frame.pointSet(ps);
             EXPECT_CALL(*this, pointsAdded(_))
                 .WillOnce(Invoke(StaticDataPointsChecker(&frame, &points, 0,
-                                                         points.size())));
+                                                         data.columnCount())));
         }
         EXPECT_CALL(*this, frameFinished(_))
             .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
@@ -511,9 +521,13 @@ MockAnalysisDataModule::setupStaticColumnCheck(
             .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));
         for (int ps = 0; ps < frame.pointSetCount(); ++ps)
         {
-            const AnalysisDataTestInputPointSet &points = frame.points(ps);
-            EXPECT_CALL(*this, pointsAdded(_))
-                .WillOnce(Invoke(StaticDataPointsChecker(&frame, &points, firstcol, n)));
+            const AnalysisDataTestInputPointSet &points = frame.pointSet(ps);
+            if (points.lastColumn() >= firstcol
+                && points.firstColumn() <= firstcol + n - 1)
+            {
+                EXPECT_CALL(*this, pointsAdded(_))
+                    .WillOnce(Invoke(StaticDataPointsChecker(&frame, &points, firstcol, n)));
+            }
         }
         EXPECT_CALL(*this, frameFinished(_))
             .WillOnce(Invoke(StaticDataFrameHeaderChecker(&frame)));