Files
hermes-webui/tests/test_issue3337_workspace_preview_highlight.py
T
nesquena-hermesandRod Boev a875bcbb9e feat(ux): enlarge Mermaid diagrams in chat (#4075) + workspace CSV table preview (#4025)
Combined light-UX release NW. Both rebased onto current master (were 96 and
247 behind; net 3-dot diffs applied, byte-identical to PR heads). Both reuse
existing renderers (chat image lightbox / chat CSV table renderer).

Review fix (#4025, Codex): the CSV table preview previously stripped the
workspace Edit affordance .csv had when it fell through to the code preview.
Restored: csv mode is editable, renderCsvPreviewContent caches raw content for
the edit textarea, and saving an edited CSV re-renders the table (not markdown).
Verified the full edit round-trip live + regression test.

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-06-14 06:12:24 +00:00

81 lines
3.5 KiB
Python

"""Regression tests for workspace file-preview syntax highlighting (#3337).
#3337 added Prism.js syntax highlighting to the workspace code preview. The
contributor PR shipped no test of its own, and a maintainer browser-test caught
a cross-file highlight-leak bug: Prism.highlightElement() propagates the
language-* class onto the parent <pre>, so previewing a .css file then a .txt
file rendered the plain text with CSS grammar. These tests pin both the feature
and the fix.
"""
from pathlib import Path
WORKSPACE_JS = (Path(__file__).resolve().parent.parent / "static" / "workspace.js").read_text(encoding="utf-8")
def _open_file_body() -> str:
start = WORKSPACE_JS.index("async function openFile(")
# The plain code/text branch is the last else block before the function ends.
return WORKSPACE_JS[start:start + 8000]
def _code_preview_helper() -> str:
start = WORKSPACE_JS.index("function renderCodePreviewContent(path, content){")
end = WORKSPACE_JS.index("\nfunction renderCsvPreviewContent(path, content){", start)
return WORKSPACE_JS[start:end]
def test_workspace_preview_assigns_prism_language_class():
body = _open_file_body()
helper = _code_preview_helper()
assert "renderCodePreviewContent(path, data.content);" in body
assert "_prismLanguageForPath(path)" in helper
assert "codeEl.className='language-'+lang" in helper
assert "Prism.highlightElement(codeEl)" in helper
def test_prism_language_map_covers_common_extensions():
assert "_PRISM_LANG_MAP" in WORKSPACE_JS
for ext_token in ["py:'python'", "js:'javascript'", "css:'css'", "json:'json'"]:
assert ext_token in WORKSPACE_JS, f"language map should include {ext_token}"
# txt/log/csv intentionally map to '' (no highlighting).
assert "txt:''" in WORKSPACE_JS
def test_prism_language_path_fallback_covers_extensionless_code_filenames():
"""Common code/config filenames without useful extensions should still
activate Prism grammar selection in workspace previews (#3365).
"""
assert "_PRISM_BASENAME_LANG_MAP" in WORKSPACE_JS
expected = {
"Dockerfile": "docker",
"Makefile": "makefile",
"makefile": "makefile",
"GNUmakefile": "makefile",
"CMakeLists.txt": "cmake",
".gitignore": "ignore",
".dockerignore": "ignore",
}
for filename, language in expected.items():
assert f"{filename.lower()!r}:{language!r}" in WORKSPACE_JS
assert "base.startsWith('dockerfile.')" in WORKSPACE_JS
def test_plain_text_files_do_not_inherit_prior_file_highlighting():
"""Cross-file leak fix: a plain-text preview after a code preview must not
inherit the previous file's language. Two guards make this hold:
1. The <pre> ancestor's stale language-* class is stripped before each render
(Prism propagates the class to the parent, so it would otherwise leak).
2. Prism.highlightElement is only called when a non-empty language was
assigned, so a class-less <code> never walks up to an ancestor class.
"""
helper = _code_preview_helper()
# Guard 1: stale language-* token stripped from the <pre> before append.
assert "pre.className=pre.className.replace(/\\blanguage-\\S+/g,'')" in helper, (
"previewCode <pre> must have stale language-* classes stripped each render"
)
# Guard 2: highlightElement gated on a truthy lang.
assert "if(lang&&typeof Prism!=='undefined'&&typeof Prism.highlightElement==='function')" in helper, (
"Prism.highlightElement must only run when a language was assigned"
)