Files
odysseus/tests/test_editor_brush_engine_js.py
T

77 lines
2.7 KiB
Python

import json
import subprocess
import textwrap
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
ENGINE = (ROOT / "static/js/editor/brush-engine.js").as_uri()
PRESETS = (ROOT / "static/js/editor/brush-presets.js").as_uri()
def run_node(body: str):
result = subprocess.run(
["node", "--input-type=module", "-e", textwrap.dedent(body)],
cwd=ROOT,
text=True,
capture_output=True,
check=True,
)
return json.loads(result.stdout)
def test_sampler_emits_even_spacing_and_flushes_endpoint():
data = run_node(
f"""
import {{ createBrushSampler }} from {json.dumps(ENGINE)};
const samples = [];
const sampler = createBrushSampler({{
getDiameter: () => 20,
getSpacing: () => 0.25,
getSmoothing: () => 0,
emit: sample => samples.push(sample),
}});
sampler.begin({{x:0,y:0,pressure:1}});
sampler.add({{x:20,y:0,pressure:0.5}});
sampler.end({{x:23,y:0,pressure:0.25}});
console.log(JSON.stringify(samples));
"""
)
assert [round(item["x"]) for item in data] == [0, 5, 10, 15, 20, 23]
assert data[-1]["pressure"] == 0.25
def test_pressure_mapping_is_independent_and_mouse_falls_back_to_full():
data = run_node(
f"""
import {{ normalisePressure, pressureValue }} from {json.dumps(ENGINE)};
console.log(JSON.stringify({{
mouse: normalisePressure(0),
size: pressureValue(100, 0.25, true),
opacityOff: pressureValue(0.8, 0.25, false),
}}));
"""
)
assert data == {"mouse": 1, "size": 25, "opacityOff": 0.8}
def test_custom_presets_roundtrip_without_mutating_built_ins():
data = run_node(
f"""
import {{ loadBrushPresets, saveCustomBrushPresets, captureBrushPreset, applyBrushPreset }} from {json.dumps(PRESETS)};
const values = new Map();
const storage = {{ getItem:key => values.get(key) || null, setItem:(key,value) => values.set(key,value) }};
const state = {{brushSize:42,brushOpacity:80,brushFlow:60,brushSoftness:20,brushSpacing:14,brushSmoothing:45,brushBlendMode:'multiply'}};
const preset = captureBrushPreset(state, 'Texture');
saveCustomBrushPresets([preset], storage);
const loaded = loadBrushPresets(storage);
const target = {{}};
applyBrushPreset(target, loaded.at(-1));
console.log(JSON.stringify({{names:loaded.map(item => item.name), target}}));
"""
)
assert data["names"][:3] == ["Soft Round", "Hard Round", "Detail"]
assert data["names"][-1] == "Texture"
assert data["target"]["brushSize"] == 42
assert data["target"]["brushBlendMode"] == "multiply"