# -*- perl -*-
# generated by perlify.pl from libsbml/src/sbml/test/TestWriteSBML.cpp
# followed by little human processing to fix syntactic specialties
# perify.pl is unable to handle right now =;) xtof
use Test::More;
BEGIN { plan tests => 72 };

use LibSBML;
use strict;
#########################

my $level   = 2;
my $version = 4;

# some global(s)
my $D = new LibSBML::SBMLDocument($level,$version);

test_WriteSBML_error();
test_WriteSBML_SBMLDocument_L1v1();
test_WriteSBML_SBMLDocument_L1v2();
test_WriteSBML_SBMLDocument_L2v1();
test_WriteSBML_SBMLDocument_L2v2();
test_WriteSBML_Model();
test_WriteSBML_Model_skipOptional();
test_WriteSBML_Model_L2v1();
test_WriteSBML_Model_L2v1_skipOptional();
test_WriteSBML_FunctionDefinition();
test_WriteSBML_Unit();
test_WriteSBML_Unit_l2v3();
test_WriteSBML_Unit_defaults();
test_WriteSBML_Unit_L2v1();
test_WriteSBML_UnitDefinition();
test_WriteSBML_UnitDefinition_full();
test_WriteSBML_UnitDefinition_L2v1();
test_WriteSBML_UnitDefinition_L2v1_full();
test_WriteSBML_Compartment();
test_WriteSBML_Compartment_unsetVolume();
test_WriteSBML_Compartment_L2v1();
test_WriteSBML_Compartment_L2v1_constant();
test_WriteSBML_Compartment_L2v1_unsetSize();
test_WriteSBML_Species();
test_WriteSBML_Species_L1v1();
test_WriteSBML_Species_defaults();
test_WriteSBML_Species_skipOptional();
test_WriteSBML_Species_L2v1();
test_WriteSBML_Species_L2v1_skipOptional();
test_WriteSBML_Parameter();
test_WriteSBML_Parameter_L1v1_required();
test_WriteSBML_Parameter_L1v2_skipOptional();
test_WriteSBML_Parameter_L2v1();
test_WriteSBML_Parameter_L2v1_skipOptional();
test_WriteSBML_Parameter_L2v1_constant();
test_WriteSBML_AlgebraicRule();
test_WriteSBML_AlgebraicRule_L2v1();
test_WriteSBML_SpeciesConcentrationRule();
test_WriteSBML_SpeciesConcentrationRule_defaults();
test_WriteSBML_SpeciesConcentrationRule_L1v1();
test_WriteSBML_SpeciesConcentrationRule_L2v1();
test_WriteSBML_CompartmentVolumeRule();
test_WriteSBML_CompartmentVolumeRule_defaults();
test_WriteSBML_CompartmentVolumeRule_L2v1();
test_WriteSBML_ParameterRule();
test_WriteSBML_ParameterRule_defaults();
test_WriteSBML_ParameterRule_L2v1();
test_WriteSBML_Reaction();
test_WriteSBML_Reaction_defaults();
test_WriteSBML_Reaction_full();
test_WriteSBML_Reaction_L2v1();
test_WriteSBML_Reaction_L2v1_full();
test_WriteSBML_SpeciesReference();
test_WriteSBML_SpeciesReference_L1v1();
test_WriteSBML_SpeciesReference_defaults();
test_WriteSBML_SpeciesReference_L2v1_1();
test_WriteSBML_SpeciesReference_L2v1_2();
test_WriteSBML_SpeciesReference_L2v1_3();
test_WriteSBML_KineticLaw();
test_WriteSBML_KineticLaw_skipOptional();
test_WriteSBML_KineticLaw_ListOfParameters();
test_WriteSBML_Event();
test_WriteSBML_Event_trigger();
test_WriteSBML_Event_delay();
test_WriteSBML_Event_both();
test_WriteSBML_Event_full();
test_WriteSBML_NaN();
test_WriteSBML_INF();
test_WriteSBML_NegINF();
test_WriteSBML_locale();
# some global(s)

#---
sub setUp {
 $D   = new LibSBML::SBMLDocument();
}

#---
sub util_NaN { use Math::BigInt; return Math::BigInt->new('foo') }

#---
sub util_PosInf { use Math::BigInt; return Math::BigInt->binf() }

#---
sub util_NegInf { use Math::BigInt; return Math::BigInt->binf('-') }

#---
sub readSBMLFromString {
 my $s = shift;
 my $rd = new LibSBML::SBMLReader;
 $rd->readSBMLFromString($s);
}

#---
sub NS_L2v2 {
 "xmlns=\"http://www.sbml.org/sbml/level2/version2\" ";
}

#---
sub SBML_END {
 "</sbml>\n";
}

#---
sub SBML_START {
 "<sbml ";
}

#---
sub LV_L2v2 {
 "level=\"2\" version=\"2\">\n";
}

#---
sub NS_L2v1 {
 "xmlns=\"http://www.sbml.org/sbml/level2\" ";
}

#---
sub XML_START {
 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
}

#---
sub LV_L1v1 {
 "level=\"1\" version=\"1\">\n";
}

#---
sub LV_L1v2 {
 "level=\"1\" version=\"2\">\n";
}

#---
sub NS_L1 {
 "xmlns=\"http://www.sbml.org/sbml/level1\" ";
}

#---
sub LV_L2v1 {
 "level=\"2\" version=\"1\">\n";
}

#---
sub wrapSBML_L1v2 {
 XML_START() . SBML_START() . NS_L1() . LV_L1v2() . $_[0] . SBML_END();
}

#---
sub wrapSBML_L2v2 {
 XML_START() . SBML_START() . NS_L2v2() . LV_L2v2() . $_[0] . SBML_END();
}

#---
sub wrapSBML_L1v1 {
 XML_START() . SBML_START() . NS_L1() . LV_L1v1() . $_[0] . SBML_END();
}

#---
sub wrapXML {
 XML_START() . $_[0];
}

#---
sub wrapSBML_L2v1 {
 XML_START() . SBML_START() . NS_L2v1() . LV_L2v1() . $_[0] . SBML_END();
}

#---
sub test_WriteSBML_error {
 my $d = new LibSBML::SBMLDocument($level,$version);
 my $w = new LibSBML::SBMLWriter();
 ok( ! $w->writeSBML($d, "/tmp/impossible/path/should/fail") );
 ok( $d->getNumErrors() == 1 );
 ok( $d->getError(0)->getErrorId() == $LibSBML::XMLFileUnwritable );
}

#---
sub test_WriteSBML_SBMLDocument_L1v1 {
 setUp();
 $D->setLevelAndVersion(1, 1, 0);
 my $expected = wrapXML("<sbml xmlns=\"http://www.sbml.org/sbml/level1\" " . 
                        "level=\"1\" version=\"1\"/>\n");
 my $S = $D->writeSBMLToString();
 ok( $expected eq $S );
}

#---
sub test_WriteSBML_SBMLDocument_L1v2 {
 setUp();
 $D->setLevelAndVersion(1, 2, 0);
 my $expected = wrapXML("<sbml xmlns=\"http://www.sbml.org/sbml/level1\" " . 
                        "level=\"1\" version=\"2\"/>\n");
 my $S = $D->writeSBMLToString();
 ok( $expected eq $S );
}

#---
sub test_WriteSBML_SBMLDocument_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1, 0);
 my $expected = wrapXML("<sbml xmlns=\"http://www.sbml.org/sbml/level2\" " . 
                        "level=\"2\" version=\"1\"/>\n");
 my $S = $D->writeSBMLToString();
 ok( $expected eq $S );
}

#---
sub test_WriteSBML_SBMLDocument_L2v2 {
 setUp();
 $D->setLevelAndVersion(2, 2, 0);
 my $expected = wrapXML("<sbml xmlns=\"http://www.sbml.org/sbml/level2/version2\" " . 
                        "level=\"2\" version=\"2\"/>\n");
 my $S = $D->writeSBMLToString();
 ok( $expected eq $S );
}

#---
sub test_WriteSBML_Model {
 setUp();
 $D->setLevelAndVersion(1, 1, 0);
 my $expected = wrapSBML_L1v1("  <model name=\"Branch\"/>\n");
 $D->createModel("Branch");
 my $S = $D->writeSBMLToString();
 ok( $expected eq $S );
}

#---
sub test_WriteSBML_Model_skipOptional {
 setUp();
 $D->setLevelAndVersion(1, 2, 0);
 my $expected = wrapSBML_L1v2("  <model/>\n");
 $D->createModel();
 my $S = $D->writeSBMLToString();
 ok( $expected eq $S );
}

#---
sub test_WriteSBML_Model_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1, 0);
 my $expected = wrapSBML_L2v1("  <model id=\"Branch\"/>\n");
 $D->createModel("Branch");
 my $S = $D->writeSBMLToString();
 ok( $expected eq $S );
}

#---
sub test_WriteSBML_Model_L2v1_skipOptional {
 setUp();
 $D->setLevelAndVersion(2, 1, 0);
 my $expected = wrapSBML_L2v1("  <model/>\n");
 $D->createModel();
 my $S = $D->writeSBMLToString();
 ok( $expected eq $S );
}

#---
sub test_WriteSBML_FunctionDefinition {
 setUp();
 my $expected = "<functionDefinition id=\"pow3\">\n" . 
                        "  <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "    <lambda>\n" . 
                        "      <bvar>\n" . 
                        "        <ci> x </ci>\n" . 
                        "      </bvar>\n" . 
                        "      <apply>\n" . 
                        "        <power/>\n" . 
                        "        <ci> x </ci>\n" . 
                        "        <cn type=\"integer\"> 3 </cn>\n" . 
                        "      </apply>\n" . 
                        "    </lambda>\n" . 
                        "  </math>\n" . 
                        "</functionDefinition>";
 my $fd = new LibSBML::FunctionDefinition($level,$version);
 $fd->setId("pow3");
 $fd->setMath(LibSBML::parseFormula("lambda(x, x^3)"));
 ok( $expected eq $fd->toSBML() );
}

#---
sub test_WriteSBML_Unit {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<unit kind=\"kilogram\" exponent=\"2\" scale=\"-3\"/>";
 my $u = new LibSBML::Unit(2,1);
 $u->setKind($LibSBML::UNIT_KIND_KILOGRAM);
 $u->setExponent(2);
 $u->setScale(-3);
 ok( $expected eq $u->toSBML() );
}

#---
sub test_WriteSBML_Unit_l2v3 {
 setUp();
 $D->setLevelAndVersion(2, 3);
 my $expected = "<unit kind=\"kilogram\" exponent=\"2\" scale=\"-3\"/>";
 my $u = new LibSBML::Unit(2,3);
 $u->setKind($LibSBML::UNIT_KIND_KILOGRAM);
 $u->setExponent(2);
 $u->setScale(-3);
 $u->setOffset(32);
 ok( $expected eq $u->toSBML());
}

#---
sub test_WriteSBML_Unit_defaults {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<unit kind=\"kilogram\"/>";
 my $u = new LibSBML::Unit(1,2);
 $u->setKind($LibSBML::UNIT_KIND_KILOGRAM);
 $u->setExponent(1);
 $u->setScale(0);
 ok( $expected eq $u->toSBML() );
}

#---
sub test_WriteSBML_Unit_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<unit kind=\"Celsius\" multiplier=\"1.8\" offset=\"32\"/>";
 my $u = new LibSBML::Unit(2,1);
 $u->setKind($LibSBML::UNIT_KIND_CELSIUS);
 $u->setMultiplier(1.8);
 $u->setOffset(32);
 ok( $expected eq $u->toSBML());
}

#---
sub test_WriteSBML_UnitDefinition {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<unitDefinition name=\"mmls\"/>";
 my $ud = new LibSBML::UnitDefinition(1,2);
 $ud->setId("mmls");
 ok( $expected eq $ud->toSBML());
}

#---
sub test_WriteSBML_UnitDefinition_full {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<unitDefinition name=\"mmls\">\n" . 
                        "  <listOfUnits>\n" . 
                        "    <unit kind=\"mole\" scale=\"-3\"/>\n" . 
                        "    <unit kind=\"litre\" exponent=\"-1\"/>\n" . 
                        "    <unit kind=\"second\" exponent=\"-1\"/>\n" . 
                        "  </listOfUnits>\n" . 
                        "</unitDefinition>";
 my $ud = new LibSBML::UnitDefinition(1,2);
 $ud->setId("mmls");
 my $u1 = new LibSBML::Unit(1,2);
 $u1->setKind($LibSBML::UNIT_KIND_MOLE);
 $u1->setScale(-3);
 my $u2 = new LibSBML::Unit(1,2);
 $u2->setKind($LibSBML::UNIT_KIND_LITRE);
 $u2->setExponent(-1);
 my $u3 = new LibSBML::Unit(1,2);
 $u3->setKind($LibSBML::UNIT_KIND_SECOND);
 $u3->setExponent(-1);

 $ud->addUnit($u1);
 $ud->addUnit($u2);
 $ud->addUnit($u3);
 ok( $expected eq $ud->toSBML());
}

#---
sub test_WriteSBML_UnitDefinition_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<unitDefinition id=\"mmls\"/>";
 my $ud = new LibSBML::UnitDefinition(2,1);
 $ud->setId("mmls");
 ok( $expected eq $ud->toSBML());
}

#---
sub test_WriteSBML_UnitDefinition_L2v1_full {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<unitDefinition id=\"Fahrenheit\">\n" . 
                        "  <listOfUnits>\n" . 
                        "    <unit kind=\"Celsius\" multiplier=\"1.8\" offset=\"32\"/>\n" . 
                        "  </listOfUnits>\n" . 
                        "</unitDefinition>";
 my $u1 = new LibSBML::Unit(2,1);
 $u1->setKind($LibSBML::UNIT_KIND_CELSIUS);
 $u1->setMultiplier(1.8);
 $u1->setOffset(32);
 my $ud = new LibSBML::UnitDefinition(2,1);
 $ud->setId("Fahrenheit");
 $ud->addUnit($u1);
 ok( $expected eq $ud->toSBML());
}

#---
sub test_WriteSBML_Compartment {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<compartment name=\"A\" volume=\"2.1\" outside=\"B\"/>";
 my $c = new LibSBML::Compartment(1,2);
 $c->setId("A");
 $c->setSize(2.1);
 $c->setOutside("B");
 ok( $expected eq $c->toSBML());
}

#---
sub test_WriteSBML_Compartment_unsetVolume {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<compartment name=\"A\"/>";
 my $c = new LibSBML::Compartment(1,2);
 $c->setId("A");
 ok( $expected eq $c->toSBML());
}

#---
sub test_WriteSBML_Compartment_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<compartment id=\"M\" spatialDimensions=\"2\" size=\"2.5\"/>";
 my $c = new LibSBML::Compartment(2,1);
 $c->setId("M");
 $c->setSize(2.5);
 $c->setSpatialDimensions(2);
 ok( $expected eq $c->toSBML());
}

#---
sub test_WriteSBML_Compartment_L2v1_constant {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<compartment id=\"cell\" size=\"1.2\" constant=\"false\"/>";
 my $c = new LibSBML::Compartment(2,1);
 $c->setId("cell");
 $c->setSize(1.2);
 $c->setConstant(0);
 ok( $expected eq $c->toSBML());
}

#---
sub test_WriteSBML_Compartment_L2v1_unsetSize {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<compartment id=\"A\"/>";
 my $c = new LibSBML::Compartment(2,1);
 $c->setId("A");
 ok( $expected eq $c->toSBML());
}

#---
sub test_WriteSBML_Species {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<species name=\"Ca2\" compartment=\"cell\" initialAmount=\"0.7\"" . 
                        " units=\"mole\" boundaryCondition=\"true\" charge=\"2\"/>";
 my $s = new LibSBML::Species(1,2);
 $s->setId("Ca2");
 $s->setCompartment("cell");
 $s->setInitialAmount(0.7);
 $s->setUnits("mole");
 $s->setBoundaryCondition(1);
 $s->setCharge(2);
 ok( $expected eq $s->toSBML());
}

#---
sub test_WriteSBML_Species_L1v1 {
 setUp();
 $D->setLevelAndVersion(1, 1);
 my $expected = "<specie name=\"Ca2\" compartment=\"cell\" initialAmount=\"0.7\"" . 
                        " units=\"mole\" boundaryCondition=\"true\" charge=\"2\"/>";
 my $s = new LibSBML::Species(1,1);
 $s->setId("Ca2");
 $s->setCompartment("cell");
 $s->setInitialAmount(0.7);
 $s->setUnits("mole");
 $s->setBoundaryCondition(1);
 $s->setCharge(2);
 ok( $expected eq $s->toSBML());
}

#---
sub test_WriteSBML_Species_defaults {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<species name=\"Ca2\" compartment=\"cell\" initialAmount=\"0.7\"" . 
                        " units=\"mole\" charge=\"2\"/>";
 my $s = new LibSBML::Species(1,2);
 $s->setId("Ca2");
 $s->setCompartment("cell");
 $s->setInitialAmount(0.7);
 $s->setUnits("mole");
 $s->setCharge(2);
 ok( $expected eq $s->toSBML());
}

#---
sub test_WriteSBML_Species_skipOptional {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<species name=\"Ca2\" compartment=\"cell\" initialAmount=\"0.7\"/>";
 my $s = new LibSBML::Species(1,2);
 $s->setId("Ca2");
 $s->setCompartment("cell");
 $s->setInitialAmount(0.7);
 ok( $expected eq $s->toSBML());
}

#---
sub test_WriteSBML_Species_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<species id=\"Ca2\" compartment=\"cell\" initialAmount=\"0.7\" " . 
                        "substanceUnits=\"mole\" constant=\"true\"/>";
 my $s = new LibSBML::Species(2,1);
 $s->setId("Ca2");
 $s->setCompartment("cell");
 $s->setInitialAmount(0.7);
 $s->setSubstanceUnits("mole");
 $s->setConstant(1);
 ok( $expected eq $s->toSBML());
}

#---
sub test_WriteSBML_Species_L2v1_skipOptional {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<species id=\"Ca2\" compartment=\"cell\"/>";
 my $s = new LibSBML::Species(2,1);
 $s->setId("Ca2");
 $s->setCompartment("cell");
 ok( $expected eq $s->toSBML());
}

#---
sub test_WriteSBML_Parameter {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<parameter name=\"Km1\" value=\"2.3\" units=\"second\"/>";
 my $p = new LibSBML::Parameter(1,2);
 $p->setId("Km1");
 $p->setValue(2.3);
 $p->setUnits("second");
 ok( $expected eq $p->toSBML());
}

#---
sub test_WriteSBML_Parameter_L1v1_required {
 setUp();
 $D->setLevelAndVersion(1, 1);
 my $expected = "<parameter name=\"Km1\" value=\"NaN\"/>";
 my $p = new LibSBML::Parameter(1,1);
 $p->setId("Km1");
 $p->unsetValue();
 ok( $expected eq $p->toSBML());
}

#---
sub test_WriteSBML_Parameter_L1v2_skipOptional {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<parameter name=\"Km1\"/>";
 my $p = new LibSBML::Parameter(1,2);
 $p->setId("Km1");
 ok( $expected eq $p->toSBML());
}

#---
sub test_WriteSBML_Parameter_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<parameter id=\"Km1\" value=\"2.3\" units=\"second\"/>";
 my $p = new LibSBML::Parameter(2,1);
 $p->setId('Km1');
 $p->setValue(2.3);
 $p->setUnits("second");
 ok( $expected eq $p->toSBML());
}

#---
sub test_WriteSBML_Parameter_L2v1_skipOptional {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<parameter id=\"Km1\"/>";
 my $p = new LibSBML::Parameter(2,1);
 $p->setId("Km1");
 ok( $expected eq $p->toSBML());
}

#---
sub test_WriteSBML_Parameter_L2v1_constant {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<parameter id=\"x\" constant=\"false\"/>";
 my $p = new LibSBML::Parameter(2,1);
 $p->setId("x");
 $p->setConstant(0);
 ok( $expected eq $p->toSBML());
}

#---
sub test_WriteSBML_AlgebraicRule {
 setUp();
 $D->setLevelAndVersion(1, 1);
 my $expected = "<algebraicRule formula=\"x + 1\"/>";
 my $r = new LibSBML::AlgebraicRule(1,1);
 $r->setFormula("x + 1");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_AlgebraicRule_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<algebraicRule>\n" . 
                        "  <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "    <apply>\n" . 
                        "      <plus/>\n" . 
                        "      <ci> x </ci>\n" . 
                        "      <cn type=\"integer\"> 1 </cn>\n" . 
                        "    </apply>\n" . 
                        "  </math>\n" . 
                        "</algebraicRule>";
 my $r = new LibSBML::AlgebraicRule(2,1);
 $r->setFormula("x + 1");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_SpeciesConcentrationRule {
 setUp();
 $D->setLevelAndVersion(1, 2, 0);
 my $expected = "<speciesConcentrationRule " . 
                        "formula=\"t * s\" type=\"rate\" species=\"s\"/>";
 $D->createModel();
 $D->getModel()->createSpecies()->setId("s");
 my $r = $D->getModel()->createRateRule();
 $r->setVariable("s");
 $r->setFormula("t * s");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_SpeciesConcentrationRule_defaults {
 setUp();
 $D->setLevelAndVersion(1, 2, 0);
 my $expected = "<speciesConcentrationRule formula=\"t * s\" species=\"s\"/>";
 $D->createModel();
 $D->getModel()->createSpecies()->setId("s");
 my $r = $D->getModel()->createAssignmentRule();
 $r->setVariable("s");
 $r->setFormula("t * s");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_SpeciesConcentrationRule_L1v1 {
 setUp();
 $D->setLevelAndVersion(1, 1, 0);
 my $expected = "<specieConcentrationRule formula=\"t * s\" specie=\"s\"/>";
 $D->createModel();
 $D->getModel()->createSpecies()->setId("s");
 my $r = $D->getModel()->createAssignmentRule();
 $r->setVariable("s");
 $r->setFormula("t * s");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_SpeciesConcentrationRule_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<assignmentRule variable=\"s\">\n" . 
                        "  <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "    <apply>\n" . 
                        "      <times/>\n" . 
                        "      <ci> t </ci>\n" . 
                        "      <ci> s </ci>\n" . 
                        "    </apply>\n" . 
                        "  </math>\n" . 
                        "</assignmentRule>";
 $D->createModel();
 $D->getModel()->createSpecies()->setId("s");
 my $r = $D->getModel()->createAssignmentRule();
 $r->setVariable("s");
 $r->setFormula("t * s");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_CompartmentVolumeRule {
 setUp();
 $D->setLevelAndVersion(1, 1, 0);
 my $expected = "<compartmentVolumeRule " . 
                        "formula=\"v + c\" type=\"rate\" compartment=\"c\"/>";
 $D->createModel();
 $D->getModel()->createCompartment()->setId("c");
 my $r = $D->getModel()->createRateRule();
 $r->setVariable("c");
 $r->setFormula("v + c");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_CompartmentVolumeRule_defaults {
 setUp();
 $D->setLevelAndVersion(1, 1, 0);
 my $expected = "<compartmentVolumeRule formula=\"v + c\" compartment=\"c\"/>";
 $D->createModel();
 $D->getModel()->createCompartment()->setId("c");
 my $r = $D->getModel()->createAssignmentRule();
 $r->setVariable("c");
 $r->setFormula("v + c");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_CompartmentVolumeRule_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<assignmentRule variable=\"c\">\n" . 
                        "  <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "    <apply>\n" . 
                        "      <plus/>\n" . 
                        "      <ci> v </ci>\n" . 
                        "      <ci> c </ci>\n" . 
                        "    </apply>\n" . 
                        "  </math>\n" . 
                        "</assignmentRule>";
 $D->createModel();
 $D->getModel()->createCompartment()->setId("c");
 my $r = $D->getModel()->createAssignmentRule();
 $r->setVariable("c");
 $r->setFormula("v + c");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_ParameterRule {
 setUp();
 $D->setLevelAndVersion(1, 1, 0);
 my $expected = "<parameterRule " . 
                        "formula=\"p * t\" type=\"rate\" name=\"p\"/>";
 $D->createModel();
 $D->getModel()->createParameter()->setId("p");
 my $r = $D->getModel()->createRateRule();
 $r->setVariable("p");
 $r->setFormula("p * t");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_ParameterRule_defaults {
 setUp();
 $D->setLevelAndVersion(1, 1, 0);
 my $expected = "<parameterRule formula=\"p * t\" name=\"p\"/>";
 $D->createModel();
 $D->getModel()->createParameter()->setId("p");
 my $r = $D->getModel()->createAssignmentRule();
 $r->setVariable("p");
 $r->setFormula("p * t");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_ParameterRule_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<rateRule variable=\"p\">\n" . 
                        "  <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "    <apply>\n" . 
                        "      <times/>\n" . 
                        "      <ci> p </ci>\n" . 
                        "      <ci> t </ci>\n" . 
                        "    </apply>\n" . 
                        "  </math>\n" . 
                        "</rateRule>";
 $D->createModel();
 $D->getModel()->createParameter()->setId("p");
 my $r = $D->getModel()->createRateRule();
 $r->setVariable("p");
 $r->setFormula("p * t");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_Reaction {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<reaction name=\"r\" reversible=\"false\" fast=\"true\"/>";
 my $r = new LibSBML::Reaction(1,2);
 $r->setId("r");
 $r->setReversible(0);
 $r->setFast(1);
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_Reaction_defaults {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<reaction name=\"r\"/>";
 my $r = new LibSBML::Reaction(1,2);
 $r->setId("r");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_Reaction_full {
 setUp();
 $D->setLevelAndVersion(1, 2, 0);
 my $expected = "<reaction name=\"v1\">\n" . 
                        "  <listOfReactants>\n" . 
                        "    <speciesReference species=\"x0\"/>\n" . 
                        "  </listOfReactants>\n" . 
                        "  <listOfProducts>\n" . 
                        "    <speciesReference species=\"s1\"/>\n" . 
                        "  </listOfProducts>\n" . 
                        "  <kineticLaw formula=\"(vm * s1)/(km + s1)\"/>\n" . 
                        "</reaction>";
 $D->createModel();
 my $r = $D->getModel()->createReaction();
 $r->setId("v1");
 $r->setReversible(1);
 $r->createReactant()->setSpecies("x0");
 $r->createProduct()->setSpecies("s1");
 $r->createKineticLaw()->setFormula("(vm * s1)/(km + s1)");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_Reaction_L2v1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<reaction id=\"r\" reversible=\"false\"/>";
 my $r = new LibSBML::Reaction(2,1);
 $r->setId("r");
 $r->setReversible(0);
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_Reaction_L2v1_full {
 setUp();
 $D->setLevelAndVersion(2, 1, 0);
 my $expected = "<reaction id=\"v1\">\n" . 
                        "  <listOfReactants>\n" . 
                        "    <speciesReference species=\"x0\"/>\n" . 
                        "  </listOfReactants>\n" . 
                        "  <listOfProducts>\n" . 
                        "    <speciesReference species=\"s1\"/>\n" . 
                        "  </listOfProducts>\n" . 
                        "  <listOfModifiers>\n" . 
                        "    <modifierSpeciesReference species=\"m1\"/>\n" . 
                        "  </listOfModifiers>\n" . 
                        "  <kineticLaw>\n" . 
                        "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "      <apply>\n" . 
                        "        <divide/>\n" . 
                        "        <apply>\n" . 
                        "          <times/>\n" . 
                        "          <ci> vm </ci>\n" . 
                        "          <ci> s1 </ci>\n" . 
                        "        </apply>\n" . 
                        "        <apply>\n" . 
                        "          <plus/>\n" . 
                        "          <ci> km </ci>\n" . 
                        "          <ci> s1 </ci>\n" . 
                        "        </apply>\n" . 
                        "      </apply>\n" . 
                        "    </math>\n" . 
                        "  </kineticLaw>\n" . 
                        "</reaction>";
 $D->createModel();
 my $r = $D->getModel()->createReaction();
 $r->setId("v1");
 $r->setReversible(1);
 $r->createReactant()->setSpecies("x0");
 $r->createProduct()->setSpecies("s1");;
 $r->createModifier()->setSpecies("m1");
 $r->createKineticLaw()->setFormula("(vm * s1)/(km + s1)");
 ok( $expected eq $r->toSBML());
}

#---
sub test_WriteSBML_SpeciesReference {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<speciesReference species=\"s\" stoichiometry=\"3\" denominator=\"2\"/>";
 my $sr = new LibSBML::SpeciesReference(1,2);
 $sr->setSpecies("s");
 $sr->setStoichiometry(3);
 $sr->setDenominator(2);
 ok( $expected eq $sr->toSBML());
}

#---
sub test_WriteSBML_SpeciesReference_L1v1 {
 setUp();
 $D->setLevelAndVersion(1, 1);
 my $expected = "<specieReference specie=\"s\" stoichiometry=\"3\" denominator=\"2\"/>";
 my $sr = new LibSBML::SpeciesReference(1,1);
 $sr->setSpecies("s");
 $sr->setStoichiometry(3);
 $sr->setDenominator(2);
 ok( $expected eq $sr->toSBML());
}

#---
sub test_WriteSBML_SpeciesReference_defaults {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<speciesReference species=\"s\"/>";
 my $sr = new LibSBML::SpeciesReference(1,2);
 $sr->setSpecies("s");
 ok( $expected eq $sr->toSBML());
}

#---
sub test_WriteSBML_SpeciesReference_L2v1_1 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<speciesReference species=\"s\">\n" . 
                        "  <stoichiometryMath>\n" . 
                        "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "      <cn type=\"rational\"> 3 <sep/> 2 </cn>\n" . 
                        "    </math>\n" . 
                        "  </stoichiometryMath>\n" . 
                        "</speciesReference>";
 my $sr = new LibSBML::SpeciesReference(2,1);
 $sr->setSpecies("s");
 $sr->setStoichiometry(3);
 $sr->setDenominator(2);
 ok( $expected eq $sr->toSBML());
}

#---
sub test_WriteSBML_SpeciesReference_L2v1_2 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<speciesReference species=\"s\" stoichiometry=\"3.2\"/>";
 my $sr = new LibSBML::SpeciesReference(2,1);
 $sr->setSpecies("s");
 $sr->setStoichiometry(3.2);
 ok( $expected eq $sr->toSBML());
}

#---
sub test_WriteSBML_SpeciesReference_L2v1_3 {
 setUp();
 $D->setLevelAndVersion(2, 1);
 my $expected = "<speciesReference species=\"s\">\n" . 
                        "  <stoichiometryMath>\n" . 
                        "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "      <apply>\n" . 
                        "        <divide/>\n" . 
                        "        <cn type=\"integer\"> 1 </cn>\n" . 
                        "        <ci> d </ci>\n" . 
                        "      </apply>\n" . 
                        "    </math>\n" . 
                        "  </stoichiometryMath>\n" . 
                        "</speciesReference>";
 my $sr = new LibSBML::SpeciesReference(2,1);
 $sr->setSpecies("s");
 my $math = LibSBML::parseFormula("1/d");
 my $stoich = new LibSBML::StoichiometryMath(2,1);
 $stoich->setMath($math);
 $sr->setStoichiometryMath($stoich);
 ok( $expected eq $sr->toSBML());
}

#---
sub test_WriteSBML_KineticLaw {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<kineticLaw formula=\"k * e\" timeUnits=\"second\" " . 
                        "substanceUnits=\"item\"/>";
 my $kl = new LibSBML::KineticLaw(1,2);
 $kl->setFormula("k * e");
 $kl->setTimeUnits("second");
 $kl->setSubstanceUnits("item");
 ok( $expected eq $kl->toSBML());
}

#---
sub test_WriteSBML_KineticLaw_skipOptional {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<kineticLaw formula=\"k * e\"/>";
 my $kl = new LibSBML::KineticLaw(1,2);
 $kl->setFormula("k * e");
 ok( $expected eq $kl->toSBML());
}

#---
sub test_WriteSBML_KineticLaw_ListOfParameters {
 setUp();
 $D->setLevelAndVersion(1, 2);
 my $expected = "<kineticLaw formula=\"nk * e\" timeUnits=\"second\" " . 
                        "substanceUnits=\"item\">\n" . 
                        "  <listOfParameters>\n" . 
                        "    <parameter name=\"n\" value=\"1.2\"/>\n" . 
                        "  </listOfParameters>\n" . 
                        "</kineticLaw>";
 my $kl = new LibSBML::KineticLaw(1,2);
 $kl->setFormula("nk * e");
 $kl->setTimeUnits("second");
 $kl->setSubstanceUnits("item");
 my $p = new LibSBML::Parameter(1,2);
 $p->setId("n");
 $p->setValue(1.2);
 $kl->addParameter($p);
 ok( $expected eq $kl->toSBML());
}

#---
sub test_WriteSBML_Event {
 setUp();
 my $expected = "<event id=\"e\"/>";
 my $e = new LibSBML::Event($level,$version);
 $e->setId("e");
 ok( $expected eq $e->toSBML());
}

#---
sub test_WriteSBML_Event_trigger {
 setUp();
 my $expected = "<event id=\"e\">\n" . 
                        "  <trigger>\n" . 
                        "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "      <apply>\n" . 
                        "        <leq/>\n" . 
                        "        <ci> P1 </ci>\n" . 
                        "        <ci> t </ci>\n" . 
                        "      </apply>\n" . 
                        "    </math>\n" . 
                        "  </trigger>\n" . 
                        "</event>";
 my $e = new LibSBML::Event($level,$version);
 $e->setId("e");
 my $node = LibSBML::parseFormula("leq(P1,t)");
 my $t = new LibSBML::Trigger($level,$version);
 $t->setMath($node);
 $e->setTrigger($t);
 $e->setTimeUnits("second");
 ok( $expected eq $e->toSBML());
}

#---
sub test_WriteSBML_Event_delay {
 setUp();
 my $expected = "<event id=\"e\">\n" . 
                        "  <delay>\n" . 
                        "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "      <cn type=\"integer\"> 5 </cn>\n" . 
                        "    </math>\n" . 
                        "  </delay>\n" . 
                        "</event>";
 my $e = new LibSBML::Event($level,$version);
 $e->setId("e");
 my $node = LibSBML::parseFormula("5");
 my $d = new LibSBML::Delay($level,$version);
 $d->setMath($node);
 $e->setDelay($d);
 ok( $expected eq $e->toSBML());
}

#---
sub test_WriteSBML_Event_both {
 setUp();
 my $expected = "<event id=\"e\">\n" . 
                        "  <trigger>\n" . 
                        "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "      <apply>\n" . 
                        "        <leq/>\n" . 
                        "        <ci> P1 </ci>\n" . 
                        "        <ci> t </ci>\n" . 
                        "      </apply>\n" . 
                        "    </math>\n" . 
                        "  </trigger>\n" . 
                        "  <delay>\n" . 
                        "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "      <cn type=\"integer\"> 5 </cn>\n" . 
                        "    </math>\n" . 
                        "  </delay>\n" . 
                        "</event>";
 my $e = new LibSBML::Event($level,$version);
 $e->setId("e");
 my $node1 = LibSBML::parseFormula("leq(P1,t)");
 my $t = new LibSBML::Trigger($level,$version);
 $t->setMath($node1);
 my $node = LibSBML::parseFormula("5");
 my $d = new LibSBML::Delay($level,$version);
 $d->setMath($node);
 $e->setDelay($d);
 $e->setTrigger($t);
 $e->setTimeUnits("second");
 ok( $expected eq $e->toSBML());
}

#---
sub test_WriteSBML_Event_full {
 setUp();
 my $expected = "<event id=\"e\">\n" . 
                        "  <trigger>\n" . 
                        "    <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "      <apply>\n" . 
                        "        <leq/>\n" . 
                        "        <ci> P1 </ci>\n" . 
                        "        <ci> t </ci>\n" . 
                        "      </apply>\n" . 
                        "    </math>\n" . 
                        "  </trigger>\n" . 
                        "  <listOfEventAssignments>\n" . 
                        "    <eventAssignment variable=\"k2\">\n" . 
                        "      <math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n" . 
                        "        <cn type=\"integer\"> 0 </cn>\n" . 
                        "      </math>\n" . 
                        "    </eventAssignment>\n" . 
                        "  </listOfEventAssignments>\n" . 
                        "</event>";
 my $e = new LibSBML::Event($level,$version);
 $e->setId("e");
 my $node = LibSBML::parseFormula("leq(P1,t)");
 my $t = new LibSBML::Trigger($level,$version);
 $t->setMath($node);
 my $math = LibSBML::parseFormula("0");
 my $ea = new LibSBML::EventAssignment($level,$version);
 $ea->setVariable("k2");
 $ea->setMath($math);
 $e->setTrigger($t);
 $e->addEventAssignment($ea);
 ok( $expected eq $e->toSBML());
}

#---
sub test_WriteSBML_NaN {
 setUp();
 my $expected = "<parameter id=\"p\" value=\"NaN\"/>";
 my $p = new LibSBML::Parameter($level,$version);
 $p->setId("p");
 $p->setValue(util_NaN());
 ok( $expected eq $p->toSBML());
}

#---
sub test_WriteSBML_INF {
 setUp();
 my $expected = "<parameter id=\"p\" value=\"INF\"/>";
 my $p = new LibSBML::Parameter($level,$version);
 $p->setId("p");
 $p->setValue(util_PosInf());
 ok( $expected eq $p->toSBML());
}

#---
sub test_WriteSBML_NegINF {
 setUp();
 my $expected = "<parameter id=\"p\" value=\"-INF\"/>";
 my $p = new LibSBML::Parameter($level,$version);
 $p->setId("p");
 $p->setValue(util_NegInf());
 ok( $expected eq $p->toSBML());
}

#---
sub test_WriteSBML_locale {
 setUp();
 my $expected = "<parameter id=\"p\" value=\"3.31\"/>";
 my $p = new LibSBML::Parameter($level,$version);
 $p->setId("p");
 $p->setValue(3.31);
 ok( $expected eq $p->toSBML());
}
