1 /**
2  * @file    TestReadFromFile1.cpp
3  * @brief   Tests for reading MathML from files into ASTNodes.
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 <sbml/common/common.h>
43 
44 #include <sbml/SBMLReader.h>
45 #include <sbml/SBMLTypes.h>
46 
47 #include <sbml/math/ASTNode.h>
48 
49 
50 
51 #include <string>
52 
53 #include <check.h>
54 
55 LIBSBML_CPP_NAMESPACE_USE
56 #define XML_HEADER    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
57 #define MATHML_HEADER "<math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n"
58 #define MATHML_FOOTER "</math>"
59 
60 #define wrapMathML(s)   XML_HEADER MATHML_HEADER s MATHML_FOOTER
61 
62 
63 
64 static bool
equals(const char * expected,const char * actual)65 equals(const char* expected, const char* actual)
66 {
67   if (!strcmp(expected, actual)) return true;
68 
69   printf("\nStrings are not equal:\n");
70   printf("Expected:\n[%s]\n", expected);
71   printf("Actual:\n[%s]\n", actual);
72 
73   return false;
74 }
75 
76 BEGIN_C_DECLS
77 
78 
79 extern char *TestDataDirectory;
80 
81 
START_TEST(test_read_MathML_1)82 START_TEST (test_read_MathML_1)
83 {
84   SBMLReader         reader;
85   SBMLDocument*      d;
86   Model*             m;
87   FunctionDefinition* fd;
88   InitialAssignment* ia;
89   Rule*              r;
90   KineticLaw*        kl;
91   char * math;
92 
93 
94   std::string filename(TestDataDirectory);
95   filename += "mathML_1-invalid.xml";
96 
97 
98   d = reader.readSBML(filename);
99 
100   m = d->getModel();
101   if (m == NULL)
102   {
103     fail("readSBML(\"mathML_1-invalid.xml\") returned a NULL pointer.");
104   }
105 
106   fail_unless( m != NULL, NULL );
107 
108   // check that whole model has been read in
109   fail_unless( m->getNumFunctionDefinitions() == 2, NULL);
110   fail_unless( m->getNumInitialAssignments() == 1, NULL);
111   fail_unless( m->getNumRules() == 2, NULL );
112   fail_unless( m->getNumReactions() == 1, NULL );
113 
114   //<functionDefinition id="fd">
115   //  <math xmlns="http://www.w3.org/1998/Math/MathML">
116   //    <lambda>
117   //      <bvar>
118   //        <ci> x </ci>
119   //      </bvar>
120   //      <apply/>
121   //    </lambda>
122   //  </math>
123   //</functionDefinition>
124   fd = m->getFunctionDefinition(0);
125   const ASTNode *fd_math = fd->getMath();
126 
127   fail_unless (fd_math->getType() == AST_LAMBDA, NULL);
128   fail_unless (fd_math->getNumChildren() == 2, NULL);
129   math = SBML_formulaToString(fd_math);
130   fail_unless (!strcmp(math, "lambda(x, )"), NULL);
131   safe_free(math);
132   fail_unless (fd_math->getParentSBMLObject() == fd, NULL);
133   fail_unless (fd_math->getNumBvars() == 1);
134   //fail_unless (fd_math->getNumVariablesWithUndeclaredUnits() == 0);
135   //fail_unless( fd_math->containsVariable("c") == false );
136   //fail_unless( fd_math->containsVariable("x") == true );
137 
138   ASTNode *child = fd_math->getRightChild();
139   fail_unless (child->getType() == AST_UNKNOWN, NULL);
140   fail_unless (child->getNumChildren() == 0, NULL);
141   math = SBML_formulaToString(child);
142   fail_unless (!strcmp(math, ""), NULL);
143   safe_free(math);
144 
145   //<functionDefinition id="fd1">
146   //  <math xmlns="http://www.w3.org/1998/Math/MathML">
147   //    <lambda>
148   //      <bvar>
149   //        <ci> x </ci>
150   //      </bvar>
151   //        <true/>
152   //    </lambda>
153   //  </math>
154   //</functionDefinition>
155   fd = m->getFunctionDefinition(1);
156   const ASTNode *fd1_math = fd->getMath();
157 
158   fail_unless (fd1_math->getType() == AST_LAMBDA, NULL);
159   fail_unless (fd1_math->getNumChildren() == 2, NULL);
160   math = SBML_formulaToString(fd1_math);
161   fail_unless (!strcmp(math, "lambda(x, true)"), NULL);
162   safe_free(math);
163   fail_unless (fd1_math->getParentSBMLObject() == fd, NULL);
164   //fail_unless (fd1_math->getNumVariablesWithUndeclaredUnits() == 0);
165   //fail_unless( fd1_math->containsVariable("c") == false );
166   //fail_unless( fd1_math->containsVariable("x") == true );
167 
168   ASTNode *child1 = fd1_math->getRightChild();
169   fail_unless (child1->getType() == AST_CONSTANT_TRUE, NULL);
170   fail_unless (child1->getNumChildren() == 0, NULL);
171 
172   math = SBML_formulaToString(child1);
173   fail_unless (!strcmp(math, "true"), NULL);
174   safe_free(math);
175 
176   //fail_unless( child1->containsVariable("c") == false );
177   //fail_unless( child1->containsVariable("x") == false );
178 
179   //<initialAssignment symbol="p1">
180   //  <math xmlns="http://www.w3.org/1998/Math/MathML">
181   //    <apply/>
182   //  </math>
183   //</initialAssignment>
184   ia = m->getInitialAssignment(0);
185   const ASTNode *ia_math = ia->getMath();
186 
187   fail_unless (ia_math->getType() == AST_UNKNOWN, NULL);
188   fail_unless (ia_math->getNumChildren() == 0, NULL);
189   math = SBML_formulaToString(ia_math);
190   fail_unless (!strcmp(math, ""), NULL);
191   safe_free(math);
192   fail_unless (ia_math->getParentSBMLObject() == ia, NULL);
193   //fail_unless (ia_math->getNumVariablesWithUndeclaredUnits() == 0);
194   //fail_unless( ia_math->containsVariable("c") == false );
195   //fail_unless( ia_math->containsVariable("x") == false );
196 
197   //<algebraicRule>
198   //  <math xmlns="http://www.w3.org/1998/Math/MathML">
199   //    <true/>
200   //  </math>
201   //</algebraicRule>
202   r = m->getRule(0);
203   const ASTNode *r_math = r->getMath();
204 
205   fail_unless (r_math->getType() == AST_CONSTANT_TRUE, NULL);
206   fail_unless (r_math->getNumChildren() == 0, NULL);
207   math = SBML_formulaToString(r_math);
208   fail_unless (!strcmp(math, "true"), NULL);
209   safe_free(math);
210   fail_unless (r_math->getParentSBMLObject() == r, NULL);
211   //fail_unless (r_math->getNumVariablesWithUndeclaredUnits() == 0);
212   //fail_unless( r_math->containsVariable("c") == false );
213   //fail_unless( r_math->containsVariable("x") == false );
214 
215   //<assignmentRule variable="p2">
216   //  <math xmlns="http://www.w3.org/1998/Math/MathML">
217   //      <infinity/>
218   //  </math>
219   //</assignmentRule>
220   r = m->getRule(1);
221   const ASTNode *r1_math = r->getMath();
222 
223   fail_unless (r1_math->getType() == AST_REAL, NULL);
224   fail_unless (r1_math->getNumChildren() == 0, NULL);
225   math = SBML_formulaToString(r1_math);
226   fail_unless (!strcmp(math, "INF"), NULL);
227   safe_free(math);
228   fail_unless (r1_math->getParentSBMLObject() == r, NULL);
229   //fail_unless (r1_math->getNumVariablesWithUndeclaredUnits() == 0);
230   //fail_unless( r1_math->containsVariable("c") == false );
231   //fail_unless( r1_math->containsVariable("x") == false );
232 
233   //<kineticLaw>
234   //  <math xmlns="http://www.w3.org/1998/Math/MathML">
235   //    <apply>
236   //      <cn> 4.5 </cn>
237   //    </apply>
238   //  </math>
239   //  <listOfParameters>
240   //    <parameter id="k" value="9" units="litre"/>
241   //  </listOfParameters>
242   //</kineticLaw>
243   kl = m->getReaction(0)->getKineticLaw();
244   const ASTNode *kl_math = kl->getMath();
245 
246   fail_unless (kl_math->getType() == AST_REAL, NULL);
247   fail_unless (kl_math->getNumChildren() == 0, NULL);
248   math = SBML_formulaToString(kl_math);
249   fail_unless (!strcmp(math, "4.5"), NULL);
250   safe_free(math);
251   fail_unless (kl_math->getParentSBMLObject() == kl, NULL);
252   //fail_unless (kl_math->getNumVariablesWithUndeclaredUnits() == 0);
253   //fail_unless( kl_math->containsVariable("c") == false );
254   //fail_unless( kl_math->containsVariable("x") == false );
255 
256   delete d;
257 }
258 END_TEST
259 
START_TEST(test_read_MathML_fromStream)260 START_TEST(test_read_MathML_fromStream)
261 {
262   const char* expected = wrapMathML
263     (
264       "  <apply>\n"
265       "    <divide/>\n"
266       "    <ci> LacIbNormalized </ci>\n"
267       "    <apply>\n"
268       "      <csymbol encoding=\"text\" definitionURL=\"http://sed-ml.org/#max\"> max </csymbol>\n"
269       "      <ci> LacIbNormalized </ci>\n"
270       "    </apply>\n"
271       "  </apply>\n"
272       );
273   std::string filename(TestDataDirectory);
274   filename += "non_sbml_symbol.xml";
275 
276   XMLErrorLog log;
277   XMLInputStream stream(filename.c_str(), true, "", &log);
278   fail_unless(stream.getSBMLNamespaces() == NULL);
279   ASTNode* node = readMathML(stream);
280 
281   std::string result = writeMathMLToStdString(node);
282 
283   fail_unless(node != NULL);
284   fail_unless(log.getNumErrors() == 0);
285 
286   fail_unless(equals(expected, result.c_str()));
287 
288 
289   delete node;
290 
291 }
292 END_TEST
293 
294 Suite *
create_suite_TestReadFromFile1(void)295 create_suite_TestReadFromFile1 (void)
296 {
297   Suite *suite = suite_create("test-data/mathML_1.xml");
298   TCase *tcase = tcase_create("test-data/mathML_1.xml");
299 
300 
301   tcase_add_test(tcase, test_read_MathML_1);
302   tcase_add_test(tcase, test_read_MathML_fromStream);
303 
304   suite_add_tcase(suite, tcase);
305 
306   return suite;
307 }
308 
309 
310 END_C_DECLS
311 
312