Implemented Delete feature in DataGridsManager.py. There is still a bug as DBEngine.delete is not implemented

Improved readability for tests using matcher
This commit is contained in:
2026-02-21 18:31:11 +01:00
parent 730f55d65b
commit d447220eae
12 changed files with 460 additions and 49 deletions

View File

@@ -1,9 +1,10 @@
import re
from dataclasses import dataclass
from typing import Optional, Any
from typing import Optional, Any, Literal
from fastcore.basics import NotStr
from fastcore.xml import FT
from fasthtml.components import Span
from myfasthtml.core.commands import Command
from myfasthtml.core.utils import quoted_str, snake_to_pascal
@@ -185,8 +186,27 @@ class TestObject:
self.attrs = kwargs
class TestLabel(TestObject):
def __init__(self, label: str, icon: str = None, command=None):
super().__init__("span")
self.label = label
self.icon = snake_to_pascal(icon) if (icon and icon[0].islower()) else icon
self.children = []
if self.icon:
self.children.append(TestIcon(self.icon, wrapper="span"))
self.children.append(Span(label))
if command:
self.attrs |= command.get_htmx_params()
def __str__(self):
icon_str = f"<svg name='{self.icon}'" if self.icon else ""
return f'<span>{icon_str}<span>{self.label}</span></span>'
class TestIcon(TestObject):
def __init__(self, name: Optional[str] = '', wrapper="div", command=None):
def __init__(self, name: Optional[str] = '', wrapper: Literal["div", "span"] = "div", command=None):
super().__init__(wrapper)
self.wrapper = wrapper
self.name = snake_to_pascal(name) if (name and name[0].islower()) else name
@@ -239,18 +259,28 @@ class Skip:
def _get_type(x):
if hasattr(x, "tag"):
return x.tag
if isinstance(x, (TestObject, TestIcon)):
if isinstance(x, TestObject):
return x.cls.__name__ if isinstance(x.cls, type) else str(x.cls)
return type(x).__name__
def _get_attr(x, attr):
if isinstance(x, TestObject) and "s" in x.attrs and isinstance(x.attrs["s"], Regex):
return x.attrs["s"].value + " />"
if hasattr(x, "attrs"):
return x.attrs.get(attr, MISSING_ATTR)
if not hasattr(x, attr):
return MISSING_ATTR
if isinstance(x, NotStr) and attr == "s":
# Special case for NotStr: return the name of the svg
svg = getattr(x, attr, MISSING_ATTR)
match = re.search(r'name\s*=\s*["\']([^"\']+)["\']', svg)
if match:
return f'<svg name="{match.group(1)}" />'
return getattr(x, attr, MISSING_ATTR)
@@ -453,9 +483,9 @@ class ErrorComparisonOutput:
expected = self.adjust(expected, actual)
actual_max_length = len(max(actual, key=len))
# expected_max_length = len(max(expected, key=len))
expected_max_length = len(max(expected, key=len))
output = []
output = [f"{' Actual ':=^{actual_max_length}} | {' Expected ':=^{expected_max_length}}"]
for a, e in zip(actual, expected):
line = f"{a:<{actual_max_length}} | {e}".rstrip()
output.append(line)