blob: bfaa193e9ba86295e249c20b96a150ce2ca0b88a [file] [log] [blame]
Henry Schreinerd8c7ee02020-07-20 13:35:21 -04001# -*- coding: utf-8 -*-
Dean Moldovana9a37b42016-08-13 00:57:24 +02002import pytest
Jason Rhinelander391c7542017-07-25 16:47:36 -04003from pybind11_tests import enums as m
Dean Moldovana9a37b42016-08-13 00:57:24 +02004
5
6def test_unscoped_enum():
Jason Rhinelander391c7542017-07-25 16:47:36 -04007 assert str(m.UnscopedEnum.EOne) == "UnscopedEnum.EOne"
8 assert str(m.UnscopedEnum.ETwo) == "UnscopedEnum.ETwo"
9 assert str(m.EOne) == "UnscopedEnum.EOne"
Boris Staletic289e5d92018-04-02 23:26:48 +020010
11 # name property
12 assert m.UnscopedEnum.EOne.name == "EOne"
13 assert m.UnscopedEnum.ETwo.name == "ETwo"
14 assert m.EOne.name == "EOne"
15 # name readonly
16 with pytest.raises(AttributeError):
17 m.UnscopedEnum.EOne.name = ""
18 # name returns a copy
19 foo = m.UnscopedEnum.EOne.name
20 foo = "bar"
21 assert m.UnscopedEnum.EOne.name == "EOne"
22
Matthieu Becaf936e12017-03-03 08:45:50 -080023 # __members__ property
Jason Rhinelander391c7542017-07-25 16:47:36 -040024 assert m.UnscopedEnum.__members__ == \
Sergei Izmailov09f08292019-09-19 19:23:27 +030025 {"EOne": m.UnscopedEnum.EOne, "ETwo": m.UnscopedEnum.ETwo, "EThree": m.UnscopedEnum.EThree}
Matthieu Becaf936e12017-03-03 08:45:50 -080026 # __members__ readonly
27 with pytest.raises(AttributeError):
Jason Rhinelander391c7542017-07-25 16:47:36 -040028 m.UnscopedEnum.__members__ = {}
Matthieu Becaf936e12017-03-03 08:45:50 -080029 # __members__ returns a copy
Jason Rhinelander391c7542017-07-25 16:47:36 -040030 foo = m.UnscopedEnum.__members__
Matthieu Becaf936e12017-03-03 08:45:50 -080031 foo["bar"] = "baz"
Jason Rhinelander391c7542017-07-25 16:47:36 -040032 assert m.UnscopedEnum.__members__ == \
Sergei Izmailov09f08292019-09-19 19:23:27 +030033 {"EOne": m.UnscopedEnum.EOne, "ETwo": m.UnscopedEnum.ETwo, "EThree": m.UnscopedEnum.EThree}
Dean Moldovana9a37b42016-08-13 00:57:24 +020034
Sergei Izmailov09f08292019-09-19 19:23:27 +030035 for docstring_line in '''An unscoped enumeration
Wenzel Jakob6d190362017-11-16 22:24:36 +010036
37Members:
38
39 EOne : Docstring for EOne
40
Wenzel Jakob6d190362017-11-16 22:24:36 +010041 ETwo : Docstring for ETwo
42
Sergei Izmailov09f08292019-09-19 19:23:27 +030043 EThree : Docstring for EThree'''.split('\n'):
44 assert docstring_line in m.UnscopedEnum.__doc__
Wenzel Jakob6d190362017-11-16 22:24:36 +010045
Tarcísio Fischer54eb8192018-10-24 06:18:58 -030046 # Unscoped enums will accept ==/!= int comparisons
Jason Rhinelander391c7542017-07-25 16:47:36 -040047 y = m.UnscopedEnum.ETwo
Dean Moldovana9a37b42016-08-13 00:57:24 +020048 assert y == 2
Tarcísio Fischer54eb8192018-10-24 06:18:58 -030049 assert 2 == y
Dean Moldovana9a37b42016-08-13 00:57:24 +020050 assert y != 3
Tarcísio Fischer54eb8192018-10-24 06:18:58 -030051 assert 3 != y
Sergei Izmailov09f08292019-09-19 19:23:27 +030052 # Compare with None
53 assert (y != None) # noqa: E711
54 assert not (y == None) # noqa: E711
55 # Compare with an object
56 assert (y != object())
57 assert not (y == object())
58 # Compare with string
59 assert y != "2"
60 assert "2" != y
61 assert not ("2" == y)
62 assert not (y == "2")
63
64 with pytest.raises(TypeError):
65 y < object()
66
67 with pytest.raises(TypeError):
68 y <= object()
69
70 with pytest.raises(TypeError):
71 y > object()
72
73 with pytest.raises(TypeError):
74 y >= object()
75
76 with pytest.raises(TypeError):
77 y | object()
78
79 with pytest.raises(TypeError):
80 y & object()
81
82 with pytest.raises(TypeError):
83 y ^ object()
Dean Moldovana9a37b42016-08-13 00:57:24 +020084
Jason Rhinelander391c7542017-07-25 16:47:36 -040085 assert int(m.UnscopedEnum.ETwo) == 2
86 assert str(m.UnscopedEnum(2)) == "UnscopedEnum.ETwo"
Dean Moldovana9a37b42016-08-13 00:57:24 +020087
Pim Schellart90d27802016-11-16 11:28:11 -050088 # order
Jason Rhinelander391c7542017-07-25 16:47:36 -040089 assert m.UnscopedEnum.EOne < m.UnscopedEnum.ETwo
90 assert m.UnscopedEnum.EOne < 2
91 assert m.UnscopedEnum.ETwo > m.UnscopedEnum.EOne
92 assert m.UnscopedEnum.ETwo > 1
93 assert m.UnscopedEnum.ETwo <= 2
94 assert m.UnscopedEnum.ETwo >= 2
95 assert m.UnscopedEnum.EOne <= m.UnscopedEnum.ETwo
96 assert m.UnscopedEnum.EOne <= 2
97 assert m.UnscopedEnum.ETwo >= m.UnscopedEnum.EOne
98 assert m.UnscopedEnum.ETwo >= 1
99 assert not (m.UnscopedEnum.ETwo < m.UnscopedEnum.EOne)
100 assert not (2 < m.UnscopedEnum.EOne)
Pim Schellart90d27802016-11-16 11:28:11 -0500101
Sergei Izmailov09f08292019-09-19 19:23:27 +0300102 # arithmetic
103 assert m.UnscopedEnum.EOne & m.UnscopedEnum.EThree == m.UnscopedEnum.EOne
104 assert m.UnscopedEnum.EOne | m.UnscopedEnum.ETwo == m.UnscopedEnum.EThree
105 assert m.UnscopedEnum.EOne ^ m.UnscopedEnum.EThree == m.UnscopedEnum.ETwo
106
Dean Moldovana9a37b42016-08-13 00:57:24 +0200107
108def test_scoped_enum():
Jason Rhinelander391c7542017-07-25 16:47:36 -0400109 assert m.test_scoped_enum(m.ScopedEnum.Three) == "ScopedEnum::Three"
110 z = m.ScopedEnum.Two
111 assert m.test_scoped_enum(z) == "ScopedEnum::Two"
Dean Moldovana9a37b42016-08-13 00:57:24 +0200112
Tarcísio Fischer54eb8192018-10-24 06:18:58 -0300113 # Scoped enums will *NOT* accept ==/!= int comparisons (Will always return False)
114 assert not z == 3
115 assert not 3 == z
116 assert z != 3
117 assert 3 != z
Sergei Izmailov09f08292019-09-19 19:23:27 +0300118 # Compare with None
119 assert (z != None) # noqa: E711
120 assert not (z == None) # noqa: E711
121 # Compare with an object
122 assert (z != object())
123 assert not (z == object())
Tarcísio Fischer54eb8192018-10-24 06:18:58 -0300124 # Scoped enums will *NOT* accept >, <, >= and <= int comparisons (Will throw exceptions)
Dean Moldovana9a37b42016-08-13 00:57:24 +0200125 with pytest.raises(TypeError):
Tarcísio Fischer54eb8192018-10-24 06:18:58 -0300126 z > 3
Dean Moldovana9a37b42016-08-13 00:57:24 +0200127 with pytest.raises(TypeError):
Tarcísio Fischer54eb8192018-10-24 06:18:58 -0300128 z < 3
129 with pytest.raises(TypeError):
130 z >= 3
131 with pytest.raises(TypeError):
132 z <= 3
Dean Moldovana9a37b42016-08-13 00:57:24 +0200133
Pim Schellart90d27802016-11-16 11:28:11 -0500134 # order
Jason Rhinelander391c7542017-07-25 16:47:36 -0400135 assert m.ScopedEnum.Two < m.ScopedEnum.Three
136 assert m.ScopedEnum.Three > m.ScopedEnum.Two
137 assert m.ScopedEnum.Two <= m.ScopedEnum.Three
138 assert m.ScopedEnum.Two <= m.ScopedEnum.Two
139 assert m.ScopedEnum.Two >= m.ScopedEnum.Two
140 assert m.ScopedEnum.Three >= m.ScopedEnum.Two
Dean Moldovana9a37b42016-08-13 00:57:24 +0200141
Dean Moldovanbad17402016-11-20 21:21:54 +0100142
Dean Moldovana9a37b42016-08-13 00:57:24 +0200143def test_implicit_conversion():
Jason Rhinelander391c7542017-07-25 16:47:36 -0400144 assert str(m.ClassWithUnscopedEnum.EMode.EFirstMode) == "EMode.EFirstMode"
145 assert str(m.ClassWithUnscopedEnum.EFirstMode) == "EMode.EFirstMode"
Dean Moldovana9a37b42016-08-13 00:57:24 +0200146
Jason Rhinelander391c7542017-07-25 16:47:36 -0400147 f = m.ClassWithUnscopedEnum.test_function
148 first = m.ClassWithUnscopedEnum.EFirstMode
149 second = m.ClassWithUnscopedEnum.ESecondMode
Dean Moldovana9a37b42016-08-13 00:57:24 +0200150
151 assert f(first) == 1
152
153 assert f(first) == f(first)
154 assert not f(first) != f(first)
155
156 assert f(first) != f(second)
157 assert not f(first) == f(second)
158
159 assert f(first) == int(f(first))
160 assert not f(first) != int(f(first))
161
162 assert f(first) != int(f(second))
163 assert not f(first) == int(f(second))
164
165 # noinspection PyDictCreation
166 x = {f(first): 1, f(second): 2}
167 x[f(first)] = 3
168 x[f(second)] = 4
169 # Hashing test
170 assert str(x) == "{EMode.EFirstMode: 3, EMode.ESecondMode: 4}"
Pim Schellart90d27802016-11-16 11:28:11 -0500171
Dean Moldovanbad17402016-11-20 21:21:54 +0100172
Pim Schellart90d27802016-11-16 11:28:11 -0500173def test_binary_operators():
Jason Rhinelander391c7542017-07-25 16:47:36 -0400174 assert int(m.Flags.Read) == 4
175 assert int(m.Flags.Write) == 2
176 assert int(m.Flags.Execute) == 1
177 assert int(m.Flags.Read | m.Flags.Write | m.Flags.Execute) == 7
178 assert int(m.Flags.Read | m.Flags.Write) == 6
179 assert int(m.Flags.Read | m.Flags.Execute) == 5
180 assert int(m.Flags.Write | m.Flags.Execute) == 3
181 assert int(m.Flags.Write | 1) == 3
Lori A. Burnsf6c4c102019-09-04 16:16:21 -0400182 assert ~m.Flags.Write == -3
Pim Schellart90d27802016-11-16 11:28:11 -0500183
Jason Rhinelander391c7542017-07-25 16:47:36 -0400184 state = m.Flags.Read | m.Flags.Write
185 assert (state & m.Flags.Read) != 0
186 assert (state & m.Flags.Write) != 0
187 assert (state & m.Flags.Execute) == 0
Pim Schellart90d27802016-11-16 11:28:11 -0500188 assert (state & 1) == 0
189
190 state2 = ~state
191 assert state2 == -7
192 assert int(state ^ state2) == -1
Wenzel Jakobe6fd2cd2017-04-28 14:46:52 +0200193
Wenzel Jakob7653a112017-04-28 22:43:14 +0200194
Wenzel Jakobe6fd2cd2017-04-28 14:46:52 +0200195def test_enum_to_int():
Wenzel Jakob31680e62019-09-20 11:06:10 +0200196 m.test_enum_to_int(m.Flags.Read)
197 m.test_enum_to_int(m.ClassWithUnscopedEnum.EMode.EFirstMode)
198 m.test_enum_to_uint(m.Flags.Read)
199 m.test_enum_to_uint(m.ClassWithUnscopedEnum.EMode.EFirstMode)
200 m.test_enum_to_long_long(m.Flags.Read)
201 m.test_enum_to_long_long(m.ClassWithUnscopedEnum.EMode.EFirstMode)
Krzysztof Fornalczyk5c8746f2018-09-11 10:59:56 +0200202
203
204def test_duplicate_enum_name():
205 with pytest.raises(ValueError) as excinfo:
206 m.register_bad_enum()
Wenzel Jakobf4245182018-09-01 01:20:24 +0200207 assert str(excinfo.value) == 'SimpleEnum: element "ONE" already exists!'