Skip to content

Commit

Permalink
Merge pull request #22 from pscosta5/translator-class
Browse files Browse the repository at this point in the history
Translator class
  • Loading branch information
paw-lu committed May 9, 2020
2 parents b636c17 + a78a7c2 commit 97b466e
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 28 deletions.
104 changes: 76 additions & 28 deletions src/dressup/converter.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,76 @@
"""Convert Unicode characters."""
import pathlib
import re
from typing import Any, Dict, MutableMapping
from typing import Any, Dict, MutableMapping, Optional

import toml

from . import exceptions


def _read_translator() -> MutableMapping[str, Any]:
class Translator(dict):
"""Translator for converting text to Unicode.
Attributes:
items (Dict[str, str]): Keys and values to prepopulate Translator.
Optional.
strict_case (bool): Whether to forbid characters from being
converted to an upper or lower case counterpart if an exact
match is not found. By default set to False.
"""

def __init__(
self, items: Optional[Dict[str, str]] = None, strict_case: bool = False
) -> None:
"""Constructor."""
if items is not None:
self.update(items)
self.strict_case = strict_case
pass

def __repr__(self) -> str:
"""Representation of Translator."""
dict_repr = (
"{"
+ ", ".join(
": ".join((f"'{item}'", f"'{key}'")) for item, key in self.items()
)
+ "}"
)
return f"Translator({dict_repr}, {self.strict_case})"

def __missing__(self, key: str) -> str:
"""Return value in the case of a missing key.
If ``strict_case`` is True, will return the key itself. If
False, will first try to return a value matching the upper or
lowercase variant of the key.
Args:
key (str): The key missing from Translator.
Returns:
str: The returned value.
"""
if self.strict_case:
return key
else:
if key.upper() in self:
return self[key.upper()]
elif key.lower() in self:
return self[key.lower()]
else:
return key


def _read_translator(strict_case: bool = False) -> MutableMapping[str, Any]:
"""Read translator from config file.
Args:
strict_case (bool): Whether to forbid characters from being
converted to an upper or lower case counterpart if an exact
match is not found. By default set to False.
Returns:
MutableMapping[str, Any]: A dictionary where the keys are the
unicode type, and the values are nested dictionaries with the
Expand All @@ -19,7 +79,11 @@ def _read_translator() -> MutableMapping[str, Any]:
"""
toml_path = pathlib.Path(__file__).parent / pathlib.Path("translator.toml")
toml_text = toml_path.read_text()
translator = toml.loads(toml_text)
unicode_mapping = toml.loads(toml_text)
translator = {
unicode_type: Translator(unicode_mapping[unicode_type], strict_case=strict_case)
for unicode_type in unicode_mapping
}
return translator


Expand Down Expand Up @@ -72,33 +136,17 @@ def show_all(
'Ħɇłłø', 'Subscript': 'ₕₑₗₗₒ', 'Superscript': 'ᴴᵉˡˡᵒ',
'Inverted': 'ɥǝןןo', 'Reversed': 'Hɘ⅃⅃o'}
"""
translator = _read_translator()
translator = _read_translator(strict_case=strict_case)
if reverse:
characters = characters[::-1]
if strict_case:
converted_characters = {
_format_names(character_type): "".join(
translator[normalize_text(character_type)].get(character, character)
for character in characters
)
for character_type in translator
}
else:
converted_characters = {
_format_names(character_type): "".join(
translator[normalize_text(character_type)].get(
character,
translator[normalize_text(character_type)].get(
character.upper(),
translator[normalize_text(character_type)].get(
character.lower(), character
),
),
)
for character in characters
)
for character_type in translator
}
converted_characters = {
_format_names(character_type): "".join(
translator[normalize_text(character_type)][character]
for character in characters
)
for character_type in translator
}

return converted_characters


Expand Down
33 changes: 33 additions & 0 deletions tests/test_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,39 @@
from dressup import converter, exceptions


def test_translator_repr() -> None:
"""Its string representation contains the init parameters."""
translator = converter.Translator({letter: "b" for letter in "ab"}, False)
assert str(translator) == "Translator({'a': 'b', 'b': 'b'}, False)"


def test_default_translatortor() -> None:
"""It returns an empty dictionary when provided to items."""
translator = converter.Translator()
assert translator == {}


def test_strict_case_translator() -> None:
"""It returns the key when no match is found."""
values = {"a": "<3"}
translator = converter.Translator(values, strict_case=True)
assert translator["A"] == "A"


def test_missing_translator_upper() -> None:
"""It returns the upper case match when no match is found."""
values = {"A": "<3"}
translator = converter.Translator(values, strict_case=False)
assert translator["a"] == "<3"


def test_missing_translator_lower() -> None:
"""It returns the lower case match when no match is found."""
values = {"a": "<3"}
translator = converter.Translator(values, strict_case=False)
assert translator["A"] == "<3"


def test_valid_toml() -> None:
"""It is a valid TOML file."""
file_text = pathlib.Path("src/dressup/translator.toml").read_text()
Expand Down

0 comments on commit 97b466e

Please sign in to comment.