1 /**
2  * @file    TestSBMLRuleConverter.cpp
3  * @brief   Tests for assignment rule sorter
4  * @author  Frank Bergmann
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/SBase.h>
45 #include <sbml/SBMLTypes.h>
46 
47 #include <sbml/conversion/SBMLConverter.h>
48 #include <sbml/conversion/SBMLConverterRegistry.h>
49 #include <sbml/conversion/SBMLRuleConverter.h>
50 
51 #include <sbml/math/FormulaParser.h>
52 
53 #include <string>
54 
55 #include <check.h>
56 
57 LIBSBML_CPP_NAMESPACE_USE
58 
59 BEGIN_C_DECLS
60 
61 
62 extern char *TestDataDirectory;
63 
64 
START_TEST(test_conversion_ruleconverter_sort)65 START_TEST (test_conversion_ruleconverter_sort)
66 {
67 
68   // create test model
69 
70   SBMLDocument doc;
71 
72   Model* model = doc.createModel();
73   model->setId("m");
74 
75   Parameter* parameter1 = model->createParameter();
76   parameter1->setId("s");
77   parameter1->setConstant(false);
78   parameter1->setValue(0);
79 
80   Parameter* parameter = model->createParameter();
81   parameter->setId("p");
82   parameter->setConstant(false);
83   parameter->setValue(0);
84 
85   AssignmentRule* rule1 = model->createAssignmentRule();
86   rule1->setVariable("s");
87   rule1->setFormula("p + 1");
88   rule1->setMetaId("m1");
89 
90   AssignmentRule* rule2 = model->createAssignmentRule();
91   rule2->setVariable("p");
92   rule2->setFormula("1");
93   rule2->setMetaId("m2");
94 
95   ConversionProperties props;
96   props.addOption("sortRules", true, "sort rules");
97 
98   SBMLConverter* converter = new SBMLRuleConverter();
99   converter->setProperties(&props);
100   converter->setDocument(&doc);
101 
102   fail_unless (converter->convert() == LIBSBML_OPERATION_SUCCESS);
103   fail_unless (model->getNumRules() == 2);
104   fail_unless (model->getRule(0)->getMetaId() == "m2");
105   fail_unless (model->getRule(1)->getMetaId() == "m1");
106 
107   delete converter;
108 }
109 END_TEST
110 
111 
START_TEST(test_conversion_ruleconverter_dontSort)112 START_TEST (test_conversion_ruleconverter_dontSort)
113 {
114 
115   // create test model
116 
117   SBMLDocument doc;
118 
119   Model* model = doc.createModel();
120   model->setId("m");
121 
122   Parameter* parameter1 = model->createParameter();
123   parameter1->setId("s");
124   parameter1->setConstant(false);
125   parameter1->setValue(0);
126 
127   Parameter* parameter = model->createParameter();
128   parameter->setId("p");
129   parameter->setConstant(false);
130   parameter->setValue(0);
131 
132   AssignmentRule* rule2 = model->createAssignmentRule();
133   rule2->setVariable("p");
134   rule2->setFormula("1");
135   rule2->setMetaId("m2");
136 
137   AssignmentRule* rule1 = model->createAssignmentRule();
138   rule1->setVariable("s");
139   rule1->setFormula("p + 1");
140   rule1->setMetaId("m1");
141 
142 
143   ConversionProperties props;
144   props.addOption("sortRules", true, "sort rules");
145 
146   SBMLConverter* converter = new SBMLRuleConverter();
147   converter->setProperties(&props);
148   converter->setDocument(&doc);
149 
150   fail_unless (converter->convert() == LIBSBML_OPERATION_SUCCESS);
151   fail_unless (model->getNumRules() == 2);
152   fail_unless (model->getRule(0)->getMetaId() == "m2");
153   fail_unless (model->getRule(1)->getMetaId() == "m1");
154 
155   delete converter;
156 }
157 END_TEST
158 
159 
160 
START_TEST(test_conversion_ruleconverter_sortIA)161 START_TEST (test_conversion_ruleconverter_sortIA)
162 {
163 
164   // create test model
165 
166   SBMLDocument doc;
167 
168   Model* model = doc.createModel();
169   model->setId("m");
170 
171   Parameter* parameter1 = model->createParameter();
172   parameter1->setId("s");
173   parameter1->setConstant(false);
174   parameter1->setValue(0);
175 
176   Parameter* parameter = model->createParameter();
177   parameter->setId("p");
178   parameter->setConstant(false);
179   parameter->setValue(0);
180 
181   InitialAssignment* ia1 = model->createInitialAssignment();
182   ia1->setSymbol("s");
183   ASTNode * math = SBML_parseFormula("p + 1");
184   ia1->setMath(math);
185   delete math;
186   ia1->setMetaId("m1");
187 
188   InitialAssignment* ia2 = model->createInitialAssignment();
189   ia2->setSymbol("p");
190   math = SBML_parseFormula("1");
191   ia2->setMath(math);
192   delete math;
193   ia2->setMetaId("m2");
194 
195   ConversionProperties props;
196   props.addOption("sortRules", true, "sort rules");
197 
198   SBMLConverter* converter = new SBMLRuleConverter();
199   converter->setProperties(&props);
200   converter->setDocument(&doc);
201 
202   fail_unless (converter->convert() == LIBSBML_OPERATION_SUCCESS);
203   fail_unless (model->getNumInitialAssignments() == 2);
204   fail_unless (model->getInitialAssignment(0)->getMetaId() == "m2");
205   fail_unless (model->getInitialAssignment(1)->getMetaId() == "m1");
206 
207   delete converter;
208 }
209 END_TEST
210 
211 
START_TEST(test_conversion_ruleconverter_dontSortIA)212 START_TEST (test_conversion_ruleconverter_dontSortIA)
213 {
214 
215   // create test model
216 
217   SBMLDocument doc;
218 
219   Model* model = doc.createModel();
220   model->setId("m");
221 
222   Parameter* parameter1 = model->createParameter();
223   parameter1->setId("s");
224   parameter1->setConstant(false);
225   parameter1->setValue(0);
226 
227   Parameter* parameter = model->createParameter();
228   parameter->setId("p");
229   parameter->setConstant(false);
230   parameter->setValue(0);
231 
232   InitialAssignment* ia2 = model->createInitialAssignment();
233   ia2->setSymbol("p");
234   ASTNode * math = SBML_parseFormula("1");
235   ia2->setMath(math);
236   delete math;
237   ia2->setMetaId("m2");
238 
239   InitialAssignment* ia1 = model->createInitialAssignment();
240   ia1->setSymbol("s");
241   math = SBML_parseFormula("p + 1");
242   ia1->setMath(math);
243   delete math;
244   ia1->setMetaId("m1");
245 
246   ConversionProperties props;
247   props.addOption("sortRules", true, "sort rules");
248 
249   SBMLConverter* converter = new SBMLRuleConverter();
250   converter->setProperties(&props);
251   converter->setDocument(&doc);
252 
253   fail_unless (converter->convert() == LIBSBML_OPERATION_SUCCESS);
254   fail_unless (model->getNumInitialAssignments() == 2);
255   fail_unless (model->getInitialAssignment(0)->getMetaId() == "m2");
256   fail_unless (model->getInitialAssignment(1)->getMetaId() == "m1");
257 
258   delete converter;
259 }
260 END_TEST
261 
262 
START_TEST(test_conversion_ruleconverter_with_alg)263 START_TEST (test_conversion_ruleconverter_with_alg)
264 {
265   // create test model
266 
267   SBMLDocument doc;
268 
269   Model* model = doc.createModel();
270   model->setId("m");
271 
272   Parameter* parameter1 = model->createParameter();
273   parameter1->setId("s");
274   parameter1->setConstant(false);
275   parameter1->setValue(0);
276 
277   Parameter* parameter = model->createParameter();
278   parameter->setId("p");
279   parameter->setConstant(false);
280   parameter->setValue(0);
281 
282   Parameter* parameter2 = model->createParameter();
283   parameter2->setId("k");
284   parameter2->setConstant(false);
285   parameter2->setValue(0);
286 
287   AlgebraicRule* rule0 = model->createAlgebraicRule();
288   rule0->setFormula("k + 2");
289   rule0->setMetaId("m0");
290 
291   AssignmentRule* rule1 = model->createAssignmentRule();
292   rule1->setVariable("s");
293   rule1->setFormula("p + 1");
294   rule1->setMetaId("m1");
295 
296   AssignmentRule* rule2 = model->createAssignmentRule();
297   rule2->setVariable("p");
298   rule2->setFormula("1");
299   rule2->setMetaId("m2");
300 
301   ConversionProperties props;
302   props.addOption("sortRules", true, "sort rules");
303 
304   SBMLConverter* converter = new SBMLRuleConverter();
305   converter->setProperties(&props);
306   converter->setDocument(&doc);
307   fail_unless (converter->convert() == LIBSBML_OPERATION_SUCCESS);
308 
309   fail_unless (model->getNumRules() == 3);
310   fail_unless (model->getRule(0)->getMetaId() == "m2");
311   fail_unless (model->getRule(1)->getMetaId() == "m1");
312   fail_unless (model->getRule(2)->getMetaId() == "m0");
313 
314   delete converter;
315 }
316 END_TEST
317 
318 
START_TEST(test_conversion_inlineFD_bug)319 START_TEST (test_conversion_inlineFD_bug)
320 {
321   std::string filename = "/inline_bug_minimal.xml";
322   filename = TestDataDirectory + filename;
323   SBMLDocument* doc = readSBMLFromFile(filename.c_str());
324 
325   ConversionProperties props;
326   props.addOption("expandFunctionDefinitions", "true");
327 
328   fail_unless(doc->getModel() != NULL);
329   fail_unless(doc->convert(props) == LIBSBML_OPERATION_SUCCESS);
330   fail_unless(doc->getModel()->getNumReactions() == 1);
331   fail_unless(doc->getModel()->getReaction(0)->isSetKineticLaw());
332   fail_unless(doc->getModel()->getReaction(0)->getKineticLaw()->getMath() != NULL);
333 
334   // all seems good ... write it
335   const ASTNode * node = doc->getModel()->getReaction(0)->getKineticLaw()->getMath();
336   std::string math = writeMathMLToStdString(node);
337   ASTNode* test = readMathMLFromString(math.c_str());
338   fail_unless(test != NULL);
339 
340   delete test;
341 
342   // additional test where the node being converted is the top-level
343   fail_unless(doc->getModel()->getNumRules() == 1);
344   fail_unless(doc->getModel()->getRule(0)->isSetMath());
345   fail_unless(doc->getModel()->getRule(0)->getMath() != NULL);
346 
347   node = doc->getModel()->getRule(0)->getMath();
348   math = writeMathMLToStdString(node);
349   test = readMathMLFromString(math.c_str());
350   fail_unless(test != NULL);
351 
352   delete test;
353   delete doc;
354 }
355 END_TEST
356 
START_TEST(test_conversion_inlineIA_bug)357 START_TEST (test_conversion_inlineIA_bug)
358 {
359   std::string filename = "/ia-ternary-lt.xml";
360   filename = TestDataDirectory + filename;
361   SBMLDocument* doc = readSBMLFromFile(filename.c_str());
362 
363   ConversionProperties props;
364   props.addOption("expandInitialAssignments", "true");
365 
366   fail_unless(doc->getModel() != NULL);
367   fail_unless(doc->convert(props) == LIBSBML_OPERATION_SUCCESS);
368   fail_unless(doc->getModel()->getNumInitialAssignments() == 0);
369   fail_unless(doc->getModel()->getParameter("x")->isSetValue());
370   fail_unless(doc->getModel()->getParameter("x")->getValue() == 3);
371 
372   delete doc;
373 }
374 END_TEST
375 
376 
377 Suite *
create_suite_TestSBMLRuleConverter(void)378 create_suite_TestSBMLRuleConverter (void)
379 {
380   Suite *suite = suite_create("SBMLRuleConverter");
381   TCase *tcase = tcase_create("SBMLRuleConverter");
382 
383   tcase_add_test(tcase, test_conversion_ruleconverter_sort);
384   tcase_add_test(tcase, test_conversion_ruleconverter_dontSort);
385   tcase_add_test(tcase, test_conversion_ruleconverter_with_alg);
386   tcase_add_test(tcase, test_conversion_ruleconverter_sortIA);
387   tcase_add_test(tcase, test_conversion_ruleconverter_dontSortIA);
388   tcase_add_test(tcase, test_conversion_inlineFD_bug);
389   tcase_add_test(tcase, test_conversion_inlineIA_bug);
390 
391 
392   suite_add_tcase(suite, tcase);
393 
394   return suite;
395 }
396 
397 
398 END_C_DECLS
399 
400