Skip to content

Commit

Permalink
Use fixtures for sample data in unit tests
Browse files Browse the repository at this point in the history
Rationale: This is more elegant way to give modifiable data than using
the `copy` module explicitly.
  • Loading branch information
jasujm committed May 3, 2020
1 parent d8bf0d8 commit 6a556cf
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 141 deletions.
2 changes: 1 addition & 1 deletion cxx/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ if (Python_FOUND)
COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PYTHON_SOURCE_DIR}
$<TARGET_PROPERTY:Python::Interpreter,LOCATION>
${STATUS_DEFINITIONS_GENERATOR_PY} ${STATUS_DEFINITIONS_HEADER}
DEPENDS ${ENUMECG_SOURCE_FILES} "${PYTHON_SOURCE_DIR}/tests/common.py"
DEPENDS ${ENUMECG_SOURCE_FILES} "${PYTHON_SOURCE_DIR}/tests/conftest.py"
MAIN_DEPENDENCY ${STATUS_DEFINITIONS_GENERATOR_PY})

set(ENHANCEDENUM_TEST "${ENHANCEDENUM_LIB}Test")
Expand Down
3 changes: 2 additions & 1 deletion cxx/tests/generate_status_hh.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

import jinja2

from tests.common import STATUS_DEFINITION_DICT, NESTED_ENUM_DEFINITION_DICT
from tests.conftest import STATUS_DEFINITION_DICT, NESTED_ENUM_DEFINITION_DICT

from enumecg import generate


Expand Down
60 changes: 0 additions & 60 deletions python/tests/common.py

This file was deleted.

113 changes: 113 additions & 0 deletions python/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import copy
import enum
import pytest

from enumecg.definitions import EnumDefinition, EnumMemberDefinition, EnumDocumentation


class Status(enum.Enum):
"""An example enumeration for testing
This is a long description of the test enum."""

INITIALIZING = "initializing"
WAITING_FOR_INPUT = "waitingForInput"
BUSY = "busy"


"""The :class:`definitions.EnumDefinition` expected to be generated from :class:`Status`
This is global constant. For copy that can be modified, please use the
:func:`status_definition()` fixture.
"""
STATUS_DEFINITION = EnumDefinition(
label_enum_typename="StatusLabel",
enhanced_enum_typename="EnhancedStatus",
value_type_typename="std::string_view",
members=[
EnumMemberDefinition(
enumerator_name="INITIALIZING",
enumerator_value_constant_name="INITIALIZING_VALUE",
enumerator_value_initializers='"initializing"',
),
EnumMemberDefinition(
enumerator_name="WAITING_FOR_INPUT",
enumerator_value_constant_name="WAITING_FOR_INPUT_VALUE",
enumerator_value_initializers='"waitingForInput"',
),
EnumMemberDefinition(
enumerator_name="BUSY",
enumerator_value_constant_name="BUSY_VALUE",
enumerator_value_initializers='"busy"',
),
],
associate_namespace_name="Statuses",
)

"""``dict`` representation of :const:`STATUS_DEFINITION`
This is global constant. For copy that can be modified, please use the
:func:`status_definition_dict()` fixture.
"""
STATUS_DEFINITION_DICT = {
"typename": "Status",
"docstring": Status.__doc__,
"members": {
"INITIALIZING": "initializing",
"WAITING_FOR_INPUT": "waitingForInput",
"BUSY": "busy",
},
}


"""Sample nested enum definition
This is global constant. For copy that can be modified, please use the
:func:`nested_enum_definition_dict()` fixture.
"""
NESTED_ENUM_DEFINITION_DICT = {
"typename": "NestedEnum",
"members": {"enumerator": (0, ("string", True))},
}


@pytest.fixture
def status_definition():
"""Return deep copy of :const:`STATUS_DEFINITION`
This definition is expected to be generated from
:class:`Status`. Can be modified by a test case because this is a
copy.
"""
return copy.deepcopy(STATUS_DEFINITION)


@pytest.fixture
def status_definition_dict():
"""Return deep copy of :const:`STATUS_DEFINITION_DICT`
This definition is expected to be generated from
:class:`Status`. Can be modified by a test case because this is a
copy.
"""
return copy.deepcopy(STATUS_DEFINITION_DICT)


@pytest.fixture
def nested_enum_definition_dict():
"""Return deep copy of :const:`NESTED_ENUM_DEFINITION_DICT`
This definition is expected to be generated from
:class:`Status`. Can be modified by a test case because this is a
copy.
"""
return copy.deepcopy(NESTED_ENUM_DEFINITION_DICT)


@pytest.fixture
def status_documentation():
"""Return :class:`definitions.EnumDocumentation` expected to be generated from :class:`Status`"""
return EnumDocumentation(
short_description="An example enumeration for testing",
long_description="This is a long description of the test enum.",
)
60 changes: 31 additions & 29 deletions python/tests/test_definitions.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,60 @@
import copy
import pytest

from .common import (
STATUS_DEFINITION,
Status,
STATUS_DEFINITION_DICT,
NESTED_ENUM_DEFINITION_DICT,
STATUS_DOCUMENTATION,
)

from enumecg.definitions import EnumDefinition, EnumMemberDefinition, make_definition

from .conftest import Status


def test_make_definition_should_return_native_definition_as_is():
assert make_definition(STATUS_DEFINITION) is STATUS_DEFINITION
def test_make_definition_should_return_native_definition_as_is(status_definition):
assert make_definition(status_definition) is status_definition


def test_make_definition_should_make_definition_from_dict():
assert make_definition(STATUS_DEFINITION_DICT) == STATUS_DEFINITION
def test_make_definition_should_make_definition_from_dict(
status_definition, status_definition_dict
):
assert make_definition(status_definition_dict) == status_definition


def test_make_definition_should_make_definition_from_python_enum():
assert make_definition(Status) == STATUS_DEFINITION
def test_make_definition_should_make_definition_from_python_enum(status_definition):
assert make_definition(Status) == status_definition


def test_make_definition_should_raise_error_on_unknown_type():
with pytest.raises(TypeError):
make_definition("this doesn't make sense")


def test_make_definition_with_label_type_as_primary():
definition = copy.copy(STATUS_DEFINITION)
definition.label_enum_typename = "Status"
definition.label_enum_documentation = STATUS_DOCUMENTATION
assert make_definition(STATUS_DEFINITION_DICT, primary_type="label") == definition
def test_make_definition_with_label_type_as_primary(
status_definition, status_definition_dict, status_documentation
):
status_definition.label_enum_typename = "Status"
status_definition.label_enum_documentation = status_documentation
assert (
make_definition(status_definition_dict, primary_type="label")
== status_definition
)


def test_make_definition_with_enhanced_type_as_primary():
definition = copy.copy(STATUS_DEFINITION)
definition.enhanced_enum_typename = "Status"
definition.enhanced_enum_documentation = STATUS_DOCUMENTATION
make_definition(STATUS_DEFINITION_DICT, primary_type="enhanced") == definition
def test_make_definition_with_enhanced_type_as_primary(
status_definition, status_definition_dict, status_documentation
):
status_definition.enhanced_enum_typename = "Status"
status_definition.enhanced_enum_documentation = status_documentation
make_definition(
status_definition_dict, primary_type="enhanced"
) == status_definition


def test_make_definition_type_deduction():
nested_enum_definition = make_definition(NESTED_ENUM_DEFINITION_DICT)
def test_make_definition_type_deduction(nested_enum_definition_dict):
nested_enum_definition = make_definition(nested_enum_definition_dict)
assert (
nested_enum_definition.value_type_typename
== "std::tuple<long, std::tuple<std::string_view, bool>>"
)


def test_make_definition_enumerator_value_initializers():
nested_enum_definition = make_definition(NESTED_ENUM_DEFINITION_DICT)
def test_make_definition_enumerator_value_initializers(nested_enum_definition_dict):
nested_enum_definition = make_definition(nested_enum_definition_dict)
assert nested_enum_definition.members[0].enumerator_value_initializers == [
"0",
['"string"', "true"],
Expand Down
8 changes: 3 additions & 5 deletions python/tests/test_enumecg.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
from enumecg import generate, generator
from enumecg.generators import CodeGenerator

from .common import STATUS_DEFINITION


def test_generator_function_should_return_code_generator():
assert type(generator()) is CodeGenerator


def test_generate_should_return_code():
assert generate(STATUS_DEFINITION, documentation="doxygen") == CodeGenerator(
def test_generate_should_return_code(status_definition):
assert generate(status_definition, documentation="doxygen") == CodeGenerator(
documentation="doxygen"
).generate_enum_definitions(STATUS_DEFINITION)
).generate_enum_definitions(status_definition)

0 comments on commit 6a556cf

Please sign in to comment.