test_pybind_wrapper.py
Go to the documentation of this file.
1 """
2 Unit test for Pybind wrap program
3 Author: Matthew Sklar, Varun Agrawal
4 Date: February 2019
5 """
6 
7 # pylint: disable=import-error, wrong-import-position, too-many-branches
8 
9 import filecmp
10 import os
11 import os.path as osp
12 import sys
13 import unittest
14 
15 sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
16 sys.path.append(
17  osp.normpath(osp.abspath(osp.join(__file__, '../../../build/wrap'))))
18 
19 from gtwrap.pybind_wrapper import PybindWrapper
20 
21 sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
22 
23 
24 class TestWrap(unittest.TestCase):
25  """Tests for Python wrapper based on Pybind11."""
26  TEST_DIR = osp.dirname(osp.realpath(__file__))
27  INTERFACE_DIR = osp.join(TEST_DIR, 'fixtures')
28  PYTHON_TEST_DIR = osp.join(TEST_DIR, 'expected', 'python')
29  PYTHON_ACTUAL_DIR = osp.join(TEST_DIR, "actual", "python")
30 
31  # Create the `actual/python` directory
32  os.makedirs(PYTHON_ACTUAL_DIR, exist_ok=True)
33 
34  def wrap_content(self,
35  sources,
36  module_name,
37  output_dir,
38  use_boost_serialization=False):
39  """
40  Common function to wrap content in `sources`.
41  """
42  with open(osp.join(self.TEST_DIR, "pybind_wrapper.tpl"),
43  encoding="UTF-8") as template_file:
44  module_template = template_file.read()
45 
46  # Create Pybind wrapper instance
47  wrapper = PybindWrapper(
48  module_name=module_name,
49  top_module_namespaces=[''],
50  ignore_classes=[''],
51  module_template=module_template,
52  use_boost_serialization=use_boost_serialization)
53 
54  output = osp.join(self.TEST_DIR, output_dir, module_name + ".cpp")
55 
56  if not osp.exists(osp.join(self.TEST_DIR, output_dir)):
57  os.mkdir(osp.join(self.TEST_DIR, output_dir))
58 
59  wrapper.wrap(sources, output)
60 
61  return output
62 
63  def compare_and_diff(self, file, actual):
64  """
65  Compute the comparison between the expected and actual file,
66  and assert if diff is zero.
67  """
68  expected = osp.join(self.PYTHON_TEST_DIR, file)
69  success = filecmp.cmp(actual, expected)
70 
71  if not success:
72  os.system(f"diff {actual} {expected}")
73  self.assertTrue(success, f"Mismatch for file {file}")
74 
75  def test_geometry(self):
76  """
77  Check generation of python geometry wrapper.
78  python3 ../pybind_wrapper.py --src geometry.h --module_name
79  geometry_py --out output/geometry_py.cc
80  """
81  source = osp.join(self.INTERFACE_DIR, 'geometry.i')
82  output = self.wrap_content([source],
83  'geometry_py',
84  self.PYTHON_ACTUAL_DIR,
85  use_boost_serialization=True)
86 
87  self.compare_and_diff('geometry_pybind.cpp', output)
88 
89  def test_functions(self):
90  """Test interface file with function info."""
91  source = osp.join(self.INTERFACE_DIR, 'functions.i')
92  output = self.wrap_content([source], 'functions_py',
93  self.PYTHON_ACTUAL_DIR)
94 
95  self.compare_and_diff('functions_pybind.cpp', output)
96 
97  def test_class(self):
98  """Test interface file with only class info."""
99  source = osp.join(self.INTERFACE_DIR, 'class.i')
100  output = self.wrap_content([source], 'class_py',
101  self.PYTHON_ACTUAL_DIR)
102 
103  self.compare_and_diff('class_pybind.cpp', output)
104 
105  def test_templates(self):
106  """Test interface file with templated class."""
107  source = osp.join(self.INTERFACE_DIR, 'templates.i')
108  output = self.wrap_content([source], 'templates_py',
109  self.PYTHON_ACTUAL_DIR)
110 
111  self.compare_and_diff('templates_pybind.cpp', output)
112 
113  def test_inheritance(self):
114  """Test interface file with class inheritance definitions."""
115  source = osp.join(self.INTERFACE_DIR, 'inheritance.i')
116  output = self.wrap_content([source], 'inheritance_py',
117  self.PYTHON_ACTUAL_DIR)
118 
119  self.compare_and_diff('inheritance_pybind.cpp', output)
120 
121  def test_namespaces(self):
122  """
123  Check generation of python wrapper for full namespace definition.
124  python3 ../pybind_wrapper.py --src namespaces.i --module_name
125  namespaces_py --out output/namespaces_py.cpp
126  """
127  source = osp.join(self.INTERFACE_DIR, 'namespaces.i')
128  output = self.wrap_content([source], 'namespaces_py',
129  self.PYTHON_ACTUAL_DIR)
130 
131  self.compare_and_diff('namespaces_pybind.cpp', output)
132 
134  """
135  Tests for operator overloading.
136  """
137  source = osp.join(self.INTERFACE_DIR, 'operator.i')
138  output = self.wrap_content([source], 'operator_py',
139  self.PYTHON_ACTUAL_DIR)
140 
141  self.compare_and_diff('operator_pybind.cpp', output)
142 
144  """
145  Tests for some unique, non-trivial features.
146  """
147  source = osp.join(self.INTERFACE_DIR, 'special_cases.i')
148  output = self.wrap_content([source], 'special_cases_py',
149  self.PYTHON_ACTUAL_DIR)
150 
151  self.compare_and_diff('special_cases_pybind.cpp', output)
152 
153  def test_enum(self):
154  """
155  Test if enum generation is correct.
156  """
157  source = osp.join(self.INTERFACE_DIR, 'enum.i')
158  output = self.wrap_content([source], 'enum_py', self.PYTHON_ACTUAL_DIR)
159 
160  self.compare_and_diff('enum_pybind.cpp', output)
161 
162 
163 if __name__ == '__main__':
164  unittest.main()
def wrap_content(self, sources, module_name, output_dir, use_boost_serialization=False)
def compare_and_diff(self, file, actual)


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:37:46