111986Sandreas.sandberg@arm.comimport pytest
212391Sjason@lowepower.comfrom pybind11_tests import enums as m
311986Sandreas.sandberg@arm.com
411986Sandreas.sandberg@arm.com
511986Sandreas.sandberg@arm.comdef test_unscoped_enum():
612391Sjason@lowepower.com    assert str(m.UnscopedEnum.EOne) == "UnscopedEnum.EOne"
712391Sjason@lowepower.com    assert str(m.UnscopedEnum.ETwo) == "UnscopedEnum.ETwo"
812391Sjason@lowepower.com    assert str(m.EOne) == "UnscopedEnum.EOne"
914299Sbbruce@ucdavis.edu
1014299Sbbruce@ucdavis.edu    # name property
1114299Sbbruce@ucdavis.edu    assert m.UnscopedEnum.EOne.name == "EOne"
1214299Sbbruce@ucdavis.edu    assert m.UnscopedEnum.ETwo.name == "ETwo"
1314299Sbbruce@ucdavis.edu    assert m.EOne.name == "EOne"
1414299Sbbruce@ucdavis.edu    # name readonly
1514299Sbbruce@ucdavis.edu    with pytest.raises(AttributeError):
1614299Sbbruce@ucdavis.edu        m.UnscopedEnum.EOne.name = ""
1714299Sbbruce@ucdavis.edu    # name returns a copy
1814299Sbbruce@ucdavis.edu    foo = m.UnscopedEnum.EOne.name
1914299Sbbruce@ucdavis.edu    foo = "bar"
2014299Sbbruce@ucdavis.edu    assert m.UnscopedEnum.EOne.name == "EOne"
2114299Sbbruce@ucdavis.edu
2212037Sandreas.sandberg@arm.com    # __members__ property
2312391Sjason@lowepower.com    assert m.UnscopedEnum.__members__ == \
2414299Sbbruce@ucdavis.edu        {"EOne": m.UnscopedEnum.EOne, "ETwo": m.UnscopedEnum.ETwo, "EThree": m.UnscopedEnum.EThree}
2512037Sandreas.sandberg@arm.com    # __members__ readonly
2612037Sandreas.sandberg@arm.com    with pytest.raises(AttributeError):
2712391Sjason@lowepower.com        m.UnscopedEnum.__members__ = {}
2812037Sandreas.sandberg@arm.com    # __members__ returns a copy
2912391Sjason@lowepower.com    foo = m.UnscopedEnum.__members__
3012037Sandreas.sandberg@arm.com    foo["bar"] = "baz"
3112391Sjason@lowepower.com    assert m.UnscopedEnum.__members__ == \
3214299Sbbruce@ucdavis.edu        {"EOne": m.UnscopedEnum.EOne, "ETwo": m.UnscopedEnum.ETwo, "EThree": m.UnscopedEnum.EThree}
3311986Sandreas.sandberg@arm.com
3414299Sbbruce@ucdavis.edu    for docstring_line in '''An unscoped enumeration
3514299Sbbruce@ucdavis.edu
3614299Sbbruce@ucdavis.eduMembers:
3714299Sbbruce@ucdavis.edu
3814299Sbbruce@ucdavis.edu  EOne : Docstring for EOne
3914299Sbbruce@ucdavis.edu
4014299Sbbruce@ucdavis.edu  ETwo : Docstring for ETwo
4114299Sbbruce@ucdavis.edu
4214299Sbbruce@ucdavis.edu  EThree : Docstring for EThree'''.split('\n'):
4314299Sbbruce@ucdavis.edu        assert docstring_line in m.UnscopedEnum.__doc__
4414299Sbbruce@ucdavis.edu
4514299Sbbruce@ucdavis.edu    # Unscoped enums will accept ==/!= int comparisons
4612391Sjason@lowepower.com    y = m.UnscopedEnum.ETwo
4711986Sandreas.sandberg@arm.com    assert y == 2
4814299Sbbruce@ucdavis.edu    assert 2 == y
4911986Sandreas.sandberg@arm.com    assert y != 3
5014299Sbbruce@ucdavis.edu    assert 3 != y
5114299Sbbruce@ucdavis.edu    # Compare with None
5214299Sbbruce@ucdavis.edu    assert (y != None)  # noqa: E711
5314299Sbbruce@ucdavis.edu    assert not (y == None)  # noqa: E711
5414299Sbbruce@ucdavis.edu    # Compare with an object
5514299Sbbruce@ucdavis.edu    assert (y != object())
5614299Sbbruce@ucdavis.edu    assert not (y == object())
5714299Sbbruce@ucdavis.edu    # Compare with string
5814299Sbbruce@ucdavis.edu    assert y != "2"
5914299Sbbruce@ucdavis.edu    assert "2" != y
6014299Sbbruce@ucdavis.edu    assert not ("2" == y)
6114299Sbbruce@ucdavis.edu    assert not (y == "2")
6214299Sbbruce@ucdavis.edu
6314299Sbbruce@ucdavis.edu    with pytest.raises(TypeError):
6414299Sbbruce@ucdavis.edu        y < object()
6514299Sbbruce@ucdavis.edu
6614299Sbbruce@ucdavis.edu    with pytest.raises(TypeError):
6714299Sbbruce@ucdavis.edu        y <= object()
6814299Sbbruce@ucdavis.edu
6914299Sbbruce@ucdavis.edu    with pytest.raises(TypeError):
7014299Sbbruce@ucdavis.edu        y > object()
7114299Sbbruce@ucdavis.edu
7214299Sbbruce@ucdavis.edu    with pytest.raises(TypeError):
7314299Sbbruce@ucdavis.edu        y >= object()
7414299Sbbruce@ucdavis.edu
7514299Sbbruce@ucdavis.edu    with pytest.raises(TypeError):
7614299Sbbruce@ucdavis.edu        y | object()
7714299Sbbruce@ucdavis.edu
7814299Sbbruce@ucdavis.edu    with pytest.raises(TypeError):
7914299Sbbruce@ucdavis.edu        y & object()
8014299Sbbruce@ucdavis.edu
8114299Sbbruce@ucdavis.edu    with pytest.raises(TypeError):
8214299Sbbruce@ucdavis.edu        y ^ object()
8311986Sandreas.sandberg@arm.com
8412391Sjason@lowepower.com    assert int(m.UnscopedEnum.ETwo) == 2
8512391Sjason@lowepower.com    assert str(m.UnscopedEnum(2)) == "UnscopedEnum.ETwo"
8611986Sandreas.sandberg@arm.com
8711986Sandreas.sandberg@arm.com    # order
8812391Sjason@lowepower.com    assert m.UnscopedEnum.EOne < m.UnscopedEnum.ETwo
8912391Sjason@lowepower.com    assert m.UnscopedEnum.EOne < 2
9012391Sjason@lowepower.com    assert m.UnscopedEnum.ETwo > m.UnscopedEnum.EOne
9112391Sjason@lowepower.com    assert m.UnscopedEnum.ETwo > 1
9212391Sjason@lowepower.com    assert m.UnscopedEnum.ETwo <= 2
9312391Sjason@lowepower.com    assert m.UnscopedEnum.ETwo >= 2
9412391Sjason@lowepower.com    assert m.UnscopedEnum.EOne <= m.UnscopedEnum.ETwo
9512391Sjason@lowepower.com    assert m.UnscopedEnum.EOne <= 2
9612391Sjason@lowepower.com    assert m.UnscopedEnum.ETwo >= m.UnscopedEnum.EOne
9712391Sjason@lowepower.com    assert m.UnscopedEnum.ETwo >= 1
9812391Sjason@lowepower.com    assert not (m.UnscopedEnum.ETwo < m.UnscopedEnum.EOne)
9912391Sjason@lowepower.com    assert not (2 < m.UnscopedEnum.EOne)
10011986Sandreas.sandberg@arm.com
10114299Sbbruce@ucdavis.edu    # arithmetic
10214299Sbbruce@ucdavis.edu    assert m.UnscopedEnum.EOne & m.UnscopedEnum.EThree == m.UnscopedEnum.EOne
10314299Sbbruce@ucdavis.edu    assert m.UnscopedEnum.EOne | m.UnscopedEnum.ETwo == m.UnscopedEnum.EThree
10414299Sbbruce@ucdavis.edu    assert m.UnscopedEnum.EOne ^ m.UnscopedEnum.EThree == m.UnscopedEnum.ETwo
10514299Sbbruce@ucdavis.edu
10611986Sandreas.sandberg@arm.com
10711986Sandreas.sandberg@arm.comdef test_scoped_enum():
10812391Sjason@lowepower.com    assert m.test_scoped_enum(m.ScopedEnum.Three) == "ScopedEnum::Three"
10912391Sjason@lowepower.com    z = m.ScopedEnum.Two
11012391Sjason@lowepower.com    assert m.test_scoped_enum(z) == "ScopedEnum::Two"
11111986Sandreas.sandberg@arm.com
11214299Sbbruce@ucdavis.edu    # Scoped enums will *NOT* accept ==/!= int comparisons (Will always return False)
11314299Sbbruce@ucdavis.edu    assert not z == 3
11414299Sbbruce@ucdavis.edu    assert not 3 == z
11514299Sbbruce@ucdavis.edu    assert z != 3
11614299Sbbruce@ucdavis.edu    assert 3 != z
11714299Sbbruce@ucdavis.edu    # Compare with None
11814299Sbbruce@ucdavis.edu    assert (z != None)  # noqa: E711
11914299Sbbruce@ucdavis.edu    assert not (z == None)  # noqa: E711
12014299Sbbruce@ucdavis.edu    # Compare with an object
12114299Sbbruce@ucdavis.edu    assert (z != object())
12214299Sbbruce@ucdavis.edu    assert not (z == object())
12314299Sbbruce@ucdavis.edu    # Scoped enums will *NOT* accept >, <, >= and <= int comparisons (Will throw exceptions)
12411986Sandreas.sandberg@arm.com    with pytest.raises(TypeError):
12514299Sbbruce@ucdavis.edu        z > 3
12611986Sandreas.sandberg@arm.com    with pytest.raises(TypeError):
12714299Sbbruce@ucdavis.edu        z < 3
12814299Sbbruce@ucdavis.edu    with pytest.raises(TypeError):
12914299Sbbruce@ucdavis.edu        z >= 3
13014299Sbbruce@ucdavis.edu    with pytest.raises(TypeError):
13114299Sbbruce@ucdavis.edu        z <= 3
13211986Sandreas.sandberg@arm.com
13311986Sandreas.sandberg@arm.com    # order
13412391Sjason@lowepower.com    assert m.ScopedEnum.Two < m.ScopedEnum.Three
13512391Sjason@lowepower.com    assert m.ScopedEnum.Three > m.ScopedEnum.Two
13612391Sjason@lowepower.com    assert m.ScopedEnum.Two <= m.ScopedEnum.Three
13712391Sjason@lowepower.com    assert m.ScopedEnum.Two <= m.ScopedEnum.Two
13812391Sjason@lowepower.com    assert m.ScopedEnum.Two >= m.ScopedEnum.Two
13912391Sjason@lowepower.com    assert m.ScopedEnum.Three >= m.ScopedEnum.Two
14011986Sandreas.sandberg@arm.com
14111986Sandreas.sandberg@arm.com
14211986Sandreas.sandberg@arm.comdef test_implicit_conversion():
14312391Sjason@lowepower.com    assert str(m.ClassWithUnscopedEnum.EMode.EFirstMode) == "EMode.EFirstMode"
14412391Sjason@lowepower.com    assert str(m.ClassWithUnscopedEnum.EFirstMode) == "EMode.EFirstMode"
14511986Sandreas.sandberg@arm.com
14612391Sjason@lowepower.com    f = m.ClassWithUnscopedEnum.test_function
14712391Sjason@lowepower.com    first = m.ClassWithUnscopedEnum.EFirstMode
14812391Sjason@lowepower.com    second = m.ClassWithUnscopedEnum.ESecondMode
14911986Sandreas.sandberg@arm.com
15011986Sandreas.sandberg@arm.com    assert f(first) == 1
15111986Sandreas.sandberg@arm.com
15211986Sandreas.sandberg@arm.com    assert f(first) == f(first)
15311986Sandreas.sandberg@arm.com    assert not f(first) != f(first)
15411986Sandreas.sandberg@arm.com
15511986Sandreas.sandberg@arm.com    assert f(first) != f(second)
15611986Sandreas.sandberg@arm.com    assert not f(first) == f(second)
15711986Sandreas.sandberg@arm.com
15811986Sandreas.sandberg@arm.com    assert f(first) == int(f(first))
15911986Sandreas.sandberg@arm.com    assert not f(first) != int(f(first))
16011986Sandreas.sandberg@arm.com
16111986Sandreas.sandberg@arm.com    assert f(first) != int(f(second))
16211986Sandreas.sandberg@arm.com    assert not f(first) == int(f(second))
16311986Sandreas.sandberg@arm.com
16411986Sandreas.sandberg@arm.com    # noinspection PyDictCreation
16511986Sandreas.sandberg@arm.com    x = {f(first): 1, f(second): 2}
16611986Sandreas.sandberg@arm.com    x[f(first)] = 3
16711986Sandreas.sandberg@arm.com    x[f(second)] = 4
16811986Sandreas.sandberg@arm.com    # Hashing test
16911986Sandreas.sandberg@arm.com    assert str(x) == "{EMode.EFirstMode: 3, EMode.ESecondMode: 4}"
17011986Sandreas.sandberg@arm.com
17111986Sandreas.sandberg@arm.com
17211986Sandreas.sandberg@arm.comdef test_binary_operators():
17312391Sjason@lowepower.com    assert int(m.Flags.Read) == 4
17412391Sjason@lowepower.com    assert int(m.Flags.Write) == 2
17512391Sjason@lowepower.com    assert int(m.Flags.Execute) == 1
17612391Sjason@lowepower.com    assert int(m.Flags.Read | m.Flags.Write | m.Flags.Execute) == 7
17712391Sjason@lowepower.com    assert int(m.Flags.Read | m.Flags.Write) == 6
17812391Sjason@lowepower.com    assert int(m.Flags.Read | m.Flags.Execute) == 5
17912391Sjason@lowepower.com    assert int(m.Flags.Write | m.Flags.Execute) == 3
18012391Sjason@lowepower.com    assert int(m.Flags.Write | 1) == 3
18114299Sbbruce@ucdavis.edu    assert ~m.Flags.Write == -3
18211986Sandreas.sandberg@arm.com
18312391Sjason@lowepower.com    state = m.Flags.Read | m.Flags.Write
18412391Sjason@lowepower.com    assert (state & m.Flags.Read) != 0
18512391Sjason@lowepower.com    assert (state & m.Flags.Write) != 0
18612391Sjason@lowepower.com    assert (state & m.Flags.Execute) == 0
18711986Sandreas.sandberg@arm.com    assert (state & 1) == 0
18811986Sandreas.sandberg@arm.com
18911986Sandreas.sandberg@arm.com    state2 = ~state
19011986Sandreas.sandberg@arm.com    assert state2 == -7
19111986Sandreas.sandberg@arm.com    assert int(state ^ state2) == -1
19212391Sjason@lowepower.com
19312391Sjason@lowepower.com
19412391Sjason@lowepower.comdef test_enum_to_int():
19512391Sjason@lowepower.com    m.test_enum_to_int(m.Flags.Read)
19612391Sjason@lowepower.com    m.test_enum_to_int(m.ClassWithUnscopedEnum.EMode.EFirstMode)
19712391Sjason@lowepower.com    m.test_enum_to_uint(m.Flags.Read)
19812391Sjason@lowepower.com    m.test_enum_to_uint(m.ClassWithUnscopedEnum.EMode.EFirstMode)
19912391Sjason@lowepower.com    m.test_enum_to_long_long(m.Flags.Read)
20012391Sjason@lowepower.com    m.test_enum_to_long_long(m.ClassWithUnscopedEnum.EMode.EFirstMode)
20114299Sbbruce@ucdavis.edu
20214299Sbbruce@ucdavis.edu
20314299Sbbruce@ucdavis.edudef test_duplicate_enum_name():
20414299Sbbruce@ucdavis.edu    with pytest.raises(ValueError) as excinfo:
20514299Sbbruce@ucdavis.edu        m.register_bad_enum()
20614299Sbbruce@ucdavis.edu    assert str(excinfo.value) == 'SimpleEnum: element "ONE" already exists!'
207