Merge remote-tracking branch 'upstream/3.4' into merge-3.4
[platform/upstream/opencv.git] / modules / python / test / test_misc.py
1 #!/usr/bin/env python
2 from __future__ import print_function
3
4 import ctypes
5 from functools import partial
6 from collections import namedtuple
7
8 import numpy as np
9 import cv2 as cv
10
11 from tests_common import NewOpenCVTests, unittest
12
13
14 def is_numeric(dtype):
15     return np.issubdtype(dtype, np.integer) or np.issubdtype(dtype, np.floating)
16
17
18 def get_limits(dtype):
19     if not is_numeric(dtype):
20         return None, None
21
22     if np.issubdtype(dtype, np.integer):
23         info = np.iinfo(dtype)
24     else:
25         info = np.finfo(dtype)
26     return info.min, info.max
27
28
29 def get_conversion_error_msg(value, expected, actual):
30     return 'Conversion "{}" of type "{}" failed\nExpected: "{}" vs Actual "{}"'.format(
31         value, type(value).__name__, expected, actual
32     )
33
34
35 def get_no_exception_msg(value):
36     return 'Exception is not risen for {} of type {}'.format(value, type(value).__name__)
37
38 class Bindings(NewOpenCVTests):
39
40     def test_inheritance(self):
41         bm = cv.StereoBM_create()
42         bm.getPreFilterCap()  # from StereoBM
43         bm.getBlockSize()  # from SteroMatcher
44
45         boost = cv.ml.Boost_create()
46         boost.getBoostType()  # from ml::Boost
47         boost.getMaxDepth()  # from ml::DTrees
48         boost.isClassifier()  # from ml::StatModel
49
50     def test_redirectError(self):
51         try:
52             cv.imshow("", None)  # This causes an assert
53             self.assertEqual("Dead code", 0)
54         except cv.error as _e:
55             pass
56
57         handler_called = [False]
58
59         def test_error_handler(status, func_name, err_msg, file_name, line):
60             handler_called[0] = True
61
62         cv.redirectError(test_error_handler)
63         try:
64             cv.imshow("", None)  # This causes an assert
65             self.assertEqual("Dead code", 0)
66         except cv.error as _e:
67             self.assertEqual(handler_called[0], True)
68             pass
69
70         cv.redirectError(None)
71         try:
72             cv.imshow("", None)  # This causes an assert
73             self.assertEqual("Dead code", 0)
74         except cv.error as _e:
75             pass
76
77     def test_overload_resolution_can_choose_correct_overload(self):
78         val = 123
79         point = (51, 165)
80         self.assertEqual(cv.utils.testOverloadResolution(val, point),
81                          'overload (int={}, point=(x={}, y={}))'.format(val, *point),
82                          "Can't select first overload if all arguments are provided as positional")
83
84         self.assertEqual(cv.utils.testOverloadResolution(val, point=point),
85                          'overload (int={}, point=(x={}, y={}))'.format(val, *point),
86                          "Can't select first overload if one of the arguments are provided as keyword")
87
88         self.assertEqual(cv.utils.testOverloadResolution(val),
89                          'overload (int={}, point=(x=42, y=24))'.format(val),
90                          "Can't select first overload if one of the arguments has default value")
91
92         rect = (1, 5, 10, 23)
93         self.assertEqual(cv.utils.testOverloadResolution(rect),
94                          'overload (rect=(x={}, y={}, w={}, h={}))'.format(*rect),
95                          "Can't select second overload if all arguments are provided")
96
97     def test_overload_resolution_fails(self):
98         def test_overload_resolution(msg, *args, **kwargs):
99             no_exception_msg = 'Overload resolution failed without any exception for: "{}"'.format(msg)
100             wrong_exception_msg = 'Overload resolution failed with wrong exception type for: "{}"'.format(msg)
101             with self.assertRaises((cv.error, Exception), msg=no_exception_msg) as cm:
102                 res = cv.utils.testOverloadResolution(*args, **kwargs)
103                 self.fail("Unexpected result for {}: '{}'".format(msg, res))
104             self.assertEqual(type(cm.exception), cv.error, wrong_exception_msg)
105
106         test_overload_resolution('wrong second arg type (keyword arg)', 5, point=(1, 2, 3))
107         test_overload_resolution('wrong second arg type', 5, 2)
108         test_overload_resolution('wrong first arg', 3.4, (12, 21))
109         test_overload_resolution('wrong first arg, no second arg', 4.5)
110         test_overload_resolution('wrong args number for first overload', 3, (12, 21), 123)
111         test_overload_resolution('wrong args number for second overload', (3, 12, 12, 1), (12, 21))
112         # One of the common problems
113         test_overload_resolution('rect with float coordinates', (4.5, 4, 2, 1))
114         test_overload_resolution('rect with wrong number of coordinates', (4, 4, 1))
115
116
117 class Arguments(NewOpenCVTests):
118
119     def _try_to_convert(self, conversion, value):
120         try:
121             result = conversion(value).lower()
122         except Exception as e:
123             self.fail(
124                 '{} "{}" is risen for conversion {} of type {}'.format(
125                     type(e).__name__, e, value, type(value).__name__
126                 )
127             )
128         else:
129             return result
130
131     def test_InputArray(self):
132         res1 = cv.utils.dumpInputArray(None)
133         # self.assertEqual(res1, "InputArray: noArray()")  # not supported
134         self.assertEqual(res1, "InputArray: empty()=true kind=0x00010000 flags=0x01010000 total(-1)=0 dims(-1)=0 size(-1)=0x0 type(-1)=CV_8UC1")
135         res2_1 = cv.utils.dumpInputArray((1, 2))
136         self.assertEqual(res2_1, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=2 dims(-1)=2 size(-1)=1x2 type(-1)=CV_64FC1")
137         res2_2 = cv.utils.dumpInputArray(1.5)  # Scalar(1.5, 1.5, 1.5, 1.5)
138         self.assertEqual(res2_2, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=4 dims(-1)=2 size(-1)=1x4 type(-1)=CV_64FC1")
139         a = np.array([[1, 2], [3, 4], [5, 6]])
140         res3 = cv.utils.dumpInputArray(a)  # 32SC1
141         self.assertEqual(res3, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=6 dims(-1)=2 size(-1)=2x3 type(-1)=CV_32SC1")
142         a = np.array([[[1, 2], [3, 4], [5, 6]]], dtype='f')
143         res4 = cv.utils.dumpInputArray(a)  # 32FC2
144         self.assertEqual(res4, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=3 dims(-1)=2 size(-1)=3x1 type(-1)=CV_32FC2")
145         a = np.array([[[1, 2]], [[3, 4]], [[5, 6]]], dtype=float)
146         res5 = cv.utils.dumpInputArray(a)  # 64FC2
147         self.assertEqual(res5, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=3 dims(-1)=2 size(-1)=1x3 type(-1)=CV_64FC2")
148         a = np.zeros((2,3,4), dtype='f')
149         res6 = cv.utils.dumpInputArray(a)
150         self.assertEqual(res6, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=6 dims(-1)=2 size(-1)=3x2 type(-1)=CV_32FC4")
151         a = np.zeros((2,3,4,5), dtype='f')
152         res7 = cv.utils.dumpInputArray(a)
153         self.assertEqual(res7, "InputArray: empty()=false kind=0x00010000 flags=0x01010000 total(-1)=120 dims(-1)=4 size(-1)=[2 3 4 5] type(-1)=CV_32FC1")
154
155     def test_InputArrayOfArrays(self):
156         res1 = cv.utils.dumpInputArrayOfArrays(None)
157         # self.assertEqual(res1, "InputArray: noArray()")  # not supported
158         self.assertEqual(res1, "InputArrayOfArrays: empty()=true kind=0x00050000 flags=0x01050000 total(-1)=0 dims(-1)=1 size(-1)=0x0")
159         res2_1 = cv.utils.dumpInputArrayOfArrays((1, 2))  # { Scalar:all(1), Scalar::all(2) }
160         self.assertEqual(res2_1, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=2 dims(-1)=1 size(-1)=2x1 type(0)=CV_64FC1 dims(0)=2 size(0)=1x4")
161         res2_2 = cv.utils.dumpInputArrayOfArrays([1.5])
162         self.assertEqual(res2_2, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=1 dims(-1)=1 size(-1)=1x1 type(0)=CV_64FC1 dims(0)=2 size(0)=1x4")
163         a = np.array([[1, 2], [3, 4], [5, 6]])
164         b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
165         res3 = cv.utils.dumpInputArrayOfArrays([a, b])
166         self.assertEqual(res3, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=2 dims(-1)=1 size(-1)=2x1 type(0)=CV_32SC1 dims(0)=2 size(0)=2x3")
167         c = np.array([[[1, 2], [3, 4], [5, 6]]], dtype='f')
168         res4 = cv.utils.dumpInputArrayOfArrays([c, a, b])
169         self.assertEqual(res4, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=3 dims(-1)=1 size(-1)=3x1 type(0)=CV_32FC2 dims(0)=2 size(0)=3x1")
170         a = np.zeros((2,3,4), dtype='f')
171         res5 = cv.utils.dumpInputArrayOfArrays([a, b])
172         self.assertEqual(res5, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=2 dims(-1)=1 size(-1)=2x1 type(0)=CV_32FC4 dims(0)=2 size(0)=3x2")
173         # TODO: fix conversion error
174         #a = np.zeros((2,3,4,5), dtype='f')
175         #res6 = cv.utils.dumpInputArray([a, b])
176         #self.assertEqual(res6, "InputArrayOfArrays: empty()=false kind=0x00050000 flags=0x01050000 total(-1)=2 dims(-1)=1 size(-1)=2x1 type(0)=CV_32FC1 dims(0)=4 size(0)=[2 3 4 5]")
177
178     def test_parse_to_bool_convertible(self):
179         try_to_convert = partial(self._try_to_convert, cv.utils.dumpBool)
180         for convertible_true in (True, 1, 64, np.bool(1), np.int8(123), np.int16(11), np.int32(2),
181                                  np.int64(1), np.bool_(3), np.bool8(12)):
182             actual = try_to_convert(convertible_true)
183             self.assertEqual('bool: true', actual,
184                              msg=get_conversion_error_msg(convertible_true, 'bool: true', actual))
185
186         for convertible_false in (False, 0, np.uint8(0), np.bool_(0), np.int_(0)):
187             actual = try_to_convert(convertible_false)
188             self.assertEqual('bool: false', actual,
189                              msg=get_conversion_error_msg(convertible_false, 'bool: false', actual))
190
191     def test_parse_to_bool_not_convertible(self):
192         for not_convertible in (1.2, np.float(2.3), 's', 'str', (1, 2), [1, 2], complex(1, 1),
193                                 complex(imag=2), complex(1.1), np.array([1, 0], dtype=np.bool)):
194             with self.assertRaises((TypeError, OverflowError),
195                                    msg=get_no_exception_msg(not_convertible)):
196                 _ = cv.utils.dumpBool(not_convertible)
197
198     def test_parse_to_bool_convertible_extra(self):
199         try_to_convert = partial(self._try_to_convert, cv.utils.dumpBool)
200         _, max_size_t = get_limits(ctypes.c_size_t)
201         for convertible_true in (-1, max_size_t):
202             actual = try_to_convert(convertible_true)
203             self.assertEqual('bool: true', actual,
204                              msg=get_conversion_error_msg(convertible_true, 'bool: true', actual))
205
206     def test_parse_to_bool_not_convertible_extra(self):
207         for not_convertible in (np.array([False]), np.array([True], dtype=np.bool)):
208             with self.assertRaises((TypeError, OverflowError),
209                                    msg=get_no_exception_msg(not_convertible)):
210                 _ = cv.utils.dumpBool(not_convertible)
211
212     def test_parse_to_int_convertible(self):
213         try_to_convert = partial(self._try_to_convert, cv.utils.dumpInt)
214         min_int, max_int = get_limits(ctypes.c_int)
215         for convertible in (-10, -1, 2, int(43.2), np.uint8(15), np.int8(33), np.int16(-13),
216                             np.int32(4), np.int64(345), (23), min_int, max_int, np.int_(33)):
217             expected = 'int: {0:d}'.format(convertible)
218             actual = try_to_convert(convertible)
219             self.assertEqual(expected, actual,
220                              msg=get_conversion_error_msg(convertible, expected, actual))
221
222     def test_parse_to_int_not_convertible(self):
223         min_int, max_int = get_limits(ctypes.c_int)
224         for not_convertible in (1.2, np.float(4), float(3), np.double(45), 's', 'str',
225                                 np.array([1, 2]), (1,), [1, 2], min_int - 1, max_int + 1,
226                                 complex(1, 1), complex(imag=2), complex(1.1)):
227             with self.assertRaises((TypeError, OverflowError, ValueError),
228                                    msg=get_no_exception_msg(not_convertible)):
229                 _ = cv.utils.dumpInt(not_convertible)
230
231     def test_parse_to_int_not_convertible_extra(self):
232         for not_convertible in (np.bool_(True), True, False, np.float32(2.3),
233                                 np.array([3, ], dtype=int), np.array([-2, ], dtype=np.int32),
234                                 np.array([1, ], dtype=np.int), np.array([11, ], dtype=np.uint8)):
235             with self.assertRaises((TypeError, OverflowError),
236                                    msg=get_no_exception_msg(not_convertible)):
237                 _ = cv.utils.dumpInt(not_convertible)
238
239     def test_parse_to_size_t_convertible(self):
240         try_to_convert = partial(self._try_to_convert, cv.utils.dumpSizeT)
241         _, max_uint = get_limits(ctypes.c_uint)
242         for convertible in (2, max_uint, (12), np.uint8(34), np.int8(12), np.int16(23),
243                             np.int32(123), np.int64(344), np.uint64(3), np.uint16(2), np.uint32(5),
244                             np.uint(44)):
245             expected = 'size_t: {0:d}'.format(convertible).lower()
246             actual = try_to_convert(convertible)
247             self.assertEqual(expected, actual,
248                              msg=get_conversion_error_msg(convertible, expected, actual))
249
250     def test_parse_to_size_t_not_convertible(self):
251         min_long, _ = get_limits(ctypes.c_long)
252         for not_convertible in (1.2, True, False, np.bool_(True), np.float(4), float(3),
253                                 np.double(45), 's', 'str', np.array([1, 2]), (1,), [1, 2],
254                                 np.float64(6), complex(1, 1), complex(imag=2), complex(1.1),
255                                 -1, min_long, np.int8(-35)):
256             with self.assertRaises((TypeError, OverflowError),
257                                    msg=get_no_exception_msg(not_convertible)):
258                 _ = cv.utils.dumpSizeT(not_convertible)
259
260     def test_parse_to_size_t_convertible_extra(self):
261         try_to_convert = partial(self._try_to_convert, cv.utils.dumpSizeT)
262         _, max_size_t = get_limits(ctypes.c_size_t)
263         for convertible in (max_size_t,):
264             expected = 'size_t: {0:d}'.format(convertible).lower()
265             actual = try_to_convert(convertible)
266             self.assertEqual(expected, actual,
267                              msg=get_conversion_error_msg(convertible, expected, actual))
268
269     def test_parse_to_size_t_not_convertible_extra(self):
270         for not_convertible in (np.bool_(True), True, False, np.array([123, ], dtype=np.uint8),):
271             with self.assertRaises((TypeError, OverflowError),
272                                    msg=get_no_exception_msg(not_convertible)):
273                 _ = cv.utils.dumpSizeT(not_convertible)
274
275     def test_parse_to_float_convertible(self):
276         try_to_convert = partial(self._try_to_convert, cv.utils.dumpFloat)
277         min_float, max_float = get_limits(ctypes.c_float)
278         for convertible in (2, -13, 1.24, float(32), np.float(32.45), np.double(12.23),
279                             np.float32(-12.3), np.float64(3.22), np.float_(-1.5), min_float,
280                             max_float, np.inf, -np.inf, float('Inf'), -float('Inf'),
281                             np.double(np.inf), np.double(-np.inf), np.double(float('Inf')),
282                             np.double(-float('Inf'))):
283             expected = 'Float: {0:.2f}'.format(convertible).lower()
284             actual = try_to_convert(convertible)
285             self.assertEqual(expected, actual,
286                              msg=get_conversion_error_msg(convertible, expected, actual))
287
288         # Workaround for Windows NaN tests due to Visual C runtime
289         # special floating point values (indefinite NaN)
290         for nan in (float('NaN'), np.nan, np.float32(np.nan), np.double(np.nan),
291                     np.double(float('NaN'))):
292             actual = try_to_convert(nan)
293             self.assertIn('nan', actual, msg="Can't convert nan of type {} to float. "
294                           "Actual: {}".format(type(nan).__name__, actual))
295
296         min_double, max_double = get_limits(ctypes.c_double)
297         for inf in (min_float * 10, max_float * 10, min_double, max_double):
298             expected = 'float: {}inf'.format('-' if inf < 0 else '')
299             actual = try_to_convert(inf)
300             self.assertEqual(expected, actual,
301                              msg=get_conversion_error_msg(inf, expected, actual))
302
303     def test_parse_to_float_not_convertible(self):
304         for not_convertible in ('s', 'str', (12,), [1, 2], np.array([1, 2], dtype=np.float),
305                                 np.array([1, 2], dtype=np.double), complex(1, 1), complex(imag=2),
306                                 complex(1.1)):
307             with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
308                 _ = cv.utils.dumpFloat(not_convertible)
309
310     def test_parse_to_float_not_convertible_extra(self):
311         for not_convertible in (np.bool_(False), True, False, np.array([123, ], dtype=int),
312                                 np.array([1., ]), np.array([False]),
313                                 np.array([True], dtype=np.bool)):
314             with self.assertRaises((TypeError, OverflowError),
315                                    msg=get_no_exception_msg(not_convertible)):
316                 _ = cv.utils.dumpFloat(not_convertible)
317
318     def test_parse_to_double_convertible(self):
319         try_to_convert = partial(self._try_to_convert, cv.utils.dumpDouble)
320         min_float, max_float = get_limits(ctypes.c_float)
321         min_double, max_double = get_limits(ctypes.c_double)
322         for convertible in (2, -13, 1.24, np.float(32.45), float(2), np.double(12.23),
323                             np.float32(-12.3), np.float64(3.22), np.float_(-1.5), min_float,
324                             max_float, min_double, max_double, np.inf, -np.inf, float('Inf'),
325                             -float('Inf'), np.double(np.inf), np.double(-np.inf),
326                             np.double(float('Inf')), np.double(-float('Inf'))):
327             expected = 'Double: {0:.2f}'.format(convertible).lower()
328             actual = try_to_convert(convertible)
329             self.assertEqual(expected, actual,
330                              msg=get_conversion_error_msg(convertible, expected, actual))
331
332         # Workaround for Windows NaN tests due to Visual C runtime
333         # special floating point values (indefinite NaN)
334         for nan in (float('NaN'), np.nan, np.double(np.nan),
335                     np.double(float('NaN'))):
336             actual = try_to_convert(nan)
337             self.assertIn('nan', actual, msg="Can't convert nan of type {} to double. "
338                           "Actual: {}".format(type(nan).__name__, actual))
339
340     def test_parse_to_double_not_convertible(self):
341         for not_convertible in ('s', 'str', (12,), [1, 2], np.array([1, 2], dtype=np.float),
342                                 np.array([1, 2], dtype=np.double), complex(1, 1), complex(imag=2),
343                                 complex(1.1)):
344             with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
345                 _ = cv.utils.dumpDouble(not_convertible)
346
347     def test_parse_to_double_not_convertible_extra(self):
348         for not_convertible in (np.bool_(False), True, False, np.array([123, ], dtype=int),
349                                 np.array([1., ]), np.array([False]),
350                                 np.array([12.4], dtype=np.double), np.array([True], dtype=np.bool)):
351             with self.assertRaises((TypeError, OverflowError),
352                                    msg=get_no_exception_msg(not_convertible)):
353                 _ = cv.utils.dumpDouble(not_convertible)
354
355     def test_parse_to_cstring_convertible(self):
356         try_to_convert = partial(self._try_to_convert, cv.utils.dumpCString)
357         for convertible in ('', 's', 'str', str(123), ('char'), np.str('test1'), np.str_('test2')):
358             expected = 'string: ' + convertible
359             actual = try_to_convert(convertible)
360             self.assertEqual(expected, actual,
361                              msg=get_conversion_error_msg(convertible, expected, actual))
362
363     def test_parse_to_cstring_not_convertible(self):
364         for not_convertible in ((12,), ('t', 'e', 's', 't'), np.array(['123', ]),
365                                 np.array(['t', 'e', 's', 't']), 1, -1.4, True, False, None):
366             with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
367                 _ = cv.utils.dumpCString(not_convertible)
368
369     def test_parse_to_string_convertible(self):
370         try_to_convert = partial(self._try_to_convert, cv.utils.dumpString)
371         for convertible in (None, '', 's', 'str', str(123), np.str('test1'), np.str_('test2')):
372             expected = 'string: ' + (convertible if convertible else '')
373             actual = try_to_convert(convertible)
374             self.assertEqual(expected, actual,
375                              msg=get_conversion_error_msg(convertible, expected, actual))
376
377     def test_parse_to_string_not_convertible(self):
378         for not_convertible in ((12,), ('t', 'e', 's', 't'), np.array(['123', ]),
379                                 np.array(['t', 'e', 's', 't']), 1, True, False):
380             with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
381                 _ = cv.utils.dumpString(not_convertible)
382
383     def test_parse_to_rect_convertible(self):
384         Rect = namedtuple('Rect', ('x', 'y', 'w', 'h'))
385         try_to_convert = partial(self._try_to_convert, cv.utils.dumpRect)
386         for convertible in ((1, 2, 4, 5), [5, 3, 10, 20], np.array([10, 20, 23, 10]),
387                             Rect(10, 30, 40, 55), tuple(np.array([40, 20, 24, 20])),
388                             list(np.array([20, 40, 30, 35]))):
389             expected = 'rect: (x={}, y={}, w={}, h={})'.format(*convertible)
390             actual = try_to_convert(convertible)
391             self.assertEqual(expected, actual,
392                              msg=get_conversion_error_msg(convertible, expected, actual))
393
394     def test_parse_to_rect_not_convertible(self):
395         for not_convertible in (np.empty(shape=(4, 1)), (), [], np.array([]), (12, ),
396                                 [3, 4, 5, 10, 123], {1: 2, 3:4, 5:10, 6:30},
397                                 '1234', np.array([1, 2, 3, 4], dtype=np.float32),
398                                 np.array([[1, 2], [3, 4], [5, 6], [6, 8]]), (1, 2, 5, 1.5)):
399             with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
400                 _ = cv.utils.dumpRect(not_convertible)
401
402     def test_parse_to_rotated_rect_convertible(self):
403         RotatedRect = namedtuple('RotatedRect', ('center', 'size', 'angle'))
404         try_to_convert = partial(self._try_to_convert, cv.utils.dumpRotatedRect)
405         for convertible in (((2.5, 2.5), (10., 20.), 12.5), [[1.5, 10.5], (12.5, 51.5), 10],
406                             RotatedRect((10, 40), np.array([10.5, 20.5]), 5),
407                             np.array([[10, 6], [50, 50], 5.5], dtype=object)):
408             center, size, angle = convertible
409             expected = 'rotated_rect: (c_x={:.6f}, c_y={:.6f}, w={:.6f},' \
410                        ' h={:.6f}, a={:.6f})'.format(center[0], center[1],
411                                                      size[0], size[1], angle)
412             actual = try_to_convert(convertible)
413             self.assertEqual(expected, actual,
414                              msg=get_conversion_error_msg(convertible, expected, actual))
415
416     def test_parse_to_rotated_rect_not_convertible(self):
417         for not_convertible in ([], (), np.array([]), (123, (45, 34), 1), {1: 2, 3: 4}, 123,
418                                 np.array([[123, 123, 14], [1, 3], 56], dtype=object), '123'):
419             with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
420                 _ = cv.utils.dumpRotatedRect(not_convertible)
421
422     def test_parse_to_term_criteria_convertible(self):
423         TermCriteria = namedtuple('TermCriteria', ('type', 'max_count', 'epsilon'))
424         try_to_convert = partial(self._try_to_convert, cv.utils.dumpTermCriteria)
425         for convertible in ((1, 10, 1e-3), [2, 30, 1e-1], np.array([10, 20, 0.5], dtype=object),
426                             TermCriteria(0, 5, 0.1)):
427             expected = 'term_criteria: (type={}, max_count={}, epsilon={:.6f}'.format(*convertible)
428             actual = try_to_convert(convertible)
429             self.assertEqual(expected, actual,
430                              msg=get_conversion_error_msg(convertible, expected, actual))
431
432     def test_parse_to_term_criteria_not_convertible(self):
433         for not_convertible in ([], (), np.array([]), [1, 4], (10,), (1.5, 34, 0.1),
434                                 {1: 5, 3: 5, 10: 10}, '145'):
435             with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
436                 _ = cv.utils.dumpTermCriteria(not_convertible)
437
438     def test_parse_to_range_convertible_to_all(self):
439         try_to_convert = partial(self._try_to_convert, cv.utils.dumpRange)
440         for convertible in ((), [], np.array([])):
441             expected = 'range: all'
442             actual = try_to_convert(convertible)
443             self.assertEqual(expected, actual,
444                              msg=get_conversion_error_msg(convertible, expected, actual))
445
446     def test_parse_to_range_convertible(self):
447         Range = namedtuple('Range', ('start', 'end'))
448         try_to_convert = partial(self._try_to_convert, cv.utils.dumpRange)
449         for convertible in ((10, 20), [-1, 3], np.array([10, 24]), Range(-4, 6)):
450             expected = 'range: (s={}, e={})'.format(*convertible)
451             actual = try_to_convert(convertible)
452             self.assertEqual(expected, actual,
453                              msg=get_conversion_error_msg(convertible, expected, actual))
454
455     def test_parse_to_range_not_convertible(self):
456         for not_convertible in ((1, ), [40, ], np.array([1, 4, 6]), {'a': 1, 'b': 40},
457                                 (1.5, 13.5), [3, 6.7], np.array([6.3, 2.1]), '14, 4'):
458             with self.assertRaises((TypeError), msg=get_no_exception_msg(not_convertible)):
459                 _ = cv.utils.dumpRange(not_convertible)
460
461
462 class SamplesFindFile(NewOpenCVTests):
463
464     def test_ExistedFile(self):
465         res = cv.samples.findFile('lena.jpg', False)
466         self.assertNotEqual(res, '')
467
468     def test_MissingFile(self):
469         res = cv.samples.findFile('non_existed.file', False)
470         self.assertEqual(res, '')
471
472     def test_MissingFileException(self):
473         try:
474             _res = cv.samples.findFile('non_existed.file', True)
475             self.assertEqual("Dead code", 0)
476         except cv.error as _e:
477             pass
478
479
480 if __name__ == '__main__':
481     NewOpenCVTests.bootstrap()