1 /**
2  * \file    TestWriteL3SBML.cpp
3  * \brief   Write SBML unit tests
4  * \author  Sarah Keating
5  *
6  * <!--------------------------------------------------------------------------
7  * This file is part of libSBML.  Please visit http://sbml.org for more
8  * information about SBML, and the latest version of libSBML.
9  *
10  * Copyright (C) 2020 jointly by the following organizations:
11  *     1. California Institute of Technology, Pasadena, CA, USA
12  *     2. University of Heidelberg, Heidelberg, Germany
13  *     3. University College London, London, UK
14  *
15  * Copyright (C) 2019 jointly by the following organizations:
16  *     1. California Institute of Technology, Pasadena, CA, USA
17  *     2. University of Heidelberg, Heidelberg, Germany
18  *
19  * Copyright (C) 2013-2018 jointly by the following organizations:
20  *     1. California Institute of Technology, Pasadena, CA, USA
21  *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
22  *     3. University of Heidelberg, Heidelberg, Germany
23  *
24  * Copyright (C) 2009-2013 jointly by the following organizations:
25  *     1. California Institute of Technology, Pasadena, CA, USA
26  *     2. EMBL European Bioinformatics Institute (EMBL-EBI), Hinxton, UK
27  *
28  * Copyright (C) 2006-2008 by the California Institute of Technology,
29  *     Pasadena, CA, USA
30  *
31  * Copyright (C) 2002-2005 jointly by the following organizations:
32  *     1. California Institute of Technology, Pasadena, CA, USA
33  *     2. Japan Science and Technology Agency, Japan
34  *
35  * This library is free software; you can redistribute it and/or modify it
36  * under the terms of the GNU Lesser General Public License as published by
37  * the Free Software Foundation.  A copy of the license agreement is provided
38  * in the file named "LICENSE.txt" included with this software distribution
39  * and also available online as http://sbml.org/software/libsbml/license.html
40  * ---------------------------------------------------------------------- -->*/
41 
42 #include <iostream>
43 #include <sstream>
44 
45 #include <sbml/xml/XMLOutputStream.h>
46 #include <sbml/xml/XMLNode.h>
47 #include <sbml/util/util.h>
48 
49 #include <sbml/SBMLTypes.h>
50 #include <sbml/SBMLWriter.h>
51 
52 #include <check.h>
53 
54 /** @cond doxygenIgnored */
55 
56 using namespace std;
57 LIBSBML_CPP_NAMESPACE_USE
58 
59 /** @endcond */
60 
61 
62 #include <sbml/common/extern.h>
63 
64 BEGIN_C_DECLS
65 
66 /**
67  * Wraps the string s in the appropriate XML boilerplate.
68  */
69 #define XML_START   "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
70 #define SBML_START  "<sbml "
71 #define NS_L3v1     "xmlns=\"http://www.sbml.org/sbml/level3/version1/core\" "
72 #define LV_L3v1     "level=\"3\" version=\"1\">\n"
73 #define SBML_END    "</sbml>\n"
74 
75 #define wrapXML(s)        XML_START s
76 #define wrapSBML_L3v1(s)  XML_START SBML_START NS_L3v1 LV_L3v1 s SBML_END
77 
78 
79 static SBMLDocument* D;
80 
81 
82 static void
WriteL3SBML_setup()83 WriteL3SBML_setup ()
84 {
85   D = new SBMLDocument();
86   D->setLevelAndVersion(3, 1, false);
87 }
88 
89 
90 static void
WriteL3SBML_teardown()91 WriteL3SBML_teardown ()
92 {
93   delete D;
94 }
95 
96 
97 static bool
equals(const char * expected,const char * actual)98 equals (const char* expected, const char* actual)
99 {
100   if ( !strcmp(expected, actual) ) return true;
101 
102   printf( "\nStrings are not equal:\n"  );
103   printf( "Expected:\n[%s]\n", expected );
104   printf( "Actual:\n[%s]\n"  , actual   );
105 
106   return false;
107 }
108 
109 
START_TEST(test_WriteL3SBML_error)110 START_TEST (test_WriteL3SBML_error)
111 {
112   SBMLDocument *d = new SBMLDocument();
113   SBMLWriter   *w = new SBMLWriter();
114 
115   fail_unless( ! w->writeSBML(d, "/tmp/impossible/path/should/fail") );
116   fail_unless( d->getNumErrors() == 1 );
117   fail_unless( d->getError(0)->getErrorId() == XMLFileUnwritable );
118 
119   delete d;
120   delete w;
121 }
122 END_TEST
123 
124 
START_TEST(test_SBMLWriter_L3_create)125 START_TEST (test_SBMLWriter_L3_create)
126 {
127   SBMLWriter_t   *w = SBMLWriter_create();
128 
129   fail_unless( w != NULL );
130 
131   SBMLWriter_free(w);
132 }
133 END_TEST
134 
135 
START_TEST(test_SBMLWriter_L3_setProgramName)136 START_TEST (test_SBMLWriter_L3_setProgramName)
137 {
138   SBMLWriter_t   *w = SBMLWriter_create();
139 
140   fail_unless( w != NULL );
141 
142   int i = SBMLWriter_setProgramName(w, "sss");
143 
144   fail_unless ( i == LIBSBML_OPERATION_SUCCESS);
145 
146   i = SBMLWriter_setProgramName(w, NULL);
147 
148   fail_unless ( i == LIBSBML_OPERATION_SUCCESS);
149 
150   SBMLWriter_free(w);
151 }
152 END_TEST
153 
154 
START_TEST(test_SBMLWriter_L3_setProgramVersion)155 START_TEST (test_SBMLWriter_L3_setProgramVersion)
156 {
157   SBMLWriter_t   *w = SBMLWriter_create();
158 
159   fail_unless( w != NULL );
160 
161   int i = SBMLWriter_setProgramVersion(w, "sss");
162 
163   fail_unless ( i == LIBSBML_OPERATION_SUCCESS);
164 
165   i = SBMLWriter_setProgramVersion(w, NULL);
166 
167   fail_unless ( i == LIBSBML_OPERATION_SUCCESS);
168 
169   SBMLWriter_free(w);
170 }
171 END_TEST
172 
173 
START_TEST(test_WriteL3SBML_SBMLDocument_L3v1)174 START_TEST (test_WriteL3SBML_SBMLDocument_L3v1)
175 {
176   const char *expected = wrapXML
177   (
178     "<sbml xmlns=\"http://www.sbml.org/sbml/level3/version1/core\" "
179     "level=\"3\" version=\"1\"/>\n"
180   );
181 
182 
183   string S = writeSBMLToStdString(D);
184 
185   fail_unless( equals(expected, S.c_str()) );
186 }
187 END_TEST
188 
189 
START_TEST(test_WriteL3SBML_Model)190 START_TEST (test_WriteL3SBML_Model)
191 {
192   const char* expected = wrapSBML_L3v1(
193     "  <model/>\n"
194     );
195 
196   Model * m = D->createModel("");
197   (void) m;
198 
199   string S = writeSBMLToStdString(D);
200 
201   fail_unless( equals(expected, S.c_str()) );
202 }
203 END_TEST
204 
205 
START_TEST(test_WriteL3SBML_Model_substanceUnits)206 START_TEST (test_WriteL3SBML_Model_substanceUnits)
207 {
208   const char* expected = wrapSBML_L3v1(
209     "  <model substanceUnits=\"mole\"/>\n"
210     );
211 
212   Model * m = D->createModel("");
213   m->setSubstanceUnits("mole");
214 
215 
216   string S = writeSBMLToStdString(D);
217 
218   fail_unless( equals(expected, S.c_str()) );
219 }
220 END_TEST
221 
222 
START_TEST(test_WriteL3SBML_Model_timeUnits)223 START_TEST (test_WriteL3SBML_Model_timeUnits)
224 {
225   const char* expected = wrapSBML_L3v1(
226     "  <model timeUnits=\"second\"/>\n"
227     );
228 
229   Model * m = D->createModel("");
230   m->setTimeUnits("second");
231 
232 
233   string S = writeSBMLToStdString(D);
234 
235   fail_unless( equals(expected, S.c_str()) );
236 }
237 END_TEST
238 
239 
START_TEST(test_WriteL3SBML_Model_otherUnits)240 START_TEST (test_WriteL3SBML_Model_otherUnits)
241 {
242   const char* expected = wrapSBML_L3v1(
243     "  <model volumeUnits=\"litre\" areaUnits=\"area\" lengthUnits=\"metre\"/>\n"
244     );
245 
246   Model * m = D->createModel("");
247   m->setVolumeUnits("litre");
248   m->setAreaUnits("area");
249   m->setLengthUnits("metre");
250 
251   string S = writeSBMLToStdString(D);
252 
253   fail_unless( equals(expected, S.c_str()) );
254 }
255 END_TEST
256 
257 
START_TEST(test_WriteL3SBML_Model_conversionFactor)258 START_TEST (test_WriteL3SBML_Model_conversionFactor)
259 {
260   const char* expected = wrapSBML_L3v1(
261     "  <model conversionFactor=\"p\"/>\n"
262     );
263 
264   Model * m = D->createModel("");
265   m->setConversionFactor("p");
266 
267 
268   string S = writeSBMLToStdString(D);
269 
270   fail_unless( equals(expected, S.c_str()) );
271 }
272 END_TEST
273 
274 
START_TEST(test_WriteL3SBML_Unit)275 START_TEST (test_WriteL3SBML_Unit)
276 {
277   const char* expected = "<unit kind=\"kilogram\" exponent=\"0.2\""
278     " scale=\"-3\" multiplier=\"3.2\"/>";
279 
280 
281   Unit* u = D->createModel()->createUnitDefinition()->createUnit();
282   u->setKind(UNIT_KIND_KILOGRAM);
283   double exp = 0.2;
284   u->setExponent(exp);
285   u->setScale(-3);
286   u->setMultiplier(3.2);
287 
288   char* sbml = u->toSBML();
289   fail_unless( equals(expected, sbml) );
290   safe_free(sbml);
291 }
292 END_TEST
293 
294 
START_TEST(test_WriteL3SBML_Unit_noValues)295 START_TEST (test_WriteL3SBML_Unit_noValues)
296 {
297   const char* expected = "<unit/>";
298 
299 
300   Unit* u = D->createModel()->createUnitDefinition()->createUnit();
301 
302   char* usbml = u->toSBML();
303   fail_unless( equals(expected, usbml) );
304   safe_free(usbml);
305 
306 }
307 END_TEST
308 
309 
START_TEST(test_WriteL3SBML_UnitDefinition)310 START_TEST (test_WriteL3SBML_UnitDefinition)
311 {
312 
313   const char* expected =
314     "<unitDefinition id=\"myUnit\">\n"
315     "  <listOfUnits>\n"
316     "    <unit kind=\"mole\" exponent=\"1\" scale=\"0\" multiplier=\"1.8\"/>\n"
317     "  </listOfUnits>\n"
318     "</unitDefinition>";
319 
320   UnitDefinition* ud = D->createModel()->createUnitDefinition();
321   ud->setId("myUnit");
322 
323   Unit* u1 = ud->createUnit();
324   u1->setKind(UnitKind_forName("mole"));
325   u1->setMultiplier(1.8);
326   u1->setScale(0);
327   u1->setExponent(1);
328 
329   char* sbml = ud->toSBML();
330   fail_unless( equals(expected, sbml) );
331   safe_free(sbml);
332 }
333 END_TEST
334 
335 
START_TEST(test_WriteL3SBML_Compartment)336 START_TEST (test_WriteL3SBML_Compartment)
337 {
338   const char* expected = "<compartment id=\"A\" constant=\"true\"/>";
339 
340   Compartment *c = D->createModel()->createCompartment();
341   c->setId("A");
342 
343   c->setConstant(true);
344 
345   char* sbml = c->toSBML();
346   fail_unless( equals(expected, sbml) );
347   safe_free(sbml);
348 }
349 END_TEST
350 
351 
START_TEST(test_WriteL3SBML_Compartment_spatialDimensions)352 START_TEST (test_WriteL3SBML_Compartment_spatialDimensions)
353 {
354   const char* expected = "<compartment id=\"A\" spatialDimensions=\"2.1\" "
355     "constant=\"false\"/>";
356 
357   const char* expected1 = "<compartment id=\"A\" constant=\"false\"/>";
358 
359   Compartment *c = D->createModel()->createCompartment();
360   c->setId("A");
361 
362   c->setConstant(false);
363   c->setSpatialDimensions(2.1);
364 
365   char* sbml = c->toSBML();
366   fail_unless( equals(expected, sbml) );
367   safe_free(sbml);
368 
369   c->unsetSpatialDimensions();
370 
371   sbml = c->toSBML();
372   fail_unless( equals(expected1, sbml) );
373   safe_free(sbml);
374 }
375 END_TEST
376 
377 
START_TEST(test_WriteL3SBML_Species)378 START_TEST (test_WriteL3SBML_Species)
379 {
380   const char* expected =
381     "<species id=\"Ca2\" compartment=\"cell\" initialAmount=\"0.7\""
382     " substanceUnits=\"mole\" hasOnlySubstanceUnits=\"false\""
383     " boundaryCondition=\"true\" constant=\"true\"/>";
384 
385 
386   Species *s = D->createModel()->createSpecies();
387   s->setId("Ca2");
388   s->setCompartment("cell");
389   s->setInitialAmount(0.7);
390   s->setUnits("mole");
391   s->setBoundaryCondition(true);
392   s->setHasOnlySubstanceUnits(false);
393   s->setConstant(true);
394 
395   char* sbml = s->toSBML();
396   fail_unless( equals(expected, sbml) );
397   safe_free(sbml);
398 }
399 END_TEST
400 
401 
START_TEST(test_WriteL3SBML_Species_conversionFactor)402 START_TEST (test_WriteL3SBML_Species_conversionFactor)
403 {
404   const char* expected =
405     "<species id=\"Ca2\" compartment=\"cell\""
406     " hasOnlySubstanceUnits=\"false\""
407     " boundaryCondition=\"true\" constant=\"true\""
408     " conversionFactor=\"p\"/>";
409 
410   const char* expected1 =
411     "<species id=\"Ca2\" compartment=\"cell\""
412     " hasOnlySubstanceUnits=\"false\""
413     " boundaryCondition=\"true\" constant=\"true\"/>";
414 
415   Species *s = D->createModel()->createSpecies();
416   s->setId("Ca2");
417   s->setCompartment("cell");
418   s->setBoundaryCondition(true);
419   s->setHasOnlySubstanceUnits(false);
420   s->setConstant(true);
421   s->setConversionFactor("p");
422 
423   char* sbml = s->toSBML();
424   fail_unless( equals(expected, sbml) );
425   safe_free(sbml);
426 
427   s->unsetConversionFactor();
428 
429   sbml = s->toSBML();
430   fail_unless( equals(expected1, sbml) );
431   safe_free(sbml);
432 }
433 END_TEST
434 
435 
START_TEST(test_WriteL3SBML_Parameter)436 START_TEST (test_WriteL3SBML_Parameter)
437 {
438   const char* expected = "<parameter id=\"Km1\" value=\"2.3\""
439     " units=\"second\" constant=\"true\"/>";
440 
441 
442   Parameter *p = D->createModel()->createParameter();
443   p->setId("Km1");
444   p->setValue(2.3);
445   p->setUnits("second");
446   p->setConstant(true);
447 
448   char* sbml = p->toSBML();
449   fail_unless( equals(expected, sbml) );
450   safe_free(sbml);
451 }
452 END_TEST
453 
454 
START_TEST(test_WriteL3SBML_Reaction)455 START_TEST (test_WriteL3SBML_Reaction)
456 {
457   const char* expected = "<reaction id=\"r\" reversible=\"false\""
458     " fast=\"true\"/>";
459 
460 
461   Reaction *r = D->createModel()->createReaction();
462   r->setId("r");
463   r->setReversible(false);
464   r->setFast(true);
465 
466   char* sbml = r->toSBML();
467   fail_unless( equals(expected, sbml) );
468   safe_free(sbml);
469 }
470 END_TEST
471 
472 
START_TEST(test_WriteL3SBML_Reaction_compartment)473 START_TEST (test_WriteL3SBML_Reaction_compartment)
474 {
475   const char* expected = "<reaction id=\"r\" reversible=\"false\""
476     " fast=\"true\" compartment=\"c\"/>";
477 
478   const char* expected1 = "<reaction id=\"r\" reversible=\"false\""
479     " fast=\"true\"/>";
480 
481   Reaction *r = D->createModel()->createReaction();
482   r->setId("r");
483   r->setReversible(false);
484   r->setFast(true);
485   r->setCompartment("c");
486 
487   char* sbml = r->toSBML();
488   fail_unless( equals(expected, sbml) );
489   safe_free(sbml);
490 
491   r->unsetCompartment();
492 
493   sbml = r->toSBML();
494   fail_unless( equals(expected1, sbml) );
495   safe_free(sbml);
496 }
497 END_TEST
498 
499 
START_TEST(test_WriteL3SBML_Reaction_full)500 START_TEST (test_WriteL3SBML_Reaction_full)
501 {
502   const char* expected =
503     "<reaction id=\"v1\" reversible=\"true\" fast=\"false\">\n"
504     "  <listOfReactants>\n"
505     "    <speciesReference species=\"x0\"/>\n"
506     "  </listOfReactants>\n"
507     "  <listOfProducts>\n"
508     "    <speciesReference species=\"s1\"/>\n"
509     "  </listOfProducts>\n"
510     "  <listOfModifiers>\n"
511     "    <modifierSpeciesReference species=\"m1\"/>\n"
512     "  </listOfModifiers>\n"
513     "  <kineticLaw>\n"
514     "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
515     "      <apply>\n"
516     "        <divide/>\n"
517     "        <apply>\n"
518     "          <times/>\n"
519     "          <ci> vm </ci>\n"
520     "          <ci> s1 </ci>\n"
521     "        </apply>\n"
522     "        <apply>\n"
523     "          <plus/>\n"
524     "          <ci> km </ci>\n"
525     "          <ci> s1 </ci>\n"
526     "        </apply>\n"
527     "      </apply>\n"
528     "    </math>\n"
529     "  </kineticLaw>\n"
530     "</reaction>";
531 
532 
533   D->createModel();
534 
535   Reaction* r = D->getModel()->createReaction();
536 
537   r->setId("v1");
538   r->setReversible(true);
539   r->setFast(false);
540 
541   r->createReactant()->setSpecies("x0");
542   r->createProduct ()->setSpecies("s1");
543   r->createModifier()->setSpecies("m1");
544 
545   r->createKineticLaw()->setFormula("(vm * s1)/(km + s1)");
546 
547   char* sbml = r->toSBML();
548   fail_unless( equals(expected, sbml) );
549   safe_free(sbml);
550 }
551 END_TEST
552 
553 
START_TEST(test_WriteL3SBML_SpeciesReference)554 START_TEST (test_WriteL3SBML_SpeciesReference)
555 {
556   const char* expected = "<speciesReference species=\"s\""
557     " stoichiometry=\"3\" constant=\"true\"/>";
558 
559 
560   SpeciesReference *sr = D->createModel()->createReaction()->createReactant();
561   sr->setSpecies("s");
562   sr->setStoichiometry(3);
563   sr->setConstant(true);
564 
565   char* sbml = sr->toSBML();
566   fail_unless( equals(expected, sbml) );
567   safe_free(sbml);
568 }
569 END_TEST
570 
571 
START_TEST(test_WriteL3SBML_KineticLaw_ListOfParameters)572 START_TEST (test_WriteL3SBML_KineticLaw_ListOfParameters)
573 {
574   const char* expected =
575     "<kineticLaw>\n"
576     "  <listOfLocalParameters>\n"
577     "    <localParameter id=\"n\" value=\"1.2\"/>\n"
578     "  </listOfLocalParameters>\n"
579     "</kineticLaw>";
580 
581   KineticLaw *kl = D->createModel()->createReaction()->createKineticLaw();
582 
583   LocalParameter *p = kl->createLocalParameter();
584   p->setId("n");
585   p->setValue(1.2);
586 
587   char* sbml = kl->toSBML();
588   fail_unless( equals(expected, sbml) );
589   safe_free(sbml);
590 }
591 END_TEST
592 
593 
START_TEST(test_WriteL3SBML_Event)594 START_TEST (test_WriteL3SBML_Event)
595 {
596   const char* expected = "<event id=\"e\" useValuesFromTriggerTime=\"true\"/>";
597 
598   Event *e = D->createModel()->createEvent();
599   e->setId("e");
600   e->setUseValuesFromTriggerTime(true);
601 
602   char* sbml = e->toSBML();
603   fail_unless( equals(expected, sbml) );
604   safe_free(sbml);
605 }
606 END_TEST
607 
608 
START_TEST(test_WriteL3SBML_Event_useValues)609 START_TEST (test_WriteL3SBML_Event_useValues)
610 {
611   const char* expected =
612     "<event id=\"e\" useValuesFromTriggerTime=\"false\">\n"
613     "  <delay/>\n"
614     "</event>";
615 
616   Event *e = D->createModel()->createEvent();
617   e->setId("e");
618   e->setUseValuesFromTriggerTime(false);
619   e->createDelay();
620 
621   char* sbml = e->toSBML();
622   fail_unless( equals(expected, sbml) );
623   safe_free(sbml);
624 }
625 END_TEST
626 
627 
START_TEST(test_WriteL3SBML_Trigger)628 START_TEST (test_WriteL3SBML_Trigger)
629 {
630   const char* expected = "<trigger/>";
631 
632   Trigger *t = D->createModel()->createEvent()->createTrigger();
633 
634   char* tsbml = t->toSBML();
635   fail_unless( equals(expected,tsbml) );
636   safe_free(tsbml);
637 }
638 END_TEST
639 
640 
START_TEST(test_WriteL3SBML_Trigger_initialValue)641 START_TEST (test_WriteL3SBML_Trigger_initialValue)
642 {
643   const char* expected = "<trigger initialValue=\"false\" persistent=\"true\"/>";
644 
645   Trigger *t = D->createModel()->createEvent()->createTrigger();
646   t->setInitialValue(false);
647   t->setPersistent(true);
648 
649   char* tsbml = t->toSBML();
650   fail_unless( equals(expected,tsbml) );
651   safe_free(tsbml);
652 }
653 END_TEST
654 
655 
START_TEST(test_WriteL3SBML_Trigger_persistent)656 START_TEST (test_WriteL3SBML_Trigger_persistent)
657 {
658   const char* expected = "<trigger initialValue=\"true\" persistent=\"false\"/>";
659 
660   Trigger *t = D->createModel()->createEvent()->createTrigger();
661   t->setPersistent(false);
662   t->setInitialValue(true);
663 
664   char* tsbml = t->toSBML();
665   fail_unless( equals(expected,tsbml) );
666   safe_free(tsbml);
667 }
668 END_TEST
669 
670 
START_TEST(test_WriteL3SBML_Priority)671 START_TEST (test_WriteL3SBML_Priority)
672 {
673   const char* expected = "<priority/>";
674 
675   Priority *p = D->createModel()->createEvent()->createPriority();
676 
677   char* sbml = p->toSBML();
678   fail_unless( equals(expected,sbml) );
679   safe_free(sbml);
680 }
681 END_TEST
682 
683 
START_TEST(test_WriteL3SBML_Event_full)684 START_TEST (test_WriteL3SBML_Event_full)
685 {
686   const char* expected =
687     "<event useValuesFromTriggerTime=\"true\">\n"
688     "  <trigger initialValue=\"true\" persistent=\"false\">\n"
689     "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
690     "      <true/>\n"
691     "    </math>\n"
692     "  </trigger>\n"
693     "  <priority>\n"
694     "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
695     "      <cn type=\"integer\"> 2 </cn>\n"
696     "    </math>\n"
697     "  </priority>\n"
698     "</event>";
699 
700   Event *e = D->createModel()->createEvent();
701   e->setUseValuesFromTriggerTime(true);
702   Trigger *t = e->createTrigger();
703   t->setInitialValue(true);
704   t->setPersistent(false);
705   ASTNode         *math1   = SBML_parseFormula("true");
706   t->setMath(math1);
707   Priority *p = e->createPriority();
708   ASTNode         *math2   = SBML_parseFormula("2");
709   p->setMath(math2);
710 
711 
712   char* sbml = e->toSBML();
713   fail_unless( equals(expected,sbml) );
714   safe_free(sbml);
715   delete math1;
716   delete math2;
717 }
718 END_TEST
719 
720 
START_TEST(test_WriteL3SBML_NaN)721 START_TEST (test_WriteL3SBML_NaN)
722 {
723   const char* expected = "<parameter id=\"p\" value=\"NaN\""
724     " constant=\"true\"/>";
725 
726   Parameter *p = D->createModel()->createParameter();
727   p->setId("p");
728   p->setValue(util_NaN());
729   p->setConstant(true);
730 
731   char* sbml = p->toSBML();
732   fail_unless( equals(expected,sbml) );
733   safe_free(sbml);
734 }
735 END_TEST
736 
737 
START_TEST(test_WriteL3SBML_INF)738 START_TEST (test_WriteL3SBML_INF)
739 {
740   const char* expected = "<parameter id=\"p\" value=\"INF\""
741     " constant=\"true\"/>";
742 
743   Parameter *p = D->createModel()->createParameter();
744   p->setId("p");
745   p->setValue(util_PosInf());
746   p->setConstant(true);
747 
748   char* sbml = p->toSBML();
749   fail_unless( equals(expected,sbml) );
750   safe_free(sbml);
751 }
752 END_TEST
753 
754 
START_TEST(test_WriteL3SBML_NegINF)755 START_TEST (test_WriteL3SBML_NegINF)
756 {
757   const char* expected = "<parameter id=\"p\" value=\"-INF\""
758     " constant=\"true\"/>";
759 
760 
761   Parameter *p = D->createModel()->createParameter();
762   p->setId("p");
763   p->setValue(util_NegInf());
764   p->setConstant(true);
765 
766   char* sbml = p->toSBML();
767   fail_unless( equals(expected,sbml) );
768   safe_free(sbml);
769 }
770 END_TEST
771 
772 
START_TEST(test_WriteL3SBML_locale)773 START_TEST (test_WriteL3SBML_locale)
774 {
775   const char* expected = "<parameter id=\"p\" value=\"3.31\""
776     " constant=\"true\"/>";
777 
778   Parameter *p = D->createModel()->createParameter();
779   p->setId("p");
780   p->setValue(3.31);
781   p->setConstant(true);
782 
783 
784   setlocale(LC_NUMERIC, "de_DE");
785 
786   char* sbml = p->toSBML();
787   fail_unless( equals(expected,sbml) );
788   safe_free(sbml);
789 
790   setlocale(LC_NUMERIC, "C");
791 }
792 END_TEST
793 
794 #ifdef USE_ZLIB
START_TEST(test_WriteL3SBML_gzip)795 START_TEST (test_WriteL3SBML_gzip)
796 {
797   const unsigned int filenum = 12;
798   const char* file[filenum] = {
799                         "../../../examples/sample-models/from-spec/level-3/algebraicrules.xml",
800                         "../../../examples/sample-models/from-spec/level-3/assignmentrules.xml",
801                         "../../../examples/sample-models/from-spec/level-3/boundarycondition.xml",
802                         "../../../examples/sample-models/from-spec/level-3/delay.xml",
803                         "../../../examples/sample-models/from-spec/level-3/dimerization.xml",
804                         "../../../examples/sample-models/from-spec/level-3/enzymekinetics.xml",
805                         "../../../examples/sample-models/from-spec/level-3/events.xml",
806                         "../../../examples/sample-models/from-spec/level-3/functiondef.xml",
807                         "../../../examples/sample-models/from-spec/level-3/multicomp.xml",
808                         "../../../examples/sample-models/from-spec/level-3/overdetermined.xml",
809                         "../../../examples/sample-models/from-spec/level-3/twodimensional.xml",
810                         "../../../examples/sample-models/from-spec/level-3/units.xml"
811                         };
812   const char* gzfile = "test.xml.gz";
813 
814   for(unsigned int i=0; i < filenum; i++)
815   {
816     SBMLDocument* d = readSBML(file[i]);
817     fail_unless( d != NULL);
818 
819     if ( ! SBMLWriter::hasZlib() )
820     {
821       fail_unless( writeSBML(d, gzfile) == false);
822       delete d;
823       continue;
824     }
825 
826     bool result = writeSBML(d, gzfile);
827     fail_unless( result );
828 
829     SBMLDocument* dg = readSBML(gzfile);
830     fail_unless( dg != NULL);
831 
832     char* dtos = d->toSBML();
833     char* dgtos = dg->toSBML();
834     fail_unless( strcmp(dtos, dgtos) == 0 );
835     safe_free(dtos);
836     safe_free(dgtos);
837 
838     delete d;
839     delete dg;
840   }
841 
842 }
843 END_TEST
844 #endif
845 
846 #ifdef USE_BZ2
START_TEST(test_WriteL3SBML_bzip2)847 START_TEST (test_WriteL3SBML_bzip2)
848 {
849   const unsigned int filenum = 12;
850   const char* file[filenum] = {
851                         "../../../examples/sample-models/from-spec/level-3/algebraicrules.xml",
852                         "../../../examples/sample-models/from-spec/level-3/assignmentrules.xml",
853                         "../../../examples/sample-models/from-spec/level-3/boundarycondition.xml",
854                         "../../../examples/sample-models/from-spec/level-3/delay.xml",
855                         "../../../examples/sample-models/from-spec/level-3/dimerization.xml",
856                         "../../../examples/sample-models/from-spec/level-3/enzymekinetics.xml",
857                         "../../../examples/sample-models/from-spec/level-3/events.xml",
858                         "../../../examples/sample-models/from-spec/level-3/functiondef.xml",
859                         "../../../examples/sample-models/from-spec/level-3/multicomp.xml",
860                         "../../../examples/sample-models/from-spec/level-3/overdetermined.xml",
861                         "../../../examples/sample-models/from-spec/level-3/twodimensional.xml",
862                         "../../../examples/sample-models/from-spec/level-3/units.xml"
863                         };
864 
865   const char* bz2file = "test.xml.bz2";
866 
867   for(unsigned int i=0; i < filenum; i++)
868   {
869     SBMLDocument* d = readSBML(file[i]);
870     fail_unless( d != NULL);
871 
872     if ( ! SBMLWriter::hasBzip2() )
873     {
874       fail_unless( writeSBML(d, bz2file) == false );
875       delete d;
876       continue;
877     }
878 
879     bool result = writeSBML(d, bz2file);
880     fail_unless( result );
881 
882     SBMLDocument* dg = readSBML(bz2file);
883     fail_unless( dg != NULL);
884 
885     char* dtos = d->toSBML();
886     char* dgtos = dg->toSBML();
887     fail_unless( strcmp(dtos, dgtos) == 0 );
888     safe_free(dtos);
889     safe_free(dgtos);
890 
891     delete d;
892     delete dg;
893   }
894 }
895 END_TEST
896 #endif
897 
898 #ifdef USE_ZLIB
START_TEST(test_WriteL3SBML_zip)899 START_TEST (test_WriteL3SBML_zip)
900 {
901   const unsigned int filenum = 12;
902   const char* file[filenum] = {
903                         "../../../examples/sample-models/from-spec/level-3/algebraicrules.xml",
904                         "../../../examples/sample-models/from-spec/level-3/assignmentrules.xml",
905                         "../../../examples/sample-models/from-spec/level-3/boundarycondition.xml",
906                         "../../../examples/sample-models/from-spec/level-3/delay.xml",
907                         "../../../examples/sample-models/from-spec/level-3/dimerization.xml",
908                         "../../../examples/sample-models/from-spec/level-3/enzymekinetics.xml",
909                         "../../../examples/sample-models/from-spec/level-3/events.xml",
910                         "../../../examples/sample-models/from-spec/level-3/functiondef.xml",
911                         "../../../examples/sample-models/from-spec/level-3/multicomp.xml",
912                         "../../../examples/sample-models/from-spec/level-3/overdetermined.xml",
913                         "../../../examples/sample-models/from-spec/level-3/twodimensional.xml",
914                         "../../../examples/sample-models/from-spec/level-3/units.xml"
915                         };
916 
917   const char* zipfile = "test.xml.zip";
918 
919   for(unsigned int i=0; i < filenum; i++)
920   {
921     SBMLDocument* d = readSBML(file[i]);
922     fail_unless( d != NULL);
923 
924     if ( ! SBMLWriter::hasZlib() )
925     {
926       fail_unless( writeSBML(d, zipfile) == false );
927       delete d;
928       continue;
929     }
930 
931     bool result = writeSBML (d, zipfile);
932     fail_unless( result );
933 
934     SBMLDocument* dg = readSBML(zipfile);
935     fail_unless( dg != NULL);
936 
937     char* dtos = d->toSBML();
938     char* dgtos = dg->toSBML();
939     fail_unless( strcmp(dtos, dgtos) == 0 );
940     safe_free(dtos);
941     safe_free(dgtos);
942 
943     delete d;
944     delete dg;
945   }
946 }
947 END_TEST
948 #endif
949 
START_TEST(test_WriteL3SBML_elements)950 START_TEST (test_WriteL3SBML_elements)
951 {
952   const char* expected = wrapSBML_L3v1(
953     "  <model>\n"
954     "    <listOfFunctionDefinitions>\n"
955     "      <functionDefinition/>\n"
956     "    </listOfFunctionDefinitions>\n"
957     "    <listOfUnitDefinitions>\n"
958     "      <unitDefinition/>\n"
959     "    </listOfUnitDefinitions>\n"
960     "    <listOfCompartments>\n"
961     "      <compartment/>\n"
962     "    </listOfCompartments>\n"
963     "    <listOfSpecies>\n"
964     "      <species/>\n"
965     "    </listOfSpecies>\n"
966     "    <listOfParameters>\n"
967     "      <parameter/>\n"
968     "    </listOfParameters>\n"
969     "    <listOfInitialAssignments>\n"
970     "      <initialAssignment/>\n"
971     "    </listOfInitialAssignments>\n"
972     "    <listOfRules>\n"
973     "      <algebraicRule/>\n"
974     "    </listOfRules>\n"
975     "    <listOfConstraints>\n"
976     "      <constraint/>\n"
977     "    </listOfConstraints>\n"
978     "    <listOfReactions>\n"
979     "      <reaction/>\n"
980     "    </listOfReactions>\n"
981     "    <listOfEvents>\n"
982     "      <event/>\n"
983     "    </listOfEvents>\n"
984     "  </model>\n");
985 
986   Model * m = D->createModel();
987   m->createUnitDefinition();
988   m->createFunctionDefinition();
989   m->createCompartment();
990   m->createEvent();
991   m->createParameter();
992   m->createAlgebraicRule();
993   m->createInitialAssignment();
994   m->createConstraint();
995   m->createReaction();
996   m->createSpecies();
997 
998   string S = writeSBMLToStdString(D);
999 
1000   fail_unless( equals(expected, S.c_str()) );
1001 }
1002 END_TEST
1003 
1004 
1005 
1006 Suite *
create_suite_WriteL3SBML()1007 create_suite_WriteL3SBML ()
1008 {
1009   Suite *suite = suite_create("WriteL3SBML");
1010   TCase *tcase = tcase_create("WriteL3SBML");
1011 
1012 
1013   tcase_add_checked_fixture(tcase, WriteL3SBML_setup, WriteL3SBML_teardown);
1014 
1015   // create/setProgramName/setProgramVersion
1016   tcase_add_test( tcase, test_SBMLWriter_L3_create );
1017   tcase_add_test( tcase, test_SBMLWriter_L3_setProgramName );
1018   tcase_add_test( tcase, test_SBMLWriter_L3_setProgramVersion );
1019 
1020   // Basic writing capability
1021   tcase_add_test( tcase, test_WriteL3SBML_error );
1022 
1023   // SBMLDocument
1024   tcase_add_test( tcase, test_WriteL3SBML_SBMLDocument_L3v1 );
1025 
1026 
1027   // Model
1028   tcase_add_test( tcase, test_WriteL3SBML_Model                   );
1029   tcase_add_test( tcase, test_WriteL3SBML_Model_substanceUnits    );
1030   tcase_add_test( tcase, test_WriteL3SBML_Model_timeUnits    );
1031   tcase_add_test( tcase, test_WriteL3SBML_Model_otherUnits    );
1032   tcase_add_test( tcase, test_WriteL3SBML_Model_conversionFactor    );
1033 
1034   //// Unit
1035   tcase_add_test( tcase, test_WriteL3SBML_Unit          );
1036   tcase_add_test( tcase, test_WriteL3SBML_Unit_noValues          );
1037 
1038   //// UnitDefinition
1039   tcase_add_test( tcase, test_WriteL3SBML_UnitDefinition           );
1040   //tcase_add_test( tcase, test_WriteL3SBML_UnitDefinition_full      );
1041   //tcase_add_test( tcase, test_WriteL3SBML_UnitDefinition_L2v1      );
1042   //tcase_add_test( tcase, test_WriteL3SBML_UnitDefinition_L2v1_full );
1043 
1044   //// Compartment
1045   tcase_add_test( tcase, test_WriteL3SBML_Compartment                );
1046   tcase_add_test( tcase, test_WriteL3SBML_Compartment_spatialDimensions );
1047 
1048   //// Species
1049   tcase_add_test( tcase, test_WriteL3SBML_Species                   );
1050   tcase_add_test( tcase, test_WriteL3SBML_Species_conversionFactor  );
1051 
1052   // Parameter
1053   tcase_add_test( tcase, test_WriteL3SBML_Parameter                   );
1054 
1055   // Reaction
1056   tcase_add_test( tcase, test_WriteL3SBML_Reaction           );
1057   tcase_add_test( tcase, test_WriteL3SBML_Reaction_compartment  );
1058   tcase_add_test( tcase, test_WriteL3SBML_Reaction_full         );
1059 
1060   //// SpeciesReference
1061 
1062   tcase_add_test( tcase, test_WriteL3SBML_SpeciesReference          );
1063 
1064   //// KineticLaw
1065   tcase_add_test( tcase, test_WriteL3SBML_KineticLaw_ListOfParameters );
1066 
1067   //// Event
1068   tcase_add_test( tcase, test_WriteL3SBML_Event         );
1069   tcase_add_test( tcase, test_WriteL3SBML_Event_useValues );
1070 
1071   //// Trigger
1072   tcase_add_test( tcase, test_WriteL3SBML_Trigger         );
1073   tcase_add_test( tcase, test_WriteL3SBML_Trigger_initialValue );
1074   tcase_add_test( tcase, test_WriteL3SBML_Trigger_persistent );
1075 
1076   tcase_add_test( tcase, test_WriteL3SBML_Priority         );
1077   tcase_add_test( tcase, test_WriteL3SBML_Event_full         );
1078    // Miscellaneous
1079   tcase_add_test( tcase, test_WriteL3SBML_NaN     );
1080   tcase_add_test( tcase, test_WriteL3SBML_INF     );
1081   tcase_add_test( tcase, test_WriteL3SBML_NegINF  );
1082   tcase_add_test( tcase, test_WriteL3SBML_locale  );
1083 
1084   // Compressed SBML
1085 #ifdef USE_ZLIB
1086 #ifndef LIBSBML_USE_VLD
1087   tcase_add_test( tcase, test_WriteL3SBML_gzip  );
1088   tcase_add_test( tcase, test_WriteL3SBML_zip  );
1089 #endif
1090 #endif
1091 
1092 #ifdef USE_BZ2
1093 #ifndef LIBSBML_USE_VLD
1094   tcase_add_test( tcase, test_WriteL3SBML_bzip2  );
1095 #endif
1096 #endif
1097 
1098   tcase_add_test( tcase, test_WriteL3SBML_elements);
1099 
1100   suite_add_tcase(suite, tcase);
1101 
1102   return suite;
1103 }
1104 
1105 
1106 END_C_DECLS
1107