test_interface_parser.py
Go to the documentation of this file.
1 """
2 GTSAM Copyright 2010-2020, Georgia Tech Research Corporation,
3 Atlanta, Georgia 30332-0415
4 All Rights Reserved
5 
6 See LICENSE for the license information
7 
8 Tests for interface_parser.
9 
10 Author: Varun Agrawal
11 """
12 
13 # pylint: disable=import-error,wrong-import-position
14 
15 import os
16 import sys
17 import unittest
18 
19 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
20 
21 from gtwrap.interface_parser import (
22  ArgumentList, Class, Constructor, Enum, Enumerator, ForwardDeclaration,
23  GlobalFunction, Include, Method, Module, Namespace, Operator, ReturnType,
24  StaticMethod, TemplatedType, Type, TypedefTemplateInstantiation, Typename,
25  Variable)
26 
27 
28 class TestInterfaceParser(unittest.TestCase):
29  """Test driver for all classes in interface_parser.py."""
30  def test_typename(self):
31  """Test parsing of Typename."""
32  typename = Typename.rule.parseString("size_t")[0]
33  self.assertEqual("size_t", typename.name)
34 
35  def test_basic_type(self):
36  """Tests for BasicType."""
37  # Check basis type
38  t = Type.rule.parseString("int x")[0]
39  self.assertEqual("int", t.typename.name)
40  self.assertTrue(t.is_basic)
41 
42  # Check const
43  t = Type.rule.parseString("const int x")[0]
44  self.assertEqual("int", t.typename.name)
45  self.assertTrue(t.is_basic)
46  self.assertTrue(t.is_const)
47 
48  # Check shared pointer
49  t = Type.rule.parseString("int* x")[0]
50  self.assertEqual("int", t.typename.name)
51  self.assertTrue(t.is_shared_ptr)
52 
53  # Check raw pointer
54  t = Type.rule.parseString("int@ x")[0]
55  self.assertEqual("int", t.typename.name)
56  self.assertTrue(t.is_ptr)
57 
58  # Check reference
59  t = Type.rule.parseString("int& x")[0]
60  self.assertEqual("int", t.typename.name)
61  self.assertTrue(t.is_ref)
62 
63  # Check const reference
64  t = Type.rule.parseString("const int& x")[0]
65  self.assertEqual("int", t.typename.name)
66  self.assertTrue(t.is_const)
67  self.assertTrue(t.is_ref)
68 
69  def test_custom_type(self):
70  """Tests for CustomType."""
71  # Check qualified type
72  t = Type.rule.parseString("gtsam::Pose3 x")[0]
73  self.assertEqual("Pose3", t.typename.name)
74  self.assertEqual(["gtsam"], t.typename.namespaces)
75  self.assertTrue(not t.is_basic)
76 
77  # Check const
78  t = Type.rule.parseString("const gtsam::Pose3 x")[0]
79  self.assertEqual("Pose3", t.typename.name)
80  self.assertEqual(["gtsam"], t.typename.namespaces)
81  self.assertTrue(t.is_const)
82 
83  # Check shared pointer
84  t = Type.rule.parseString("gtsam::Pose3* x")[0]
85  self.assertEqual("Pose3", t.typename.name)
86  self.assertEqual(["gtsam"], t.typename.namespaces)
87  self.assertTrue(t.is_shared_ptr)
88  self.assertEqual("std::shared_ptr<gtsam::Pose3>",
89  t.to_cpp(use_boost=False))
90  self.assertEqual("boost::shared_ptr<gtsam::Pose3>",
91  t.to_cpp(use_boost=True))
92 
93  # Check raw pointer
94  t = Type.rule.parseString("gtsam::Pose3@ x")[0]
95  self.assertEqual("Pose3", t.typename.name)
96  self.assertEqual(["gtsam"], t.typename.namespaces)
97  self.assertTrue(t.is_ptr)
98 
99  # Check reference
100  t = Type.rule.parseString("gtsam::Pose3& x")[0]
101  self.assertEqual("Pose3", t.typename.name)
102  self.assertEqual(["gtsam"], t.typename.namespaces)
103  self.assertTrue(t.is_ref)
104 
105  # Check const reference
106  t = Type.rule.parseString("const gtsam::Pose3& x")[0]
107  self.assertEqual("Pose3", t.typename.name)
108  self.assertEqual(["gtsam"], t.typename.namespaces)
109  self.assertTrue(t.is_const)
110  self.assertTrue(t.is_ref)
111 
113  """Test a templated type."""
114  t = TemplatedType.rule.parseString("Eigen::Matrix<double, 3, 4>")[0]
115  self.assertEqual("Matrix", t.typename.name)
116  self.assertEqual(["Eigen"], t.typename.namespaces)
117  self.assertEqual("double", t.typename.instantiations[0].name)
118  self.assertEqual("3", t.typename.instantiations[1].name)
119  self.assertEqual("4", t.typename.instantiations[2].name)
120 
121  t = TemplatedType.rule.parseString(
122  "gtsam::PinholeCamera<gtsam::Cal3S2>")[0]
123  self.assertEqual("PinholeCamera", t.typename.name)
124  self.assertEqual(["gtsam"], t.typename.namespaces)
125  self.assertEqual("Cal3S2", t.typename.instantiations[0].name)
126  self.assertEqual(["gtsam"], t.typename.instantiations[0].namespaces)
127 
128  t = TemplatedType.rule.parseString("PinholeCamera<Cal3S2*>")[0]
129  self.assertEqual("PinholeCamera", t.typename.name)
130  self.assertEqual("Cal3S2", t.typename.instantiations[0].name)
131  self.assertTrue(t.template_params[0].is_shared_ptr)
132 
134  """Test no arguments."""
135  empty_args = ArgumentList.rule.parseString("")[0]
136  self.assertEqual(0, len(empty_args))
137 
139  """Test arguments list for a method/function."""
140  arg_string = "int a, C1 c1, C2& c2, C3* c3, "\
141  "const C4 c4, const C5& c5,"\
142  "const C6* c6"
143  args = ArgumentList.rule.parseString(arg_string)[0]
144 
145  self.assertEqual(7, len(args.args_list))
146  self.assertEqual(['a', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6'],
147  args.args_names())
148 
150  """
151  Test arguments list where the arguments are qualified with `const`
152  and can be either raw pointers, shared pointers or references.
153  """
154  arg_string = "double x1, double* x2, double& x3, double@ x4, " \
155  "const double x5, const double* x6, const double& x7, const double@ x8"
156  args = ArgumentList.rule.parseString(arg_string)[0].args_list
157  self.assertEqual(8, len(args))
158  self.assertFalse(args[1].ctype.is_ptr and args[1].ctype.is_shared_ptr
159  and args[1].ctype.is_ref)
160  self.assertTrue(args[1].ctype.is_shared_ptr)
161  self.assertTrue(args[2].ctype.is_ref)
162  self.assertTrue(args[3].ctype.is_ptr)
163  self.assertTrue(args[4].ctype.is_const)
164  self.assertTrue(args[5].ctype.is_shared_ptr and args[5].ctype.is_const)
165  self.assertTrue(args[6].ctype.is_ref and args[6].ctype.is_const)
166  self.assertTrue(args[7].ctype.is_ptr and args[7].ctype.is_const)
167 
169  """Test arguments list where the arguments can be templated."""
170  arg_string = "std::pair<string, double> steps, vector<T*> vector_of_pointers"
171  args = ArgumentList.rule.parseString(arg_string)[0]
172  args_list = args.args_list
173  self.assertEqual(2, len(args_list))
174  self.assertEqual("std::pair<string, double>",
175  args_list[0].ctype.to_cpp(False))
176  self.assertEqual("vector<std::shared_ptr<T>>",
177  args_list[1].ctype.to_cpp(False))
178  self.assertEqual("vector<boost::shared_ptr<T>>",
179  args_list[1].ctype.to_cpp(True))
180 
182  """Tests any expression that is a valid default argument"""
183  args = ArgumentList.rule.parseString(
184  "string c = \"\", string s=\"hello\", int a=3, "
185  "int b, double pi = 3.1415, "
186  "gtsam::KeyFormatter kf = gtsam::DefaultKeyFormatter, "
187  "std::vector<size_t> p = std::vector<size_t>(), "
188  "std::vector<size_t> l = (1, 2, 'name', \"random\", 3.1415)"
189  )[0].args_list
190 
191  # Test for basic types
192  self.assertEqual(args[0].default, "")
193  self.assertEqual(args[1].default, "hello")
194  self.assertEqual(args[2].default, 3)
195  # No default argument should set `default` to None
196  self.assertIsNone(args[3].default)
197 
198  self.assertEqual(args[4].default, 3.1415)
199 
200  # Test non-basic type
201  self.assertEqual(repr(args[5].default.typename),
202  'gtsam::DefaultKeyFormatter')
203  # Test templated type
204  self.assertEqual(repr(args[6].default.typename), 'std::vector<size_t>')
205  # Test for allowing list as default argument
206  self.assertEqual(args[7].default, (1, 2, 'name', "random", 3.1415))
207 
208  def test_return_type(self):
209  """Test ReturnType"""
210  # Test void
211  return_type = ReturnType.rule.parseString("void")[0]
212  self.assertEqual("void", return_type.type1.typename.name)
213  self.assertTrue(return_type.type1.is_basic)
214 
215  # Test basis type
216  return_type = ReturnType.rule.parseString("size_t")[0]
217  self.assertEqual("size_t", return_type.type1.typename.name)
218  self.assertTrue(not return_type.type2)
219  self.assertTrue(return_type.type1.is_basic)
220 
221  # Test with qualifiers
222  return_type = ReturnType.rule.parseString("int&")[0]
223  self.assertEqual("int", return_type.type1.typename.name)
224  self.assertTrue(return_type.type1.is_basic
225  and return_type.type1.is_ref)
226 
227  return_type = ReturnType.rule.parseString("const int")[0]
228  self.assertEqual("int", return_type.type1.typename.name)
229  self.assertTrue(return_type.type1.is_basic
230  and return_type.type1.is_const)
231 
232  # Test pair return
233  return_type = ReturnType.rule.parseString("pair<char, int>")[0]
234  self.assertEqual("char", return_type.type1.typename.name)
235  self.assertEqual("int", return_type.type2.typename.name)
236 
237  def test_method(self):
238  """Test for a class method."""
239  ret = Method.rule.parseString("int f();")[0]
240  self.assertEqual("f", ret.name)
241  self.assertEqual(0, len(ret.args))
242  self.assertTrue(not ret.is_const)
243 
244  ret = Method.rule.parseString("int f() const;")[0]
245  self.assertEqual("f", ret.name)
246  self.assertEqual(0, len(ret.args))
247  self.assertTrue(ret.is_const)
248 
249  ret = Method.rule.parseString(
250  "int f(const int x, const Class& c, Class* t) const;")[0]
251  self.assertEqual("f", ret.name)
252  self.assertEqual(3, len(ret.args))
253 
255  """Test for static methods."""
256  ret = StaticMethod.rule.parseString("static int f();")[0]
257  self.assertEqual("f", ret.name)
258  self.assertEqual(0, len(ret.args))
259 
260  ret = StaticMethod.rule.parseString(
261  "static int f(const int x, const Class& c, Class* t);")[0]
262  self.assertEqual("f", ret.name)
263  self.assertEqual(3, len(ret.args))
264 
265  def test_constructor(self):
266  """Test for class constructor."""
267  ret = Constructor.rule.parseString("f();")[0]
268  self.assertEqual("f", ret.name)
269  self.assertEqual(0, len(ret.args))
270 
271  ret = Constructor.rule.parseString(
272  "f(const int x, const Class& c, Class* t);")[0]
273  self.assertEqual("f", ret.name)
274  self.assertEqual(3, len(ret.args))
275 
277  """Test for operator overloading."""
278  # Unary operator
279  wrap_string = "gtsam::Vector2 operator-() const;"
280  ret = Operator.rule.parseString(wrap_string)[0]
281  self.assertEqual("operator", ret.name)
282  self.assertEqual("-", ret.operator)
283  self.assertEqual("Vector2", ret.return_type.type1.typename.name)
284  self.assertEqual("gtsam::Vector2",
285  ret.return_type.type1.typename.to_cpp())
286  self.assertTrue(len(ret.args) == 0)
287  self.assertTrue(ret.is_unary)
288 
289  # Binary operator
290  wrap_string = "gtsam::Vector2 operator*(const gtsam::Vector2 &v) const;"
291  ret = Operator.rule.parseString(wrap_string)[0]
292  self.assertEqual("operator", ret.name)
293  self.assertEqual("*", ret.operator)
294  self.assertEqual("Vector2", ret.return_type.type1.typename.name)
295  self.assertEqual("gtsam::Vector2",
296  ret.return_type.type1.typename.to_cpp())
297  self.assertTrue(len(ret.args) == 1)
298  self.assertEqual("const gtsam::Vector2 &",
299  repr(ret.args.args_list[0].ctype))
300  self.assertTrue(not ret.is_unary)
301 
303  """Test for typedef'd instantiation of a template."""
304  typedef = TypedefTemplateInstantiation.rule.parseString("""
305  typedef gtsam::BearingFactor<gtsam::Pose2, gtsam::Point2, gtsam::Rot2>
306  BearingFactor2D;
307  """)[0]
308  self.assertEqual("BearingFactor2D", typedef.new_name)
309  self.assertEqual("BearingFactor", typedef.typename.name)
310  self.assertEqual(["gtsam"], typedef.typename.namespaces)
311  self.assertEqual(3, len(typedef.typename.instantiations))
312 
313  def test_base_class(self):
314  """Test a base class."""
315  ret = Class.rule.parseString("""
316  virtual class Base {
317  };
318  """)[0]
319  self.assertEqual("Base", ret.name)
320  self.assertEqual(0, len(ret.ctors))
321  self.assertEqual(0, len(ret.methods))
322  self.assertEqual(0, len(ret.static_methods))
323  self.assertEqual(0, len(ret.properties))
324  self.assertTrue(ret.is_virtual)
325 
326  def test_empty_class(self):
327  """Test an empty class declaration."""
328  ret = Class.rule.parseString("""
329  class FactorIndices {};
330  """)[0]
331  self.assertEqual("FactorIndices", ret.name)
332  self.assertEqual(0, len(ret.ctors))
333  self.assertEqual(0, len(ret.methods))
334  self.assertEqual(0, len(ret.static_methods))
335  self.assertEqual(0, len(ret.properties))
336  self.assertTrue(not ret.is_virtual)
337 
338  def test_class(self):
339  """Test a non-trivial class."""
340  ret = Class.rule.parseString("""
341  class SymbolicFactorGraph {
342  SymbolicFactorGraph();
343  SymbolicFactorGraph(const gtsam::SymbolicBayesNet& bayesNet);
344  SymbolicFactorGraph(const gtsam::SymbolicBayesTree& bayesTree);
345 
346  // Dummy static method
347  static gtsam::SymbolidFactorGraph CreateGraph();
348 
349  void push_back(gtsam::SymbolicFactor* factor);
350  void print(string s) const;
351  bool equals(const gtsam::SymbolicFactorGraph& rhs, double tol) const;
352  size_t size() const;
353  bool exists(size_t idx) const;
354 
355  // Standard interface
356  gtsam::KeySet keys() const;
357  void push_back(const gtsam::SymbolicFactorGraph& graph);
358  void push_back(const gtsam::SymbolicBayesNet& bayesNet);
359  void push_back(const gtsam::SymbolicBayesTree& bayesTree);
360 
361  /* Advanced interface */
362  void push_factor(size_t key);
363  void push_factor(size_t key1, size_t key2);
364  void push_factor(size_t key1, size_t key2, size_t key3);
365  void push_factor(size_t key1, size_t key2, size_t key3, size_t key4);
366 
367  gtsam::SymbolicBayesNet* eliminateSequential();
368  gtsam::SymbolicBayesNet* eliminateSequential(
369  const gtsam::Ordering& ordering);
370  gtsam::SymbolicBayesTree* eliminateMultifrontal();
371  gtsam::SymbolicBayesTree* eliminateMultifrontal(
372  const gtsam::Ordering& ordering);
373  pair<gtsam::SymbolicBayesNet*, gtsam::SymbolicFactorGraph*>
374  eliminatePartialSequential(const gtsam::Ordering& ordering);
375  pair<gtsam::SymbolicBayesNet*, gtsam::SymbolicFactorGraph*>
376  eliminatePartialSequential(const gtsam::KeyVector& keys);
377  pair<gtsam::SymbolicBayesTree*, gtsam::SymbolicFactorGraph*>
378  eliminatePartialMultifrontal(const gtsam::Ordering& ordering);
379  gtsam::SymbolicBayesNet* marginalMultifrontalBayesNet(
380  const gtsam::Ordering& ordering);
381  gtsam::SymbolicBayesNet* marginalMultifrontalBayesNet(
382  const gtsam::KeyVector& key_vector,
383  const gtsam::Ordering& marginalizedVariableOrdering);
384  gtsam::SymbolicFactorGraph* marginal(const gtsam::KeyVector& key_vector);
385  };
386  """)[0]
387 
388  self.assertEqual("SymbolicFactorGraph", ret.name)
389  self.assertEqual(3, len(ret.ctors))
390  self.assertEqual(23, len(ret.methods))
391  self.assertEqual(1, len(ret.static_methods))
392  self.assertEqual(0, len(ret.properties))
393  self.assertTrue(not ret.is_virtual)
394 
396  """Test for class inheritance."""
397  ret = Class.rule.parseString("""
398  virtual class Null: gtsam::noiseModel::mEstimator::Base {
399  Null();
400  void print(string s) const;
401  static gtsam::noiseModel::mEstimator::Null* Create();
402 
403  // enabling serialization functionality
404  void serializable() const;
405  };
406  """)[0]
407  self.assertEqual("Null", ret.name)
408  self.assertEqual(1, len(ret.ctors))
409  self.assertEqual(2, len(ret.methods))
410  self.assertEqual(1, len(ret.static_methods))
411  self.assertEqual(0, len(ret.properties))
412  self.assertEqual("Base", ret.parent_class.name)
413  self.assertEqual(["gtsam", "noiseModel", "mEstimator"],
414  ret.parent_class.namespaces)
415  self.assertTrue(ret.is_virtual)
416 
417  ret = Class.rule.parseString(
418  "class ForwardKinematicsFactor : gtsam::BetweenFactor<gtsam::Pose3> {};"
419  )[0]
420  self.assertEqual("ForwardKinematicsFactor", ret.name)
421  self.assertEqual("BetweenFactor", ret.parent_class.name)
422  self.assertEqual(["gtsam"], ret.parent_class.namespaces)
423  self.assertEqual("Pose3", ret.parent_class.instantiations[0].name)
424  self.assertEqual(["gtsam"],
425  ret.parent_class.instantiations[0].namespaces)
426 
428  """Test for class with nested enum."""
429  ret = Class.rule.parseString("""
430  class Pet {
431  Pet(const string &name, Kind type);
432  enum Kind { Dog, Cat };
433  };
434  """)[0]
435  self.assertEqual(ret.name, "Pet")
436  self.assertEqual(ret.enums[0].name, "Kind")
437 
438  def test_include(self):
439  """Test for include statements."""
440  include = Include.rule.parseString(
441  "#include <gtsam/slam/PriorFactor.h>")[0]
442  self.assertEqual("gtsam/slam/PriorFactor.h", include.header)
443 
445  """Test for forward declarations."""
446  fwd = ForwardDeclaration.rule.parseString(
447  "virtual class Test:gtsam::Point3;")[0]
448 
449  fwd_name = fwd.name
450  self.assertEqual("Test", fwd_name.name)
451  self.assertTrue(fwd.is_virtual)
452 
453  def test_function(self):
454  """Test for global/free function."""
455  func = GlobalFunction.rule.parseString("""
456  gtsam::Values localToWorld(const gtsam::Values& local,
457  const gtsam::Pose2& base, const gtsam::KeyVector& keys);
458  """)[0]
459  self.assertEqual("localToWorld", func.name)
460  self.assertEqual("Values", func.return_type.type1.typename.name)
461  self.assertEqual(3, len(func.args))
462 
464  """Test for global variable."""
465  variable = Variable.rule.parseString("string kGravity;")[0]
466  self.assertEqual(variable.name, "kGravity")
467  self.assertEqual(variable.ctype.typename.name, "string")
468 
469  variable = Variable.rule.parseString("string kGravity = 9.81;")[0]
470  self.assertEqual(variable.name, "kGravity")
471  self.assertEqual(variable.ctype.typename.name, "string")
472  self.assertEqual(variable.default, 9.81)
473 
474  variable = Variable.rule.parseString(
475  "const string kGravity = 9.81;")[0]
476  self.assertEqual(variable.name, "kGravity")
477  self.assertEqual(variable.ctype.typename.name, "string")
478  self.assertTrue(variable.ctype.is_const)
479  self.assertEqual(variable.default, 9.81)
480 
481  def test_enumerator(self):
482  """Test for enumerator."""
483  enumerator = Enumerator.rule.parseString("Dog")[0]
484  self.assertEqual(enumerator.name, "Dog")
485 
486  enumerator = Enumerator.rule.parseString("Cat")[0]
487  self.assertEqual(enumerator.name, "Cat")
488 
489  def test_enum(self):
490  """Test for enums."""
491  enum = Enum.rule.parseString("""
492  enum Kind {
493  Dog,
494  Cat
495  };
496  """)[0]
497  self.assertEqual(enum.name, "Kind")
498  self.assertEqual(enum.enumerators[0].name, "Dog")
499  self.assertEqual(enum.enumerators[1].name, "Cat")
500 
501  def test_namespace(self):
502  """Test for namespace parsing."""
503  namespace = Namespace.rule.parseString("""
504  namespace gtsam {
505  #include <gtsam/geometry/Point2.h>
506  class Point2 {
507  Point2();
508  Point2(double x, double y);
509  double x() const;
510  double y() const;
511  int dim() const;
512  char returnChar() const;
513  void argChar(char a) const;
514  void argUChar(unsigned char a) const;
515  };
516 
517  #include <gtsam/geometry/Point3.h>
518  class Point3 {
519  Point3(double x, double y, double z);
520  double norm() const;
521 
522  // static functions - use static keyword and uppercase
523  static double staticFunction();
524  static gtsam::Point3 StaticFunctionRet(double z);
525 
526  // enabling serialization functionality
527  void serialize() const; // Just triggers a flag internally
528  };
529  }""")[0]
530  self.assertEqual("gtsam", namespace.name)
531 
532  def test_module(self):
533  """Test module parsing."""
534  module = Module.parseString("""
535  namespace one {
536  namespace two {
537  namespace three {
538  class Class123 {
539  };
540  }
541  class Class12a {
542  };
543  }
544  namespace two_dummy {
545  namespace three_dummy{
546 
547  }
548  namespace fourth_dummy{
549 
550  }
551  }
552  namespace two {
553  class Class12b {
554 
555  };
556  }
557  int oneVar;
558  }
559 
560  class Global{
561  };
562  int globalVar;
563  """)
564 
565  # print("module: ", module)
566  # print(dir(module.content[0].name))
567  self.assertEqual(["one", "Global", "globalVar"],
568  [x.name for x in module.content])
569  self.assertEqual(["two", "two_dummy", "two", "oneVar"],
570  [x.name for x in module.content[0].content])
571 
572 
573 if __name__ == '__main__':
574  unittest.main()
str repr(handle h)
Definition: pytypes.h:1536
size_t len(handle h)
Definition: pytypes.h:1514


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:46:03