1 /**
2  * @file    TestReadFbcExtension.cpp
3  * @brief   Unit tests of writing FbcExtension
4  * @author  Fank T. Bergmann
5  *
6  * $Id: $
7  * $HeadURL: $
8  */
9 
10 #include <limits>
11 
12 #include <iostream>
13 #include <check.h>
14 #include <sbml/SBMLTypes.h>
15 #include <sbml/extension/SBMLExtensionRegistry.h>
16 #include <sbml/conversion/ConversionProperties.h>
17 #include <sbml/packages/fbc/extension/FbcModelPlugin.h>
18 #include <sbml/packages/fbc/extension/FbcExtension.h>
19 #include <sbml/packages/fbc/common/FbcExtensionTypes.h>
20 #include <sbml/packages/fbc/validator/FbcSBMLError.h>
21 #include <sbml/conversion/SBMLConverterRegistry.h>
22 #include <string>
23 
24 /** @cond doxygenIgnored */
25 
26 using namespace std;
27 LIBSBML_CPP_NAMESPACE_USE
28 
29 /** @endcond doxygenIgnored */
30 
31 CK_CPPSTART
32 
33 extern char *TestDataDirectory;
34 
START_TEST(test_FbcExtension_read_L3V1V1)35 START_TEST(test_FbcExtension_read_L3V1V1)
36 {
37   char *filename = safe_strcat(TestDataDirectory, "fbc_example1.xml");
38   SBMLDocument *document = readSBMLFromFile(filename);
39 
40   fail_unless(document->getPackageName() == "core");
41 
42   Model *model = document->getModel();
43 
44   fail_unless(model != NULL);
45   fail_unless(model->getPackageName() == "core");
46   fail_unless(document->getNumErrors() == 0);
47 
48   // get the fbc plugin
49 
50   FbcModelPlugin* mplugin = static_cast<FbcModelPlugin*>(model->getPlugin("fbc"));
51   fail_unless(mplugin != NULL);
52 
53   fail_unless(mplugin->getNumObjectives() == 1);
54   fail_unless(mplugin->getListOfObjectives()->getPackageName() == "fbc");
55 
56   Objective* objective = mplugin->getObjective(0);
57   fail_unless(objective->getId() == "obj1");
58   fail_unless(objective->getType() == "maximize");
59   fail_unless(objective->getNumFluxObjectives() == 1);
60   fail_unless(objective->getPackageName() == "fbc");
61 
62   fail_unless(objective->getListOfFluxObjectives()->getPackageName() == "fbc");
63 
64   FluxObjective* fluxObjective = objective->getFluxObjective(0);
65   fail_unless(fluxObjective->getReaction() == "J8");
66   fail_unless(fluxObjective->getPackageName() == "fbc");
67   fail_unless(fluxObjective->getCoefficient() == 1);
68 
69   fail_unless(mplugin->getNumFluxBounds() == 1);
70   fail_unless(mplugin->getListOfFluxBounds()->getPackageName() == "fbc");
71 
72   FluxBound* bound = mplugin->getFluxBound(0);
73   fail_unless(bound != NULL);
74 
75   fail_unless(bound->getId() == "bound1");
76   fail_unless(bound->getPackageName() == "fbc");
77   fail_unless(bound->getReaction() == "J0");
78   fail_unless(bound->getOperation() == "equal");
79   fail_unless(bound->getValue() == 10);
80 
81   safe_free(filename);
82   delete document;
83 }
84 END_TEST
85 
START_TEST(test_FbcExtension_read_L3V1V1_defaultNS)86 START_TEST(test_FbcExtension_read_L3V1V1_defaultNS)
87 {
88   char *filename = safe_strcat(TestDataDirectory, "fbc_example1_defaultNS.xml");
89 
90   SBMLDocument *document = readSBMLFromFile(filename);
91 
92   fail_unless(document->getPackageName() == "core");
93 
94   Model *model = document->getModel();
95 
96   fail_unless(model != NULL);
97   fail_unless(model->getPackageName() == "core");
98   fail_unless(document->getNumErrors() == 0);
99 
100   // get the fbc plugin
101 
102   FbcModelPlugin* mplugin = static_cast<FbcModelPlugin*>(model->getPlugin("fbc"));
103   fail_unless(mplugin != NULL);
104 
105   fail_unless(mplugin->getNumObjectives() == 1);
106   fail_unless(mplugin->getListOfObjectives()->getPackageName() == "fbc");
107 
108   Objective* objective = mplugin->getObjective(0);
109   fail_unless(objective->getId() == "obj1");
110   fail_unless(objective->getType() == "maximize");
111   fail_unless(objective->getNumFluxObjectives() == 1);
112   fail_unless(objective->getPackageName() == "fbc");
113 
114   fail_unless(objective->getListOfFluxObjectives()->getPackageName() == "fbc");
115 
116   FluxObjective* fluxObjective = objective->getFluxObjective(0);
117   fail_unless(fluxObjective->getReaction() == "J8");
118   fail_unless(fluxObjective->getPackageName() == "fbc");
119   fail_unless(fluxObjective->getCoefficient() == 1);
120 
121   fail_unless(mplugin->getNumFluxBounds() == 1);
122   fail_unless(mplugin->getListOfFluxBounds()->getPackageName() == "fbc");
123 
124   FluxBound* bound = mplugin->getFluxBound(0);
125   fail_unless(bound->getId() == "bound1");
126   fail_unless(bound->getPackageName() == "fbc");
127   fail_unless(bound->getReaction() == "J0");
128   fail_unless(bound->getOperation() == "equal");
129   fail_unless(bound->getValue() == 10);
130 
131   safe_free(filename);
132   delete document;
133 }
134 END_TEST
135 
START_TEST(test_FbcExtension_read_L3V1V1_unknown_elements)136 START_TEST(test_FbcExtension_read_L3V1V1_unknown_elements)
137 {
138   const char* s1 =
139     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
140     "<sbml xmlns=\"http://www.sbml.org/sbml/level3/version1/core\" xmlns:fbc=\"http://www.sbml.org/sbml/level3/version1/fbc/version1\" level=\"3\" version=\"1\" fbc:required=\"false\">\n"
141     "  <model>\n"
142     "    <listOfCompartments>\n"
143     "      <compartment id=\"cytosol\" constant=\"true\"/>\n"
144     "    </listOfCompartments>\n"
145     "    <listOfSpecies>\n"
146     "      <species id=\"ATPm\" compartment=\"mitochon\" initialConcentration=\"2\" hasOnlySubstanceUnits=\"false\" boundaryCondition=\"false\" constant=\"false\"/>\n"
147     "    </listOfSpecies>\n"
148     "    <listOfFluxBounds xmlns=\"http://www.sbml.org/sbml/level3/version1/fbc/version1\">\n"
149     "       <fluxBound id=\"bound1\" reaction=\"J0\" operation=\"equal\" value=\"10\" unkown=\"something\"/>\n"
150     "     </listOfFluxBounds>\n"
151     "     <listOfObjectives xmlns=\"http://www.sbml.org/sbml/level3/version1/fbc/version1\" activeObjective=\"obj1\">\n"
152     "       <objective id=\"obj1\" type=\"maximize\" unkown=\"something\">\n"
153     "         <listOfFluxes>\n"
154     "           <fluxObjective reaction=\"J8\" coefficient=\"1\" unkown=\"something\"/>\n"
155     "         </listOfFluxes>\n"
156     "       </objective>\n"
157     "     </listOfObjectives>\n"
158     "  </model>\n"
159     "</sbml>\n"
160     ;
161 
162   SBMLDocument *document = readSBMLFromString(s1);
163   Model *model = document->getModel();
164 
165   //document->printErrors();
166   //cout << document->getNumErrors() << endl;
167 
168   fail_unless(model != NULL);
169   fail_unless(document->getNumErrors() == 3);
170 
171   delete document;
172 }
173 END_TEST
174 
START_TEST(test_FbcExtension_OpertationTypes)175 START_TEST(test_FbcExtension_OpertationTypes)
176 {
177   // it seems we will drop the strict bounds, without breaking the models
178   // so we collapse the types
179   fail_unless(FluxBoundOperation_fromString("less") == FluxBoundOperation_fromString("lessEqual"));
180   fail_unless(FluxBoundOperation_fromString("greater") == FluxBoundOperation_fromString("greaterEqual"));
181 
182   fail_unless(strcmp(FluxBoundOperation_toString(FLUXBOUND_OPERATION_GREATER),
183     FluxBoundOperation_toString(FLUXBOUND_OPERATION_GREATER_EQUAL)) == 0);
184   fail_unless(strcmp(FluxBoundOperation_toString(FLUXBOUND_OPERATION_LESS),
185     FluxBoundOperation_toString(FLUXBOUND_OPERATION_LESS_EQUAL)) == 0);
186 }
187 END_TEST
188 
START_TEST(test_FbcExtension_read_L3V1V1_with_wonky_chemicals)189 START_TEST(test_FbcExtension_read_L3V1V1_with_wonky_chemicals)
190 {
191   const char* modelString = "<?xml version='1.0' encoding='UTF-8'?>"
192     "<sbml xmlns:html='http://www.w3.org/1999/xhtml' xmlns='http://www.sbml.org/sbml/level3/version1/core' xmlns:fbc='http://www.sbml.org/sbml/level3/version1/fbc/version1' level='3' version='1' fbc:required='false'>"
193     "  <model metaid='xxx' id='yyy' timeUnits='dimensionless'>"
194     "    <listOfCompartments>"
195     "      <compartment id='Internal_Species' name='Internal_Species' spatialDimensions='3' size='1' constant='false'/>"
196     "      <compartment id='External_Species' name='External_Species' spatialDimensions='3' size='1' constant='false'/>"
197     "    </listOfCompartments>"
198     "    <listOfSpecies>"
199     "      <species metaid='meta_B1' id='B1' name='Protein component' compartment='Internal_Species' initialConcentration='0' hasOnlySubstanceUnits='false' boundaryCondition='false' constant='false' fbc:chemicalFormula='PROTEIN COMPONENT'>"
200     "        <notes>"
201     "          <html:p>chemFormula: Protein component</html:p>"
202     "        </notes>"
203     "        <annotation>"
204     "          <listOfKeyValueData xmlns='http://pysces.sourceforge.net/KeyValueData'>"
205     "            <data id='chemFormula' type='string' value='Protein component'/>"
206     "          </listOfKeyValueData>"
207     "        </annotation>"
208     "      </species>"
209     "      <species metaid='meta_B2' id='B2' name='DNA component' compartment='Internal_Species' initialConcentration='0' hasOnlySubstanceUnits='false' boundaryCondition='false' constant='false' fbc:chemicalFormula='DNA COMPONENT'>"
210     "        <notes>"
211     "          <html:p>chemFormula: DNA component</html:p>"
212     "        </notes>"
213     "        <annotation>"
214     "          <listOfKeyValueData xmlns='http://pysces.sourceforge.net/KeyValueData'>"
215     "            <data id='chemFormula' type='string' value='DNA component'/>"
216     "          </listOfKeyValueData>"
217     "        </annotation>"
218     "      </species>"
219     "    </listOfSpecies>"
220     "    <listOfReactions>"
221     "      <reaction metaid='meta_R00192' id='R00192' name='R106' reversible='false' fast='false'>"
222     "        <notes>"
223     "          <html:p>EC Number: 3.3.1.1</html:p>"
224     "          <html:p>GENE ASSOCIATION: sll1234</html:p>"
225     "        </notes>"
226     "        <annotation>"
227     "          <listOfKeyValueData xmlns='http://pysces.sourceforge.net/KeyValueData'>"
228     "            <data id='EC_Number' type='string' value='3.3.1.1'/>"
229     "            <data id='GENE_ASSOCIATION' type='string' value='sll1234'/>"
230     "          </listOfKeyValueData>"
231     "        </annotation>"
232     "        <listOfReactants>"
233     "          <speciesReference species='B1' stoichiometry='1' constant='true'/>"
234     "        </listOfReactants>"
235     "        <listOfProducts>"
236     "          <speciesReference species='B2' stoichiometry='1' constant='true'/>"
237     "        </listOfProducts>"
238     "      </reaction>"
239     "    </listOfReactions>"
240     "    <fbc:listOfFluxBounds>"
241     "      <fbc:fluxBound fbc:reaction='R00192' fbc:operation='greaterEqual' fbc:value='0'/>"
242     "      <fbc:fluxBound fbc:reaction='R00192' fbc:operation='lessEqual' fbc:value='999999'/>     "
243     "    </fbc:listOfFluxBounds>"
244     "    <fbc:listOfObjectives fbc:activeObjective='obj'>"
245     "      <fbc:objective fbc:id='obj' fbc:type='maximize'>"
246     "        <fbc:listOfFluxObjectives>"
247     "          <fbc:fluxObjective fbc:reaction='R00192' fbc:coefficient='1'/>"
248     "        </fbc:listOfFluxObjectives>"
249     "      </fbc:objective>"
250     "    </fbc:listOfObjectives>"
251     "  </model>"
252     "</sbml>";
253 
254   SBMLDocument* doc = readSBMLFromString(modelString);
255   doc->checkConsistency();
256   fail_unless(doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
257 
258   //convert to cobra just to test
259   ConversionProperties prop;
260   prop.addOption("convert fbc to cobra", true);
261   fail_unless(doc->convert(prop) == LIBSBML_OPERATION_SUCCESS);
262 
263   // add species with notes
264   Species* testSpecies = doc->getModel()->createSpecies();
265   testSpecies->initDefaults();
266   testSpecies->setId("testSpecies");
267   testSpecies->setNotes(
268     "<body xmlns='http://www.w3.org/1999/xhtml'>"
269     "  <p>FORMULA: Fe2S2X</p>                   "
270     "  <p>CHARGE: -1</p>                        "
271     "</body>                                    "
272     );
273 
274   // convert it back
275   prop.addOption("convert cobra", true);
276   fail_unless(doc->convert(prop) == LIBSBML_OPERATION_SUCCESS);
277 
278   // check the formula
279   Species* tested = doc->getModel()->getSpecies("testSpecies");
280   fail_unless(tested != NULL);
281   FbcSpeciesPlugin* fbcSpeciesPlugin = dynamic_cast<FbcSpeciesPlugin*>(tested->getPlugin("fbc"));
282   fail_unless(fbcSpeciesPlugin != NULL);
283   fail_unless(fbcSpeciesPlugin->getCharge() == -1);
284   fail_unless(fbcSpeciesPlugin->getChemicalFormula() == "Fe2S2X");
285 
286   delete doc;
287 }
288 END_TEST
289 
START_TEST(test_FbcExtension_read_and_validate_chemicals)290 START_TEST(test_FbcExtension_read_and_validate_chemicals)
291 {
292   FbcPkgNamespaces *ns = new FbcPkgNamespaces();
293   SBMLDocument*doc = new SBMLDocument(ns);
294   doc->setPackageRequired("fbc", false);
295   Model* model = doc->createModel();
296   Compartment* comp = model->createCompartment();
297   comp->initDefaults();
298   comp->setId("comp");
299   comp->setSize(1);
300   Species *s = model->createSpecies();
301   s->initDefaults();
302   s->setId("s1");
303   s->setCompartment("comp");
304   s->setInitialAmount(1);
305   FbcSpeciesPlugin* splugin = static_cast<FbcSpeciesPlugin*>(s->getPlugin("fbc"));
306   fail_unless(splugin != NULL);
307 
308   // valid
309   splugin->setChemicalFormula("H2O");
310   doc->checkInternalConsistency();
311   fail_unless(!doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
312 
313   // valid
314   doc->getErrorLog()->clearLog();
315   splugin->setChemicalFormula("HO");
316   doc->checkInternalConsistency();
317   fail_unless(!doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
318 
319   // valid
320   doc->getErrorLog()->clearLog();
321   splugin->setChemicalFormula("");
322   doc->checkInternalConsistency();
323   fail_unless(!doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
324 
325   // invalid
326   doc->getErrorLog()->clearLog();
327   splugin->setChemicalFormula("hO");
328   doc->checkInternalConsistency();
329   fail_unless(doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
330 
331   // invalid
332   doc->getErrorLog()->clearLog();
333   splugin->setChemicalFormula("h1O");
334   doc->checkInternalConsistency();
335   fail_unless(doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
336 
337   // invalid
338   doc->getErrorLog()->clearLog();
339   splugin->setChemicalFormula("1hO");
340   doc->checkInternalConsistency();
341   fail_unless(doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
342 
343   // invalid
344   doc->getErrorLog()->clearLog();
345   splugin->setChemicalFormula("hO");
346   doc->checkInternalConsistency();
347   fail_unless(doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
348 
349   // invalid
350   doc->getErrorLog()->clearLog();
351   splugin->setChemicalFormula("_hO");
352   doc->checkInternalConsistency();
353   fail_unless(doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
354 
355   // invalid
356   doc->getErrorLog()->clearLog();
357   splugin->setChemicalFormula("H 2 O");
358   doc->checkInternalConsistency();
359   fail_unless(doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
360 
361   // invalid
362   doc->getErrorLog()->clearLog();
363   splugin->setChemicalFormula("H*_)(++2 O");
364   doc->checkInternalConsistency();
365   fail_unless(doc->getErrorLog()->contains(FbcSpeciesFormulaMustBeString));
366 
367   delete ns;
368   delete doc;
369 }
370 END_TEST
371 
START_TEST(test_FbcExtension_read_and_convert)372 START_TEST(test_FbcExtension_read_and_convert)
373 {
374   char *filename = safe_strcat(TestDataDirectory, "cobra-l2.xml");
375   SBMLDocument *document = readSBMLFromFile(filename);
376 
377   // ensure we have a model, and it has no errors
378   fail_unless(document->getModel() != NULL);
379   fail_unless(document->getNumErrors(LIBSBML_SEV_ERROR) == 0);
380   document->checkConsistency();
381   fail_unless(document->getNumErrors(LIBSBML_SEV_ERROR) == 0);
382 
383   // convert to L3
384   ConversionProperties props;
385   props.addOption("convert cobra", true);
386   props.addOption("checkCompatibility", true);
387 
388   int result = document->convert(props);
389 
390   // ensure that all is well with the model
391   fail_unless(result == LIBSBML_OPERATION_SUCCESS);
392   fail_unless(document->getNumErrors(LIBSBML_SEV_ERROR) == 0);
393 
394   Model* model = document->getModel();
395 
396   // NOW let us look at the units
397   fail_unless(model->isSetSubstanceUnits());
398   fail_unless(model->getSubstanceUnits() == "substance");
399   fail_unless(model->isSetTimeUnits());
400   fail_unless(model->isSetExtentUnits());
401   fail_unless(model->isSetAreaUnits());
402   fail_unless(model->isSetLengthUnits());
403 
404   // ok ... since we have all the units defined, there ought to be unit definitions
405   fail_unless(model->getNumUnitDefinitions() > 0);
406 
407   UnitDefinition* substance = model->getUnitDefinition("substance");
408   fail_unless(substance != NULL);
409 
410   Species* species = model->getSpecies("M_gamma_radiation_c");
411   fail_unless(species != NULL);
412 
413   FbcSpeciesPlugin* splug = dynamic_cast<FbcSpeciesPlugin*>(species->getPlugin("fbc"));
414   fail_unless(splug != NULL);
415 
416   fail_unless(splug->isSetCharge());
417   fail_unless(splug->getCharge() == 0);
418 
419   species = model->getSpecies("M_A3MP_c");
420   fail_unless(species != NULL);
421 
422   splug = dynamic_cast<FbcSpeciesPlugin*>(species->getPlugin("fbc"));
423   fail_unless(splug != NULL);
424 
425   fail_unless(splug->isSetCharge());
426   fail_unless(splug->getCharge() == 1);
427 
428   species = model->getSpecies("M_AC_c");
429   fail_unless(species != NULL);
430 
431   splug = dynamic_cast<FbcSpeciesPlugin*>(species->getPlugin("fbc"));
432   fail_unless(splug != NULL);
433 
434   fail_unless(splug->isSetCharge());
435   fail_unless(splug->getCharge() == 0);
436 
437   species = model->getSpecies("M_A23CMP_c");
438   fail_unless(species != NULL);
439 
440   splug = dynamic_cast<FbcSpeciesPlugin*>(species->getPlugin("fbc"));
441   fail_unless(splug != NULL);
442 
443   fail_unless(splug->isSetCharge());
444   fail_unless(splug->getCharge() == 1);
445 
446 
447 
448   std::string finalModel = writeSBMLToStdString(document);
449 
450   safe_free((void*)(filename));
451   delete document;
452 }
453 END_TEST
454 
455 
START_TEST(test_FbcExtension_read_and_convert_V1ToV2)456 START_TEST(test_FbcExtension_read_and_convert_V1ToV2)
457 {
458   // part 1 ... convert cobra to v1
459 
460   char *filename = safe_strcat(TestDataDirectory, "cobra-l2.xml");
461   SBMLDocument *document = readSBMLFromFile(filename);
462 
463   // ensure we have a model, and it has no errors
464   fail_unless(document->getModel() != NULL);
465   fail_unless(document->getNumErrors(LIBSBML_SEV_ERROR) == 0);
466   document->checkConsistency();
467   fail_unless(document->getNumErrors(LIBSBML_SEV_ERROR) == 0);
468 
469   std::string original = writeSBMLToStdString(document);
470 
471   // convert to L3
472   {
473     ConversionProperties props;
474     props.addOption("convert cobra", true);
475     props.addOption("checkCompatibility", true);
476 
477     int result = document->convert(props);
478 
479     // ensure that all is well with the model
480     fail_unless(result == LIBSBML_OPERATION_SUCCESS);
481 
482     fail_unless(document->getLevel() == 3);
483     fail_unless(document->getVersion() == 1);
484     fail_unless(document->getPlugin("fbc") != NULL);
485     fail_unless(document->getPlugin("fbc")->getPackageVersion() == 1);
486 
487   }
488 
489   std::string l3v1 = writeSBMLToStdString(document);
490 
491   // part 2 ... convert v1 to v2
492   {
493     ConversionProperties props;
494     props.addOption("convert fbc v1 to fbc v2", true);
495     props.addOption("strict", true);
496 
497     int result = document->convert(props);
498 
499     // ensure that all is well with the model
500     fail_unless(result == LIBSBML_OPERATION_SUCCESS);
501     fail_unless(document->getLevel() == 3);
502     fail_unless(document->getVersion() == 1);
503     fail_unless(document->getPlugin("fbc") != NULL);
504     fail_unless(document->getPlugin("fbc")->getPackageVersion() == 2);
505   }
506 
507   //std::string l3v1v2 = writeSBMLToStdString(document);
508 
509   // part 3 ... convert v2 to v1
510 
511   {
512     ConversionProperties props;
513     props.addOption("convert fbc v2 to fbc v1", true);
514 
515     int result = document->convert(props);
516 
517     // ensure that all is well with the model
518     fail_unless(result == LIBSBML_OPERATION_SUCCESS);
519     fail_unless(document->getLevel() == 3);
520     fail_unless(document->getVersion() == 1);
521     fail_unless(document->getPlugin("fbc") != NULL);
522     fail_unless(document->getPlugin("fbc")->getPackageVersion() == 1);
523 
524   }
525 
526   //std::string l3v1v1 = writeSBMLToStdString(document);
527   safe_free((void*)(filename));
528   delete document;
529 
530 }
531 END_TEST
532 
533 static bool
equals(const char * expected,const char * actual)534 equals(const char* expected, const char* actual)
535 {
536   if (!strcmp(expected, actual)) return true;
537 
538   printf("\nStrings are not equal:\n");
539   printf("Expected:\n[%s]\n", expected);
540   printf("Actual:\n[%s]\n", actual);
541 
542   return false;
543 }
544 
545 
546 
START_TEST(test_FbcExtension_read_L3V2V1_check_id)547 START_TEST(test_FbcExtension_read_L3V2V1_check_id)
548 {
549   const char* s1 =
550     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
551     "<sbml xmlns=\"http://www.sbml.org/sbml/level3/version2/core\" xmlns:fbc=\"http://www.sbml.org/sbml/level3/version1/fbc/version1\" level=\"3\" version=\"2\" fbc:required=\"false\">\n"
552     "  <model>\n"
553     "    <listOfCompartments>\n"
554     "      <compartment id=\"cytosol\" constant=\"true\"/>\n"
555     "    </listOfCompartments>\n"
556     "    <listOfSpecies>\n"
557     "      <species id=\"ATPm\" compartment=\"mitochon\" initialConcentration=\"2\" hasOnlySubstanceUnits=\"false\" boundaryCondition=\"false\" constant=\"false\"/>\n"
558     "    </listOfSpecies>\n"
559     "    <fbc:listOfFluxBounds>\n"
560     "      <fbc:fluxBound fbc:id=\"bound1\" fbc:reaction=\"J0\" fbc:operation=\"equal\" fbc:value=\"10\"/>\n"
561     "    </fbc:listOfFluxBounds>\n"
562     "    <fbc:listOfObjectives fbc:activeObjective=\"obj1\">\n"
563     "      <fbc:objective fbc:id=\"obj1\" fbc:type=\"maximize\"/>\n"
564     "    </fbc:listOfObjectives>\n"
565     "  </model>\n"
566     "</sbml>\n"
567     ;
568 
569   SBMLDocument *document = readSBMLFromString(s1);
570 
571   char * output = writeSBMLToString(document);
572 
573   fail_unless(equals(s1, output));
574 
575   safe_free(output);
576 
577   delete document;
578 }
579 END_TEST
580 
581 
582 Suite *
create_suite_ReadFbcExtension(void)583 create_suite_ReadFbcExtension(void)
584 {
585   Suite *suite = suite_create("ReadFbcExtension");
586   TCase *tcase = tcase_create("ReadFbcExtension");
587 
588   tcase_add_test(tcase, test_FbcExtension_OpertationTypes);
589   tcase_add_test(tcase, test_FbcExtension_read_L3V1V1);
590   tcase_add_test(tcase, test_FbcExtension_read_L3V1V1_defaultNS);
591   tcase_add_test(tcase, test_FbcExtension_read_L3V1V1_unknown_elements);
592   tcase_add_test(tcase, test_FbcExtension_read_L3V1V1_with_wonky_chemicals);
593   tcase_add_test(tcase, test_FbcExtension_read_and_validate_chemicals);
594   tcase_add_test(tcase, test_FbcExtension_read_and_convert);
595   tcase_add_test(tcase, test_FbcExtension_read_and_convert_V1ToV2);
596   tcase_add_test(tcase, test_FbcExtension_read_L3V2V1_check_id);
597   suite_add_tcase(suite, tcase);
598 
599   return suite;
600 }
601 
602 CK_CPPEND
603