Spaces:
Running on Zero
Running on Zero
Daryl Lim Claude Opus 4.8 (1M context) commited on
Commit ·
c15ff11
1
Parent(s): 9fdec8c
test: cover Textbox toolbar buttons and update test counts
Browse filesAdd fast tests asserting the input textbox exposes no toolbar buttons
(guards the removed invalid clear button) and the output textbox has a
copy button — the buttons config was previously untested, which let
buttons=["clear"] slip through. Update test counts (48->50, 38->40
fast, test_app.py 28->30) in CLAUDE.md and README.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- CLAUDE.md +3 -3
- README.md +2 -2
- tests/test_app.py +14 -0
CLAUDE.md
CHANGED
|
@@ -25,8 +25,8 @@ uv run ruff format .
|
|
| 25 |
uv run ty check
|
| 26 |
|
| 27 |
# Test
|
| 28 |
-
uv run pytest # all
|
| 29 |
-
uv run pytest -m "not slow" #
|
| 30 |
uv run pytest -m slow # 10 model tests only (CUDA only)
|
| 31 |
|
| 32 |
# Generate language mapping (dev only)
|
|
@@ -41,7 +41,7 @@ uv run scripts/generate_langmap.py <path-to-paper.pdf>
|
|
| 41 |
|
| 42 |
**`scripts/`** — `generate_langmap.py` parses the MADLAD-400 paper PDF (Table 9, pages 16-22) using pdfplumber and generates the static language mapping with region assignments. Dev-only tool; requires `requirements-dev.txt` dependencies.
|
| 43 |
|
| 44 |
-
**`tests/`** —
|
| 45 |
|
| 46 |
## Tooling
|
| 47 |
|
|
|
|
| 25 |
uv run ty check
|
| 26 |
|
| 27 |
# Test
|
| 28 |
+
uv run pytest # all 50 tests (slow require CUDA + model download)
|
| 29 |
+
uv run pytest -m "not slow" # 40 fast tests only
|
| 30 |
uv run pytest -m slow # 10 model tests only (CUDA only)
|
| 31 |
|
| 32 |
# Generate language mapping (dev only)
|
|
|
|
| 41 |
|
| 42 |
**`scripts/`** — `generate_langmap.py` parses the MADLAD-400 paper PDF (Table 9, pages 16-22) using pdfplumber and generates the static language mapping with region assignments. Dev-only tool; requires `requirements-dev.txt` dependencies.
|
| 43 |
|
| 44 |
+
**`tests/`** — 50 tests (40 fast, 10 slow). `test_langmap.py` has 10 fast tests for mapping validation (dict shape, regions, spot-checks). `test_app.py` has 30 fast tests (signatures, device fallback, UI layout with symmetric dropdowns, swap button, textbox config including toolbar buttons, handler wiring, no HTML elements, locale codes, no title) and 10 slow tests (translation with various parameters, language mapping). Slow tests require CUDA and model download; auto-skipped without CUDA.
|
| 45 |
|
| 46 |
## Tooling
|
| 47 |
|
README.md
CHANGED
|
@@ -38,6 +38,6 @@ The Gradio interface launches at `http://localhost:7860`.
|
|
| 38 |
uv run ruff check . # lint
|
| 39 |
uv run ruff format . # format
|
| 40 |
uv run ty check # type check
|
| 41 |
-
uv run pytest -m "not slow" #
|
| 42 |
-
uv run pytest # all
|
| 43 |
```
|
|
|
|
| 38 |
uv run ruff check . # lint
|
| 39 |
uv run ruff format . # format
|
| 40 |
uv run ty check # type check
|
| 41 |
+
uv run pytest -m "not slow" # 40 fast tests
|
| 42 |
+
uv run pytest # all 50 tests (slow require CUDA + model download)
|
| 43 |
```
|
tests/test_app.py
CHANGED
|
@@ -153,6 +153,13 @@ def test_input_textbox_has_no_placeholder(demo):
|
|
| 153 |
assert interactive[0].placeholder is None, f"Expected no placeholder, got {interactive[0].placeholder!r}"
|
| 154 |
|
| 155 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
def test_output_textbox_is_non_interactive(demo):
|
| 157 |
"""Output textbox should be non-interactive."""
|
| 158 |
textboxes = [b for b in demo.blocks.values() if type(b).__name__ == "Textbox"]
|
|
@@ -174,6 +181,13 @@ def test_output_placeholder(demo):
|
|
| 174 |
assert output[0].placeholder == "Translation"
|
| 175 |
|
| 176 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
def test_demo_has_translate_button(demo):
|
| 178 |
"""UI should have a Translate button."""
|
| 179 |
buttons = [b for b in demo.blocks.values() if type(b).__name__ == "Button"]
|
|
|
|
| 153 |
assert interactive[0].placeholder is None, f"Expected no placeholder, got {interactive[0].placeholder!r}"
|
| 154 |
|
| 155 |
|
| 156 |
+
def test_input_textbox_has_no_buttons(demo):
|
| 157 |
+
"""Input textbox should expose no toolbar buttons (invalid 'clear' button removed)."""
|
| 158 |
+
textboxes = [b for b in demo.blocks.values() if type(b).__name__ == "Textbox"]
|
| 159 |
+
interactive = [t for t in textboxes if t.interactive is not False]
|
| 160 |
+
assert interactive[0].buttons == [], f"Expected no buttons, got {interactive[0].buttons!r}"
|
| 161 |
+
|
| 162 |
+
|
| 163 |
def test_output_textbox_is_non_interactive(demo):
|
| 164 |
"""Output textbox should be non-interactive."""
|
| 165 |
textboxes = [b for b in demo.blocks.values() if type(b).__name__ == "Textbox"]
|
|
|
|
| 181 |
assert output[0].placeholder == "Translation"
|
| 182 |
|
| 183 |
|
| 184 |
+
def test_output_textbox_has_copy_button(demo):
|
| 185 |
+
"""Output textbox should expose a copy button."""
|
| 186 |
+
textboxes = [b for b in demo.blocks.values() if type(b).__name__ == "Textbox"]
|
| 187 |
+
output = [t for t in textboxes if t.interactive is False]
|
| 188 |
+
assert output[0].buttons == ["copy"], f"Expected ['copy'], got {output[0].buttons!r}"
|
| 189 |
+
|
| 190 |
+
|
| 191 |
def test_demo_has_translate_button(demo):
|
| 192 |
"""UI should have a Translate button."""
|
| 193 |
buttons = [b for b in demo.blocks.values() if type(b).__name__ == "Button"]
|