END_TEST


START_TEST (test_UnitDefinition_createWithNS )
{
  XMLNamespaces_t *xmlns = XMLNamespaces_create();
  XMLNamespaces_add(xmlns, "http://www.sbml.org", "testsbml");
  SBMLNamespaces_t *sbmlns = SBMLNamespaces_create(2,1);
  SBMLNamespaces_addNamespaces(sbmlns,xmlns);

  UnitDefinition_t *object = 
    UnitDefinition_createWithNS (sbmlns);


  fail_unless( SBase_getTypeCode  ((SBase_t *) object) == SBML_UNIT_DEFINITION );
  fail_unless( SBase_getMetaId    ((SBase_t *) object) == NULL );
  fail_unless( SBase_getNotes     ((SBase_t *) object) == NULL );
  fail_unless( SBase_getAnnotation((SBase_t *) object) == NULL );

  fail_unless( SBase_getLevel       ((SBase_t *) object) == 2 );
  fail_unless( SBase_getVersion     ((SBase_t *) object) == 1 );

  fail_unless( UnitDefinition_getNamespaces     (object) != NULL );
  fail_unless( XMLNamespaces_getLength(
                        UnitDefinition_getNamespaces(object)) == 2 );

  UnitDefinition_free(object);
}
END_TEST


START_TEST (test_SBMLDocument_setLevelAndVersion_Error)
{
  SBMLDocument_t *d  = SBMLDocument_create();
  SBMLDocument_setLevelAndVersion(d, 2, 1);
  
  Model_t        *m1 = Model_create(2, 1);

  /* add unitDefinition */
  Unit_t * u = Unit_create(2, 1);
  Unit_setKind(u, UnitKind_forName("mole"));
  Unit_setOffset(u, 3.2);

  UnitDefinition_t *ud = 
    UnitDefinition_create(2, 1);
  UnitDefinition_setId(ud, "ud");
  UnitDefinition_addUnit(ud, u);

  Model_addUnitDefinition(m1, ud);
  SBMLDocument_setModel(d, m1);

  fail_unless(SBMLDocument_setLevelAndVersionStrict(d,2,2) == 0);
  fail_unless(SBMLDocument_setLevelAndVersionStrict(d,2,3) == 0);
  fail_unless(SBMLDocument_setLevelAndVersionStrict(d,1,2) == 0);
  fail_unless(SBMLDocument_setLevelAndVersionStrict(d,1,1) == 0);

  SBMLDocument_free(d);
  Model_free(m1);
  Unit_free(u);
  UnitDefinition_free(ud);
}
END_TEST


START_TEST (test_UnitDefinition_free_NULL)
{
  UnitDefinition_free(NULL);
}
END_TEST


START_TEST (test_unitdefinition_convert_SI2)
{
  UnitDefinition *ud = new UnitDefinition(1, 1);
  UnitDefinition *ud1;
  
  Unit * u = ud->createUnit();
  u->setKind(UNIT_KIND_FARAD);

  ud1 = UnitDefinition::convertToSI(ud);

  fail_unless( ud1->getNumUnits() == 4);
  fail_unless( ud1->getLevel() == 1);
  fail_unless( ud1->getVersion() == 1);
  fail_unless( ud1->getUnit(0)->getKind() == UNIT_KIND_AMPERE );
  fail_unless( ud1->getUnit(0)->getExponent() == 2);
  fail_unless( ud1->getUnit(1)->getKind() == UNIT_KIND_KILOGRAM );
  fail_unless( ud1->getUnit(1)->getExponent() == -1);
  fail_unless( ud1->getUnit(2)->getKind() == UNIT_KIND_METRE );
  fail_unless( ud1->getUnit(2)->getExponent() == -2);
  fail_unless( ud1->getUnit(3)->getKind() == UNIT_KIND_SECOND );
  fail_unless( ud1->getUnit(3)->getExponent() == 4);


  UnitDefinition_free(ud);
}
END_TEST


START_TEST (test_UnitDefinition_printUnits)
{
  UnitDefinition_t *ud = UnitDefinition_create(2, 4);
  UnitDefinition_setId(ud, "mmls");

  Unit_t *perTime = UnitDefinition_createUnit(ud);
  Unit_setKind( perTime  , UnitKind_forName("second")   );
  Unit_setExponent( perTime, -1);

  char * ud_str = UnitDefinition_printUnits(ud, 0);
  fail_unless(!strcmp(ud_str, 
               "second (exponent = -1, multiplier = 1, scale = 0)"));

  char * ud_str1 = UnitDefinition_printUnits(ud, 1);
  fail_unless(!strcmp(ud_str1, "(1 second)^-1"));

  UnitDefinition_t *ud1 = UnitDefinition_create(2, 4);
  UnitDefinition_setId(ud1, "mmls");
  Unit_t *u = UnitDefinition_createUnit(ud1);

  Unit_setKind(u, UNIT_KIND_KILOGRAM);
  Unit_setExponent(u, 1);
  Unit_setScale(u, 2);
  Unit_setMultiplier(u, 3.0);

  char * ud_str2 = UnitDefinition_printUnits(ud1, 0);
  fail_unless(!strcmp(ud_str2, 
               "kilogram (exponent = 1, multiplier = 3, scale = 2)"));

  char * ud_str3 = UnitDefinition_printUnits(ud1, 1);
  fail_unless(!strcmp(ud_str3, "(300 kilogram)^1"));

  safe_free(ud_str);
  safe_free(ud_str1);
  safe_free(ud_str2);
  safe_free(ud_str3);
  UnitDefinition_free(ud);
  UnitDefinition_free(ud1);
}
END_TEST


START_TEST (test_UnitDefinition_createUnit)
{
  UnitDefinition_t *m = UnitDefinition_create(2, 2);
  
  Unit_t *p = UnitDefinition_createUnit(m);

  fail_unless( UnitDefinition_getNumUnits(m) == 1);
  fail_unless( SBase_getLevel((SBase_t *) (p)) == 2 );
  fail_unless( SBase_getVersion((SBase_t *) (p)) == 2 );

  UnitDefinition_free(m);
}
END_TEST


START_TEST (test_UnitDefinition_addUnit4)
{
  UnitDefinition_t *m = UnitDefinition_create(2, 2);
  Unit_t *p = NULL; 

  int i = UnitDefinition_addUnit(m, p);

  fail_unless( i == LIBSBML_OPERATION_FAILED);
  fail_unless( UnitDefinition_getNumUnits(m) == 0);

  UnitDefinition_free(m);
}
END_TEST


//START_TEST (test_UnitDefinition_createWith)
//{
//  UnitDefinition_t *ud = UnitDefinition_createWith("mmls", "");
//
//
//  fail_unless( SBase_getTypeCode  ((SBase_t *) ud) == SBML_UNIT_DEFINITION );
//  fail_unless( SBase_getMetaId    ((SBase_t *) ud) == NULL );
//  fail_unless( SBase_getNotes     ((SBase_t *) ud) == NULL );
//  fail_unless( SBase_getAnnotation((SBase_t *) ud) == NULL );
//
//  fail_unless( UnitDefinition_getName(ud) == NULL );
//
//  fail_unless( !strcmp(UnitDefinition_getId(ud), "mmls") );
//  fail_unless(UnitDefinition_isSetId(ud));
//
//  fail_unless(UnitDefinition_getNumUnits(ud) == 0);
//
//  UnitDefinition_free(ud);
//}
//END_TEST


START_TEST (test_UnitDefinition_createWithName)
{
  UnitDefinition_t *ud = UnitDefinition_create(2, 4);
  UnitDefinition_setName(ud, "mmol_per_liter_per_sec");


  fail_unless( SBase_getTypeCode  ((SBase_t *) ud) == SBML_UNIT_DEFINITION );
  fail_unless( SBase_getMetaId    ((SBase_t *) ud) == NULL );
  fail_unless( SBase_getNotes     ((SBase_t *) ud) == NULL );
  fail_unless( SBase_getAnnotation((SBase_t *) ud) == NULL );

  fail_unless( UnitDefinition_getId(ud) == NULL );

  fail_unless( !strcmp(UnitDefinition_getName(ud), "mmol_per_liter_per_sec"),
               NULL );

  fail_unless(UnitDefinition_isSetName(ud));

  fail_unless(UnitDefinition_getNumUnits(ud) == 0);

  UnitDefinition_free(ud);
}
END_TEST


START_TEST (test_UnitDefinition_isVariantOfSubstancePerTime_3)
{
  UnitDefinition_t *ud = 
    UnitDefinition_create(2, 2);
  Unit_t *dim   = Unit_create(2, 2);
  Unit_setKind( dim  , UnitKind_forName("dimensionless")   );

  Unit_t *perTime = UnitDefinition_createUnit(ud);
  Unit_setKind( perTime  , UnitKind_forName("second")   );
  Unit_setExponent( perTime, -1);

  Unit_t *u = UnitDefinition_createUnit(ud);

  fail_unless( !UnitDefinition_isVariantOfSubstancePerTime(ud) );

  Unit_setKind(u, UNIT_KIND_GRAM);
  Unit_setExponent(u, 1);

  fail_unless(  UnitDefinition_isVariantOfSubstancePerTime(ud) );

  Unit_setScale(u, -1);
  Unit_setScale(perTime, -1);
  fail_unless(  UnitDefinition_isVariantOfSubstancePerTime(ud) );

  Unit_setMultiplier(u, 2);
  fail_unless(  UnitDefinition_isVariantOfSubstancePerTime(ud) );

  Unit_setOffset(u, 3);
  fail_unless(  UnitDefinition_isVariantOfSubstancePerTime(ud) );

  Unit_setExponent(u, -3);
  fail_unless( !UnitDefinition_isVariantOfSubstancePerTime(ud) );

  Unit_setExponent(u, 1);
  Unit_setExponent(perTime, -3);
  fail_unless( !UnitDefinition_isVariantOfSubstancePerTime(ud) );
  
  Unit_setExponent(perTime, -1);
  UnitDefinition_addUnit( ud, dim   );
  fail_unless(  UnitDefinition_isVariantOfSubstancePerTime(ud) );

  UnitDefinition_free(ud);
  Unit_free(dim);
}
END_TEST


START_TEST (test_UnitDefinition_addUnit3)
{
  UnitDefinition_t *m = UnitDefinition_create(2, 2);
  Unit_t *p 
    = Unit_create(1, 2);
  Unit_setKind(p, UNIT_KIND_MOLE);

  int i = UnitDefinition_addUnit(m, p);

  fail_unless( i == LIBSBML_LEVEL_MISMATCH);
  fail_unless( UnitDefinition_getNumUnits(m) == 0);

  Unit_free(p);
  UnitDefinition_free(m);
}
END_TEST


START_TEST (test_UnitDefinition_addUnit1)
{
  UnitDefinition_t *m = UnitDefinition_create(2, 2);
  Unit_t *p 
    = Unit_create(2, 2);

  int i = UnitDefinition_addUnit(m, p);

  fail_unless( i == LIBSBML_INVALID_OBJECT);

  Unit_setKind(p, UNIT_KIND_MOLE);
  i = UnitDefinition_addUnit(m, p);

  fail_unless( i == LIBSBML_OPERATION_SUCCESS);
  fail_unless( UnitDefinition_getNumUnits(m) == 1);

  Unit_free(p);
  UnitDefinition_free(m);
}
END_TEST


START_TEST (test_unitdefinition_convert_SI1)
{
  UnitDefinition *ud = new UnitDefinition(2, 1);
  UnitDefinition *ud1;
  
  Unit * u = ud->createUnit();
  u->setKind(UNIT_KIND_HERTZ);

  ud1 = UnitDefinition::convertToSI(ud);

  fail_unless( ud1->getNumUnits() == 1);
  fail_unless( ud1->getUnit(0)->getKind() == UNIT_KIND_SECOND );
  fail_unless( ud1->getUnit(0)->getExponent() == -1);
  fail_unless( ud1->getLevel() == 2);
  fail_unless( ud1->getVersion() == 1);


  UnitDefinition_free(ud);
}
void
UnitDefinitionTest_teardown (void)
{
  UnitDefinition_free(UD);
}