feat: dynamic mode
This commit is contained in:
@@ -199,6 +199,61 @@ def test_table_with_color():
|
||||
assert "`F0f0" in result.micron # green color tag
|
||||
|
||||
|
||||
def test_form_field():
|
||||
source = '''page "Demo" 50
|
||||
form "test"
|
||||
field "name" 20 "Enter name..."'''
|
||||
result = uframe.compile(source)
|
||||
assert "name:" in result.ascii
|
||||
assert "[" in result.ascii
|
||||
assert "]" in result.ascii
|
||||
# Micron should have form tag
|
||||
assert "`<" in result.micron or "<" in result.micron
|
||||
|
||||
|
||||
def test_form_radio():
|
||||
source = '''page "Demo" 50
|
||||
form "test"
|
||||
radio "mode" "Ping" | "Trace" | "Page"'''
|
||||
result = uframe.compile(source)
|
||||
assert "(•)" in result.ascii # first option selected
|
||||
assert "( )" in result.ascii # other options unselected
|
||||
assert "Ping" in result.ascii
|
||||
assert "Trace" in result.ascii
|
||||
|
||||
|
||||
def test_form_checkbox():
|
||||
source = '''page "Demo" 50
|
||||
form "test"
|
||||
checkbox "agree" "I agree to terms"'''
|
||||
result = uframe.compile(source)
|
||||
assert "[ ]" in result.ascii
|
||||
assert "I agree to terms" in result.ascii
|
||||
|
||||
|
||||
def test_form_button():
|
||||
source = '''page "Demo" 50
|
||||
form "test"
|
||||
button "Submit" "/page/submit.mu"'''
|
||||
result = uframe.compile(source)
|
||||
assert "Submit" in result.ascii
|
||||
assert "submit.mu" in result.micron
|
||||
|
||||
|
||||
def test_form_complete():
|
||||
source = '''page "Search" 50
|
||||
form "search"
|
||||
field "query" 24 "Search term..."
|
||||
radio "scope" "Local" | "Network"
|
||||
checkbox "cache" "Include cached"
|
||||
button "Go" "/page/search.mu"'''
|
||||
result = uframe.compile(source)
|
||||
assert "query:" in result.ascii
|
||||
assert "(•)" in result.ascii
|
||||
assert "[ ]" in result.ascii
|
||||
assert "Go" in result.ascii
|
||||
|
||||
|
||||
def test_full_dashboard():
|
||||
"""Integration test: a realistic dashboard layout."""
|
||||
source = '''page "Node Status" 60
|
||||
|
||||
124
backend/uframe/tests/test_dynamic.py
Normal file
124
backend/uframe/tests/test_dynamic.py
Normal file
@@ -0,0 +1,124 @@
|
||||
"""Tests for dynamic page features — source, if/for, codegen."""
|
||||
|
||||
import uframe
|
||||
|
||||
|
||||
def test_static_page_not_dynamic():
|
||||
result = uframe.compile('page "Test" 40\n heading 1 "Hello"')
|
||||
assert not result.is_dynamic
|
||||
assert result.script == ""
|
||||
|
||||
|
||||
def test_source_makes_dynamic():
|
||||
source = '''page "Test" 40
|
||||
source cpu : shell "echo 42"
|
||||
heading 1 "CPU: $cpu"'''
|
||||
result = uframe.compile(source)
|
||||
assert result.is_dynamic
|
||||
assert result.script != ""
|
||||
assert "#!/usr/bin/env python3" in result.script
|
||||
assert "_shell" in result.script
|
||||
|
||||
|
||||
def test_cache_control():
|
||||
source = '''page "Test" 40
|
||||
cache 0
|
||||
heading 1 "Live"'''
|
||||
result = uframe.compile(source)
|
||||
assert result.is_dynamic
|
||||
assert "_cache_seconds = 0" in result.script
|
||||
|
||||
|
||||
def test_if_block():
|
||||
source = '''page "Test" 40
|
||||
source val : shell "echo 50"
|
||||
if $val > 90
|
||||
text "Critical"'''
|
||||
result = uframe.compile(source)
|
||||
assert result.is_dynamic
|
||||
assert "if {val} > 90:" in result.script
|
||||
|
||||
|
||||
def test_for_loop():
|
||||
source = '''page "Test" 40
|
||||
source items : shell "echo hello"
|
||||
for item in $items
|
||||
text "$item"'''
|
||||
result = uframe.compile(source)
|
||||
assert result.is_dynamic
|
||||
assert "for item in _iter({items}):" in result.script
|
||||
|
||||
|
||||
def test_let_variable():
|
||||
"""let + source makes it dynamic; let alone is static."""
|
||||
source = '''page "Test" 40
|
||||
let name = "Relay Alpha"
|
||||
source ts : python "datetime.now().isoformat()"
|
||||
heading 1 "$name"'''
|
||||
result = uframe.compile(source)
|
||||
assert result.is_dynamic
|
||||
assert "name = 'Relay Alpha'" in result.script
|
||||
|
||||
|
||||
def test_state_declaration():
|
||||
source = '''page "Test" 40
|
||||
state "counter" "/tmp/counter.json"
|
||||
heading 1 "Visits"'''
|
||||
result = uframe.compile(source)
|
||||
assert result.is_dynamic
|
||||
assert "_load_state" in result.script
|
||||
assert "/tmp/counter.json" in result.script
|
||||
|
||||
|
||||
def test_on_submit():
|
||||
source = '''page "Test" 40
|
||||
form "search"
|
||||
field "query" 20 "Search..."
|
||||
button "Go" "/page/test.mu"
|
||||
on_submit "search"
|
||||
text "Results for $query"'''
|
||||
result = uframe.compile(source)
|
||||
assert result.is_dynamic
|
||||
assert "_get_field" in result.script
|
||||
|
||||
|
||||
def test_codegen_has_runtime():
|
||||
source = '''page "Test" 40
|
||||
source data : shell "echo ok"
|
||||
text "$data"'''
|
||||
result = uframe.compile(source)
|
||||
script = result.script
|
||||
# Verify the runtime helpers are included
|
||||
assert "def _shell" in script
|
||||
assert "def _get_field" in script
|
||||
assert "def _load_state" in script
|
||||
assert "def _iter" in script
|
||||
assert "import uframe" in script
|
||||
assert "result.micron" in script
|
||||
|
||||
|
||||
def test_codegen_complete_dashboard():
|
||||
source = '''page "Dashboard" 60
|
||||
cache 0
|
||||
source cpu : shell "echo 42"
|
||||
source mem : shell "echo 67"
|
||||
|
||||
box double "Node Status"
|
||||
text "System Monitor"
|
||||
|
||||
gauge "CPU" $cpu 100 28 warn=75 crit=90
|
||||
gauge "MEM" $mem 100 28 warn=80 crit=95
|
||||
|
||||
if $cpu > 90
|
||||
text "ALERT: CPU critical"
|
||||
|
||||
divider heavy
|
||||
link "Home" "/page/index.mu"'''
|
||||
result = uframe.compile(source)
|
||||
assert result.is_dynamic
|
||||
script = result.script
|
||||
assert "#!/usr/bin/env python3" in script
|
||||
assert "_cache_seconds = 0" in script
|
||||
assert "_shell" in script
|
||||
assert "if {cpu} > 90:" in script
|
||||
assert "uframe.compile" in script
|
||||
Reference in New Issue
Block a user