Skip to content

Commit

Permalink
Use Python enums to enumerate the possible documentation styles in En…
Browse files Browse the repository at this point in the history
…umECG
  • Loading branch information
jasujm committed May 10, 2020
1 parent 017f958 commit f88b5b7
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 36 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ Changed
- Change the format of ``dict`` representation of enumerators to
have more explicit ordering of members
- Improvements to the documentation
- Use Python enums to enumerate the possible primary types in EnumECG
- Use Python enums to enumerate the possible primary types and documentation
styles in the EnumECG library

Version 0.3
-----------
Expand Down
12 changes: 8 additions & 4 deletions python/enumecg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,28 @@


def generator(
*, documentation: typing.Optional[str] = None
*, documentation: typing.Union[generators.DocumentationStyle, str, None] = None
) -> generators.CodeGenerator:
"""Create code generator for an enhanced enum type
Creates an instance of :class:`generators.CodeGenerator`.
Parameters:
documentation: See :ref:`enumecg-documentation-generation`.
documentation: A string or an enumerator indicating the documentation
style. See :ref:`enumecg-documentation-generation`.
Returns:
The :class:`generators.CodeGenerator` instance.
"""
if documentation is not None:
documentation = generators.DocumentationStyle(documentation)
return generators.CodeGenerator(documentation=documentation)


def generate(
enum,
*,
documentation: typing.Optional[str] = None,
documentation: typing.Union[generators.DocumentationStyle, str, None] = None,
primary_type: typing.Union[definitions.PrimaryType, str, None] = None,
value_type: typing.Optional[str] = None
) -> str:
Expand All @@ -60,7 +63,8 @@ def generate(
Parameters:
enum: The enum definition
documentation: See :ref:`enumecg-documentation-generation`.
documentation: A string or an enumerator indicating the documentation
style. See :ref:`enumecg-documentation-generation`.
primary_type: A string or an enumerator indicating the
primary type. See :ref:`enumecg-primary-enum`.
value_type: See :ref:`enumerator-value-type`.
Expand Down
10 changes: 7 additions & 3 deletions python/enumecg/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,23 @@
import yaml

from . import generate
from .generators import CodeGenerator
from .generators import DocumentationStyle
from .definitions import PrimaryType


def _get_enum_values(Enum):
return [e.value for e in Enum.__members__.values()]


@click.command()
@click.option(
"--documentation",
type=click.Choice(CodeGenerator.DOCUMENTATION_CHOICES),
type=click.Choice(_get_enum_values(DocumentationStyle)),
help="Documentation style",
)
@click.option(
"--primary-type",
type=click.Choice([e.value for e in PrimaryType.__members__.values()]),
type=click.Choice(_get_enum_values(PrimaryType)),
help="Primary enumeration type",
)
@click.option("--value-type", help="Enumerator value type")
Expand Down
7 changes: 6 additions & 1 deletion python/enumecg/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ class PrimaryType(py_enum.Enum):
"""

label = "label"
"""Label enum is the primary type"""

enhanced = "enhanced"
"""Enhanced enum is the primary type"""


@dataclasses.dataclass
Expand Down Expand Up @@ -101,7 +104,9 @@ def _make_definition_from_dict(enum_dict, *, primary_type, value_type):
for (n, member) in enumerate(members)
],
associate_namespace_name=formatter.join(formatter.parts[0], pluralize=True),
label_enum_documentation=documentation if primary_type == PrimaryType.label else None,
label_enum_documentation=documentation
if primary_type == PrimaryType.label
else None,
enhanced_enum_documentation=documentation
if primary_type == PrimaryType.enhanced
else None,
Expand Down
28 changes: 16 additions & 12 deletions python/enumecg/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,25 @@
"""

import collections.abc as cabc
import enum
import typing

import jinja2

from . import definitions


class DocumentationStyle(enum.Enum):
"""Possible documentation styles
These are the accepted choices for the ``documentation`` argument
in :func:`CodeGenerator()`.
"""

doxygen = "doxygen"
"""Doxygen documentation style"""


def _make_initializer_list(value):
if isinstance(value, str):
return value
Expand Down Expand Up @@ -50,23 +62,15 @@ class CodeGenerator:
:func:`enumecg.generator()` function.
"""

DOCUMENTATION_CHOICES = ["doxygen"]
"""Possible documentation styles
These are the accepted choices for the ``documentation`` argument
in :func:`CodeGenerator()`.
"""

_JINJA_ENV = _create_jinja_env()

def __init__(self, *, documentation: typing.Optional[str] = None):
def __init__(self, *, documentation: typing.Optional[DocumentationStyle] = None):
"""
Parameters:
documentation: See :ref:`enumecg-documentation-generation`.
documentation: A :class:`DocumentationStyle` enumerator indicating the
documentation style. See :ref:`enumecg-documentation-generation`.
"""
if documentation and documentation not in self.DOCUMENTATION_CHOICES:
raise ValueError(f"Unsupported documentation style: {documentation!r}")
self._documentation = documentation
self._documentation = documentation.value if documentation else None
self._enum_definitions_template = self._JINJA_ENV.get_template(
"enum_definitions.hh.in"
)
Expand Down
4 changes: 3 additions & 1 deletion python/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ def test_cli_should_have_documentation_option(cli_runner, enum_file, status_defi
def test_cli_should_have_primeray_type_option(
cli_runner, enum_file, status_definition_dict, primary_type
):
result = cli_runner.invoke(cli, ["--primary-type", primary_type.value, str(enum_file)])
result = cli_runner.invoke(
cli, ["--primary-type", primary_type.value, str(enum_file)]
)
assert (
result.output
== generate(status_definition_dict, primary_type=primary_type) + "\n"
Expand Down
7 changes: 6 additions & 1 deletion python/tests/test_definitions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import pytest

from enumecg.definitions import EnumDefinition, EnumMemberDefinition, make_definition, PrimaryType
from enumecg.definitions import (
EnumDefinition,
EnumMemberDefinition,
make_definition,
PrimaryType,
)

from .conftest import Status

Expand Down
25 changes: 23 additions & 2 deletions python/tests/test_enumecg.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import pytest

from enumecg import generate, generator
from enumecg.generators import CodeGenerator
from enumecg.generators import CodeGenerator, DocumentationStyle
from enumecg.definitions import PrimaryType


def test_generator_function_should_return_code_generator():
Expand All @@ -8,5 +11,23 @@ def test_generator_function_should_return_code_generator():

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


@pytest.mark.parametrize("primary_type", PrimaryType)
def test_generate_should_accept_primary_type_as_string(
status_definition_dict, primary_type
):
assert generate(
status_definition_dict, primary_type=primary_type.value
) == generate(status_definition_dict, primary_type=primary_type)


@pytest.mark.parametrize("documentation", DocumentationStyle)
def test_generate_should_accept_documentation_as_string(
status_definition_dict, documentation
):
assert generate(
status_definition_dict, documentation=documentation.value
) == generate(status_definition_dict, documentation=documentation)
17 changes: 6 additions & 11 deletions python/tests/test_generators.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
import re

from enumecg.generators import CodeGenerator
from enumecg.generators import CodeGenerator, DocumentationStyle

from .conftest import STATUS_DEFINITION

Expand Down Expand Up @@ -63,7 +63,7 @@ def test_enum_definitions_should_not_contain_documentation_if_not_requested(

def test_enum_definitions_should_contain_documentation_if_requested(status_definition):
assert "/**" in _generate_enum_definitions(
status_definition, documentation="doxygen"
status_definition, documentation=DocumentationStyle.doxygen
)


Expand All @@ -72,7 +72,7 @@ def test_label_enum_documentation_should_contain_short_description(
):
status_definition.label_enum_documentation = status_documentation
assert status_documentation.short_description in _generate_enum_definitions(
status_definition, documentation="doxygen"
status_definition, documentation=DocumentationStyle.doxygen
)


Expand All @@ -81,7 +81,7 @@ def test_label_enum_documentation_should_contain_long_description(
):
status_definition.label_enum_documentation = status_documentation
assert status_documentation.long_description in _generate_enum_definitions(
status_definition, documentation="doxygen"
status_definition, documentation=DocumentationStyle.doxygen
)


Expand All @@ -90,7 +90,7 @@ def test_enhanced_enum_documentation_should_contain_short_description(
):
status_definition.enhanced_enum_documentation = status_documentation
assert status_documentation.short_description in _generate_enum_definitions(
status_definition, documentation="doxygen"
status_definition, documentation=DocumentationStyle.doxygen
)


Expand All @@ -99,10 +99,5 @@ def test_enhanced_enum_documentation_should_contain_long_description(
):
status_definition.enhanced_enum_documentation = status_documentation
assert status_documentation.long_description in _generate_enum_definitions(
status_definition, documentation="doxygen"
status_definition, documentation=DocumentationStyle.doxygen
)


def test_unsupported_documentation_style():
with pytest.raises(ValueError):
CodeGenerator(documentation="invalid")

0 comments on commit f88b5b7

Please sign in to comment.