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