Skip to content

Commit

Permalink
Add support for the VBML 'rawCharacters' component field
Browse files Browse the repository at this point in the history
  • Loading branch information
jparise committed Apr 8, 2024
1 parent 7063b41 commit 0243c7f
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
### Added
- All clients now support a user-provided [httpx.Client](https://www.python-httpx.org/api/#client)
objects.
- Add support for the VBML `absolutePosition` style.
- Added support for the VBML `absolutePosition` style.
- Added support for the VBML `rawCharacters` component field.

### Changed
- The `encode_*()` functions now consistently specify keyword-only arguments.
Expand Down
29 changes: 23 additions & 6 deletions src/vesta/vbml.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@

from __future__ import annotations

from typing import Any
from typing import Dict
from typing import Literal
from typing import Mapping
from typing import Optional
from typing import TypedDict

from .chars import Rows

__all__ = ["Component", "Props", "Style"]

#: Map of dynamic properties that can be injected into message templates.
Expand Down Expand Up @@ -87,17 +90,22 @@ class Component:
will be cast to uppercase. A new row can be forced by inserting a newline
(``\\n``) sequence.
Alternatively, a ``raw_characters`` character array can be provided to set
the initial (background) state of the component. ``raw_characters`` takes
precedence over ``template``.
A ``style`` dictionary can be provided. Individual :py:class:`Style` values
can also be given as keyword arguments (``height``, ``width``, ``justify``,
``align``, ``absolute_position``), and they will override any values from
the ``style`` dictionary.
"""

__slots__ = ["template", "style"]
__slots__ = ["template", "raw_characters", "style"]

def __init__(
self,
template: str,
template: Optional[str] = None,
raw_characters: Optional[Rows] = None,
style: Optional[Style] = None,
*,
height: Optional[int] = None,
Expand All @@ -106,7 +114,11 @@ def __init__(
align: Optional[Alignment] = None,
absolute_position: Optional[Position] = None,
):
if not (template is not None or raw_characters is not None):
raise ValueError("expected template or raw_characters")

self.template = template
self.raw_characters = raw_characters
self.style: Style = style or {}
if height is not None:
self.style["height"] = height
Expand All @@ -119,8 +131,13 @@ def __init__(
if absolute_position is not None:
self.style["absolutePosition"] = absolute_position

def asdict(self) -> Dict:
def asdict(self) -> Dict[str, Any]:
"""Returns the component's JSON dictionary representation."""
if not self.style:
return {"template": self.template}
return {"template": self.template, "style": self.style}
d: Dict[str, Any] = {}
if self.raw_characters is not None:
d["rawCharacters"] = self.raw_characters
elif self.template is not None:
d["template"] = self.template
if self.style:
d["style"] = self.style
return d
12 changes: 12 additions & 0 deletions tests/test_vbml.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
import pytest

from vesta.vbml import Component


class TestComponent:
def test_template(self):
assert Component("template").asdict() == {"template": "template"}

def test_raw_characters(self):
assert Component(raw_characters=[]).asdict() == {"rawCharacters": []}

def test_template_and_raw_characters(self):
assert Component("t", raw_characters=[]).asdict() == {"rawCharacters": []}

def test_template_or_raw_characters_required(self):
with pytest.raises(ValueError, match="expected template or raw_characters"):
Component()

def test_style(self):
assert Component("template", style={}).asdict() == {"template": "template"}
assert Component(
Expand Down

0 comments on commit 0243c7f

Please sign in to comment.