codekingpro/portable-devtools
115k
1import pytest
2
3import numpy as np
4
5from . import util
6
7
8class TestString(util.F2PyTest):
9 sources = [util.getpath("tests", "src", "string", "char.f90")]
10
11 @pytest.mark.slow
12 def test_char(self):
13 strings = np.array(["ab", "cd", "ef"], dtype="c").T
14 inp, out = self.module.char_test.change_strings(
15 strings, strings.shape[1])
16 assert inp == pytest.approx(strings)
17 expected = strings.copy()
18 expected[1, :] = "AAA"
19 assert out == pytest.approx(expected)
20
21
22class TestDocStringArguments(util.F2PyTest):
23 sources = [util.getpath("tests", "src", "string", "string.f")]
24
25 def test_example(self):
26 a = np.array(b"123\0\0")
27 b = np.array(b"123\0\0")
28 c = np.array(b"123")
29 d = np.array(b"123")
30
31 self.module.foo(a, b, c, d)
32
33 assert a.tobytes() == b"123\0\0"
34 assert b.tobytes() == b"B23\0\0"
35 assert c.tobytes() == b"123"
36 assert d.tobytes() == b"D23"
37
38
39class TestFixedString(util.F2PyTest):
40 sources = [util.getpath("tests", "src", "string", "fixed_string.f90")]
41
42 @staticmethod
43 def _sint(s, start=0, end=None):
44 """Return the content of a string buffer as integer value.
45
46 For example:
47 _sint('1234') -> 4321
48 _sint('123A') -> 17321
49 """
50 if isinstance(s, np.ndarray):
51 s = s.tobytes()
52 elif isinstance(s, str):
53 s = s.encode()
54 assert isinstance(s, bytes)
55 if end is None:
56 end = len(s)
57 i = 0
58 for j in range(start, min(end, len(s))):
59 i += s[j] * 10**j
60 return i
61
62 def _get_input(self, intent="in"):
63 if intent in ["in"]:
64 yield ""
65 yield "1"
66 yield "1234"
67 yield "12345"
68 yield b""
69 yield b"\0"
70 yield b"1"
71 yield b"\01"
72 yield b"1\0"
73 yield b"1234"
74 yield b"12345"
75 yield np.ndarray((), np.bytes_, buffer=b"") # array(b'', dtype='|S0')
76 yield np.array(b"") # array(b'', dtype='|S1')
77 yield np.array(b"\0")
78 yield np.array(b"1")
79 yield np.array(b"1\0")
80 yield np.array(b"\01")
81 yield np.array(b"1234")
82 yield np.array(b"123\0")
83 yield np.array(b"12345")
84
85 def test_intent_in(self):
86 for s in self._get_input():
87 r = self.module.test_in_bytes4(s)
88 # also checks that s is not changed inplace
89 expected = self._sint(s, end=4)
90 assert r == expected, s
91
92 def test_intent_inout(self):
93 for s in self._get_input(intent="inout"):
94 rest = self._sint(s, start=4)
95 r = self.module.test_inout_bytes4(s)
96 expected = self._sint(s, end=4)
97 assert r == expected
98
99 # check that the rest of input string is preserved
100 assert rest == self._sint(s, start=4)
101 