mirror of
https://github.com/nesquena/hermes-webui.git
synced 2026-05-24 18:50:15 +00:00
49a2a424d5
- Fenced code blocks with json/yaml lang get Tree/Raw toggle - Recursive DOM builder (_buildTreeDOM) with type-colored values (green strings, blue numbers, amber booleans, muted nulls) - Auto-collapse at depth 2+, default tree for >=10 lines blocks - YAML parsing via js-yaml (lazy, CDN-loaded) - CSS: tree-view, tree-node, collapsible, type-colored classes - i18n: tree_view, raw_view keys in all 7 locales - 14 tests: renderer, types, collapse, CSS, i18n Closes #484
104 lines
4.2 KiB
Python
104 lines
4.2 KiB
Python
"""Tests for issue #484 — collapsible JSON/YAML tree viewer."""
|
|
import pytest
|
|
|
|
|
|
class TestTreeRenderer:
|
|
"""Fenced JSON/YAML blocks should get a tree view toggle."""
|
|
|
|
def test_json_blocks_get_tree_wrapper(self):
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
assert "code-tree-wrap" in content
|
|
assert "data-raw" in content
|
|
assert "data-lang" in content
|
|
|
|
def test_json_yaml_lang_detection(self):
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
assert "lang==='json'||lang==='yaml'" in content
|
|
|
|
def test_initTreeViews_function_exists(self):
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
assert "function initTreeViews()" in content
|
|
|
|
def test_buildTreeDOM_function_exists(self):
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
assert "function _buildTreeDOM(val, depth)" in content
|
|
|
|
def test_initTreeViews_called_in_post_render(self):
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
count = content.count("initTreeViews()")
|
|
assert count >= 2, f"initTreeViews() called {count} times, expected >= 2"
|
|
|
|
def test_tree_handles_all_value_types(self):
|
|
"""_buildTreeDOM should handle null, boolean, number, string, array, object."""
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
for cls in ("tree-null", "tree-bool", "tree-num", "tree-str", "tree-array", "tree-object"):
|
|
assert cls in content, f"Missing type class: {cls}"
|
|
|
|
def test_tree_collapse_support(self):
|
|
"""Tree nodes should be collapsible with collapsed/expanded states."""
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
assert "tree-collapsed" in content
|
|
assert "tree-collapsible" in content
|
|
assert "classList.toggle" in content
|
|
|
|
def test_tree_depth_auto_collapse(self):
|
|
"""Nested levels beyond depth 2 should be collapsed by default."""
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
assert "depth>=2" in content
|
|
|
|
def test_toggle_button_uses_i18n(self):
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
assert "t('raw_view')" in content
|
|
assert "t('tree_view')" in content
|
|
|
|
def test_yaml_support_via_jsyaml(self):
|
|
"""YAML should be parsed via jsyaml if available."""
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
assert "jsyaml" in content
|
|
|
|
def test_short_json_defaults_to_raw(self):
|
|
"""Blocks under 10 lines should default to raw view."""
|
|
with open("static/ui.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
assert "lineCount>=10" in content
|
|
|
|
|
|
class TestTreeCSS:
|
|
"""CSS classes for tree viewer."""
|
|
|
|
def test_tree_css_classes_exist(self):
|
|
with open("static/style.css", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
for cls in (".code-tree-wrap", ".tree-view", ".tree-hidden", ".tree-toggle-btn",
|
|
".tree-node", ".tree-collapsible", ".tree-children", ".tree-collapsed",
|
|
".tree-key", ".tree-str", ".tree-num", ".tree-bool", ".tree-null",
|
|
".tree-comma", ".tree-item"):
|
|
assert cls in content, f"Missing CSS: {cls}"
|
|
|
|
def test_tree_colors_match_types(self):
|
|
with open("static/style.css", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
# Green strings, blue numbers, amber booleans
|
|
assert "#4ade80" in content # tree-str green
|
|
assert "#60a5fa" in content # tree-key/tree-num blue
|
|
assert "#fbbf24" in content # tree-bool amber
|
|
|
|
|
|
class TestTreeI18n:
|
|
def test_i18n_keys_present(self):
|
|
with open("static/i18n.js", "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
for key in ("tree_view", "raw_view"):
|
|
count = content.count(key)
|
|
assert count >= 7, f"{key} found {count} times, expected >= 7"
|