mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-02 13:02:20 +02:00
Squash Odysseus development history
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
import json
|
||||
import subprocess
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
MODULE = (ROOT / "static/js/editor/text-layer.js").as_uri()
|
||||
|
||||
|
||||
def run_node(body: str):
|
||||
script = textwrap.dedent(
|
||||
f"""
|
||||
import {{ normalizeTextData, rasterizeTextLayer, renderTextLayer }} from {json.dumps(MODULE)};
|
||||
let id = 0;
|
||||
function canvas(tag='canvas') {{
|
||||
const value = {{tag, width:0, height:0, draws:[], fills:[], strokes:[]}};
|
||||
const ctx = {{
|
||||
font:'', textBaseline:'', textAlign:'left', fillStyle:'', strokeStyle:'',
|
||||
lineWidth:0, lineJoin:'', imageSmoothingEnabled:false, imageSmoothingQuality:'low',
|
||||
measureText(text) {{ return {{width:String(text).length * 10}}; }},
|
||||
fillText(...args) {{ value.fills.push(args); }},
|
||||
strokeText(...args) {{ value.strokes.push(args); }},
|
||||
drawImage(...args) {{ value.draws.push(args.map(item => item?.tag || item)); }},
|
||||
clearRect() {{}}, translate() {{}}, rotate() {{}}, scale() {{}},
|
||||
}};
|
||||
value.getContext = () => ctx;
|
||||
return value;
|
||||
}}
|
||||
globalThis.document = {{createElement:() => canvas(`canvas-${{++id}}`)}};
|
||||
{body}
|
||||
"""
|
||||
)
|
||||
result = subprocess.run(
|
||||
["node", "--input-type=module", "-e", script],
|
||||
cwd=ROOT,
|
||||
text=True,
|
||||
capture_output=True,
|
||||
check=True,
|
||||
)
|
||||
return json.loads(result.stdout)
|
||||
|
||||
|
||||
def test_text_renderer_keeps_editable_metadata_and_builds_raster_cache():
|
||||
result = run_node(
|
||||
"""
|
||||
const target = canvas('target');
|
||||
const layer = {
|
||||
canvas:target, ctx:target.getContext('2d'),
|
||||
text:{
|
||||
content:'Hello\\nWorld', fontFamily:'Georgia', fontSize:20,
|
||||
fontWeight:'700', fontStyle:'italic', align:'center', color:'#ff0000',
|
||||
strokeColor:'#000000', strokeWidth:2, lineHeight:1.5,
|
||||
transform:{scaleX:2,scaleY:1.5,rotation:15,flipH:true,flipV:false},
|
||||
},
|
||||
};
|
||||
renderTextLayer(layer);
|
||||
console.log(JSON.stringify({
|
||||
kind:layer.kind, content:layer.text.content, font:layer.text.fontFamily,
|
||||
transform:layer.text.transform, size:[layer.canvas.width,layer.canvas.height],
|
||||
finalDraw:layer.canvas.draws.at(-1),
|
||||
}));
|
||||
"""
|
||||
)
|
||||
|
||||
assert result["kind"] == "text"
|
||||
assert result["content"] == "Hello\nWorld"
|
||||
assert result["font"] == "Georgia"
|
||||
assert result["transform"] == {
|
||||
"scaleX": 2, "scaleY": 1.5, "rotation": 15, "flipH": True, "flipV": False
|
||||
}
|
||||
assert result["size"][0] > 100
|
||||
assert result["size"][1] > 80
|
||||
assert result["finalDraw"][1:] == [0, 0]
|
||||
|
||||
|
||||
def test_text_data_normalization_bounds_invalid_values():
|
||||
result = run_node(
|
||||
"""
|
||||
console.log(JSON.stringify(normalizeTextData({
|
||||
content:42, fontSize:-5, align:'diagonal', lineHeight:99,
|
||||
transform:{scaleX:0,scaleY:'bad',rotation:'bad',flipV:1},
|
||||
})));
|
||||
"""
|
||||
)
|
||||
|
||||
assert result["content"] == "42"
|
||||
assert result["fontSize"] == 1
|
||||
assert result["align"] == "left"
|
||||
assert result["lineHeight"] == 5
|
||||
assert result["letterSpacing"] == 0
|
||||
assert result["frameWidth"] == 320
|
||||
assert result["frameHeight"] == 0
|
||||
assert result["verticalAlign"] == "top"
|
||||
assert result["transform"]["scaleX"] == 0.01
|
||||
assert result["transform"]["scaleY"] == 1
|
||||
assert result["transform"]["rotation"] == 0
|
||||
assert result["transform"]["flipV"] is True
|
||||
|
||||
|
||||
def test_rasterize_text_layer_clears_retained_metadata_only_for_text():
|
||||
result = run_node(
|
||||
"""
|
||||
const text = {kind:'text', text:{content:'Still editable'}};
|
||||
const raster = {kind:'raster', text:null};
|
||||
console.log(JSON.stringify({
|
||||
changed:rasterizeTextLayer(text), text,
|
||||
rasterChanged:rasterizeTextLayer(raster), raster,
|
||||
}));
|
||||
"""
|
||||
)
|
||||
|
||||
assert result["changed"] is True
|
||||
assert result["text"] == {"kind": "raster", "text": None}
|
||||
assert result["rasterChanged"] is False
|
||||
assert result["raster"] == {"kind": "raster", "text": None}
|
||||
|
||||
|
||||
def test_text_tool_is_retained_across_editor_subsystems():
|
||||
editor = (ROOT / "static/js/galleryEditor.js").read_text(encoding="utf-8")
|
||||
toolbar = (ROOT / "static/js/editor/build/toolbar.js").read_text(encoding="utf-8")
|
||||
controls = (ROOT / "static/js/editor/build/controls.js").read_text(encoding="utf-8")
|
||||
codec = (ROOT / "static/js/editor/document-codec.js").read_text(encoding="utf-8")
|
||||
geometry = (ROOT / "static/js/editor/document-geometry.js").read_text(encoding="utf-8")
|
||||
transform = (ROOT / "static/js/editor/tools/transform-session.js").read_text(encoding="utf-8")
|
||||
panel = (ROOT / "static/js/editor/layer-panel.js").read_text(encoding="utf-8")
|
||||
merge = (ROOT / "static/js/editor/wire-merge-buttons.js").read_text(encoding="utf-8")
|
||||
|
||||
assert "{ id: 'text', label: 'Text'" in toolbar
|
||||
assert "key: 'T'" in toolbar
|
||||
assert 'id="ge-text-section"' in controls
|
||||
assert "if (state.tool === 'text') return _placeText(e);" in editor
|
||||
assert "kind: l.kind || 'raster'" in editor
|
||||
assert "text: _cloneDocumentValue(l.text, null)" in editor
|
||||
assert "kind: layer.kind || 'raster'" in codec
|
||||
assert "text: cloneDocumentValue(layer.text, null)" in codec
|
||||
assert "scaleTextLayer(layer, scaleX, scaleY)" in geometry
|
||||
assert "rotateTextLayer(layer, normalized)" in geometry
|
||||
assert "renderTextLayer(layer)" in transform
|
||||
assert 'id="ge-text-rasterize"' in controls
|
||||
assert "layer.kind = 'raster'" in editor
|
||||
assert "layer.text = null" in editor
|
||||
assert "rasterizeTextLayer(layer);" in panel
|
||||
assert "rasterizeTextLayer(layer);" in merge
|
||||
assert "_rasterizeTextLayer(layer)" in editor
|
||||
assert 'id="ge-text-letter-spacing"' in controls
|
||||
assert 'id="ge-text-frame-width"' in controls
|
||||
assert 'id="ge-text-frame-height"' in controls
|
||||
assert 'id="ge-text-vertical-align"' in controls
|
||||
assert 'id="ge-text-auto-width"' in controls
|
||||
assert 'autoWidth: !!document.getElementById(\'ge-text-auto-width\')?.checked' in editor
|
||||
assert "createTextEditOverlay" in editor
|
||||
|
||||
|
||||
def test_text_auto_width_control_does_not_share_move_tool_selector():
|
||||
controls = (ROOT / "static/js/editor/build/controls.js").read_text(encoding="utf-8")
|
||||
assert 'class="ge-text-auto-width-option"' in controls
|
||||
assert 'class="ge-auto-select-option ge-text-auto-width-option"' not in controls
|
||||
Reference in New Issue
Block a user