Files
odysseus/tests/test_editor_adj_popup_slider_params.py
T

44 lines
1.8 KiB
Python

"""Every adjustment popup that renders slider rows must store their values.
``buildAdjBody`` renders ``sliderRow`` controls per adjustment type, and
``onAdjSliderInput`` maps a moved slider onto ``layer._stagedAdj.params``. A
type with rows but no input branch shows a working slider whose value is
silently dropped on OK (Vibrance regressed exactly this way). The browser
behavior is covered by tests/e2e/photo-editor/adjustment-layers.spec.js.
"""
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
POPUP = (ROOT / "static/js/editor/fx/adj-popup.js").read_text(encoding="utf-8")
def _function_body(name: str, next_name: str) -> str:
start = POPUP.index(f"function {name}(")
return POPUP[start:POPUP.index(f"function {next_name}(", start)]
def _types_with_slider_rows() -> set[str]:
builder = _function_body("buildAdjBody", "onAdjSliderInput")
branches = re.split(r"\}\s*else if \(|if \(type === ", builder)
types = set()
for branch in branches:
names = re.findall(r"type === '([a-z-]+)'", "type === " + branch.split(")", 1)[0])
if names and "sliderRow(" in branch:
types.update(names)
return types
def test_every_slider_adjustment_type_writes_its_params():
rendered = _types_with_slider_rows()
assert {"exposure", "white-balance", "vibrance", "black-white"} <= rendered, rendered
handler = _function_body("onAdjSliderInput", "wireCurveEditor")
handled = set(re.findall(r"type === '([a-z-]+)'", handler))
missing = sorted(rendered - handled)
assert not missing, f"slider rows whose input is never stored: {missing}"
def test_vibrance_slider_stores_the_raw_value():
handler = _function_body("onAdjSliderInput", "wireCurveEditor")
assert re.search(r"else if \(type === 'vibrance'\) \{\s*p\[key\] = raw;", handler)