Working version of DataGridColumnsManager.py where columns can be updated

This commit is contained in:
2026-01-25 21:40:32 +01:00
parent e31d9026ce
commit 05d4e5cd89
7 changed files with 702 additions and 34 deletions

View File

@@ -258,7 +258,7 @@ def test_i_can_render_component_with_no_data(self, component):
**Test order:**
1. **First test:** Global structure (UTR-11.1)
2. **Following tests:** Details of each section (UTR-11.2 to UTR-11.10)
2. **Following tests:** Details of each section (UTR-11.2 to UTR-11.11)
---
@@ -410,8 +410,19 @@ expected = Div(style="width: 250px; overflow: hidden; display: flex;")
**How to choose:**
1. **Read the source code** to see how the icon is rendered
2. If `mk.icon()` or equivalent wraps the icon in a Div → use `TestIcon()`
3. If the icon is directly included without wrapper → use `TestIconNotStr()`
2. If `mk.icon()` wraps the icon in a Div → use `TestIcon()` (default `wrapper="div"`)
3. If `mk.label(..., icon=...)` wraps the icon in a Span → use `TestIcon(..., wrapper="span")`
4. If the icon is directly included without wrapper → use `TestIconNotStr()`
**The `wrapper` parameter:**
Different `mk` helpers use different wrappers for icons:
| Helper method | Wrapper element | TestIcon usage |
|---------------|-----------------|----------------|
| `mk.icon(my_icon)` | `<div>` | `TestIcon("name")` |
| `mk.label("Text", icon=my_icon)` | `<span>` | `TestIcon("name", wrapper="span")` |
| Direct: `Div(my_icon)` | none | `TestIconNotStr("name")` |
**The `name` parameter:**
- **Exact name**: Use the exact import name (e.g., `TestIcon("panel_right_expand20_regular")`) to validate a specific icon
@@ -420,25 +431,30 @@ expected = Div(style="width: 250px; overflow: hidden; display: flex;")
**Examples:**
```python
# Example 1: Wrapped icon (typically with mk.icon())
# Example 1: Icon via mk.icon() - wrapper is Div (default)
# Source code: mk.icon(panel_right_expand20_regular, size=20)
# Rendered: <div><NotStr .../></div>
# Rendered: <div><svg .../></div>
expected = Header(
Div(
TestIcon("panel_right_expand20_regular"), # ✅ With wrapper
TestIcon("panel_right_expand20_regular"), # ✅ wrapper="div" (default)
cls=Contains("flex", "gap-1")
)
)
# Example 2: Direct icon (used without helper)
# Example 2: Icon via mk.label() - wrapper is Span
# Source code: mk.label("Back", icon=chevron_left20_regular, command=...)
# Rendered: <label><span><svg .../></span><span>Back</span></label>
back_icon = find_one(details, TestIcon("chevron_left20_regular", wrapper="span")) # ✅ wrapper="span"
# Example 3: Direct icon (used without helper)
# Source code: Span(dismiss_circle16_regular, cls="icon")
# Rendered: <span><NotStr .../></span>
# Rendered: <span><svg .../></span>
expected = Span(
TestIconNotStr("dismiss_circle16_regular"), # ✅ Without wrapper
cls=Contains("icon")
)
# Example 3: Verify any wrapped icon
# Example 4: Verify any wrapped icon
expected = Div(
TestIcon(""), # Accepts any wrapped icon
cls=Contains("icon-wrapper")
@@ -446,7 +462,10 @@ expected = Div(
```
**Debugging tip:**
If your test fails with `TestIcon()`, try `TestIconNotStr()` and vice-versa. The error message will show you the actual structure.
If your test fails with `TestIcon()`:
1. Check if the wrapper is `<span>` instead of `<div>` → try `wrapper="span"`
2. Check if there's no wrapper at all → try `TestIconNotStr()`
3. The error message will show you the actual structure
---
@@ -467,11 +486,60 @@ expected = Script("(function() { const id = '...'; initResizer(id); })()")
---
#### **UTR-11.9: Remove default `enctype` attribute when searching for Form elements**
**Principle:** FastHTML's `Form()` component automatically adds `enctype="multipart/form-data"` as a default attribute. When using `find()` or `find_one()` to search for a Form, you must remove this attribute from the expected pattern.
**Why:** The actual Form in your component may not have this attribute, causing the match to fail.
**Problem:**
```python
# ❌ FAILS - Form() has default enctype that may not exist in actual form
form = find_one(details, Form()) # AssertionError: Found 0 elements
```
**Solution:**
```python
# ✅ WORKS - Remove the default enctype attribute
expected_form = Form()
del expected_form.attrs["enctype"]
form = find_one(details, expected_form)
```
**Alternative - Search with specific attribute:**
```python
# ✅ ALSO WORKS - Search by a known attribute
form = find_one(details, Form(cls=Contains("my-form-class")))
# But still need to delete enctype if Form() is used as pattern
```
**Complete example:**
```python
def test_column_details_contains_form(self, component):
"""Test that column details contains a form with required fields."""
details = component.mk_column_details(col_def)
# Create Form pattern and remove default enctype
expected_form = Form()
del expected_form.attrs["enctype"]
form = find_one(details, expected_form)
assert form is not None
# Now search within the found form
title_input = find_one(form, Input(name="title"))
assert title_input is not None
```
**Note:** This is a FastHTML-specific behavior. Always check for similar default attributes when tests fail unexpectedly with "Found 0 elements".
---
### **HOW TO DOCUMENT TESTS**
---
#### **UTR-11.9: Justify the choice of tested elements**
#### **UTR-11.10: Justify the choice of tested elements**
**Principle:** In the test documentation section (after the description docstring), explain **why each tested element or attribute was chosen**. What makes it important for the functionality?
@@ -518,7 +586,7 @@ def test_left_drawer_is_rendered_when_open(self, layout):
---
#### **UTR-11.10: Count tests with explicit messages**
#### **UTR-11.11: Count tests with explicit messages**
**Principle:** When you count elements with `assert len()`, ALWAYS add an explicit message explaining why this number is expected.
@@ -548,7 +616,7 @@ assert len(resizers) == 1
2. **Documentation format**: Every render test MUST have a docstring with:
- First line: Brief description of what is being tested
- Blank line
- Justification section explaining why tested elements matter (see UTR-11.9)
- Justification section explaining why tested elements matter (see UTR-11.10)
- List of important elements/attributes being tested with explanations (in English)
3. **No inline comments**: Do NOT add comments on each line of the expected structure (except for structural clarification in global layout tests like `# left drawer`)
@@ -572,7 +640,7 @@ assert len(resizers) == 1
---
#### **Summary: The 11 UTR-11 sub-rules**
#### **Summary: The 12 UTR-11 sub-rules**
**Prerequisite**
- **UTR-11.0**: ⭐⭐⭐ Read `docs/testing_rendered_components.md` (MANDATORY)
@@ -590,10 +658,11 @@ assert len(resizers) == 1
- **UTR-11.6**: Always `Contains()` for `cls` and `style`
- **UTR-11.7**: `TestIcon()` or `TestIconNotStr()` to test icon presence
- **UTR-11.8**: `TestScript()` for JavaScript
- **UTR-11.9**: Remove default `enctype` from `Form()` patterns
**How to document**
- **UTR-11.9**: Justify the choice of tested elements
- **UTR-11.10**: Explicit messages for `assert len()`
- **UTR-11.10**: Justify the choice of tested elements
- **UTR-11.11**: Explicit messages for `assert len()`
---
@@ -601,7 +670,7 @@ assert len(resizers) == 1
- Reference specific patterns from the documentation
- Explain why you chose to test certain elements and not others
- Justify the use of predicates vs exact values
- Always include justification documentation (see UTR-11.9)
- Always include justification documentation (see UTR-11.10)
---