mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-16 11:52:25 +02:00
Photoshop-parity editor client: layers, selection/masking, brushes,
smart filters, LUT import, Quick Edit, mobile gestures, workspaces,
batch operations, and the service-worker versioning (v978->v1006).
Source: vendor/photocraft (ad1cff44) photo-editor client files, merged
onto upstream/dev (a8c147b2). Conflict resolution documented in
pr_work/A_conflicts.md; editor files taken from vendor/photocraft
(upstream's editor is an earlier snapshot of the same feature).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
129 lines
5.4 KiB
Python
129 lines
5.4 KiB
Python
"""Static contract tests for the View > Panels visibility feature.
|
|
|
|
The panel-visibility module, its CSS, the View/Window menu markup, the wiring
|
|
and the control-op catalog are plain JavaScript, so these tests assert the
|
|
contract at the source level (the project's editor suites are contract/static,
|
|
not a JS runtime).
|
|
"""
|
|
import re
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
MODULE = ROOT / "static/js/editor/panel-visibility.js"
|
|
CSS = ROOT / "static/css/13-image-editor.css"
|
|
TOPBAR = ROOT / "static/js/editor/build/topbar.js"
|
|
VIEW_WIRE = ROOT / "static/js/editor/wire-view-menu.js"
|
|
EXTRA_WIRE = ROOT / "static/js/editor/wire-extra-menus.js"
|
|
GALLERY = ROOT / "static/js/galleryEditor.js"
|
|
SW = ROOT / "static/sw.js"
|
|
|
|
|
|
def _read(path):
|
|
return path.read_text(encoding="utf-8")
|
|
|
|
|
|
def test_module_registry_and_api():
|
|
src = _read(MODULE)
|
|
assert "export const PANELS = Object.freeze([" in src
|
|
for pid in ["swatches", "gradients", "patterns", "properties", "adjustments",
|
|
"histogram", "info", "channels", "paths", "character",
|
|
"navigator", "history", "actions", "layers", "options"]:
|
|
assert f"id: '{pid}'" in src, pid
|
|
for fn in ["export function isVisible(id)",
|
|
"export function list()",
|
|
"export function apply()",
|
|
"export function setVisible(id, visible)",
|
|
"export function toggle(id)",
|
|
"export function showAll()",
|
|
"export function hideAll()",
|
|
"export function reset()",
|
|
"export function subscribe(fn)"]:
|
|
assert fn in src, fn
|
|
|
|
|
|
def test_module_persists_and_tags_dom():
|
|
src = _read(MODULE)
|
|
assert "const STORAGE_KEY = 'ge-panel-visibility';" in src
|
|
assert 'localStorage.setItem(STORAGE_KEY, JSON.stringify(map))' in src
|
|
assert 'data-panel-hidden' in src
|
|
# Tags the wrapper, the tab-strip item, the compact select option,
|
|
# the collapsed group, the pinned Layers strip and the Tool Options bar.
|
|
assert '.ge-dock-panel[data-panel="${id}"]' in src
|
|
assert '.ge-dock-tab-item[data-panel="${id}"]' in src
|
|
assert '.ge-dock-select option[value="${id}"]' in src
|
|
assert '.ge-dock-group[data-group="${group}"]' in src
|
|
assert "document.querySelector('.ge-layers')" in src
|
|
assert "document.querySelector('.ge-controls')" in src
|
|
|
|
|
|
def test_css_hides_tagged_nodes():
|
|
src = _read(CSS)
|
|
assert '.ge-dock-panel[data-panel-hidden="1"]' in src
|
|
assert '.ge-dock-tab-item[data-panel-hidden="1"]' in src
|
|
assert '.ge-dock-group[data-panel-hidden="1"]' in src
|
|
assert '.ge-dock-divider[data-panel-hidden="1"]' in src
|
|
assert '.ge-layers[data-panel-hidden="1"]' in src
|
|
assert '.ge-controls[data-panel-hidden="1"]' in src
|
|
|
|
|
|
def test_view_menu_has_panels_group_and_layout_actions():
|
|
src = _read(TOPBAR)
|
|
assert '<div class="ge-menu-label">Panels</div>' in src
|
|
assert '<div class="ge-menu-label">Panel layout</div>' in src
|
|
for pid in ["options", "layers", "swatches", "gradients", "patterns",
|
|
"properties", "adjustments", "histogram", "info", "channels",
|
|
"paths", "character", "navigator", "history", "actions"]:
|
|
assert f'data-view-action="panel-{pid}"' in src, pid
|
|
for action in ["panel-show-all", "panel-hide-all", "panel-reset"]:
|
|
assert f'data-view-action="{action}"' in src, action
|
|
|
|
|
|
def test_view_menu_wiring():
|
|
src = _read(VIEW_WIRE)
|
|
assert "import * as panelVisibility from './panel-visibility.js';" in src
|
|
assert '[data-view-action="panel-${panel.id}"]' in src
|
|
assert "item?.classList.toggle('active', !!panel.visible);" in src
|
|
assert "if (action === 'panel-show-all')" in src
|
|
assert "if (action === 'panel-hide-all')" in src
|
|
assert "if (action === 'panel-reset')" in src
|
|
assert "if (action.startsWith('panel-'))" in src
|
|
assert "panelVisibility.toggle(action.slice('panel-'.length))" in src
|
|
|
|
|
|
def test_window_menu_keeps_the_show_panel_contract():
|
|
# The Window menu stays a "bring a panel to front / focus it" menu; panel
|
|
# show/hide toggles live in the View menu (above). Guards against the two
|
|
# menus claiming the same data-window-action values.
|
|
src = _read(TOPBAR)
|
|
for action in ["options", "layers", "properties", "character", "adjustments",
|
|
"swatches", "gradients", "channels", "paths", "patterns",
|
|
"histogram", "info", "navigator", "history", "actions"]:
|
|
assert f'data-window-action="{action}"' in src, action
|
|
assert 'data-window-action="panel-' not in src
|
|
|
|
|
|
def test_window_menu_wiring_targets_existing_surfaces():
|
|
src = _read(EXTRA_WIRE)
|
|
assert "togglePanel?.(action)" in src
|
|
assert "click('ge-history-btn')" in src
|
|
assert 'data-window-action="panel-' not in src
|
|
assert "panelVisibility" not in src
|
|
|
|
|
|
def test_gallery_editor_mounts_and_exposes_control_ops():
|
|
src = _read(GALLERY)
|
|
assert "import * as panelVisibility from './editor/panel-visibility.js';" in src
|
|
assert "panelVisibility.apply();" in src
|
|
assert "window.gePanelVisibility = panelVisibility;" in src
|
|
for op in ["panels.list", "panels.setVisible", "panels.toggle",
|
|
"panels.showAll", "panels.hideAll", "panels.reset"]:
|
|
assert f"'{op}':" in src, op
|
|
assert "panelVisibility.setVisible(p.id, p.visible !== false)" in src
|
|
assert "panelVisibility.toggle(p.id)" in src
|
|
|
|
|
|
def test_sw_cache_name_bumped():
|
|
src = _read(SW)
|
|
assert re.search(r"odysseus-v\d+-pr40-editor-precache", src)
|