diff --git a/pdm.lock b/pdm.lock index 298c0cf..5299e14 100644 --- a/pdm.lock +++ b/pdm.lock @@ -47,7 +47,7 @@ summary = "File identification library for Python" [[package]] name = "importlib-metadata" -version = "4.10.1" +version = "4.11.0" requires_python = ">=3.7" summary = "Read metadata from Python packages" dependencies = [ @@ -118,7 +118,7 @@ summary = "Python parsing module" [[package]] name = "pytest" -version = "7.0.0" +version = "7.0.1" requires_python = ">=3.6" summary = "pytest: simple powerful testing with Python" dependencies = [ @@ -159,7 +159,7 @@ summary = "A lil' TOML parser" [[package]] name = "typing-extensions" -version = "4.0.1" +version = "4.1.0" requires_python = ">=3.6" summary = "Backported and Experimental Type Hints for Python 3.6+" @@ -190,7 +190,7 @@ summary = "Backport of pathlib-compatible object wrapper for zip files" [metadata] lock_version = "3.1" -content_hash = "sha256:5ecc9808abf19a40b79590047aa69bd9956738961234498ed1dd2dc09973e828" +content_hash = "sha256:be80cde9d007abeb2c0d352d9a69fa5aefc29a1345919aebfd5685df9e3b639f" [metadata.files] "atomicwrites 1.4.0" = [ @@ -225,9 +225,9 @@ content_hash = "sha256:5ecc9808abf19a40b79590047aa69bd9956738961234498ed1dd2dc09 {file = "identify-2.4.9-py2.py3-none-any.whl", hash = "sha256:bff7c4959d68510bc28b99d664b6a623e36c6eadc933f89a4e0a9ddff9b4fee4"}, {file = "identify-2.4.9.tar.gz", hash = "sha256:e926ae3b3dc142b6a7a9c65433eb14ccac751b724ee255f7c2ed3b5970d764fb"}, ] -"importlib-metadata 4.10.1" = [ - {file = "importlib_metadata-4.10.1-py3-none-any.whl", hash = "sha256:899e2a40a8c4a1aec681feef45733de8a6c58f3f6a0dbed2eb6574b4387a77b6"}, - {file = "importlib_metadata-4.10.1.tar.gz", hash = "sha256:951f0d8a5b7260e9db5e41d429285b5f451e928479f19d80818878527d36e95e"}, +"importlib-metadata 4.11.0" = [ + {file = "importlib_metadata-4.11.0-py3-none-any.whl", hash = "sha256:6affcdb3aec542dd98df8211e730bba6c5f2bec8288d47bacacde898f548c9ad"}, + {file = "importlib_metadata-4.11.0.tar.gz", hash = "sha256:9e5e553bbba1843cb4a00823014b907616be46ee503d2b9ba001d214a8da218f"}, ] "iniconfig 1.1.1" = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -261,9 +261,9 @@ content_hash = "sha256:5ecc9808abf19a40b79590047aa69bd9956738961234498ed1dd2dc09 {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, ] -"pytest 7.0.0" = [ - {file = "pytest-7.0.0-py3-none-any.whl", hash = "sha256:42901e6bd4bd4a0e533358a86e848427a49005a3256f657c5c8f8dd35ef137a9"}, - {file = "pytest-7.0.0.tar.gz", hash = "sha256:dad48ffda394e5ad9aa3b7d7ddf339ed502e5e365b1350e0af65f4a602344b11"}, +"pytest 7.0.1" = [ + {file = "pytest-7.0.1-py3-none-any.whl", hash = "sha256:9ce3ff477af913ecf6321fe337b93a2c0dcf2a0a1439c43f5452112c1e4280db"}, + {file = "pytest-7.0.1.tar.gz", hash = "sha256:e30905a0c131d3d94b89624a1cc5afec3e0ba2fbdb151867d8e0ebd49850f171"}, ] "pyyaml 6.0" = [ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, @@ -312,9 +312,9 @@ content_hash = "sha256:5ecc9808abf19a40b79590047aa69bd9956738961234498ed1dd2dc09 {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -"typing-extensions 4.0.1" = [ - {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, - {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, +"typing-extensions 4.1.0" = [ + {file = "typing_extensions-4.1.0-py3-none-any.whl", hash = "sha256:c13180fbaa7cd97065a4915ceba012bdb31dc34743e63ddee16360161d358414"}, + {file = "typing_extensions-4.1.0.tar.gz", hash = "sha256:ba97c5143e5bb067b57793c726dd857b1671d4b02ced273ca0538e71ff009095"}, ] "virtualenv 20.13.1" = [ {file = "virtualenv-20.13.1-py2.py3-none-any.whl", hash = "sha256:45e1d053cad4cd453181ae877c4ffc053546ae99e7dd049b9ff1d9be7491abf7"}, diff --git a/pglet/barchart.py b/pglet/barchart.py index 3a26159..bee1d4d 100644 --- a/pglet/barchart.py +++ b/pglet/barchart.py @@ -1,9 +1,15 @@ -from typing import Optional, Union, Literal +from typing import Optional, Union +try: + from typing import Literal +except ImportError: + from typing_extensions import Literal + from beartype import beartype + from pglet.control import Control -DATA_MODE = Literal["default", "fraction", "percentage", None] +DataMode = Literal["default", "fraction", "percentage", None] class BarChart(Control): @@ -11,7 +17,7 @@ def __init__( self, id=None, tooltips=None, - data_mode: DATA_MODE = None, + data_mode: DataMode = None, points=None, width=None, height=None, @@ -65,7 +71,7 @@ def data_mode(self): @data_mode.setter @beartype - def data_mode(self, value: DATA_MODE): + def data_mode(self, value: DataMode): self._set_attr("dataMode", value) def _get_children(self): diff --git a/pglet/callout.py b/pglet/callout.py index d432d56..e77d813 100644 --- a/pglet/callout.py +++ b/pglet/callout.py @@ -1,8 +1,14 @@ -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype import beartype + from pglet.control import Control -POSITION = Literal[ +Position = Literal[ None, "topLeft", "topCenter", @@ -26,7 +32,7 @@ def __init__( self, id=None, target=None, - position: POSITION = None, + position: Position = None, gap=None, beak=None, beak_width=None, @@ -105,7 +111,7 @@ def position(self): @position.setter @beartype - def position(self, value: POSITION): + def position(self, value: Position): self._set_attr("position", value) # gap diff --git a/pglet/checkbox.py b/pglet/checkbox.py index 6145dae..7b5347b 100644 --- a/pglet/checkbox.py +++ b/pglet/checkbox.py @@ -1,8 +1,14 @@ -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype import beartype + from pglet.control import Control -BOX_SIDE = Literal[None, "start", "end"] +BoxSide = Literal[None, "start", "end"] class Checkbox(Control): @@ -12,7 +18,7 @@ def __init__( id=None, value=None, value_field=None, - box_side: BOX_SIDE = None, + box_side: BoxSide = None, focused=None, data=None, width=None, @@ -89,7 +95,7 @@ def box_side(self): @box_side.setter @beartype - def box_side(self, value: BOX_SIDE): + def box_side(self, value: BoxSide): self._set_attr("boxSide", value) # focused diff --git a/pglet/combobox.py b/pglet/combobox.py index 69dfd70..05cfb9c 100644 --- a/pglet/combobox.py +++ b/pglet/combobox.py @@ -1,10 +1,14 @@ -from typing import List, Literal, Optional +from typing import List, Optional +try: + from typing import Literal +except: + from typing_extensions import Literal from beartype import beartype from pglet.control import Control -ITEM_TYPE = Literal[None, "normal", "divider", "header", "selectAll", "select_all"] +ItemType = Literal[None, "normal", "divider", "header", "selectAll", "select_all"] class ComboBox(Control): @@ -183,7 +187,7 @@ def on_blur(self, handler): class Option(Control): - def __init__(self, key=None, text=None, item_type: ITEM_TYPE = None, disabled=None): + def __init__(self, key=None, text=None, item_type: ItemType = None, disabled=None): Control.__init__(self) assert key != None or text != None, "key or text must be specified" self.key = key @@ -219,7 +223,7 @@ def item_type(self): @item_type.setter @beartype - def item_type(self, value: ITEM_TYPE): + def item_type(self, value: ItemType): self._set_attr("itemtype", value) # disabled diff --git a/pglet/connection.py b/pglet/connection.py index 7f08941..036f548 100644 --- a/pglet/connection.py +++ b/pglet/connection.py @@ -3,7 +3,6 @@ import threading import uuid -from pglet.event import Event from pglet.protocol import * from pglet.reconnecting_websocket import ReconnectingWebSocket diff --git a/pglet/control.py b/pglet/control.py index 252f4c4..0885b0d 100644 --- a/pglet/control.py +++ b/pglet/control.py @@ -1,16 +1,22 @@ import datetime as dt import threading -from typing import Literal, Optional -from beartype import beartype +from typing import Optional from difflib import SequenceMatcher +try: + from typing import Literal +except: + from typing_extensions import Literal + +from beartype import beartype + from pglet.protocol import Command -BORDER_STYLE = Literal[ +BorderStyle = Literal[ None, "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset" ] -TEXT_SIZE = Literal[ +TextSize = Literal[ None, "tiny", "xSmall", @@ -25,7 +31,7 @@ "mega", ] -TEXT_ALIGN = Literal[None, "left", "right", "center", "justify"] +TextAlign = Literal[None, "left", "right", "center", "justify"] class Control: diff --git a/pglet/dialog.py b/pglet/dialog.py index 4006ec2..225e2a0 100644 --- a/pglet/dialog.py +++ b/pglet/dialog.py @@ -1,8 +1,14 @@ -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype import beartype + from pglet.control import Control -TYPE = Literal[None, "normal", "largeHeader", "close"] +DialogType = Literal[None, "normal", "largeHeader", "close"] class Dialog(Control): @@ -12,7 +18,7 @@ def __init__( open=None, title=None, sub_text=None, - type: TYPE = None, + type: DialogType = None, auto_dismiss=None, width=None, max_width=None, @@ -117,7 +123,7 @@ def type(self): @type.setter @beartype - def type(self, value: TYPE): + def type(self, value: DialogType): self._set_attr("type", value) # auto_dismiss diff --git a/pglet/dropdown.py b/pglet/dropdown.py index 572388d..ab15a93 100644 --- a/pglet/dropdown.py +++ b/pglet/dropdown.py @@ -1,10 +1,14 @@ -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal from beartype import beartype from pglet.control import Control -ITEM_TYPE = Literal[None, "normal", "divider", "header"] +ItemType = Literal[None, "normal", "divider", "header"] class Dropdown(Control): @@ -142,7 +146,7 @@ def on_blur(self, handler): class Option(Control): - def __init__(self, key=None, text=None, item_type: ITEM_TYPE = None, disabled=None): + def __init__(self, key=None, text=None, item_type: ItemType = None, disabled=None): Control.__init__(self) assert key != None or text != None, "key or text must be specified" self.key = key @@ -178,7 +182,7 @@ def item_type(self): @item_type.setter @beartype - def item_type(self, value: ITEM_TYPE): + def item_type(self, value: ItemType): self._set_attr("itemtype", value) # disabled diff --git a/pglet/grid.py b/pglet/grid.py index 640ac26..2ff1c94 100644 --- a/pglet/grid.py +++ b/pglet/grid.py @@ -1,20 +1,25 @@ from __future__ import annotations -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal from beartype import beartype + from pglet.control import Control -SELECTION_MODE = Literal[None, "single", "multiple"] -SORTABLE = Literal[None, "string", "number", False] -SORTED = Literal[None, False, "asc", "desc"] +SelectionMode = Literal[None, "single", "multiple"] +Sortable = Literal[None, "string", "number", False] +Sorted = Literal[None, False, "asc", "desc"] class Grid(Control): def __init__( self, id=None, - selection_mode: SELECTION_MODE = None, + selection_mode: SelectionMode = None, compact=None, header_visible=None, shimmer_lines=None, @@ -116,7 +121,7 @@ def selection_mode(self): @selection_mode.setter @beartype - def selection_mode(self, value: SELECTION_MODE): + def selection_mode(self, value: SelectionMode): self._set_attr("selection", value) # compact @@ -228,9 +233,9 @@ def __init__( icon=None, icon_only=None, field_name=None, - sortable: SORTABLE = None, + sortable: Sortable = None, sort_field=None, - sorted: SORTED = None, + sorted: Sorted = None, resizable=None, min_width=None, max_width=None, @@ -300,7 +305,7 @@ def sortable(self): @sortable.setter @beartype - def sortable(self, value: SORTABLE): + def sortable(self, value: Sortable): self._set_attr("sortable", value) # sort_field @@ -319,7 +324,7 @@ def sorted(self): @sorted.setter @beartype - def sorted(self, value: SORTED): + def sorted(self, value: Sorted): self._set_attr("sorted", value) # resizable diff --git a/pglet/iframe.py b/pglet/iframe.py index eeda747..e85e91c 100644 --- a/pglet/iframe.py +++ b/pglet/iframe.py @@ -1,5 +1,5 @@ from beartype import beartype -from pglet.control import Control, BORDER_STYLE +from pglet.control import Control, BorderStyle class IFrame(Control): @@ -8,7 +8,7 @@ def __init__( id=None, src=None, border=None, - border_style: BORDER_STYLE = None, + border_style: BorderStyle = None, border_width=None, border_color=None, border_radius=None, @@ -68,7 +68,7 @@ def border_style(self): @border_style.setter @beartype - def border_style(self, value: BORDER_STYLE): + def border_style(self, value: BorderStyle): self._set_attr("borderStyle", value) # border_width diff --git a/pglet/image.py b/pglet/image.py index 4b3e709..7d8b5e2 100644 --- a/pglet/image.py +++ b/pglet/image.py @@ -1,8 +1,14 @@ -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype import beartype -from pglet.control import Control, BORDER_STYLE -FIT = Literal[ +from pglet.control import Control, BorderStyle + +Fit = Literal[ None, "none", "contain", "cover", "center", "centerContain", "centerCover" ] @@ -15,8 +21,8 @@ def __init__( alt=None, title=None, maximize_frame=None, - fit: FIT = None, - border_style: BORDER_STYLE = None, + fit: Fit = None, + border_style: BorderStyle = None, border_width=None, border_color=None, border_radius=None, @@ -96,7 +102,7 @@ def fit(self): @fit.setter @beartype - def fit(self, value: FIT): + def fit(self, value: Fit): self._set_attr("fit", value) # border_style @@ -106,7 +112,7 @@ def border_style(self): @border_style.setter @beartype - def border_style(self, value: BORDER_STYLE): + def border_style(self, value: BorderStyle): self._set_attr("borderStyle", value) # border_width diff --git a/pglet/linechart.py b/pglet/linechart.py index bb24d9d..83fdbf9 100644 --- a/pglet/linechart.py +++ b/pglet/linechart.py @@ -1,8 +1,14 @@ -from typing import Literal, Optional, Union +from typing import Optional, Union +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype import beartype + from pglet.control import Control -X_TYPE = Literal[None, "number", "date"] +XType = Literal[None, "number", "date"] class LineChart(Control): @@ -16,7 +22,7 @@ def __init__( y_max=None, y_ticks=None, y_format=None, - x_type: X_TYPE = None, + x_type: XType = None, lines=None, width=None, height=None, @@ -139,7 +145,7 @@ def x_type(self): @x_type.setter @beartype - def x_type(self, value: X_TYPE): + def x_type(self, value: XType): self._set_attr("xType", value) def _get_children(self): diff --git a/pglet/link.py b/pglet/link.py index bc72bdb..9851c78 100644 --- a/pglet/link.py +++ b/pglet/link.py @@ -1,6 +1,8 @@ -from typing import Literal, Optional +from typing import Optional + from beartype import beartype -from pglet.control import Control, TEXT_ALIGN + +from pglet.control import Control, TextAlign class Link(Control): @@ -15,7 +17,7 @@ def __init__( bold=None, italic=None, pre=None, - align: TEXT_ALIGN = None, + align: TextAlign = None, on_click=None, controls=None, width=None, @@ -158,7 +160,7 @@ def align(self): @align.setter @beartype - def align(self, value: TEXT_ALIGN): + def align(self, value: TextAlign): self._set_attr("align", value) def _get_children(self): diff --git a/pglet/message.py b/pglet/message.py index c60ae26..867144e 100644 --- a/pglet/message.py +++ b/pglet/message.py @@ -1,15 +1,21 @@ -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype import beartype + from pglet.control import Control -TYPE = Literal[None, "info", "error", "blocked", "severeWarning", "success", "warning"] +MessageType = Literal[None, "info", "error", "blocked", "severeWarning", "success", "warning"] class Message(Control): def __init__( self, value=None, - type: TYPE = None, + type: MessageType = None, id=None, multiline=None, truncated=None, @@ -85,7 +91,7 @@ def type(self): @type.setter @beartype - def type(self, value: TYPE): + def type(self, value: MessageType): self._set_attr("type", value) # multiline diff --git a/pglet/nav.py b/pglet/nav.py index 817f7e5..4a88ba0 100644 --- a/pglet/nav.py +++ b/pglet/nav.py @@ -1,5 +1,7 @@ from typing import Optional + from beartype import beartype + from pglet.control import Control diff --git a/pglet/page.py b/pglet/page.py index 9b1d0b1..7db5004 100644 --- a/pglet/page.py +++ b/pglet/page.py @@ -1,7 +1,11 @@ import json import logging import threading -from typing import List, Literal, Optional +from typing import List, Optional +try: + from typing import Literal +except: + from typing_extensions import Literal from beartype import beartype @@ -11,7 +15,7 @@ from pglet.control_event import ControlEvent from pglet.protocol import Command -ALIGN = Literal[ +Align = Literal[ None, "start", "end", @@ -271,7 +275,7 @@ def horizontal_align(self): @horizontal_align.setter @beartype - def horizontal_align(self, value: ALIGN): + def horizontal_align(self, value: Align): self._set_attr("horizontalAlign", value) # vertical_align @@ -281,7 +285,7 @@ def vertical_align(self): @vertical_align.setter @beartype - def vertical_align(self, value: ALIGN): + def vertical_align(self, value: Align): self._set_attr("verticalAlign", value) # gap diff --git a/pglet/panel.py b/pglet/panel.py index 6566cd9..0ec5b52 100644 --- a/pglet/panel.py +++ b/pglet/panel.py @@ -1,9 +1,14 @@ -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype import beartype from pglet.control import Control -TYPE = Literal[ +PanelType = Literal[ None, "small", "smallLeft", @@ -23,7 +28,7 @@ def __init__( id=None, open=None, title=None, - type: TYPE = None, + type: PanelType = None, auto_dismiss=None, light_dismiss=None, width=None, @@ -117,7 +122,7 @@ def type(self): @type.setter @beartype - def type(self, value: TYPE): + def type(self, value: PanelType): self._set_attr("type", value) # auto_dismiss diff --git a/pglet/persona.py b/pglet/persona.py index e654fd9..9a01e67 100644 --- a/pglet/persona.py +++ b/pglet/persona.py @@ -1,12 +1,18 @@ -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal from beartype import beartype from pglet.control import Control -SIZE = Literal[None, 8, 24, 32, 40, 48, 56, 72, 100, 120] -PRESENCE = Literal[None, "none", "offline", "online", "away", "blocked", "busy", "dnd"] -INITIALS_COLOR = Literal[ +Size = Literal[None, 8, 24, 32, 40, 48, 56, 72, 100, 120] + +Presence = Literal[None, "none", "offline", "online", "away", "blocked", "busy", "dnd"] + +InitialsColor = Literal[ None, "blue", "burgundy", @@ -40,13 +46,13 @@ def __init__( id=None, image_url=None, image_alt=None, - initials_color: INITIALS_COLOR = None, + initials_color: InitialsColor = None, initials_text_color=None, secondary_text=None, tertiary_text=None, optional_text=None, - size: SIZE = None, - presence: PRESENCE = None, + size: Size = None, + presence: Presence = None, hide_details=None, visible=None, ): @@ -102,7 +108,7 @@ def initials_color(self): @initials_color.setter @beartype - def initials_color(self, value: INITIALS_COLOR): + def initials_color(self, value: InitialsColor): self._set_attr("initialscolor", value) # initials_text_color @@ -148,7 +154,7 @@ def size(self): @size.setter @beartype - def size(self, value: SIZE): + def size(self, value: Size): self._set_attr("size", value) # presence @@ -158,7 +164,7 @@ def presence(self): @presence.setter @beartype - def presence(self, value: PRESENCE): + def presence(self, value: Presence): self._set_attr("presence", value) # hide_details diff --git a/pglet/spinbutton.py b/pglet/spinbutton.py index 1a1960e..bfe3867 100644 --- a/pglet/spinbutton.py +++ b/pglet/spinbutton.py @@ -1,10 +1,14 @@ -from typing import Literal, Optional, Union +from typing import Optional, Union +try: + from typing import Literal +except: + from typing_extensions import Literal from beartype import beartype from pglet.control import Control -POSITION = Literal[None, "left", "top", "right", "bottom"] +Position = Literal[None, "left", "top", "right", "bottom"] class SpinButton(Control): @@ -17,7 +21,7 @@ def __init__( max=None, step=None, icon=None, - label_position: POSITION = None, + label_position: Position = None, focused=None, data=None, on_change=None, @@ -91,7 +95,7 @@ def label_position(self): @label_position.setter @beartype - def label_position(self, value: POSITION): + def label_position(self, value: Position): self._set_attr("labelposition", value) # min diff --git a/pglet/spinner.py b/pglet/spinner.py index 9606aef..2de9b5a 100644 --- a/pglet/spinner.py +++ b/pglet/spinner.py @@ -1,8 +1,13 @@ -from typing import Literal +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype._decor.main import beartype + from pglet.control import Control -POSITION = Literal[None, "left", "top", "right", "bottom"] +Position = Literal[None, "left", "top", "right", "bottom"] class Spinner(Control): @@ -10,7 +15,7 @@ def __init__( self, label=None, id=None, - label_position: POSITION = None, + label_position: Position = None, size=None, width=None, height=None, @@ -61,5 +66,5 @@ def label_position(self): @label_position.setter @beartype - def label_position(self, value: POSITION): + def label_position(self, value: Position): self._set_attr("labelPosition", value) diff --git a/pglet/stack.py b/pglet/stack.py index 77d608d..9ed886a 100644 --- a/pglet/stack.py +++ b/pglet/stack.py @@ -1,8 +1,14 @@ -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype import beartype -from pglet.control import Control, BORDER_STYLE -ALIGN = Literal[ +from pglet.control import Control, BorderStyle + +Align = Literal[ None, "start", "end", @@ -22,8 +28,8 @@ def __init__( id=None, horizontal=None, vertical_fill=None, - horizontal_align: ALIGN = None, - vertical_align: ALIGN = None, + horizontal_align: Align = None, + vertical_align: Align = None, min_width=None, max_width=None, min_height=None, @@ -31,7 +37,7 @@ def __init__( gap=None, wrap=None, bgcolor=None, - border_style: BORDER_STYLE = None, + border_style: BorderStyle = None, border_width=None, border_color=None, border_radius=None, @@ -127,7 +133,7 @@ def horizontal_align(self): @horizontal_align.setter @beartype - def horizontal_align(self, value: ALIGN): + def horizontal_align(self, value: Align): self._set_attr("horizontalAlign", value) # vertical_align @@ -137,7 +143,7 @@ def vertical_align(self): @vertical_align.setter @beartype - def vertical_align(self, value: ALIGN): + def vertical_align(self, value: Align): self._set_attr("verticalAlign", value) # min_width @@ -211,7 +217,7 @@ def border_style(self): @border_style.setter @beartype - def border_style(self, value: BORDER_STYLE): + def border_style(self, value: BorderStyle): self._set_attr("borderStyle", value) # border_width diff --git a/pglet/text.py b/pglet/text.py index 77692e1..4271cd9 100644 --- a/pglet/text.py +++ b/pglet/text.py @@ -1,8 +1,14 @@ -from typing import Literal, Optional +from typing import Optional +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype import beartype -from pglet.control import Control, BORDER_STYLE, TEXT_SIZE, TEXT_ALIGN -VERTICAL_ALIGN = Literal[None, "top", "center", "bottom"] +from pglet.control import Control, BorderStyle, TextSize, TextAlign + +VerticalAlign = Literal[None, "top", "center", "bottom"] class Text(Control): @@ -11,9 +17,9 @@ def __init__( value=None, id=None, markdown=None, - align: TEXT_ALIGN = None, - vertical_align: VERTICAL_ALIGN = None, - size: TEXT_SIZE = None, + align: TextAlign = None, + vertical_align: VerticalAlign = None, + size: TextSize = None, bold=None, italic=None, pre=None, @@ -21,7 +27,7 @@ def __init__( block=None, color=None, bgcolor=None, - border_style: BORDER_STYLE = None, + border_style: BorderStyle = None, border_width=None, border_color=None, border_radius=None, @@ -90,7 +96,7 @@ def align(self): @align.setter @beartype - def align(self, value: TEXT_ALIGN): + def align(self, value: TextAlign): self._set_attr("align", value) # vertical_align @@ -100,7 +106,7 @@ def vertical_align(self): @vertical_align.setter @beartype - def vertical_align(self, value: VERTICAL_ALIGN): + def vertical_align(self, value: VerticalAlign): self._set_attr("verticalAlign", value) # size @@ -110,7 +116,7 @@ def size(self): @size.setter @beartype - def size(self, value: TEXT_SIZE): + def size(self, value: TextSize): self._set_attr("size", value) # bold @@ -188,7 +194,7 @@ def border_style(self): @border_style.setter @beartype - def border_style(self, value: BORDER_STYLE): + def border_style(self, value: BorderStyle): self._set_attr("borderStyle", value) # border_width diff --git a/pglet/textbox.py b/pglet/textbox.py index 526282f..24f0f9e 100644 --- a/pglet/textbox.py +++ b/pglet/textbox.py @@ -2,7 +2,7 @@ from beartype import beartype -from pglet.control import TEXT_ALIGN, Control +from pglet.control import TextAlign, Control class Textbox(Control): @@ -33,7 +33,7 @@ def __init__( height=None, padding=None, margin=None, - align: TEXT_ALIGN = None, + align: TextAlign = None, visible=None, disabled=None, ): @@ -160,7 +160,7 @@ def align(self): @align.setter @beartype - def align(self, value: TEXT_ALIGN): + def align(self, value: TextAlign): self._set_attr("align", value) # multiline diff --git a/pglet/verticalbarchart.py b/pglet/verticalbarchart.py index 57e2c88..c3c23f2 100644 --- a/pglet/verticalbarchart.py +++ b/pglet/verticalbarchart.py @@ -1,8 +1,14 @@ -from typing import Optional, Union, Literal +from typing import Optional, Union +try: + from typing import Literal +except: + from typing_extensions import Literal + from beartype import beartype + from pglet.control import Control -X_TYPE = Literal[None, "string", "number"] +XType = Literal[None, "string", "number"] class VerticalBarChart(Control): @@ -17,7 +23,7 @@ def __init__( y_max=None, y_ticks=None, y_format=None, - x_type: X_TYPE = None, + x_type: XType = None, points=None, width=None, height=None, @@ -136,7 +142,7 @@ def x_type(self): @x_type.setter @beartype - def x_type(self, value: X_TYPE): + def x_type(self, value: XType): self._set_attr("xType", value) # bar_width diff --git a/pyproject.toml b/pyproject.toml index 61fc478..1d2cdb0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ authors = [ dependencies = [ "websocket-client>=1.2.1", "beartype>=0.9.1", + 'typing_extensions; python_version < "3.8"' ] requires-python = ">=3.7" license = { text = "MIT" } diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..a473d4d --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,7 @@ +import pglet +import pytest + + +@pytest.fixture +def page(): + return pglet.page("test_update", no_window=True) diff --git a/tests/test_barchart.py b/tests/test_barchart.py index 3679c23..d853f20 100644 --- a/tests/test_barchart.py +++ b/tests/test_barchart.py @@ -1,6 +1,7 @@ import pglet from pglet import BarChart from pglet.barchart import Point +from pglet.protocol import Command def test_barchart_add(): @@ -22,10 +23,31 @@ def test_barchart_add(): ) assert isinstance(bc, pglet.Control) assert isinstance(bc, pglet.BarChart) - assert bc.get_cmd_str() == ( - 'barchart datamode="default" tooltips="false"\n' - " data\n" - ' p color="green" legend="legend" x="1" xtooltip="x tooltip" y="100" ytooltip="y tooltip"\n' - ' p x="80" y="200"\n' - ' p x="100" y="300"' - ), "Test failed" + assert bc.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["barchart"], + attrs={"datamode": "default", "tooltips": "false"}, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["data"], attrs={}, lines=[], commands=[]), + Command( + indent=4, + name=None, + values=["p"], + attrs={ + "color": "green", + "legend": "legend", + "x": "1", + "xtooltip": "x tooltip", + "y": "100", + "ytooltip": "y tooltip", + }, + lines=[], + commands=[], + ), + Command(indent=4, name=None, values=["p"], attrs={"x": "80", "y": "200"}, lines=[], commands=[]), + Command(indent=4, name=None, values=["p"], attrs={"x": "100", "y": "300"}, lines=[], commands=[]), + ], "Test failed" diff --git a/tests/test_button.py b/tests/test_button.py index 542bed9..4193fe7 100644 --- a/tests/test_button.py +++ b/tests/test_button.py @@ -1,6 +1,7 @@ import pglet import pytest from pglet import Button, button +from pglet.protocol import Command def test_button_primary_must_be_bool(): @@ -12,9 +13,16 @@ def test_button_add(): b = Button(id="button1", text="My button", primary=True, data="this is data") assert isinstance(b, pglet.Control) assert isinstance(b, pglet.Button) - assert b.get_cmd_str() == ( - 'button id="button1" data="this is data" primary="true" text="My button"' - ), "Test failed" + assert b.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["button"], + attrs={"data": "this is data", "primary": "true", "text": "My button", "id": ("button1", True)}, + lines=[], + commands=[], + ) + ], "Test failed" def test_button_with_all_properties(): @@ -54,13 +62,48 @@ def test_button_with_all_properties(): assert isinstance(b, pglet.Control) assert isinstance(b, pglet.Button) - assert b.get_cmd_str() == ( - 'button action="false" compound="false" data="data" icon="Mail" ' - 'iconcolor="red" newwindow="true" primary="false" secondarytext="This is secondary text" ' - 'split="false" text="This is text" title="This is title" toolbar="true" url="https://google.com"\n' - ' item divider="false" icon="Mail" iconcolor="blue" icononly="true" newwindow="false" ' - 'secondarytext="Item1 secondary text" split="false" text="Item1 text" url="https://google.com"\n' - ' item text="Item1Item1"\n' - ' item text="Item1Item2"\n' - ' item text="Item2 text"' - ), "Test failed" + assert b.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["button"], + attrs={ + "action": "false", + "compound": "false", + "data": "data", + "icon": "Mail", + "iconcolor": "red", + "newwindow": "true", + "primary": "false", + "secondarytext": "This is secondary text", + "split": "false", + "text": "This is text", + "title": "This is title", + "toolbar": "true", + "url": "https://google.com", + }, + lines=[], + commands=[], + ), + Command( + indent=2, + name=None, + values=["item"], + attrs={ + "divider": "false", + "icon": "Mail", + "iconcolor": "blue", + "icononly": "true", + "newwindow": "false", + "secondarytext": "Item1 secondary text", + "split": "false", + "text": "Item1 text", + "url": "https://google.com", + }, + lines=[], + commands=[], + ), + Command(indent=4, name=None, values=["item"], attrs={"text": "Item1Item1"}, lines=[], commands=[]), + Command(indent=4, name=None, values=["item"], attrs={"text": "Item1Item2"}, lines=[], commands=[]), + Command(indent=2, name=None, values=["item"], attrs={"text": "Item2 text"}, lines=[], commands=[]), + ], "Test failed" diff --git a/tests/test_callout.py b/tests/test_callout.py index ee07991..3d8b871 100644 --- a/tests/test_callout.py +++ b/tests/test_callout.py @@ -1,5 +1,6 @@ import pglet from pglet import Callout, Text +from pglet.protocol import Command def test_callout_add(): @@ -18,8 +19,24 @@ def test_callout_add(): assert isinstance(c, pglet.Control) assert isinstance(c, pglet.Callout) - assert c.get_cmd_str() == ( - 'callout beak="true" beakwidth="10" cover="true" focus="false" gap="100" pagepadding="10" ' - 'position="leftBottom" target="button1" visible="true"\n' - ' text value="This is callout"' - ), "Test failed" + assert c.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["callout"], + attrs={ + "beak": "true", + "beakwidth": "10", + "cover": "true", + "focus": "false", + "gap": "100", + "pagepadding": "10", + "position": "leftBottom", + "target": "button1", + "visible": "true", + }, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["text"], attrs={"value": "This is callout"}, lines=[], commands=[]), + ], "Test failed" diff --git a/tests/test_checkbox.py b/tests/test_checkbox.py index fe01e98..c212bd5 100644 --- a/tests/test_checkbox.py +++ b/tests/test_checkbox.py @@ -1,15 +1,19 @@ import pglet from pglet import Checkbox +from pglet.protocol import Command def test_checkbox_add(): - c = Checkbox( - label="Do you agree?", value=True, visible=True, box_side="side1", data="data1" - ) + c = Checkbox(label="Do you agree?", value=True, visible=True, box_side="start", data="data1") assert isinstance(c, pglet.Control) assert isinstance(c, pglet.Checkbox) - # raise Exception(s.get_cmd_str()) - assert c.get_cmd_str() == ( - 'checkbox boxside="side1" data="data1" label="Do you agree?" ' - 'value="true" visible="true"' - ), "Test failed" + assert c.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["checkbox"], + attrs={"boxside": "start", "data": "data1", "label": "Do you agree?", "value": "true", "visible": "true"}, + lines=[], + commands=[], + ) + ], "Test failed" diff --git a/tests/test_choicegroup.py b/tests/test_choicegroup.py index fd3635f..7a81fd4 100644 --- a/tests/test_choicegroup.py +++ b/tests/test_choicegroup.py @@ -1,5 +1,6 @@ import pglet from pglet.choicegroup import Option +from pglet.protocol import Command def test_option(): @@ -21,11 +22,25 @@ def test_choicegroup(): assert isinstance(cg, pglet.Control) assert isinstance(cg, pglet.ChoiceGroup) - assert cg.get_cmd_str() == ( - 'choicegroup id="list1" label="Your favorite color:" value="list1"\n' - ' option icon="Shop" iconcolor="Green" key="key1" text="value1"\n' - ' option key="key2" text="value2"' - ), "Test failed" + assert cg.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["choicegroup"], + attrs={"label": "Your favorite color:", "value": "list1", "id": ("list1", True)}, + lines=[], + commands=[], + ), + Command( + indent=2, + name=None, + values=["option"], + attrs={"icon": "Shop", "iconcolor": "Green", "key": "key1", "text": "value1"}, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["option"], attrs={"key": "key2", "text": "value2"}, lines=[], commands=[]), + ], "Test failed" cgo = Option("key1") assert isinstance(cgo, Option) @@ -37,11 +52,18 @@ def test_choicegroup_with_just_keys(): label="Your favorite color:", options=[Option(key="key1"), Option(key="key2")], ) - assert cg.get_cmd_str(indent=" ") == ( - ' choicegroup id="list1" label="Your favorite color:"\n' - ' option key="key1"\n' - ' option key="key2"' - ), "Test failed" + assert cg.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["choicegroup"], + attrs={"label": "Your favorite color:", "id": ("list1", True)}, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["option"], attrs={"key": "key1"}, lines=[], commands=[]), + Command(indent=2, name=None, values=["option"], attrs={"key": "key2"}, lines=[], commands=[]), + ], "Test failed" cgo = Option("key1") assert isinstance(cgo, Option) diff --git a/tests/test_dialog.py b/tests/test_dialog.py index 0e77756..65bed1c 100644 --- a/tests/test_dialog.py +++ b/tests/test_dialog.py @@ -1,5 +1,6 @@ import pglet from pglet import Button, Dialog, Text +from pglet.protocol import Command def test_dialog_add(): @@ -21,12 +22,29 @@ def test_dialog_add(): assert isinstance(d, pglet.Control) assert isinstance(d, pglet.Dialog) - assert d.get_cmd_str() == ( - 'dialog autodismiss="true" blocking="false" data="data1" fixedtop="true" ' - 'height="100" maxwidth="200" open="true" subtext="sub_text1" ' - 'title="Hello" type="close" width="100"\n' - ' text value="Are you sure?"\n' - " footer\n" - ' button text="OK"\n' - ' button text="Cancel"' - ), "Test failed" + assert d.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["dialog"], + attrs={ + "autodismiss": "true", + "blocking": "false", + "data": "data1", + "fixedtop": "true", + "height": "100", + "maxwidth": "200", + "open": "true", + "subtext": "sub_text1", + "title": "Hello", + "type": "close", + "width": "100", + }, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["text"], attrs={"value": "Are you sure?"}, lines=[], commands=[]), + Command(indent=2, name=None, values=["footer"], attrs={}, lines=[], commands=[]), + Command(indent=4, name=None, values=["button"], attrs={"text": "OK"}, lines=[], commands=[]), + Command(indent=4, name=None, values=["button"], attrs={"text": "Cancel"}, lines=[], commands=[]), + ], "Test failed" diff --git a/tests/test_dropdown.py b/tests/test_dropdown.py index 3f44efe..e7805ee 100644 --- a/tests/test_dropdown.py +++ b/tests/test_dropdown.py @@ -1,5 +1,6 @@ import pglet from pglet.dropdown import Option +from pglet.protocol import Command def test_option(): @@ -17,11 +18,18 @@ def test_dropdown(): assert isinstance(dd, pglet.Control) assert isinstance(dd, pglet.Dropdown) - assert dd.get_cmd_str() == ( - 'dropdown id="list1" label="Your favorite color:"\n' - ' option key="key1" text="value1"\n' - ' option key="key2" text="value2"' - ), "Test failed" + assert dd.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["dropdown"], + attrs={"label": "Your favorite color:", "id": ("list1", True)}, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["option"], attrs={"key": "key1", "text": "value1"}, lines=[], commands=[]), + Command(indent=2, name=None, values=["option"], attrs={"key": "key2", "text": "value2"}, lines=[], commands=[]), + ], "Test failed" do = Option("key1") assert isinstance(do, Option) @@ -33,11 +41,18 @@ def test_dropdown_with_just_keys(): label="Your favorite color:", options=[Option(key="key1"), Option(key="key2")], ) - assert dd.get_cmd_str(indent=" ") == ( - ' dropdown id="list1" label="Your favorite color:"\n' - ' option key="key1"\n' - ' option key="key2"' - ), "Test failed" + assert dd.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["dropdown"], + attrs={"label": "Your favorite color:", "id": ("list1", True)}, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["option"], attrs={"key": "key1"}, lines=[], commands=[]), + Command(indent=2, name=None, values=["option"], attrs={"key": "key2"}, lines=[], commands=[]), + ], "Test failed" do = Option("key1") assert isinstance(do, Option) diff --git a/tests/test_grid.py b/tests/test_grid.py index 0757fc8..7dd50db 100644 --- a/tests/test_grid.py +++ b/tests/test_grid.py @@ -16,12 +16,7 @@ def __init__(self, first_name, last_name): indent=0, name=None, values=["grid"], - attrs={ - "compact": "true", - "headervisible": "true", - "selection": "multiple", - "shimmerlines": "1", - }, + attrs={"compact": "true", "headervisible": "true", "selection": "multiple", "shimmerlines": "1"}, lines=[], commands=[], ), @@ -38,7 +33,7 @@ def __init__(self, first_name, last_name): "minwidth": "100", "name": "First name", "resizable": "false", - "sortable": "True", + "sortable": "string", "sorted": "false", "sortfield": "sort field name", }, @@ -85,9 +80,9 @@ def test_grid_add__with_class(): name="First name", icon="mail", icon_only=True, - sortable="True", + sortable="string", sort_field="sort field name", - sorted="false", + sorted=False, resizable=False, min_width=100, max_width=200, @@ -117,9 +112,9 @@ def test_grid_add__with_dict(): name="First name", icon="mail", icon_only=True, - sortable="True", + sortable="string", sort_field="sort field name", - sorted="false", + sorted=False, resizable=False, min_width=100, max_width=200, diff --git a/tests/test_icon.py b/tests/test_icon.py index 211241d..e3aa42d 100644 --- a/tests/test_icon.py +++ b/tests/test_icon.py @@ -1,5 +1,6 @@ import pglet from pglet import Icon +from pglet.protocol import Command def test_icon_add(): @@ -7,6 +8,13 @@ def test_icon_add(): assert isinstance(c, pglet.Control) assert isinstance(c, pglet.Icon) # raise Exception(s.get_cmd_str()) - assert c.get_cmd_str() == ( - 'icon color="#FF7F50" name="Mail" size="tiny"' - ), "Test failed" + assert c.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["icon"], + attrs={"color": "#FF7F50", "name": "Mail", "size": "tiny"}, + lines=[], + commands=[], + ) + ], "Test failed" diff --git a/tests/test_image.py b/tests/test_image.py index 9612a8a..3e3ce04 100644 --- a/tests/test_image.py +++ b/tests/test_image.py @@ -1,5 +1,6 @@ import pglet from pglet import Image +from pglet.protocol import Command def test_image_add(): @@ -11,7 +12,18 @@ def test_image_add(): ) assert isinstance(i, pglet.Control) assert isinstance(i, pglet.Image) - assert i.get_cmd_str() == ( - 'image alt="This is image" maximizeframe="false" ' - 'src="https://www.w3schools.com/css/img_5terre.jpg" title="This is title"' - ), "Test failed" + assert i.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["image"], + attrs={ + "alt": "This is image", + "maximizeframe": "false", + "src": "https://www.w3schools.com/css/img_5terre.jpg", + "title": "This is title", + }, + lines=[], + commands=[], + ) + ], "Test failed" diff --git a/tests/test_linechart.py b/tests/test_linechart.py index 4a05141..0b19bf2 100644 --- a/tests/test_linechart.py +++ b/tests/test_linechart.py @@ -1,6 +1,7 @@ import pglet from pglet import LineChart from pglet.linechart import Data, Point +from pglet.protocol import Command def test_verticalbarchart_add(): @@ -28,13 +29,42 @@ def test_verticalbarchart_add(): ) assert isinstance(lc, pglet.Control) assert isinstance(lc, pglet.LineChart) - assert lc.get_cmd_str() == ( - 'linechart legend="true" strokewidth="4" tooltips="true" xtype="number" ' - 'yformat="{y}%" ymax="100" ymin="0" yticks="2"\n' - ' data color="yellow" legend="yellow color"\n' - ' p x="1" y="100"\n' - ' p x="5" y="50"\n' - ' data color="green" legend="green color"\n' - ' p x="10" y="20"\n' - ' p x="20" y="10"' - ), "Test failed" + assert lc.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["linechart"], + attrs={ + "legend": "true", + "strokewidth": "4", + "tooltips": "true", + "xtype": "number", + "yformat": "{y}%", + "ymax": "100", + "ymin": "0", + "yticks": "2", + }, + lines=[], + commands=[], + ), + Command( + indent=2, + name=None, + values=["data"], + attrs={"color": "yellow", "legend": "yellow color"}, + lines=[], + commands=[], + ), + Command(indent=4, name=None, values=["p"], attrs={"x": "1", "y": "100"}, lines=[], commands=[]), + Command(indent=4, name=None, values=["p"], attrs={"x": "5", "y": "50"}, lines=[], commands=[]), + Command( + indent=2, + name=None, + values=["data"], + attrs={"color": "green", "legend": "green color"}, + lines=[], + commands=[], + ), + Command(indent=4, name=None, values=["p"], attrs={"x": "10", "y": "20"}, lines=[], commands=[]), + Command(indent=4, name=None, values=["p"], attrs={"x": "20", "y": "10"}, lines=[], commands=[]), + ], "Test failed" diff --git a/tests/test_link.py b/tests/test_link.py index 9f13949..d1250a9 100644 --- a/tests/test_link.py +++ b/tests/test_link.py @@ -1,5 +1,6 @@ import pglet from pglet import Link, Text +from pglet.protocol import Command """ def test_button_primary_must_be_bool(): @@ -13,9 +14,16 @@ def test_link_add(): l = Link(value="search", url="http://google.com", align="left", new_window=True) assert isinstance(l, pglet.Control) assert isinstance(l, pglet.Link) - assert l.get_cmd_str() == ( - 'link align="left" newwindow="true" url="http://google.com" value="search"' - ), "Test failed" + assert l.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["link"], + attrs={"align": "left", "newwindow": "true", "url": "http://google.com", "value": "search"}, + lines=[], + commands=[], + ) + ], "Test failed" def test_link_with_controls(): @@ -31,9 +39,23 @@ def test_link_with_controls(): ) assert isinstance(l, pglet.Control) assert isinstance(l, pglet.Link) - assert l.get_cmd_str() == ( - 'link align="right" pre="true" size="large1" title="Link title" ' - 'url="https://google.com" value="Visit google" width="100"\n' - ' text value="LinkText1"\n' - ' text value="LinkText2"' - ), "Test failed" + assert l.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["link"], + attrs={ + "align": "right", + "pre": "true", + "size": "large1", + "title": "Link title", + "url": "https://google.com", + "value": "Visit google", + "width": "100", + }, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["text"], attrs={"value": "LinkText1"}, lines=[], commands=[]), + Command(indent=2, name=None, values=["text"], attrs={"value": "LinkText2"}, lines=[], commands=[]), + ], "Test failed" diff --git a/tests/test_message.py b/tests/test_message.py index 6e74e76..c1422c5 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -1,5 +1,6 @@ import pglet from pglet.message import MessageButton +from pglet.protocol import Command def test_button(): @@ -20,11 +21,32 @@ def test_message(): assert isinstance(m, pglet.Control) assert isinstance(m, pglet.Message) - assert m.get_cmd_str() == ( - 'message dismiss="true" value="This is message"\n' - ' button action="Yes" text="Yes, I agree"\n' - ' button action="No" text="No, I disagree"' - ), "Test failed" + assert m.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["message"], + attrs={"dismiss": "true", "value": "This is message"}, + lines=[], + commands=[], + ), + Command( + indent=2, + name=None, + values=["button"], + attrs={"action": "Yes", "text": "Yes, I agree"}, + lines=[], + commands=[], + ), + Command( + indent=2, + name=None, + values=["button"], + attrs={"action": "No", "text": "No, I disagree"}, + lines=[], + commands=[], + ), + ], "Test failed" def test_message_button_with_just_text(): @@ -39,8 +61,15 @@ def test_message_button_with_just_text(): assert isinstance(m, pglet.Control) assert isinstance(m, pglet.Message) - assert m.get_cmd_str() == ( - 'message dismiss="true" value="This is message"\n' - ' button text="Yes, I agree"\n' - ' button text="No, I disagree"' - ), "Test failed" + assert m.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["message"], + attrs={"dismiss": "true", "value": "This is message"}, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["button"], attrs={"text": "Yes, I agree"}, lines=[], commands=[]), + Command(indent=2, name=None, values=["button"], attrs={"text": "No, I disagree"}, lines=[], commands=[]), + ], "Test failed" diff --git a/tests/test_nav.py b/tests/test_nav.py index 34680bd..743da2a 100644 --- a/tests/test_nav.py +++ b/tests/test_nav.py @@ -1,5 +1,6 @@ import pglet from pglet.nav import Item +from pglet.protocol import Command def test_item(): @@ -28,11 +29,28 @@ def test_nav(): assert isinstance(n, pglet.Control) assert isinstance(n, pglet.Nav) - assert n.get_cmd_str() == ( - 'nav id="list1" value="list1"\n' - ' item expanded="true" icon="mail" iconcolor="green" key="key1" newwindow="true" text="item1" url="https://google.com"\n' - ' item key="key2" text="item2"' - ), "Test failed" + assert n.get_cmd_str() == [ + Command( + indent=0, name=None, values=["nav"], attrs={"value": "list1", "id": ("list1", True)}, lines=[], commands=[] + ), + Command( + indent=2, + name=None, + values=["item"], + attrs={ + "expanded": "true", + "icon": "mail", + "iconcolor": "green", + "key": "key1", + "newwindow": "true", + "text": "item1", + "url": "https://google.com", + }, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["item"], attrs={"key": "key2", "text": "item2"}, lines=[], commands=[]), + ], "Test failed" ni = Item("key1") assert isinstance(ni, Item) @@ -40,9 +58,13 @@ def test_nav(): def test_nav_with_just_keys(): n = pglet.Nav(id="list1", value="list1", items=[Item(key="key1"), Item(key="key2")]) - assert n.get_cmd_str(indent=" ") == ( - ' nav id="list1" value="list1"\n' ' item key="key1"\n' ' item key="key2"' - ), "Test failed" + assert n.get_cmd_str() == [ + Command( + indent=0, name=None, values=["nav"], attrs={"value": "list1", "id": ("list1", True)}, lines=[], commands=[] + ), + Command(indent=2, name=None, values=["item"], attrs={"key": "key1"}, lines=[], commands=[]), + Command(indent=2, name=None, values=["item"], attrs={"key": "key2"}, lines=[], commands=[]), + ], "Test failed" ni = Item("key1") assert isinstance(ni, Item) diff --git a/tests/test_page.py b/tests/test_page.py index 01551c8..35b0c2f 100644 --- a/tests/test_page.py +++ b/tests/test_page.py @@ -1,8 +1,2 @@ -import pglet - - -def test_page(): - # create page - p = pglet.page("test_page", local=True, no_window=True) - - assert p.url != "" and p.url.startswith("http"), "Test failed" +def test_page(page): + assert page.url != "" and page.url.startswith("http"), "Test failed" diff --git a/tests/test_panel.py b/tests/test_panel.py index f83e2ed..e32a63f 100644 --- a/tests/test_panel.py +++ b/tests/test_panel.py @@ -1,5 +1,6 @@ import pglet from pglet import Button, Panel, Text +from pglet.protocol import Command def test_panel_add(): @@ -18,11 +19,26 @@ def test_panel_add(): assert isinstance(p, pglet.Control) assert isinstance(p, pglet.Panel) - assert p.get_cmd_str() == ( - 'panel autodismiss="true" blocking="false" data="data1" lightdismiss="false" ' - 'open="true" title="Hello" type="small" width="100"\n' - ' text value="Are you sure?"\n' - " footer\n" - ' button text="OK"\n' - ' button text="Cancel"' - ), "Test failed" + assert p.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["panel"], + attrs={ + "autodismiss": "true", + "blocking": "false", + "data": "data1", + "lightdismiss": "false", + "open": "true", + "title": "Hello", + "type": "small", + "width": "100", + }, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["text"], attrs={"value": "Are you sure?"}, lines=[], commands=[]), + Command(indent=2, name=None, values=["footer"], attrs={}, lines=[], commands=[]), + Command(indent=4, name=None, values=["button"], attrs={"text": "OK"}, lines=[], commands=[]), + Command(indent=4, name=None, values=["button"], attrs={"text": "Cancel"}, lines=[], commands=[]), + ], "Test failed" diff --git a/tests/test_piechart.py b/tests/test_piechart.py index ef195aa..a492351 100644 --- a/tests/test_piechart.py +++ b/tests/test_piechart.py @@ -1,6 +1,7 @@ import pglet from pglet import PieChart from pglet.piechart import Point +from pglet.protocol import Command def test_piechart_add(): @@ -18,9 +19,30 @@ def test_piechart_add(): assert isinstance(pc, pglet.Control) assert isinstance(pc, pglet.PieChart) - assert pc.get_cmd_str() == ( - 'piechart innerradius="42" innervalue="40" legend="true" tooltips="true" width="100%"\n' - " data\n" - ' p color="yellow" legend="Yellow color" tooltip="20%" value="20"\n' - ' p color="green" legend="Green color" tooltip="30%" value="30"' - ), "Test failed" + assert pc.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["piechart"], + attrs={"innerradius": "42", "innervalue": "40", "legend": "true", "tooltips": "true", "width": "100%"}, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["data"], attrs={}, lines=[], commands=[]), + Command( + indent=4, + name=None, + values=["p"], + attrs={"color": "yellow", "legend": "Yellow color", "tooltip": "20%", "value": "20"}, + lines=[], + commands=[], + ), + Command( + indent=4, + name=None, + values=["p"], + attrs={"color": "green", "legend": "Green color", "tooltip": "30%", "value": "30"}, + lines=[], + commands=[], + ), + ], "Test failed" diff --git a/tests/test_progress.py b/tests/test_progress.py index dfc8789..bd665a9 100644 --- a/tests/test_progress.py +++ b/tests/test_progress.py @@ -1,5 +1,6 @@ import pglet from pglet import Progress +from pglet.protocol import Command def test_progress_add(): @@ -7,6 +8,13 @@ def test_progress_add(): assert isinstance(c, pglet.Control) assert isinstance(c, pglet.Progress) # raise Exception(s.get_cmd_str()) - assert c.get_cmd_str() == ( - 'progress label="Doing something..." value="10"' - ), "Test failed" + assert c.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["progress"], + attrs={"label": "Doing something...", "value": "10"}, + lines=[], + commands=[], + ) + ], "Test failed" diff --git a/tests/test_searchbox.py b/tests/test_searchbox.py index 814463f..98be730 100644 --- a/tests/test_searchbox.py +++ b/tests/test_searchbox.py @@ -1,5 +1,6 @@ import pglet from pglet import SearchBox +from pglet.protocol import Command def test_searchbox_add(): @@ -13,7 +14,21 @@ def test_searchbox_add(): ) assert isinstance(sb, pglet.Control) assert isinstance(sb, pglet.SearchBox) - assert sb.get_cmd_str() == ( - 'searchbox data="data1" icon="icon1" iconcolor="color1" ' - 'onchange="false" placeholder="search for something" underlined="true" value=""' - ), "Test failed" + assert sb.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["searchbox"], + attrs={ + "data": "data1", + "icon": "icon1", + "iconcolor": "color1", + "onchange": "false", + "placeholder": "search for something", + "underlined": "true", + "value": "", + }, + lines=[], + commands=[], + ) + ], "Test failed" diff --git a/tests/test_slider.py b/tests/test_slider.py index aa4f8f7..179e97a 100644 --- a/tests/test_slider.py +++ b/tests/test_slider.py @@ -1,8 +1,9 @@ import pglet from pglet import Slider +from pglet.protocol import Command -def test_searchbox_add(): +def test_slider_add(): s = Slider( value=1, label="To what extend you agree", @@ -16,7 +17,23 @@ def test_searchbox_add(): ) assert isinstance(s, pglet.Control) assert isinstance(s, pglet.Slider) - assert s.get_cmd_str() == ( - 'slider height="200" label="To what extend you agree" max="10" min="0" showvalue="true" ' - 'step="1" value="1" valueformat="current_value is {value}" vertical="true"' - ), "Test failed" + assert s.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["slider"], + attrs={ + "height": "200", + "label": "To what extend you agree", + "max": "10", + "min": "0", + "showvalue": "true", + "step": "1", + "value": "1", + "valueformat": "current_value is {value}", + "vertical": "true", + }, + lines=[], + commands=[], + ) + ], "Test failed" diff --git a/tests/test_spinbutton.py b/tests/test_spinbutton.py index 7de14de..33ac1f5 100644 --- a/tests/test_spinbutton.py +++ b/tests/test_spinbutton.py @@ -1,8 +1,9 @@ import pglet from pglet import SpinButton +from pglet.protocol import Command -def test_searchbox_add(): +def test_spinbutton_add(): s = SpinButton( value=1, label="To what extent you agree", @@ -15,7 +16,22 @@ def test_searchbox_add(): ) assert isinstance(s, pglet.Control) assert isinstance(s, pglet.SpinButton) - assert s.get_cmd_str() == ( - 'spinbutton data="data1" icon="icon_name" ' - 'label="To what extent you agree" max="10" min="0" step="1" value="1" width="200"' - ), "Test failed" + assert s.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["spinbutton"], + attrs={ + "data": "data1", + "icon": "icon_name", + "label": "To what extent you agree", + "max": "10", + "min": "0", + "step": "1", + "value": "1", + "width": "200", + }, + lines=[], + commands=[], + ) + ], "Test failed" diff --git a/tests/test_stack.py b/tests/test_stack.py index fbabc78..7643d20 100644 --- a/tests/test_stack.py +++ b/tests/test_stack.py @@ -1,5 +1,6 @@ import pglet from pglet import Button, Stack, Textbox +from pglet.protocol import Command def test_stack_add(): @@ -10,19 +11,34 @@ def test_stack_add(): vertical_align="baseline", gap="large", wrap=True, - scrollx=True, - scrolly=True, + scroll_x=True, + scroll_y=True, controls=[Textbox(id="firstName"), Textbox(id="lastName")], ) assert isinstance(s, pglet.Control) assert isinstance(s, pglet.Stack) # raise Exception(s.get_cmd_str()) - assert s.get_cmd_str() == ( - 'stack gap="large" horizontal="true" horizontalalign="center" ' - 'scrollx="true" scrolly="true" verticalalign="baseline" verticalfill="true" wrap="true"\n' - ' textbox id="firstName"\n' - ' textbox id="lastName"' - ), "Test failed" + assert s.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["stack"], + attrs={ + "gap": "large", + "horizontal": "true", + "horizontalalign": "center", + "scrollx": "true", + "scrolly": "true", + "verticalalign": "baseline", + "verticalfill": "true", + "wrap": "true", + }, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["textbox"], attrs={"id": ("firstName", True)}, lines=[], commands=[]), + Command(indent=2, name=None, values=["textbox"], attrs={"id": ("lastName", True)}, lines=[], commands=[]), + ], "Test failed" def test_nested_stacks_add(): @@ -42,11 +58,25 @@ def test_nested_stacks_add(): assert isinstance(s, pglet.Control) assert isinstance(s, pglet.Stack) # raise Exception(s.get_cmd_str()) - assert s.get_cmd_str() == ( - "stack\n" - ' textbox id="firstName"\n' - ' textbox id="lastName"\n' - ' stack horizontal="true"\n' - ' button id="ok" primary="true" text="OK"\n' - ' button id="cancel" text="Cancel"' - ), "Test failed" + assert s.get_cmd_str() == [ + Command(indent=0, name=None, values=["stack"], attrs={}, lines=[], commands=[]), + Command(indent=2, name=None, values=["textbox"], attrs={"id": ("firstName", True)}, lines=[], commands=[]), + Command(indent=2, name=None, values=["textbox"], attrs={"id": ("lastName", True)}, lines=[], commands=[]), + Command(indent=2, name=None, values=["stack"], attrs={"horizontal": "true"}, lines=[], commands=[]), + Command( + indent=4, + name=None, + values=["button"], + attrs={"primary": "true", "text": "OK", "id": ("ok", True)}, + lines=[], + commands=[], + ), + Command( + indent=4, + name=None, + values=["button"], + attrs={"text": "Cancel", "id": ("cancel", True)}, + lines=[], + commands=[], + ), + ], "Test failed" diff --git a/tests/test_text.py b/tests/test_text.py index 5158a05..24f8476 100644 --- a/tests/test_text.py +++ b/tests/test_text.py @@ -1,5 +1,6 @@ import pglet from pglet import Button, Stack, Text +from pglet.protocol import Command def test_text_add(): @@ -16,41 +17,66 @@ def test_text_add(): block=False, color="#9FE2BF", bgcolor="#FF7F50", - border="1px solid #550000", border_style="dotted", border_width="1", border_color="yellow", border_radius="4px", - border_left="1px solid #550000", - border_right="1px solid #550000", - border_top="1px solid #550000", - border_bottom="1px solid #550000", ) assert isinstance(c, pglet.Control) assert isinstance(c, pglet.Text) # raise Exception(s.get_cmd_str()) # assert c.get_cmd_str() == ('text align="left" block="false" bold='true italic="false" nowrap="true" pre="false" size="tiny" value="Hello,\\nworld!" verticalAlign="left"'), "Test failed" - assert c.get_cmd_str() == ( - 'text align="left" bgcolor="#FF7F50" block="false" bold="true" ' - 'border="1px solid #550000" borderbottom="1px solid #550000" bordercolor="yellow" ' - 'borderleft="1px solid #550000" borderradius="4px" borderright="1px solid #550000" ' - 'borderstyle="dotted" bordertop="1px solid #550000" borderwidth="1" color="#9FE2BF" ' - 'italic="false" markdown="true" nowrap="true" pre="false" size="tiny" value="Hello,\\nworld!" ' - 'verticalalign="top"' - ), "Test failed" + assert c.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["text"], + attrs={ + "align": "left", + "bgcolor": "#FF7F50", + "block": "false", + "bold": "true", + "bordercolor": "yellow", + "borderradius": "4px", + "borderstyle": "dotted", + "borderwidth": "1", + "color": "#9FE2BF", + "italic": "false", + "markdown": "true", + "nowrap": "true", + "pre": "false", + "size": "tiny", + "value": "Hello,\nworld!", + "verticalalign": "top", + }, + lines=[], + commands=[], + ) + ], "Test failed" def test_text_double_quotes(): c = Text(value='Hello, "world!"') # raise Exception(c.get_cmd_str()) - assert c.get_cmd_str() == ('text value="Hello, \\"world!\\""'), "Test failed" + assert c.get_cmd_str() == [ + Command(indent=0, name=None, values=["text"], attrs={"value": 'Hello, "world!"'}, lines=[], commands=[]) + ], "Test failed" def test_add_text_inside_stack(): - txt = Text(id="txt1", value='Hello, "world!"') - btn = Button(text="Super button") - stack = Stack(id="header", controls=[txt, btn]) + text = Text(id="txt1", value='Hello, "world!"') + button = Button(text="Super button") + stack = Stack(id="header", controls=[text, button]) - # open page - p = pglet.page("test_text", local=True, no_window=True) - p.clean() + assert stack.get_cmd_str() == [ + Command(indent=0, name=None, values=["stack"], attrs={"id": ("header", True)}, lines=[], commands=[]), + Command( + indent=2, + name=None, + values=["text"], + attrs={"value": 'Hello, "world!"', "id": ("txt1", True)}, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["button"], attrs={"text": "Super button"}, lines=[], commands=[]), + ], "Test failed" diff --git a/tests/test_textbox.py b/tests/test_textbox.py index ef19bf6..7328794 100644 --- a/tests/test_textbox.py +++ b/tests/test_textbox.py @@ -1,10 +1,18 @@ import pglet +from pglet.protocol import Command def test_textbox_add(): tb = pglet.Textbox(id="txt1", label="Your name:") assert isinstance(tb, pglet.Control) assert isinstance(tb, pglet.Textbox) - assert ( - tb.get_cmd_str(indent=" ") == ' textbox id="txt1" label="Your name:"' - ), "Test failed" + assert [ + Command( + indent=" ", + name=None, + values=["textbox"], + attrs={"label": "Your name:", "id": ("txt1", True)}, + lines=[], + commands=[], + ) + ], "Test failed" diff --git a/tests/test_toggle.py b/tests/test_toggle.py index 3760bf6..192f829 100644 --- a/tests/test_toggle.py +++ b/tests/test_toggle.py @@ -1,5 +1,6 @@ import pglet from pglet import Toggle +from pglet.protocol import Command """ def test_button_primary_must_be_bool(): @@ -19,6 +20,19 @@ def test_toggle_add(): ) assert isinstance(t, pglet.Control) assert isinstance(t, pglet.Toggle) - assert t.get_cmd_str() == ( - 'toggle inline="true" label="This is toggle" offtext="off text" ontext="on text" value="true"' - ), "Test failed" + assert t.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["toggle"], + attrs={ + "inline": "true", + "label": "This is toggle", + "offtext": "off text", + "ontext": "on text", + "value": "true", + }, + lines=[], + commands=[], + ) + ], "Test failed" diff --git a/tests/test_toolbar.py b/tests/test_toolbar.py index 330e2f4..8512d8a 100644 --- a/tests/test_toolbar.py +++ b/tests/test_toolbar.py @@ -1,5 +1,6 @@ import pglet from pglet import Toolbar, toolbar +from pglet.protocol import Command def test_toolbar_add(): @@ -37,14 +38,46 @@ def test_toolbar_add(): assert isinstance(t, pglet.Control) assert isinstance(t, pglet.Toolbar) - assert t.get_cmd_str() == ( - 'toolbar inverted="true"\n' - ' item divider="true" icon="icon" iconcolor="green" icononly="false" newwindow="true" ' - 'secondarytext="text2" split="true" text="text1" url="url"\n' - " overflow\n" - ' item divider="true" icon="icon" iconcolor="green" icononly="false" newwindow="true" ' - 'secondarytext="text22" split="true" text="text12" url="url2"\n' - ' item text="overflow"\n' - " far\n" - ' item text="far"' - ), "Test failed" + assert t.get_cmd_str() == [ + Command(indent=0, name=None, values=["toolbar"], attrs={"inverted": "true"}, lines=[], commands=[]), + Command( + indent=2, + name=None, + values=["item"], + attrs={ + "divider": "true", + "icon": "icon", + "iconcolor": "green", + "icononly": "false", + "newwindow": "true", + "secondarytext": "text2", + "split": "true", + "text": "text1", + "url": "url", + }, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["overflow"], attrs={}, lines=[], commands=[]), + Command( + indent=4, + name=None, + values=["item"], + attrs={ + "divider": "true", + "icon": "icon", + "iconcolor": "green", + "icononly": "false", + "newwindow": "true", + "secondarytext": "text22", + "split": "true", + "text": "text12", + "url": "url2", + }, + lines=[], + commands=[], + ), + Command(indent=4, name=None, values=["item"], attrs={"text": "overflow"}, lines=[], commands=[]), + Command(indent=2, name=None, values=["far"], attrs={}, lines=[], commands=[]), + Command(indent=4, name=None, values=["item"], attrs={"text": "far"}, lines=[], commands=[]), + ], "Test failed" diff --git a/tests/test_update.py b/tests/test_update.py index d193929..1b8526c 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -1,13 +1,6 @@ -import pglet -import pytest from pglet import Textbox -@pytest.fixture -def page(): - return pglet.page("test_update", local=True, no_window=True) - - def test_update_single_control(page): txt = Textbox(id="txt1", label="First name:") page.add(txt) diff --git a/tests/test_verticalbarchart.py b/tests/test_verticalbarchart.py index 597a1dc..47d2f7f 100644 --- a/tests/test_verticalbarchart.py +++ b/tests/test_verticalbarchart.py @@ -1,5 +1,6 @@ import pglet from pglet import VerticalBarChart +from pglet.protocol import Command from pglet.verticalbarchart import Point @@ -29,11 +30,41 @@ def test_verticalbarchart_add(): ) assert isinstance(vbc, pglet.Control) assert isinstance(vbc, pglet.VerticalBarChart) - assert vbc.get_cmd_str() == ( - 'verticalbarchart barwidth="56" colors="green yellow" legend="true" tooltips="false" ' - 'xtype="number" yformat="format{y}" ymax="1000" ymin="0" yticks="200"\n' - " data\n" - ' p color="green" legend="legend" x="1" xtooltip="x tooltip" y="100" ytooltip="y tooltip"\n' - ' p x="80" y="200"\n' - ' p x="100" y="300"' - ), "Test failed" + assert vbc.get_cmd_str() == [ + Command( + indent=0, + name=None, + values=["verticalbarchart"], + attrs={ + "barwidth": "56", + "colors": "green yellow", + "legend": "true", + "tooltips": "false", + "xtype": "number", + "yformat": "format{y}", + "ymax": "1000", + "ymin": "0", + "yticks": "200", + }, + lines=[], + commands=[], + ), + Command(indent=2, name=None, values=["data"], attrs={}, lines=[], commands=[]), + Command( + indent=4, + name=None, + values=["p"], + attrs={ + "color": "green", + "legend": "legend", + "x": "1", + "xtooltip": "x tooltip", + "y": "100", + "ytooltip": "y tooltip", + }, + lines=[], + commands=[], + ), + Command(indent=4, name=None, values=["p"], attrs={"x": "80", "y": "200"}, lines=[], commands=[]), + Command(indent=4, name=None, values=["p"], attrs={"x": "100", "y": "300"}, lines=[], commands=[]), + ], "Test failed"