Move enum tests into a new file

There are more enum tests than 'constants and functions'.
This commit is contained in:
Dean Moldovan 2016-08-13 00:57:24 +02:00
parent 382db5b2e7
commit a9a37b4e31
6 changed files with 131 additions and 107 deletions

View File

@ -7,6 +7,7 @@ set(PYBIND11_TEST_FILES
test_buffers.cpp test_buffers.cpp
test_callbacks.cpp test_callbacks.cpp
test_constants_and_functions.cpp test_constants_and_functions.cpp
test_enum.cpp
test_eval.cpp test_eval.cpp
test_exceptions.cpp test_exceptions.cpp
test_inheritance.cpp test_inheritance.cpp

View File

@ -30,6 +30,7 @@ void init_ex_stl_binder_vector(py::module &);
void init_ex_eval(py::module &); void init_ex_eval(py::module &);
void init_ex_custom_exceptions(py::module &); void init_ex_custom_exceptions(py::module &);
void init_ex_numpy_dtypes(py::module &); void init_ex_numpy_dtypes(py::module &);
void init_ex_enum(py::module &);
void init_issues(py::module &); void init_issues(py::module &);
#if defined(PYBIND11_TEST_EIGEN) #if defined(PYBIND11_TEST_EIGEN)
@ -74,6 +75,7 @@ PYBIND11_PLUGIN(pybind11_tests) {
init_ex_eval(m); init_ex_eval(m);
init_ex_custom_exceptions(m); init_ex_custom_exceptions(m);
init_ex_numpy_dtypes(m); init_ex_numpy_dtypes(m);
init_ex_enum(m);
init_issues(m); init_issues(m);
#if defined(PYBIND11_TEST_EIGEN) #if defined(PYBIND11_TEST_EIGEN)

View File

@ -9,33 +9,13 @@
#include "pybind11_tests.h" #include "pybind11_tests.h"
enum EMyEnumeration { enum MyEnum { EFirstEntry = 1, ESecondEntry };
EFirstEntry = 1,
ESecondEntry
};
enum class ECMyEnum {
Two = 2,
Three
};
class ExampleWithEnum {
public:
enum EMode {
EFirstMode = 1,
ESecondMode
};
static EMode test_function(EMode mode) {
return mode;
}
};
std::string test_function1() { std::string test_function1() {
return "test_function()"; return "test_function()";
} }
std::string test_function2(EMyEnumeration k) { std::string test_function2(MyEnum k) {
return "test_function(enum=" + std::to_string(k) + ")"; return "test_function(enum=" + std::to_string(k) + ")";
} }
@ -43,10 +23,6 @@ std::string test_function3(int i) {
return "test_function(" + std::to_string(i) + ")"; return "test_function(" + std::to_string(i) + ")";
} }
std::string test_ecenum(ECMyEnum z) {
return "test_ecenum(ECMyEnum::" + std::string(z == ECMyEnum::Two ? "Two" : "Three") + ")";
}
py::bytes return_bytes() { py::bytes return_bytes() {
const char *data = "\x01\x00\x02\x00"; const char *data = "\x01\x00\x02\x00";
return std::string(data, 4); return std::string(data, 4);
@ -63,29 +39,17 @@ std::string print_bytes(py::bytes bytes) {
} }
void init_ex_constants_and_functions(py::module &m) { void init_ex_constants_and_functions(py::module &m) {
m.attr("some_constant") = py::int_(14);
m.def("test_function", &test_function1); m.def("test_function", &test_function1);
m.def("test_function", &test_function2); m.def("test_function", &test_function2);
m.def("test_function", &test_function3); m.def("test_function", &test_function3);
m.def("test_ecenum", &test_ecenum);
m.attr("some_constant") = py::int_(14);
py::enum_<EMyEnumeration>(m, "EMyEnumeration") py::enum_<MyEnum>(m, "MyEnum")
.value("EFirstEntry", EFirstEntry) .value("EFirstEntry", EFirstEntry)
.value("ESecondEntry", ESecondEntry) .value("ESecondEntry", ESecondEntry)
.export_values(); .export_values();
py::enum_<ECMyEnum>(m, "ECMyEnum")
.value("Two", ECMyEnum::Two)
.value("Three", ECMyEnum::Three)
;
py::class_<ExampleWithEnum> exenum_class(m, "ExampleWithEnum");
exenum_class.def_static("test_function", &ExampleWithEnum::test_function);
py::enum_<ExampleWithEnum::EMode>(exenum_class, "EMode")
.value("EFirstMode", ExampleWithEnum::EFirstMode)
.value("ESecondMode", ExampleWithEnum::ESecondMode)
.export_values();
m.def("return_bytes", &return_bytes); m.def("return_bytes", &return_bytes);
m.def("print_bytes", &print_bytes); m.def("print_bytes", &print_bytes);
} }

View File

@ -1,4 +1,3 @@
import pytest
def test_constants(): def test_constants():
@ -8,74 +7,12 @@ def test_constants():
def test_function_overloading(): def test_function_overloading():
from pybind11_tests import EMyEnumeration, test_function from pybind11_tests import MyEnum, test_function
assert test_function() == "test_function()" assert test_function() == "test_function()"
assert test_function(7) == "test_function(7)" assert test_function(7) == "test_function(7)"
assert test_function(EMyEnumeration.EFirstEntry) == "test_function(enum=1)" assert test_function(MyEnum.EFirstEntry) == "test_function(enum=1)"
assert test_function(EMyEnumeration.ESecondEntry) == "test_function(enum=2)" assert test_function(MyEnum.ESecondEntry) == "test_function(enum=2)"
def test_unscoped_enum():
from pybind11_tests import EMyEnumeration, EFirstEntry
assert str(EMyEnumeration.EFirstEntry) == "EMyEnumeration.EFirstEntry"
assert str(EMyEnumeration.ESecondEntry) == "EMyEnumeration.ESecondEntry"
assert str(EFirstEntry) == "EMyEnumeration.EFirstEntry"
# no TypeError exception for unscoped enum ==/!= int comparisons
y = EMyEnumeration.ESecondEntry
assert y == 2
assert y != 3
assert int(EMyEnumeration.ESecondEntry) == 2
assert str(EMyEnumeration(2)) == "EMyEnumeration.ESecondEntry"
def test_scoped_enum():
from pybind11_tests import ECMyEnum, test_ecenum
assert test_ecenum(ECMyEnum.Three) == "test_ecenum(ECMyEnum::Three)"
z = ECMyEnum.Two
assert test_ecenum(z) == "test_ecenum(ECMyEnum::Two)"
# expected TypeError exceptions for scoped enum ==/!= int comparisons
with pytest.raises(TypeError):
assert z == 2
with pytest.raises(TypeError):
assert z != 3
def test_implicit_conversion():
from pybind11_tests import ExampleWithEnum
assert str(ExampleWithEnum.EMode.EFirstMode) == "EMode.EFirstMode"
assert str(ExampleWithEnum.EFirstMode) == "EMode.EFirstMode"
f = ExampleWithEnum.test_function
first = ExampleWithEnum.EFirstMode
second = ExampleWithEnum.ESecondMode
assert f(first) == 1
assert f(first) == f(first)
assert not f(first) != f(first)
assert f(first) != f(second)
assert not f(first) == f(second)
assert f(first) == int(f(first))
assert not f(first) != int(f(first))
assert f(first) != int(f(second))
assert not f(first) == int(f(second))
# noinspection PyDictCreation
x = {f(first): 1, f(second): 2}
x[f(first)] = 3
x[f(second)] = 4
# Hashing test
assert str(x) == "{EMode.EFirstMode: 3, EMode.ESecondMode: 4}"
def test_bytes(): def test_bytes():

57
tests/test_enum.cpp Normal file
View File

@ -0,0 +1,57 @@
/*
tests/test_enums.cpp -- enumerations
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file.
*/
#include "pybind11_tests.h"
enum UnscopedEnum {
EOne = 1,
ETwo
};
enum class ScopedEnum {
Two = 2,
Three
};
class ClassWithUnscopedEnum {
public:
enum EMode {
EFirstMode = 1,
ESecondMode
};
static EMode test_function(EMode mode) {
return mode;
}
};
std::string test_scoped_enum(ScopedEnum z) {
return "ScopedEnum::" + std::string(z == ScopedEnum::Two ? "Two" : "Three");
}
void init_ex_enum(py::module &m) {
m.def("test_scoped_enum", &test_scoped_enum);
py::enum_<UnscopedEnum>(m, "UnscopedEnum")
.value("EOne", EOne)
.value("ETwo", ETwo)
.export_values();
py::enum_<ScopedEnum>(m, "ScopedEnum")
.value("Two", ScopedEnum::Two)
.value("Three", ScopedEnum::Three)
;
py::class_<ClassWithUnscopedEnum> exenum_class(m, "ClassWithUnscopedEnum");
exenum_class.def_static("test_function", &ClassWithUnscopedEnum::test_function);
py::enum_<ClassWithUnscopedEnum::EMode>(exenum_class, "EMode")
.value("EFirstMode", ClassWithUnscopedEnum::EFirstMode)
.value("ESecondMode", ClassWithUnscopedEnum::ESecondMode)
.export_values();
}

63
tests/test_enum.py Normal file
View File

@ -0,0 +1,63 @@
import pytest
def test_unscoped_enum():
from pybind11_tests import UnscopedEnum, EOne
assert str(UnscopedEnum.EOne) == "UnscopedEnum.EOne"
assert str(UnscopedEnum.ETwo) == "UnscopedEnum.ETwo"
assert str(EOne) == "UnscopedEnum.EOne"
# no TypeError exception for unscoped enum ==/!= int comparisons
y = UnscopedEnum.ETwo
assert y == 2
assert y != 3
assert int(UnscopedEnum.ETwo) == 2
assert str(UnscopedEnum(2)) == "UnscopedEnum.ETwo"
def test_scoped_enum():
from pybind11_tests import ScopedEnum, test_scoped_enum
assert test_scoped_enum(ScopedEnum.Three) == "ScopedEnum::Three"
z = ScopedEnum.Two
assert test_scoped_enum(z) == "ScopedEnum::Two"
# expected TypeError exceptions for scoped enum ==/!= int comparisons
with pytest.raises(TypeError):
assert z == 2
with pytest.raises(TypeError):
assert z != 3
def test_implicit_conversion():
from pybind11_tests import ClassWithUnscopedEnum
assert str(ClassWithUnscopedEnum.EMode.EFirstMode) == "EMode.EFirstMode"
assert str(ClassWithUnscopedEnum.EFirstMode) == "EMode.EFirstMode"
f = ClassWithUnscopedEnum.test_function
first = ClassWithUnscopedEnum.EFirstMode
second = ClassWithUnscopedEnum.ESecondMode
assert f(first) == 1
assert f(first) == f(first)
assert not f(first) != f(first)
assert f(first) != f(second)
assert not f(first) == f(second)
assert f(first) == int(f(first))
assert not f(first) != int(f(first))
assert f(first) != int(f(second))
assert not f(first) == int(f(second))
# noinspection PyDictCreation
x = {f(first): 1, f(second): 2}
x[f(first)] = 3
x[f(second)] = 4
# Hashing test
assert str(x) == "{EMode.EFirstMode: 3, EMode.ESecondMode: 4}"