Skip to content

Commit 13413bb

Browse files
committed
pytestify xferfcn_input_test.py
remove a lot of duplicate code by converting everything into a single parametrized test function.
1 parent f680cf9 commit 13413bb

1 file changed

Lines changed: 74 additions & 254 deletions

File tree

control/tests/xferfcn_input_test.py

100644100755
Lines changed: 74 additions & 254 deletions
Original file line numberDiff line numberDiff line change
@@ -1,259 +1,79 @@
1-
#!/usr/bin/env python
2-
#
3-
# xferfcn_input_test.py - test inputs to TransferFunction class
4-
# jed-frey, 18 Feb 2017 (based on xferfcn_test.py)
1+
"""xferfcn_input_test.py - test inputs to TransferFunction class
52
6-
import unittest
7-
import numpy as np
3+
jed-frey, 18 Feb 2017 (based on xferfcn_test.py)
4+
BG, 31 Jul 2020 convert to pytest and parametrize into single function
5+
"""
86

9-
from numpy import int, int8, int16, int32, int64
10-
from numpy import float, float16, float32, float64, longdouble
11-
from numpy import all, ndarray, array
7+
import numpy as np
8+
import pytest
129

1310
from control.xferfcn import _clean_part
1411

15-
16-
class TestXferFcnInput(unittest.TestCase):
17-
"""These are tests for functionality of cleaning and validating XferFcnInput."""
18-
19-
# Tests for raising exceptions.
20-
def test_clean_part_bad_input_type(self):
21-
"""Give the part cleaner invalid input type."""
22-
23-
self.assertRaises(TypeError, _clean_part, [[0., 1.], [2., 3.]])
24-
25-
def test_clean_part_bad_input_type2(self):
26-
"""Give the part cleaner another invalid input type."""
27-
self.assertRaises(TypeError, _clean_part, [1, "a"])
28-
29-
def test_clean_part_scalar(self):
30-
"""Test single scalar value."""
31-
num = 1
32-
num_ = _clean_part(num)
33-
34-
assert isinstance(num_, list)
35-
assert np.all([isinstance(part, list) for part in num_])
36-
np.testing.assert_array_equal(num_[0][0], array([1.0], dtype=float))
37-
38-
def test_clean_part_list_scalar(self):
39-
"""Test single scalar value in list."""
40-
num = [1]
41-
num_ = _clean_part(num)
42-
43-
assert isinstance(num_, list)
44-
assert np.all([isinstance(part, list) for part in num_])
45-
np.testing.assert_array_equal(num_[0][0], array([1.0], dtype=float))
46-
47-
def test_clean_part_tuple_scalar(self):
48-
"""Test single scalar value in tuple."""
49-
num = (1)
50-
num_ = _clean_part(num)
51-
52-
assert isinstance(num_, list)
53-
assert np.all([isinstance(part, list) for part in num_])
54-
np.testing.assert_array_equal(num_[0][0], array([1.0], dtype=float))
55-
56-
def test_clean_part_list(self):
57-
"""Test multiple values in a list."""
58-
num = [1, 2]
59-
num_ = _clean_part(num)
60-
61-
assert isinstance(num_, list)
62-
assert np.all([isinstance(part, list) for part in num_])
63-
np.testing.assert_array_equal(num_[0][0], array([1.0, 2.0], dtype=float))
64-
65-
def test_clean_part_tuple(self):
66-
"""Test multiple values in tuple."""
67-
num = (1, 2)
68-
num_ = _clean_part(num)
69-
70-
assert isinstance(num_, list)
71-
assert np.all([isinstance(part, list) for part in num_])
72-
np.testing.assert_array_equal(num_[0][0], array([1.0, 2.0], dtype=float))
73-
74-
def test_clean_part_all_scalar_types(self):
75-
"""Test single scalar value for all valid data types."""
76-
for dtype in [int, int8, int16, int32, int64, float, float16, float32, float64, longdouble]:
77-
num = dtype(1)
78-
num_ = _clean_part(num)
79-
80-
assert isinstance(num_, list)
81-
assert np.all([isinstance(part, list) for part in num_])
82-
np.testing.assert_array_equal(num_[0][0], array([1.0], dtype=float))
83-
84-
def test_clean_part_np_array(self):
85-
"""Test multiple values in numpy array."""
86-
num = np.array([1, 2])
87-
num_ = _clean_part(num)
88-
89-
assert isinstance(num_, list)
90-
assert np.all([isinstance(part, list) for part in num_])
91-
np.testing.assert_array_equal(num_[0][0], array([1.0, 2.0], dtype=float))
92-
93-
def test_clean_part_all_np_array_types(self):
94-
"""Test scalar value in numpy array of ndim=0 for all data types."""
95-
for dtype in [int, int8, int16, int32, int64, float, float16, float32, float64, longdouble]:
96-
num = np.array(1, dtype=dtype)
97-
num_ = _clean_part(num)
98-
99-
assert isinstance(num_, list)
100-
assert np.all([isinstance(part, list) for part in num_])
101-
np.testing.assert_array_equal(num_[0][0], array([1.0], dtype=float))
102-
103-
def test_clean_part_all_np_array_types2(self):
104-
"""Test numpy array for all types."""
105-
for dtype in [int, int8, int16, int32, int64, float, float16, float32, float64, longdouble]:
106-
num = np.array([1, 2], dtype=dtype)
107-
num_ = _clean_part(num)
108-
109-
assert isinstance(num_, list)
110-
assert np.all([isinstance(part, list) for part in num_])
111-
np.testing.assert_array_equal(num_[0][0], array([1.0, 2.0], dtype=float))
112-
113-
def test_clean_part_list_all_types(self):
114-
"""Test list of a single value for all data types."""
115-
for dtype in [int, int8, int16, int32, int64, float, float16, float32, float64, longdouble]:
116-
num = [dtype(1)]
117-
num_ = _clean_part(num)
118-
assert isinstance(num_, list)
119-
assert np.all([isinstance(part, list) for part in num_])
120-
np.testing.assert_array_equal(num_[0][0], array([1.0], dtype=float))
121-
122-
def test_clean_part_list_all_types2(self):
123-
"""List of list of numbers of all data types."""
124-
for dtype in [int, int8, int16, int32, int64, float, float16, float32, float64, longdouble]:
125-
num = [dtype(1), dtype(2)]
126-
num_ = _clean_part(num)
127-
assert isinstance(num_, list)
128-
assert np.all([isinstance(part, list) for part in num_])
129-
np.testing.assert_array_equal(num_[0][0], array([1.0, 2.0], dtype=float))
130-
131-
def test_clean_part_tuple_all_types(self):
132-
"""Test tuple of a single value for all data types."""
133-
for dtype in [int, int8, int16, int32, int64, float, float16, float32, float64, longdouble]:
134-
num = (dtype(1),)
135-
num_ = _clean_part(num)
136-
assert isinstance(num_, list)
137-
assert np.all([isinstance(part, list) for part in num_])
138-
np.testing.assert_array_equal(num_[0][0], array([1.0], dtype=float))
139-
140-
def test_clean_part_tuple_all_types2(self):
141-
"""Test tuple of a single value for all data types."""
142-
for dtype in [int, int8, int16, int32, int64, float, float16, float32, float64, longdouble]:
143-
num = (dtype(1), dtype(2))
144-
num_ = _clean_part(num)
145-
assert isinstance(num_, list)
146-
assert np.all([isinstance(part, list) for part in num_])
147-
np.testing.assert_array_equal(num_[0][0], array([1, 2], dtype=float))
148-
149-
def test_clean_part_list_list_list_int(self):
150-
""" Test an int in a list of a list of a list."""
151-
num = [[[1]]]
152-
num_ = _clean_part(num)
153-
assert isinstance(num_, list)
154-
assert np.all([isinstance(part, list) for part in num_])
155-
np.testing.assert_array_equal(num_[0][0], array([1.0], dtype=float))
156-
157-
def test_clean_part_list_list_list_float(self):
158-
""" Test a float in a list of a list of a list."""
159-
num = [[[1.0]]]
160-
num_ = _clean_part(num)
161-
assert isinstance(num_, list)
162-
assert np.all([isinstance(part, list) for part in num_])
163-
np.testing.assert_array_equal(num_[0][0], array([1.0], dtype=float))
164-
165-
def test_clean_part_list_list_list_ints(self):
166-
"""Test 2 lists of ints in a list in a list."""
167-
num = [[[1, 1], [2, 2]]]
168-
num_ = _clean_part(num)
169-
170-
assert isinstance(num_, list)
171-
assert np.all([isinstance(part, list) for part in num_])
172-
np.testing.assert_array_equal(num_[0][0], array([1.0, 1.0], dtype=float))
173-
np.testing.assert_array_equal(num_[0][1], array([2.0, 2.0], dtype=float))
174-
175-
def test_clean_part_list_list_list_floats(self):
176-
"""Test 2 lists of ints in a list in a list."""
177-
num = [[[1.0, 1.0], [2.0, 2.0]]]
178-
num_ = _clean_part(num)
179-
180-
assert isinstance(num_, list)
181-
assert np.all([isinstance(part, list) for part in num_])
182-
np.testing.assert_array_equal(num_[0][0], array([1.0, 1.0], dtype=float))
183-
np.testing.assert_array_equal(num_[0][1], array([2.0, 2.0], dtype=float))
184-
185-
def test_clean_part_list_list_array(self):
186-
"""List of list of numpy arrays for all valid types."""
187-
for dtype in int, int8, int16, int32, int64, float, float16, float32, float64, longdouble:
188-
num = [[array([1, 1], dtype=dtype), array([2, 2], dtype=dtype)]]
189-
num_ = _clean_part(num)
190-
191-
assert isinstance(num_, list)
192-
assert np.all([isinstance(part, list) for part in num_])
193-
np.testing.assert_array_equal(num_[0][0], array([1.0, 1.0], dtype=float))
194-
np.testing.assert_array_equal(num_[0][1], array([2.0, 2.0], dtype=float))
195-
196-
def test_clean_part_tuple_list_array(self):
197-
"""Tuple of list of numpy arrays for all valid types."""
198-
for dtype in int, int8, int16, int32, int64, float, float16, float32, float64, longdouble:
199-
num = ([array([1, 1], dtype=dtype), array([2, 2], dtype=dtype)],)
200-
num_ = _clean_part(num)
201-
202-
assert isinstance(num_, list)
203-
assert np.all([isinstance(part, list) for part in num_])
204-
np.testing.assert_array_equal(num_[0][0], array([1.0, 1.0], dtype=float))
205-
np.testing.assert_array_equal(num_[0][1], array([2.0, 2.0], dtype=float))
206-
207-
def test_clean_part_list_tuple_array(self):
208-
"""List of tuple of numpy array for all valid types."""
209-
for dtype in int, int8, int16, int32, int64, float, float16, float32, float64, longdouble:
210-
num = [(array([1, 1], dtype=dtype), array([2, 2], dtype=dtype))]
211-
num_ = _clean_part(num)
212-
213-
assert isinstance(num_, list)
214-
assert np.all([isinstance(part, list) for part in num_])
215-
np.testing.assert_array_equal(num_[0][0], array([1.0, 1.0], dtype=float))
216-
np.testing.assert_array_equal(num_[0][1], array([2.0, 2.0], dtype=float))
217-
218-
def test_clean_part_tuple_tuples_arrays(self):
219-
"""Tuple of tuples of numpy arrays for all valid types."""
220-
for dtype in int, int8, int16, int32, int64, float, float16, float32, float64, longdouble:
221-
num = ((array([1, 1], dtype=dtype), array([2, 2], dtype=dtype)),
222-
(array([3, 4], dtype=dtype), array([4, 4], dtype=dtype)))
223-
num_ = _clean_part(num)
224-
225-
assert isinstance(num_, list)
226-
assert np.all([isinstance(part, list) for part in num_])
227-
np.testing.assert_array_equal(num_[0][0], array([1.0, 1.0], dtype=float))
228-
np.testing.assert_array_equal(num_[0][1], array([2.0, 2.0], dtype=float))
229-
230-
def test_clean_part_list_tuples_arrays(self):
231-
"""List of tuples of numpy arrays for all valid types."""
232-
for dtype in int, int8, int16, int32, int64, float, float16, float32, float64, longdouble:
233-
num = [(array([1, 1], dtype=dtype), array([2, 2], dtype=dtype)),
234-
(array([3, 4], dtype=dtype), array([4, 4], dtype=dtype))]
235-
num_ = _clean_part(num)
236-
237-
assert isinstance(num_, list)
238-
assert np.all([isinstance(part, list) for part in num_])
239-
np.testing.assert_array_equal(num_[0][0], array([1.0, 1.0], dtype=float))
240-
np.testing.assert_array_equal(num_[0][1], array([2.0, 2.0], dtype=float))
241-
242-
def test_clean_part_list_list_arrays(self):
243-
"""List of list of numpy arrays for all valid types."""
244-
for dtype in int, int8, int16, int32, int64, float, float16, float32, float64, longdouble:
245-
num = [[array([1, 1], dtype=dtype), array([2, 2], dtype=dtype)],
246-
[array([3, 3], dtype=dtype), array([4, 4], dtype=dtype)]]
247-
num_ = _clean_part(num)
248-
249-
assert len(num_) == 2
250-
assert np.all([isinstance(part, list) for part in num_])
251-
assert np.all([len(part) == 2 for part in num_])
252-
np.testing.assert_array_equal(num_[0][0], array([1.0, 1.0], dtype=float))
253-
np.testing.assert_array_equal(num_[0][1], array([2.0, 2.0], dtype=float))
254-
np.testing.assert_array_equal(num_[1][0], array([3.0, 3.0], dtype=float))
255-
np.testing.assert_array_equal(num_[1][1], array([4.0, 4.0], dtype=float))
256-
257-
258-
if __name__ == "__main__":
259-
unittest.main()
12+
cases = {
13+
"scalar":
14+
(1, lambda dtype, v: dtype(v)),
15+
"scalar in 0d array":
16+
(1, lambda dtype, v: np.array(v, dtype=dtype)),
17+
"numpy array":
18+
([1, 2], lambda dtype, v: np.array(v, dtype=dtype)),
19+
"list of scalar":
20+
(1, lambda dtype, v: [dtype(v)]),
21+
"list of scalars":
22+
([1, 2], lambda dtype, v: [dtype(vi) for vi in v]),
23+
"list of list of list of scalar":
24+
(1, lambda dtype, v: [[[dtype(v)]]]),
25+
"list of list of list of scalars":
26+
([[1, 1], [2, 2]],
27+
lambda dtype, v: [[[dtype(vi) for vi in vr] for vr in v]]),
28+
"tuple of scalar":
29+
(1, lambda dtype, v: (dtype(v),)),
30+
"tuple of scalars":
31+
([1, 2], lambda dtype, v: tuple(dtype(vi) for vi in v)),
32+
"list of list of numpy arrays":
33+
([[1, 1], [2, 2]],
34+
lambda dtype, v: [[np.array(vr, dtype=dtype) for vr in v]]),
35+
"tuple of list of numpy arrays":
36+
([[1, 1], [2, 2]],
37+
lambda dtype, v: ([np.array(vr, dtype=dtype) for vr in v],)),
38+
"list of tuple of numpy arrays":
39+
([[1, 1], [2, 2]],
40+
lambda dtype, v: [tuple(np.array(vr, dtype=dtype) for vr in v)]),
41+
"tuple of tuples of numpy arrays":
42+
([[[1, 1], [2, 2]], [[3, 3], [4, 4]]],
43+
lambda dtype, v: tuple(tuple(np.array(vr, dtype=dtype) for vr in vp)
44+
for vp in v)),
45+
"list of tuples of numpy arrays":
46+
([[[1, 1], [2, 2]], [[3, 3], [4, 4]]],
47+
lambda dtype, v: [tuple(np.array(vr, dtype=dtype) for vr in vp)
48+
for vp in v]),
49+
"list of lists of numpy arrays":
50+
([[[1, 1], [2, 2]], [[3, 3], [4, 4]]],
51+
lambda dtype, v: [[np.array(vr, dtype=dtype) for vr in vp]
52+
for vp in v]),
53+
}
54+
55+
56+
@pytest.mark.parametrize("dtype",
57+
[np.int, np.int8, np.int16, np.int32, np.int64,
58+
np.float, np.float16, np.float32, np.float64,
59+
np.longdouble])
60+
@pytest.mark.parametrize("num, fun", cases.values(), ids=cases.keys())
61+
def test_clean_part(num, fun, dtype):
62+
"""Test clean part for various inputs"""
63+
numa = fun(dtype, num)
64+
num_ = _clean_part(numa)
65+
ref_ = np.array(num, dtype=np.float, ndmin=3)
66+
67+
assert isinstance(num_, list)
68+
assert np.all([isinstance(part, list) for part in num_])
69+
for i, numi in enumerate(num_):
70+
assert len(numi) == ref_.shape[1]
71+
for j, numj in enumerate(numi):
72+
np.testing.assert_array_equal(numj, ref_[i, j, ...])
73+
74+
75+
@pytest.mark.parametrize("badinput", [[[0., 1.], [2., 3.]], "a"])
76+
def test_clean_part_bad_input(badinput):
77+
"""Give the part cleaner invalid input type."""
78+
with pytest.raises(TypeError):
79+
_clean_part(badinput)

0 commit comments

Comments
 (0)