Skip to content

Commit 63ccfab

Browse files
committed
unittest: add test for std::optional if available
+ unittest: make bind_optional and test_optional.py into template files + cmake: instantiate boost and std optional tests using configure_file
1 parent 0afe3c9 commit 63ccfab

File tree

5 files changed

+174
-20
lines changed

5 files changed

+174
-20
lines changed

unittest/CMakeLists.txt

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,24 @@ if(NOT NUMPY_WITH_BROKEN_UFUNC_SUPPORT)
3939
endif()
4040
add_lib_unit_test(std_vector)
4141
add_lib_unit_test(user_struct)
42-
add_lib_unit_test(bind_optional)
42+
43+
function(config_bind_optional tagname opttype)
44+
set(MODNAME bind_optional_${tagname})
45+
set(OPTIONAL ${opttype})
46+
configure_file(bind_optional.cpp.in ${MODNAME}.cpp)
47+
48+
set(py_file test_optional_${tagname}.py)
49+
configure_file(python/test_optional.py.in ${CMAKE_CURRENT_SOURCE_DIR}/python/${py_file})
50+
add_lib_unit_test(${MODNAME})
51+
message(STATUS "Adding unit test py-optional-${tagname} with file ${py_file} and module ${MODNAME}")
52+
add_python_unit_test("py-optional-${tagname}" "unittest/python/${py_file}"
53+
"unittest")
54+
endfunction()
55+
56+
config_bind_optional(boost "boost::optional")
57+
if(CMAKE_CXX_STANDARD GREATER 14 AND CMAKE_CXX_STANDARD LESS 98)
58+
config_bind_optional(std "std::optional")
59+
endif()
4360

4461
add_python_unit_test("py-matrix" "unittest/python/test_matrix.py" "unittest")
4562

@@ -98,6 +115,3 @@ set_tests_properties("py-std-vector" PROPERTIES DEPENDS ${PYWRAP})
98115
add_python_unit_test("py-user-struct" "unittest/python/test_user_struct.py"
99116
"python;unittest")
100117
set_tests_properties("py-std-vector" PROPERTIES DEPENDS ${PYWRAP})
101-
102-
add_python_unit_test("py-optional" "unittest/python/test_optional.py"
103-
"unittest")

unittest/bind_optional.cpp renamed to unittest/bind_optional.cpp.in

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
#include "eigenpy/eigenpy.hpp"
22
#include "eigenpy/optional.hpp"
3+
#ifdef EIGENPY_WITH_CXX17_SUPPORT
4+
#include <optional>
5+
#endif
36

4-
#define OPTIONAL boost::optional
5-
#define OPT_NONE boost::none
7+
#cmakedefine OPTIONAL @OPTIONAL@
68

7-
using opt_dbl = OPTIONAL<double>;
9+
typedef eigenpy::detail::nullopt_helper<OPTIONAL> none_helper;
10+
static auto OPT_NONE = none_helper::value();
11+
typedef OPTIONAL<double> opt_dbl;
812

913
struct mystruct {
1014
OPTIONAL<int> a;
1115
opt_dbl b;
1216
OPTIONAL<std::string> msg{"i am struct"};
13-
mystruct() : a(OPT_NONE), b(boost::none) {}
17+
mystruct() : a(OPT_NONE), b(OPT_NONE) {}
1418
mystruct(int a, const opt_dbl &b = OPT_NONE) : a(a), b(b) {}
1519
};
1620

@@ -36,13 +40,13 @@ OPTIONAL<Eigen::MatrixXd> random_mat_if_true(bool flag) {
3640
return OPT_NONE;
3741
}
3842

39-
BOOST_PYTHON_MODULE(bind_optional) {
43+
BOOST_PYTHON_MODULE(@MODNAME@) {
4044
using namespace eigenpy;
41-
OptionalConverter<int>::registration();
42-
OptionalConverter<double>::registration();
43-
OptionalConverter<std::string>::registration();
44-
OptionalConverter<mystruct>::registration();
45-
OptionalConverter<Eigen::MatrixXd>::registration();
45+
OptionalConverter<int, OPTIONAL>::registration();
46+
OptionalConverter<double, OPTIONAL>::registration();
47+
OptionalConverter<std::string, OPTIONAL>::registration();
48+
OptionalConverter<mystruct, OPTIONAL>::registration();
49+
OptionalConverter<Eigen::MatrixXd, OPTIONAL>::registration();
4650
enableEigenPy();
4751

4852
bp::class_<mystruct>("mystruct", bp::no_init)

unittest/python/test_optional.py renamed to unittest/python/test_optional.py.in

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import bind_optional
1+
import importlib
2+
3+
bind_optional = importlib.import_module("@MODNAME@")
24

35

46
def test_none_if_zero():
@@ -58,8 +60,8 @@ def test_random_mat():
5860
assert M.shape == (4, 4)
5961

6062

61-
if __name__ == "__main__":
62-
import pytest
63-
import sys
64-
65-
sys.exit(pytest.main(sys.argv))
63+
test_none_if_zero()
64+
test_struct_ctors()
65+
test_struct_setters()
66+
test_factory()
67+
test_random_mat()
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import importlib
2+
3+
bind_optional = importlib.import_module("bind_optional_boost")
4+
5+
6+
def test_none_if_zero():
7+
x = bind_optional.none_if_zero(0)
8+
y = bind_optional.none_if_zero(-1)
9+
assert x is None
10+
assert y == -1
11+
12+
13+
def test_struct_ctors():
14+
# test struct ctors
15+
16+
struct = bind_optional.mystruct()
17+
assert struct.a is None
18+
assert struct.b is None
19+
assert struct.msg == "i am struct"
20+
21+
## no 2nd arg automatic overload using bp::optional
22+
struct = bind_optional.mystruct(2)
23+
assert struct.a == 2
24+
assert struct.b is None
25+
26+
struct = bind_optional.mystruct(13, -1.0)
27+
assert struct.a == 13
28+
assert struct.b == -1.0
29+
30+
31+
def test_struct_setters():
32+
struct = bind_optional.mystruct()
33+
struct.a = 1
34+
assert struct.a == 1
35+
36+
struct.b = -3.14
37+
assert struct.b == -3.14
38+
39+
# set to None
40+
struct.a = None
41+
struct.b = None
42+
struct.msg = None
43+
assert struct.a is None
44+
assert struct.b is None
45+
assert struct.msg is None
46+
47+
48+
def test_factory():
49+
struct = bind_optional.create_if_true(False, None)
50+
assert struct is None
51+
struct = bind_optional.create_if_true(True, None)
52+
assert struct.a == 0
53+
assert struct.b is None
54+
55+
56+
def test_random_mat():
57+
M = bind_optional.random_mat_if_true(False)
58+
assert M is None
59+
M = bind_optional.random_mat_if_true(True)
60+
assert M.shape == (4, 4)
61+
62+
63+
test_none_if_zero()
64+
test_struct_ctors()
65+
test_struct_setters()
66+
test_factory()
67+
test_random_mat()
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import importlib
2+
3+
bind_optional = importlib.import_module("bind_optional_std")
4+
5+
6+
def test_none_if_zero():
7+
x = bind_optional.none_if_zero(0)
8+
y = bind_optional.none_if_zero(-1)
9+
assert x is None
10+
assert y == -1
11+
12+
13+
def test_struct_ctors():
14+
# test struct ctors
15+
16+
struct = bind_optional.mystruct()
17+
assert struct.a is None
18+
assert struct.b is None
19+
assert struct.msg == "i am struct"
20+
21+
## no 2nd arg automatic overload using bp::optional
22+
struct = bind_optional.mystruct(2)
23+
assert struct.a == 2
24+
assert struct.b is None
25+
26+
struct = bind_optional.mystruct(13, -1.0)
27+
assert struct.a == 13
28+
assert struct.b == -1.0
29+
30+
31+
def test_struct_setters():
32+
struct = bind_optional.mystruct()
33+
struct.a = 1
34+
assert struct.a == 1
35+
36+
struct.b = -3.14
37+
assert struct.b == -3.14
38+
39+
# set to None
40+
struct.a = None
41+
struct.b = None
42+
struct.msg = None
43+
assert struct.a is None
44+
assert struct.b is None
45+
assert struct.msg is None
46+
47+
48+
def test_factory():
49+
struct = bind_optional.create_if_true(False, None)
50+
assert struct is None
51+
struct = bind_optional.create_if_true(True, None)
52+
assert struct.a == 0
53+
assert struct.b is None
54+
55+
56+
def test_random_mat():
57+
M = bind_optional.random_mat_if_true(False)
58+
assert M is None
59+
M = bind_optional.random_mat_if_true(True)
60+
assert M.shape == (4, 4)
61+
62+
63+
test_none_if_zero()
64+
test_struct_ctors()
65+
test_struct_setters()
66+
test_factory()
67+
test_random_mat()

0 commit comments

Comments
 (0)