test_matlab_wrapper.py
Go to the documentation of this file.
1 """
2 Unit tests for Matlab wrap program
3 Author: Matthew Sklar, Varun Agrawal
4 Date: March 2019
5 """
6 # pylint: disable=import-error, wrong-import-position
7 
8 import filecmp
9 import os
10 import os.path as osp
11 import sys
12 import unittest
13 
14 from loguru import logger
15 
16 sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
17 
18 import gtwrap.interface_parser as parser
19 import gtwrap.template_instantiator as instantiator
20 from gtwrap.matlab_wrapper import MatlabWrapper
21 
22 
23 class TestWrap(unittest.TestCase):
24  """
25  Test the Matlab wrapper
26  """
27  TEST_DIR = osp.dirname(osp.realpath(__file__))
28  INTERFACE_DIR = osp.join(TEST_DIR, "fixtures")
29  MATLAB_TEST_DIR = osp.join(TEST_DIR, "expected", "matlab")
30  MATLAB_ACTUAL_DIR = osp.join(TEST_DIR, "actual", "matlab")
31 
32  # Create the `actual/matlab` directory
33  os.makedirs(MATLAB_ACTUAL_DIR, exist_ok=True)
34 
35  # set the log level to INFO by default
36  logger.remove() # remove the default sink
37  logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
38 
39  def generate_content(self, cc_content, path=MATLAB_ACTUAL_DIR):
40  """Generate files and folders from matlab wrapper content.
41 
42  Keyword arguments:
43  cc_content -- the content to generate formatted as
44  (file_name, file_content) or
45  (folder_name, [(file_name, file_content)])
46  path -- the path to the files parent folder within the main folder
47  """
48  for c in cc_content:
49  if isinstance(c, list):
50  if len(c) == 0:
51  continue
52  logger.debug("c object: {}".format(c[0][0]))
53  path_to_folder = osp.join(path, c[0][0])
54 
55  if not osp.isdir(path_to_folder):
56  try:
57  os.makedirs(path_to_folder, exist_ok=True)
58  except OSError:
59  pass
60 
61  for sub_content in c:
62  logger.debug("sub object: {}".format(sub_content[1][0][0]))
63  self.generate_content(sub_content[1], path_to_folder)
64 
65  elif isinstance(c[1], list):
66  path_to_folder = osp.join(path, c[0])
67 
68  logger.debug(
69  "[generate_content_global]: {}".format(path_to_folder))
70  if not osp.isdir(path_to_folder):
71  try:
72  os.makedirs(path_to_folder, exist_ok=True)
73  except OSError:
74  pass
75  for sub_content in c[1]:
76  path_to_file = osp.join(path_to_folder, sub_content[0])
77  logger.debug(
78  "[generate_global_method]: {}".format(path_to_file))
79  with open(path_to_file, 'w') as f:
80  f.write(sub_content[1])
81 
82  else:
83  path_to_file = osp.join(path, c[0])
84 
85  logger.debug("[generate_content]: {}".format(path_to_file))
86  if not osp.isdir(path_to_file):
87  try:
88  os.mkdir(path)
89  except OSError:
90  pass
91 
92  with open(path_to_file, 'w') as f:
93  f.write(c[1])
94 
95  def compare_and_diff(self, file):
96  """
97  Compute the comparison between the expected and actual file,
98  and assert if diff is zero.
99  """
100  output = osp.join(self.MATLAB_ACTUAL_DIR, file)
101  expected = osp.join(self.MATLAB_TEST_DIR, file)
102  success = filecmp.cmp(output, expected)
103  if not success:
104  print("Differ in file: {}".format(file))
105  os.system("diff {} {}".format(output, expected))
106  self.assertTrue(success, "Mismatch for file {0}".format(file))
107 
108  def test_geometry(self):
109  """
110  Check generation of matlab geometry wrapper.
111  python3 wrap/matlab_wrapper.py --src wrap/tests/geometry.h
112  --module_name geometry --out wrap/tests/actual-matlab
113  """
114  with open(osp.join(self.INTERFACE_DIR, 'geometry.i'), 'r') as f:
115  content = f.read()
116 
117  if not osp.exists(self.MATLAB_ACTUAL_DIR):
118  os.mkdir(self.MATLAB_ACTUAL_DIR)
119 
120  module = parser.Module.parseString(content)
121 
122  instantiator.instantiate_namespace_inplace(module)
123 
124  # Create MATLAB wrapper instance
125  wrapper = MatlabWrapper(
126  module=module,
127  module_name='geometry',
128  top_module_namespace=['gtsam'],
129  ignore_classes=[''],
130  )
131 
132  cc_content = wrapper.wrap()
133 
134  self.generate_content(cc_content)
135 
136  self.assertTrue(osp.isdir(osp.join(self.MATLAB_ACTUAL_DIR, '+gtsam')))
137 
138  files = ['+gtsam/Point2.m', '+gtsam/Point3.m', 'geometry_wrapper.cpp']
139 
140  for file in files:
141  self.compare_and_diff(file)
142 
143  def test_functions(self):
144  """Test interface file with function info."""
145  with open(osp.join(self.INTERFACE_DIR, 'functions.i'), 'r') as f:
146  content = f.read()
147 
148  if not osp.exists(self.MATLAB_ACTUAL_DIR):
149  os.mkdir(self.MATLAB_ACTUAL_DIR)
150 
151  module = parser.Module.parseString(content)
152 
153  instantiator.instantiate_namespace_inplace(module)
154 
155  wrapper = MatlabWrapper(
156  module=module,
157  module_name='functions',
158  top_module_namespace=['gtsam'],
159  ignore_classes=[''],
160  )
161 
162  cc_content = wrapper.wrap()
163 
164  self.generate_content(cc_content)
165 
166  files = [
167  'functions_wrapper.cpp', 'aGlobalFunction.m', 'load2D.m',
168  'MultiTemplatedFunctionDoubleSize_tDouble.m',
169  'MultiTemplatedFunctionStringSize_tDouble.m',
170  'overloadedGlobalFunction.m', 'TemplatedFunctionRot3.m'
171  ]
172 
173  for file in files:
174  self.compare_and_diff(file)
175 
176  def test_class(self):
177  """Test interface file with only class info."""
178  with open(osp.join(self.INTERFACE_DIR, 'class.i'), 'r') as f:
179  content = f.read()
180 
181  if not osp.exists(self.MATLAB_ACTUAL_DIR):
182  os.mkdir(self.MATLAB_ACTUAL_DIR)
183 
184  module = parser.Module.parseString(content)
185 
186  instantiator.instantiate_namespace_inplace(module)
187 
188  wrapper = MatlabWrapper(
189  module=module,
190  module_name='class',
191  top_module_namespace=['gtsam'],
192  ignore_classes=[''],
193  )
194 
195  cc_content = wrapper.wrap()
196 
197  self.generate_content(cc_content)
198 
199  files = [
200  'class_wrapper.cpp', 'FunDouble.m', 'FunRange.m',
201  'MultipleTemplatesIntDouble.m', 'MultipleTemplatesIntFloat.m',
202  'MyFactorPosePoint2.m', 'MyVector3.m', 'MyVector12.m',
203  'PrimitiveRefDouble.m', 'Test.m'
204  ]
205 
206  for file in files:
207  self.compare_and_diff(file)
208 
209  def test_inheritance(self):
210  """Test interface file with class inheritance definitions."""
211  with open(osp.join(self.INTERFACE_DIR, 'inheritance.i'), 'r') as f:
212  content = f.read()
213 
214  if not osp.exists(self.MATLAB_ACTUAL_DIR):
215  os.mkdir(self.MATLAB_ACTUAL_DIR)
216 
217  module = parser.Module.parseString(content)
218 
219  instantiator.instantiate_namespace_inplace(module)
220 
221  wrapper = MatlabWrapper(
222  module=module,
223  module_name='inheritance',
224  top_module_namespace=['gtsam'],
225  ignore_classes=[''],
226  )
227 
228  cc_content = wrapper.wrap()
229 
230  self.generate_content(cc_content)
231 
232  files = [
233  'inheritance_wrapper.cpp', 'MyBase.m', 'MyTemplateMatrix.m',
234  'MyTemplatePoint2.m'
235  ]
236 
237  for file in files:
238  self.compare_and_diff(file)
239 
240  def test_namspaces(self):
241  """
242  Test interface file with full namespace definition.
243  """
244  with open(osp.join(self.INTERFACE_DIR, 'namespaces.i'), 'r') as f:
245  content = f.read()
246 
247  if not osp.exists(self.MATLAB_ACTUAL_DIR):
248  os.mkdir(self.MATLAB_ACTUAL_DIR)
249 
250  module = parser.Module.parseString(content)
251 
252  instantiator.instantiate_namespace_inplace(module)
253 
254  wrapper = MatlabWrapper(
255  module=module,
256  module_name='namespaces',
257  top_module_namespace=['gtsam'],
258  ignore_classes=[''],
259  )
260 
261  cc_content = wrapper.wrap()
262 
263  self.generate_content(cc_content)
264 
265  files = [
266  'namespaces_wrapper.cpp', '+ns1/aGlobalFunction.m',
267  '+ns1/ClassA.m', '+ns1/ClassB.m', '+ns2/+ns3/ClassB.m',
268  '+ns2/aGlobalFunction.m', '+ns2/ClassA.m', '+ns2/ClassC.m',
269  '+ns2/overloadedGlobalFunction.m', 'ClassD.m'
270  ]
271 
272  for file in files:
273  self.compare_and_diff(file)
274 
276  """
277  Tests for some unique, non-trivial features.
278  """
279  with open(osp.join(self.INTERFACE_DIR, 'special_cases.i'), 'r') as f:
280  content = f.read()
281 
282  if not osp.exists(self.MATLAB_ACTUAL_DIR):
283  os.mkdir(self.MATLAB_ACTUAL_DIR)
284 
285  module = parser.Module.parseString(content)
286 
287  instantiator.instantiate_namespace_inplace(module)
288 
289  wrapper = MatlabWrapper(
290  module=module,
291  module_name='special_cases',
292  top_module_namespace=['gtsam'],
293  ignore_classes=[''],
294  )
295 
296  cc_content = wrapper.wrap()
297 
298  self.generate_content(cc_content)
299 
300  files = [
301  'special_cases_wrapper.cpp',
302  '+gtsam/PinholeCameraCal3Bundler.m',
303  '+gtsam/NonlinearFactorGraph.m',
304  ]
305 
306  for file in files:
307  self.compare_and_diff(file)
308 
309 if __name__ == '__main__':
310  unittest.main()
void print(const Matrix &A, const string &s, ostream &stream)
Definition: Matrix.cpp:155
bool isinstance(handle obj)
Definition: pytypes.h:384
def generate_content(self, cc_content, path=MATLAB_ACTUAL_DIR)
size_t len(handle h)
Definition: pytypes.h:1514


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