From e33573c3fb15379d4cdd4be2042b3c44746c5619 Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Wed, 19 Aug 2026 20:42:24 -0700 Subject: [PATCH] Fix for #1330: add spaces after commas for generated IDs. --- test/c_api_core/CAPICoreTest.cpp | 112 ++++++++++++++++++++++++++++++- wrappers/C/rrc_api.cpp | 40 +++++------ 2 files changed, 130 insertions(+), 22 deletions(-) diff --git a/test/c_api_core/CAPICoreTest.cpp b/test/c_api_core/CAPICoreTest.cpp index 94668b9e26..526ab6b7f9 100644 --- a/test/c_api_core/CAPICoreTest.cpp +++ b/test/c_api_core/CAPICoreTest.cpp @@ -336,7 +336,7 @@ TEST_F(CAPICoreTest, CheckGetEC) { std::vector expectedRxns( { "_J0", "_J1" }); std::vector expectedIds( - { "ec(_J0,A)", "ec(_J0,AP)", "ec(_J0,K)", "ec(_J0,Vm1)", "ec(_J0,Km1)", "ec(_J1,A)", "ec(_J1,AP)", "ec(_J1,K)", "ec(_J1,Vm1)", "ec(_J1,Km1)"}); + { "ec(_J0, A)", "ec(_J0, AP)", "ec(_J0, K)", "ec(_J0, Vm1)", "ec(_J0, Km1)", "ec(_J1, A)", "ec(_J1, AP)", "ec(_J1, K)", "ec(_J1, Vm1)", "ec(_J1, Km1)"}); for (int r = 0; r < actual->Count; r++) { RRListItem* element = actual->Items[r]; @@ -363,7 +363,7 @@ TEST_F(CAPICoreTest, CheckGetUEC) { std::vector expectedRxns( { "_J0", "_J1" }); std::vector expectedIds( - { "uec(_J0,A)", "uec(_J0,AP)", "uec(_J0,K)", "uec(_J0,Vm1)", "uec(_J0,Km1)", "uec(_J1,A)", "uec(_J1,AP)", "uec(_J1,K)", "uec(_J1,Vm1)", "uec(_J1,Km1)"}); + { "uec(_J0, A)", "uec(_J0, AP)", "uec(_J0, K)", "uec(_J0, Vm1)", "uec(_J0, Km1)", "uec(_J1, A)", "uec(_J1, AP)", "uec(_J1, K)", "uec(_J1, Vm1)", "uec(_J1, Km1)"}); for (int r = 0; r < actual->Count; r++) { RRListItem* element = actual->Items[r]; @@ -381,6 +381,114 @@ TEST_F(CAPICoreTest, CheckGetUEC) { freeRRInstance(rrH); } +TEST_F(CAPICoreTest, CheckGetFluxControlCoefficientIds) { + + RRHandle rrH = createRRInstance(); + ASSERT_TRUE(loadSBMLFromFileE(rrH, (cAPICoreModelsDir / path("steadystate.xml")).string().c_str(), true)); + + RRListPtr actual = getFluxControlCoefficientIds(rrH); + std::vector expectedRxns( + { "_J0", "_J1" }); + std::vector expectedIds( + { "cc(_J0, K)", "cc(_J0, Vm1)", "cc(_J0, Km1)", "cc(_J1, K)", "cc(_J1, Vm1)", "cc(_J1, Km1)"}); + + for (int r = 0; r < actual->Count; r++) { + RRListItem* element = actual->Items[r]; + RRList* sublist = element->data.lValue; + char* id = sublist->Items[0]->data.sValue; + EXPECT_STREQ(id, expectedRxns[r].c_str()); + RRList* subsublist = sublist->Items[1]->data.lValue; + for (int sr=0; sr < subsublist->Count; sr++) { + char* id = subsublist->Items[sr]->data.sValue; + EXPECT_STREQ(id, expectedIds[r*subsublist->Count + sr].c_str()); + } + } + + freeRRList(actual); + freeRRInstance(rrH); +} + +TEST_F(CAPICoreTest, CheckGetUnscaledFluxControlCoefficientIds) { + + RRHandle rrH = createRRInstance(); + ASSERT_TRUE(loadSBMLFromFileE(rrH, (cAPICoreModelsDir / path("steadystate.xml")).string().c_str(), true)); + + RRListPtr actual = getUnscaledFluxControlCoefficientIds(rrH); + std::vector expectedRxns( + { "_J0", "_J1" }); + std::vector expectedIds( + { "ucc(_J0, K)", "ucc(_J0, Vm1)", "ucc(_J0, Km1)", "ucc(_J1, K)", "ucc(_J1, Vm1)", "ucc(_J1, Km1)"}); + + for (int r = 0; r < actual->Count; r++) { + RRListItem* element = actual->Items[r]; + RRList* sublist = element->data.lValue; + char* id = sublist->Items[0]->data.sValue; + EXPECT_STREQ(id, expectedRxns[r].c_str()); + RRList* subsublist = sublist->Items[1]->data.lValue; + for (int sr=0; sr < subsublist->Count; sr++) { + char* id = subsublist->Items[sr]->data.sValue; + EXPECT_STREQ(id, expectedIds[r*subsublist->Count + sr].c_str()); + } + } + + freeRRList(actual); + freeRRInstance(rrH); +} + +TEST_F(CAPICoreTest, CheckGetConcentrationControlCoefficientIds) { + + RRHandle rrH = createRRInstance(); + ASSERT_TRUE(loadSBMLFromFileE(rrH, (cAPICoreModelsDir / path("steadystate.xml")).string().c_str(), true)); + + RRListPtr actual = getConcentrationControlCoefficientIds(rrH); + std::vector expectedSpecies( + { "A", "AP" }); + std::vector expectedIds( + { "cc(A, K)", "cc(A, Vm1)", "cc(A, Km1)", "cc(AP, K)", "cc(AP, Vm1)", "cc(AP, Km1)"}); + + for (int r = 0; r < actual->Count; r++) { + RRListItem* element = actual->Items[r]; + RRList* sublist = element->data.lValue; + char* id = sublist->Items[0]->data.sValue; + EXPECT_STREQ(id, expectedSpecies[r].c_str()); + RRList* subsublist = sublist->Items[1]->data.lValue; + for (int sr=0; sr < subsublist->Count; sr++) { + char* id = subsublist->Items[sr]->data.sValue; + EXPECT_STREQ(id, expectedIds[r*subsublist->Count + sr].c_str()); + } + } + + freeRRList(actual); + freeRRInstance(rrH); +} + +TEST_F(CAPICoreTest, CheckGetUnscaledConcentrationControlCoefficientIds) { + + RRHandle rrH = createRRInstance(); + ASSERT_TRUE(loadSBMLFromFileE(rrH, (cAPICoreModelsDir / path("steadystate.xml")).string().c_str(), true)); + + RRListPtr actual = getUnscaledConcentrationControlCoefficientIds(rrH); + std::vector expectedSpecies( + { "A", "AP" }); + std::vector expectedIds( + { "ucc(A, K)", "ucc(A, Vm1)", "ucc(A, Km1)", "ucc(AP, K)", "ucc(AP, Vm1)", "ucc(AP, Km1)"}); + + for (int r = 0; r < actual->Count; r++) { + RRListItem* element = actual->Items[r]; + RRList* sublist = element->data.lValue; + char* id = sublist->Items[0]->data.sValue; + EXPECT_STREQ(id, expectedSpecies[r].c_str()); + RRList* subsublist = sublist->Items[1]->data.lValue; + for (int sr=0; sr < subsublist->Count; sr++) { + char* id = subsublist->Items[sr]->data.sValue; + EXPECT_STREQ(id, expectedIds[r*subsublist->Count + sr].c_str()); + } + } + + freeRRList(actual); + freeRRInstance(rrH); +} + TEST_F(CAPICoreTest, CheckSetTimeCourseSelectionListEx) { RRHandle rrH = createRRInstance(); diff --git a/wrappers/C/rrc_api.cpp b/wrappers/C/rrc_api.cpp index 578995a817..17f8da9e28 100644 --- a/wrappers/C/rrc_api.cpp +++ b/wrappers/C/rrc_api.cpp @@ -2965,17 +2965,17 @@ static ArrayList RoadRunner_getUnscaledFluxControlCoefficientIds(RoadRunner *rr) for(int i = 0; i < oParameters.size(); i++) { - oInner.push_back("ucc(" + s + "," + oParameters[i] + ")"); + oInner.push_back("ucc(" + s + ", " + oParameters[i] + ")"); } for(int i = 0; i < oBoundary.size(); i++) { - oInner.push_back("ucc(" + s + "," + oBoundary[i] + ")"); + oInner.push_back("ucc(" + s + ", " + oBoundary[i] + ")"); } for(int i = 0; i < oConservation.size(); i++) { - oInner.push_back("ucc(" + s + "," + oConservation[i] + ")"); + oInner.push_back("ucc(" + s + ", " + oConservation[i] + ")"); } oCCReaction.Add(oInner); @@ -3098,17 +3098,17 @@ ArrayList sel_getFluxControlCoefficientIds(RoadRunner* rr) for(int i = 0; i < oParameters.size(); i++) { - oInner.add("cc(" + s + "," + oParameters[i] + ")"); + oInner.add("cc(" + s + ", " + oParameters[i] + ")"); } for(int i = 0; i < oBoundary.size(); i++) { - oInner.add("cc(" + s + "," + oBoundary[i] + ")"); + oInner.add("cc(" + s + ", " + oBoundary[i] + ")"); } for(int i = 0; i < oConservation.size(); i++) { - oInner.add("cc(" + s + "," + oConservation[i] + ")"); + oInner.add("cc(" + s + ", " + oConservation[i] + ")"); } oCCReaction.Add(oInner); @@ -3205,17 +3205,17 @@ ArrayList sel_getConcentrationControlCoefficientIds(RoadRunner* rr) for(int i = 0; i < oParameters.size(); i++) { - oInner.add("cc(" + s + "," + oParameters[i] + ")"); + oInner.add("cc(" + s + ", " + oParameters[i] + ")"); } for(int i = 0; i < oBoundary.size(); i++) { - oInner.add("cc(" + s + "," + oBoundary[i] + ")"); + oInner.add("cc(" + s + ", " + oBoundary[i] + ")"); } for(int i = 0; i < oConservation.size(); i++) { - oInner.add("cc(" + s + "," + oConservation[i] + ")"); + oInner.add("cc(" + s + ", " + oConservation[i] + ")"); } oCCFloating.Add(oInner); @@ -3243,17 +3243,17 @@ ArrayList sel_getUnscaledConcentrationControlCoefficientIds(RoadRunner* rr) for(int i = 0; i < oParameters.size(); i++) { - oInner.push_back("ucc(" + s + "," + oParameters[i] + ")"); + oInner.push_back("ucc(" + s + ", " + oParameters[i] + ")"); } for(int i = 0; i < oBoundary.size(); i++) { - oInner.push_back("ucc(" + s + "," + oBoundary[i] + ")"); + oInner.push_back("ucc(" + s + ", " + oBoundary[i] + ")"); } for(int i = 0; i < oConservation.size(); i++) { - oInner.push_back("ucc(" + s + "," + oConservation[i] + ")"); + oInner.push_back("ucc(" + s + ", " + oConservation[i] + ")"); } oCCFloating.Add(oInner); @@ -3282,22 +3282,22 @@ ArrayList sel_getElasticityCoefficientIds(RoadRunner* rr) for(int j = 0; j < floatingSpeciesNames.size(); j++) { - oInner.add(format("ec({0},{1})", reac_name, floatingSpeciesNames[j])); + oInner.add(format("ec({0}, {1})", reac_name, floatingSpeciesNames[j])); } for(int j = 0; j < boundarySpeciesNames.size(); j++) { - oInner.add(format("ec({0},{1})", reac_name, boundarySpeciesNames[j])); + oInner.add(format("ec({0}, {1})", reac_name, boundarySpeciesNames[j])); } for(int j = 0; j < globalParameterNames.size(); j++) { - oInner.add(format("ec({0},{1})", reac_name, globalParameterNames[j])); + oInner.add(format("ec({0}, {1})", reac_name, globalParameterNames[j])); } for(int j = 0; j < conservationNames.size(); j++) { - oInner.add(format("ec({0},{1})", reac_name, conservationNames[j])); + oInner.add(format("ec({0}, {1})", reac_name, conservationNames[j])); } oCCReaction.Add(oInner); @@ -3327,25 +3327,25 @@ ArrayList sel_getUnscaledElasticityCoefficientIds(RoadRunner* rr) for(int j = 0; j < oFloating.size(); j++) { string variable = oFloating[j]; - oInner.add(format("uec({0},{1})", reac_name, variable)); + oInner.add(format("uec({0}, {1})", reac_name, variable)); } for(int j = 0; j < oBoundary.size(); j++) { string variable = oBoundary[j]; - oInner.add(format("uec({0},{1})", reac_name, variable)); + oInner.add(format("uec({0}, {1})", reac_name, variable)); } for(int j = 0; j < oGlobalParameters.size(); j++) { string variable = oGlobalParameters[j]; - oInner.add(format("uec({0},{1})", reac_name, variable)); + oInner.add(format("uec({0}, {1})", reac_name, variable)); } for(int j = 0; j < oConservation.size(); j++) { string variable = oConservation[j]; - oInner.add(format("uec({0},{1})", reac_name, variable)); + oInner.add(format("uec({0}, {1})", reac_name, variable)); } oCCReaction.Add(oInner);