@@ -58,15 +58,15 @@ int main() {
5858
5959 table.setColumnLabel (0 , " zero" );
6060 table.setColumnLabel (2 , " two" );
61-
61+
6262 ASSERT (table.getColumnLabel (0 ) == " zero" );
6363 ASSERT (table.getColumnLabel (2 ) == " two" );
6464
6565 table.setColumnLabel (0 , " 0" );
6666 table.setColumnLabel (2 , " 2" );
6767
6868 const auto & labels = table.getColumnLabels ();
69- for (size_t i = 0 ; i < labels.size (); ++i)
69+ for (size_t i = 0 ; i < labels.size (); ++i)
7070 if (labels.at (i) != std::to_string (i))
7171 throw Exception{" Test failed: labels.at(i) != "
7272 " std::to_string(i)" };
@@ -78,10 +78,6 @@ int main() {
7878 }
7979
8080 // Test exceptions (table should be empty here).
81- SimTK_TEST_MUST_THROW_EXC (table.getRowAtIndex (0 ),
82- OpenSim::EmptyTable);
83- SimTK_TEST_MUST_THROW_EXC (table.updRowAtIndex (0 ),
84- OpenSim::EmptyTable);
8581 SimTK_TEST_MUST_THROW_EXC (table.getDependentColumnAtIndex (0 ),
8682 OpenSim::EmptyTable);
8783 SimTK_TEST_MUST_THROW_EXC (table.updDependentColumnAtIndex (0 ),
@@ -134,7 +130,7 @@ int main() {
134130 table.updMatrixBlock (0 , 0 , table.getNumRows (), table.getNumColumns ()) -= 2 ;
135131
136132 table.updTableMetaData ().setValueForKey (" DataRate" , 600 );
137- table.updTableMetaData ().setValueForKey (" Filename" ,
133+ table.updTableMetaData ().setValueForKey (" Filename" ,
138134 std::string{" /path/to/file" });
139135
140136 ASSERT (table.hasColumn (0 ));
@@ -168,16 +164,16 @@ int main() {
168164 " != std::to_string(i + 1)" };
169165 }
170166
171- const auto & col_index_ref
167+ const auto & col_index_ref
172168 = dep_metadata_ref.getValueArrayForKey (" column-index" );
173169 for (unsigned i = 0 ; i < 5 ; ++i)
174170 if (col_index_ref[i].getValue <unsigned >() != i + 1 )
175171 throw Exception{" Test failed: col_index_ref[i].getValue<unsigned>()"
176172 " != i + 1" };
177173
178174 const auto & ind_metadata_ref = table.getIndependentMetaData ();
179-
180- if (ind_metadata_ref.getValueForKey (" labels" ).getValue <std::string>()
175+
176+ if (ind_metadata_ref.getValueForKey (" labels" ).getValue <std::string>()
181177 != std::string{" 0" })
182178 throw Exception{" Test failed: ind_metadata_ref.getValueForKey"
183179 " (\" labels\" ).getValue<std::string>() != std::string{\" 0\" }" };
@@ -216,7 +212,7 @@ int main() {
216212 // ASSERT(table.getNumRows() == 5 && table.getNumColumns() == 7);
217213
218214 const auto & tab_metadata_ref = table.getTableMetaData ();
219- if (tab_metadata_ref.getValueForKey (" DataRate" ).getValue <int >()
215+ if (tab_metadata_ref.getValueForKey (" DataRate" ).getValue <int >()
220216 != 600 )
221217 throw Exception{" Test failed: tab_metadata_ref.getValueForKey"
222218 " (\" DataRate\" ).getValue<int>() != 600" };
@@ -312,7 +308,7 @@ int main() {
312308 }
313309 }
314310 }
315-
311+
316312 std::cout << " Test DataTable flatten() for Vec3." << std::endl;
317313 auto tableFlat = tableVec3.flatten ({" _x" , " _y" , " _z" });
318314 expLabels = {" col0_x" , " col0_y" , " col0_z" ,
@@ -337,7 +333,7 @@ int main() {
337333
338334 std::cout << " Test DataTable flattening constructor for Quaternion."
339335 << std::endl;
340- DataTable_<double , Quaternion> tableQuat{};
336+ DataTable_<double , Quaternion> tableQuat{};
341337 tableQuat.setColumnLabels ({" col0" , " col1" , " col2" });
342338 tableQuat.appendRow (0.1 , {{1 , 1 , 1 , 1 }, {2 , 2 , 2 , 2 }, {3 , 3 , 3 , 3 }});
343339 tableQuat.appendRow (0.2 , {{3 , 3 , 3 , 3 }, {1 , 1 , 1 , 1 }, {2 , 2 , 2 , 2 }});
@@ -412,7 +408,7 @@ int main() {
412408 ASSERT (nearRowVec3[0 ][i] == 2 );
413409
414410 std::cout << tableVec3 << std::endl;
415-
411+
416412 TimeSeriesTable_<double > tableDouble{tableVec3};
417413 std::vector<std::string> expLabels{" col0_1" , " col0_2" , " col0_3" ,
418414 " col1_1" , " col1_2" , " col1_3" ,
@@ -458,7 +454,7 @@ int main() {
458454
459455 std::cout << " Test TimeSeriesTable flattening constructor for "
460456 " Quaternion" << std::endl;
461- TimeSeriesTable_<Quaternion> tableQuat{};
457+ TimeSeriesTable_<Quaternion> tableQuat{};
462458 tableQuat.setColumnLabels ({" col0" , " col1" , " col2" });
463459 tableQuat.appendRow (0.1 , {{1 , 1 , 1 , 1 }, {2 , 2 , 2 , 2 }, {3 , 3 , 3 , 3 }});
464460 tableQuat.appendRow (0.2 , {{3 , 3 , 3 , 3 }, {1 , 1 , 1 , 1 }, {2 , 2 , 2 , 2 }});
@@ -539,7 +535,7 @@ int main() {
539535 ASSERT (tableDouble.getColumnLabels ().size () == 18 );
540536 ASSERT (tableDouble.getNumRows () == 3 );
541537 ASSERT (tableDouble.getNumColumns () == 18 );
542-
538+
543539 std::cout << tableDouble << std::endl;
544540 }
545541 {
@@ -571,7 +567,7 @@ int main() {
571567 ASSERT (tableVec3_1.getTableMetaData <std::string>(" string" ) == " string" );
572568 ASSERT (tableVec3_1.getTableMetaData <int >(" int" ) == 10 );
573569 std::cout << tableVec3_1 << std::endl;
574-
570+
575571 std::cout << " Test DataTable packing for Vec3 with suffix unspecified."
576572 << std::endl;
577573 auto tableVec3_2 = tableDouble.pack <SimTK::Vec3>();
@@ -649,7 +645,7 @@ int main() {
649645 ASSERT (tableVec3_1.getTableMetaData <std::string>(" string" ) == " string" );
650646 ASSERT (tableVec3_1.getTableMetaData <int >(" int" ) == 10 );
651647 std::cout << tableVec3_1 << std::endl;
652-
648+
653649 std::cout << " Test TimeSeriesTable packing for Vec3 with suffix"
654650 " unspecified."
655651 << std::endl;
@@ -701,5 +697,62 @@ int main() {
701697 std::cout << tableSVec << std::endl;
702698 }
703699
700+ {
701+ std::cout << " Test that TimeSeriesTable can have 0 columns."
702+ << std::endl;
703+ TimeSeriesTable table (std::vector<double >{1.5 , 2.5 , 3.5 });
704+ std::vector<std::string> expLabels = {};
705+ ASSERT (table.getColumnLabels () == expLabels);
706+ ASSERT (table.getNumRows () == 3 );
707+ ASSERT (table.getNumColumns () == 0 );
708+
709+ // Can append an empty row.
710+ table.appendRow (4.5 , {});
711+ ASSERT (table.getNumRows () == 4 );
712+ ASSERT (table.getNumColumns () == 0 );
713+
714+ table.removeRowAtIndex (3 );
715+ ASSERT (table.getNumRows () == 3 );
716+ ASSERT (table.getNumColumns () == 0 );
717+
718+ table.appendRow (4.5 , {});
719+ ASSERT (table.getNumRows () == 4 );
720+ ASSERT (table.getNumColumns () == 0 );
721+
722+ // Cannot append a non-empty row.
723+ SimTK_TEST_MUST_THROW_EXC (table.appendRow (5.5 , {6.1 }),
724+ IncorrectNumColumns);
725+
726+ // Can append a column to a table that has no columns yet.
727+ table.appendColumn (" col1" , {5.4 , 5.3 , 5.6 , 5.8 });
728+ ASSERT (table.getNumRows () == 4 );
729+ ASSERT (table.getNumColumns () == 1 );
730+
731+ // Appending a column with an incorrect number of rows.
732+ SimTK_TEST_MUST_THROW_EXC (table.appendColumn (" col2" , {5.4 , 5.3 , 5.6 }),
733+ IncorrectNumRows);
734+
735+ // Can appendRow after appendColumn.
736+ table.appendRow (5.5 , {1.3 });
737+ ASSERT (table.getNumRows () == 5 );
738+ ASSERT (table.getNumColumns () == 1 );
739+
740+ // Can create an empty table by providing an empty indVec.
741+ TimeSeriesTable emptyTable (std::vector<double >{});
742+ // Bu we can't append columns to an empty table.
743+ SimTK_TEST_MUST_THROW_EXC (emptyTable.appendColumn (" col0" , {}),
744+ InvalidCall);
745+
746+ // Ensure that we are validating the time stamps are increasing
747+ SimTK_TEST_MUST_THROW_EXC (
748+ TimeSeriesTable (std::vector<double >{1.5 , 1.6 , 1.6 }),
749+ TimestampGreaterThanEqualToNext);
750+ SimTK_TEST_MUST_THROW_EXC (
751+ TimeSeriesTable (std::vector<double >{1.5 , 1.6 , 1.4 }),
752+ TimestampGreaterThanEqualToNext);
753+ SimTK_TEST_MUST_THROW_EXC (table.appendRow (-0.3 , {0.6 }),
754+ TimestampLessThanEqualToPrevious);
755+ }
756+
704757 return 0 ;
705758}
0 commit comments