Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert testComponentInterface.cpp to use catch (#3555) #3563

Merged
merged 1 commit into from
Sep 25, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 66 additions & 76 deletions OpenSim/Common/Test/testComponentInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
#include <simbody/internal/Force.h>
#include <simbody/internal/MobilizedBody_Pin.h>
#include <simbody/internal/MobilizedBody_Ground.h>

#define CATCH_CONFIG_MAIN
#include <OpenSim/Auxiliary/catch.hpp>

#include <random>

namespace
Expand Down Expand Up @@ -444,7 +448,8 @@ class CompoundFoo : public Foo {
SimTK_NICETYPENAME_LITERAL(Foo);
SimTK_NICETYPENAME_LITERAL(Bar);

void testMisc() {
TEST_CASE("Component Interface Misc.")
{
// Define the Simbody system
MultibodySystem system;

Expand Down Expand Up @@ -836,7 +841,9 @@ void testMisc() {
theWorld.print("Nested_" + modelFile);
}

void testThrowOnDuplicateNames() {
// un-disable test for duplicate names when we re-enable the exception
TEST_CASE("Component Interface Throws on Duplicate Names", "[.disabled]")
{
TheWorld theWorld;
theWorld.setName("World");
theWorld.finalizeFromProperties();
Expand All @@ -862,7 +869,8 @@ void testThrowOnDuplicateNames() {
// finalizeFromProperties() after copying. This test makes sure that you get an
// exception if you did not call finalizeFromProperties() before calling a
// method like getComponentList().
void testExceptionsFinalizeFromPropertiesAfterCopy() {
TEST_CASE("Component Interface Exceptions Finalize From Properties After Copy")
{
TheWorld theWorld;
{
MultibodySystem system;
Expand All @@ -875,7 +883,8 @@ void testExceptionsFinalizeFromPropertiesAfterCopy() {
}
}

void testListInputs() {
TEST_CASE("Component Interface List Inputs")
{
MultibodySystem system;
TheWorld theWorld;
theWorld.setName("World");
Expand Down Expand Up @@ -937,7 +946,8 @@ void testListInputs() {
ASSERT(tabReporter->getTable().getNumRows() == 0);
}

void testListSockets() {
TEST_CASE("Component Interface List Sockets")
{
MultibodySystem system;
TheWorld theWorld;
theWorld.setName("world");
Expand Down Expand Up @@ -971,7 +981,8 @@ void testListSockets() {
// TODO redo with the property list / the reference connect().
}

void testSocketCanConnectTo() {
TEST_CASE("Component Interface Socket::canConnectTo")
{
TheWorld theWorld;
theWorld.setName("world");

Expand All @@ -993,7 +1004,8 @@ void testSocketCanConnectTo() {
SimTK_TEST(!bar.getSocket("childFoo").canConnectTo(theWorld));
}

void testInputCanConnectTo() {
TEST_CASE("Component Interface Input::canConnectTo")
{
TheWorld theWorld;
theWorld.setName("world");

Expand All @@ -1015,7 +1027,7 @@ void testInputCanConnectTo() {
SimTK_TEST(!foo.getInput("input1").canConnectTo(bar));
}

void testComponentPathNames()
TEST_CASE("Component Interface Component Path Names")
{
Foo foo;
foo.setName("LegWithConstrainedFoot/foot");
Expand Down Expand Up @@ -1145,7 +1157,8 @@ void testComponentPathNames()
top.connect();
}

void testFindComponent() {
TEST_CASE("Component Interface Component::findComponent")
{
class A : public Component {
OpenSim_DECLARE_CONCRETE_OBJECT(A, Component);
public:
Expand Down Expand Up @@ -1200,7 +1213,8 @@ void testFindComponent() {
SimTK_TEST(&b3->getConnectee<A>("socket_a") == a3);
}

void testTraversePathToComponent() {
TEST_CASE("Component Interface can Traverse Path to Component")
{
class A : public Component {
OpenSim_DECLARE_CONCRETE_OBJECT(A, Component);
public:
Expand Down Expand Up @@ -1294,8 +1308,8 @@ void testTraversePathToComponent() {
SimTK_TEST(&top.getComponent<Component>("tx/tx") == btx);
}

void testGetStateVariableValue() {

TEST_CASE("Component Interface Component::getStateVariableValue")
{
TheWorld top;
top.setName("top");
Sub* a = new Sub();
Expand Down Expand Up @@ -1329,7 +1343,8 @@ void testGetStateVariableValue() {
OpenSim::Exception);
}

void testGetStateVariableValueComponentPath() {
TEST_CASE("Component Interface getStateVariableValue with Component Path")
{
using CP = ComponentPath;

TheWorld top;
Expand Down Expand Up @@ -1365,7 +1380,7 @@ void testGetStateVariableValueComponentPath() {
OpenSim::Exception);
}

void testInputOutputConnections()
TEST_CASE("Component Interface Input/Output Connections")
{
{
TheWorld world;
Expand Down Expand Up @@ -1468,7 +1483,8 @@ void testInputOutputConnections()
}
}

void testInputConnecteePaths() {
TEST_CASE("Component Interface Input Connectee Paths")
{
{
std::string componentPath, outputName, channelName, alias;
AbstractInput::parseConnecteePath("/foo/bar|output",
Expand Down Expand Up @@ -1513,7 +1529,8 @@ void testInputConnecteePaths() {
// TODO test invalid names as well.
}

void testExceptionsForConnecteeTypeMismatch() {
TEST_CASE("Component Interface Exceptions when Connectee Type Mismatches")
{
// Create Component classes for use in the following tests.
// --------------------------------------------------------
// This class has Outputs.
Expand Down Expand Up @@ -1637,7 +1654,8 @@ void testExceptionsForConnecteeTypeMismatch() {
}
}

void testExceptionsSocketNameExistsAlready() {
TEST_CASE("Component Interface Throws Exceptions if Socket Name Exists Already")
{
// Make sure that it is not possible for a class to have more than one
// socket with a given name, even if the connectee types are different.

Expand Down Expand Up @@ -1681,7 +1699,8 @@ void testExceptionsSocketNameExistsAlready() {
// leads to a compiling error (duplicate member variable).
}

void testExceptionsInputNameExistsAlready() {
TEST_CASE("Component Interface Throws Exception if Input Name Exists Already")
{
// Make sure that it is not possible for a class to have more than one
// input with a given name, even if the connectee types are different.

Expand Down Expand Up @@ -1744,7 +1763,8 @@ void testExceptionsInputNameExistsAlready() {
}
}

void testExceptionsOutputNameExistsAlready() {
TEST_CASE("Component Interface Throws Exceptions if Output Name Exists Already")
{
// Make sure that it is not possible for a class to have more than one
// output with a given name, even if the types are different.

Expand Down Expand Up @@ -1827,7 +1847,8 @@ void assertEqual(const RowVec& a, const RowVec& b) {
ASSERT_EQUAL(a[i], b[i], 1e-10);
}

void testTableSource() {
TEST_CASE("Component Interface Table Source")
{
using namespace OpenSim;
using namespace SimTK;

Expand Down Expand Up @@ -1925,7 +1946,8 @@ void testTableSource() {
std::cout << report << std::endl;
}

void testTableReporter() {
TEST_CASE("Component Interface TableReporter Usage")
{
// TableReporter works fine even if its input has no connectees.
{
TheWorld model;
Expand Down Expand Up @@ -1987,11 +2009,14 @@ void writeTimeSeriesTableForInputConnecteeSerialization() {
dataFileNameForInputConnecteeSerialization);
}

void testListInputConnecteeSerialization() {
TEST_CASE("Component Interface List Input Connectee Serialization Behavior")
{
// We build a model, store the input connectee paths, then
// recreate the same model from a serialization, and make sure the
// connectee paths are the same.

writeTimeSeriesTableForInputConnecteeSerialization();
adamkewley marked this conversation as resolved.
Show resolved Hide resolved

// Helper function.
auto getConnecteePaths = [](const AbstractInput& in) {
const auto numConnectees = in.getNumConnectees();
Expand Down Expand Up @@ -2085,10 +2110,12 @@ void testListInputConnecteeSerialization() {
}
}

void testSingleValueInputConnecteeSerialization() {

TEST_CASE("Component Interface Single Value Input Connectee Serialization Behavior")
{
// Test normal behavior of single-value input (de)serialization.
// -------------------------------------------------------------

writeTimeSeriesTableForInputConnecteeSerialization();
adamkewley marked this conversation as resolved.
Show resolved Hide resolved

// Build a model and serialize it.
std::string modelFileName = "testComponentInterface_"
Expand Down Expand Up @@ -2254,7 +2281,8 @@ void testSingleValueInputConnecteeSerialization() {
}
}

void testAliasesAndLabels() {
TEST_CASE("Component Interface Aliases and Labels Behavior")
{
auto theWorld = std::unique_ptr<TheWorld>(new TheWorld());
theWorld->setName("world");

Expand Down Expand Up @@ -2327,8 +2355,8 @@ void testAliasesAndLabels() {
SimTK_TEST(foo->getInput("listInput1").getLabel(1) == "thud");
}

void testGetAbsolutePathStringSpeed() {
TEST_CASE("Component Interface Get Absolute Path String Speed")
{
std::clock_t constructStartTime = std::clock();

TheWorld* A = new TheWorld();
Expand Down Expand Up @@ -2385,7 +2413,8 @@ void testGetAbsolutePathStringSpeed() {
cout << "getName avgTime = " << avgTime / numTrials << "s" << endl;
}

void testFormattedDateTime() {
TEST_CASE("Component Interface Formatted DateTime Works as Expected")
{
std::string withMicroseconds = getFormattedDateTime(true, "%Y");
std::string withoutMicroseconds = getFormattedDateTime(false, "%Y");
SimTK_TEST(withMicroseconds.find(withoutMicroseconds) == 0);
Expand All @@ -2403,7 +2432,8 @@ struct ComponentWithCacheVariable : public Component {
template<class T>
using CacheVariable = Component::CacheVariable<T>;

void testCacheVariableInterface() {
TEST_CASE("Component Interface CacheVariable<T> Behavior")
{
// can default-initialize without throwing an exception
{
CacheVariable<double> cv;
Expand Down Expand Up @@ -2631,7 +2661,7 @@ void testCacheVariableInterface() {
// if downstream code tries to read an optional SimpleProperty without
// checking whether it's populated or not, it should throw an exception
// rather than segfaulting
void testIncorrectlyReadingAnOptionalSimplePropertyDoesNotSegfault()
TEST_CASE("Component Interface: Incorrectly Reading An Optional Simple Property Should Not Segfault (#3409/#3411)")
{
ComponentWithOptionalSimpleProperty c;

Expand All @@ -2650,7 +2680,7 @@ void testIncorrectlyReadingAnOptionalSimplePropertyDoesNotSegfault()
// OpenSim <=4.4) tries to read an optional ObjectProperty without checking
// whether it's populated or not, it should throw an exception rather
// than segfaulting
void testIncorrectlyReadingAnOptionalObjectPropertyDoesNotSegfault()
TEST_CASE("Component Interface: Incorrectly Reading an Optional Object Property Should Not Segfault (#3347)")
{
ComponentWithOptionalObjectProperty c;

Expand All @@ -2663,51 +2693,11 @@ void testIncorrectlyReadingAnOptionalObjectPropertyDoesNotSegfault()
}
}

int main() {

//Register new types for testing deserialization
const bool g_TestFixtureTypesAreRegistered = []()
{
// ensure new types are globally registered for testing deserialization
Object::registerType(Foo());
Object::registerType(Bar());
Object::registerType(TheWorld());

SimTK_START_TEST("testComponentInterface");
SimTK_SUBTEST(testMisc);
// Uncomment test for duplicate names when we re-enable the exception
//SimTK_SUBTEST(testThrowOnDuplicateNames);
SimTK_SUBTEST(testExceptionsFinalizeFromPropertiesAfterCopy);
SimTK_SUBTEST(testListInputs);
SimTK_SUBTEST(testListSockets);
SimTK_SUBTEST(testSocketCanConnectTo);
SimTK_SUBTEST(testInputCanConnectTo);
SimTK_SUBTEST(testComponentPathNames);
SimTK_SUBTEST(testFindComponent);
SimTK_SUBTEST(testTraversePathToComponent);
SimTK_SUBTEST(testGetStateVariableValue);
SimTK_SUBTEST(testGetStateVariableValueComponentPath);
SimTK_SUBTEST(testInputOutputConnections);
SimTK_SUBTEST(testInputConnecteePaths);
SimTK_SUBTEST(testExceptionsForConnecteeTypeMismatch);
SimTK_SUBTEST(testExceptionsSocketNameExistsAlready);
SimTK_SUBTEST(testExceptionsInputNameExistsAlready);
SimTK_SUBTEST(testExceptionsOutputNameExistsAlready);
SimTK_SUBTEST(testTableSource);
SimTK_SUBTEST(testTableReporter);
SimTK_SUBTEST(testAliasesAndLabels);

writeTimeSeriesTableForInputConnecteeSerialization();
SimTK_SUBTEST(testListInputConnecteeSerialization);
SimTK_SUBTEST(testSingleValueInputConnecteeSerialization);

// This is commented out since it adds ~20-30sec without testing
// any new functionality. Make sure to uncomment to use (and
// consider commenting other subtests for more stable benchmark).
//SimTK_SUBTEST(testGetAbsolutePathStringSpeed);

SimTK_SUBTEST(testFormattedDateTime);
SimTK_SUBTEST(testCacheVariableInterface);
SimTK_SUBTEST(testIncorrectlyReadingAnOptionalSimplePropertyDoesNotSegfault);
SimTK_SUBTEST(testIncorrectlyReadingAnOptionalObjectPropertyDoesNotSegfault);


SimTK_END_TEST();
}
return true;
}();