mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-03 13:32:21 +02:00
Squash Odysseus development history
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
import json
|
||||
import subprocess
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
MODULE = (ROOT / "static/js/editor/layer-clipping.js").as_uri()
|
||||
|
||||
|
||||
def run_node(body: str):
|
||||
script = textwrap.dedent(
|
||||
f"""
|
||||
import {{canToggleLayerClipping,clippingBaseForLayer,drawLayerStack,normalizeLayerClipping}} from {json.dumps(MODULE)};
|
||||
{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_clipping_topology_stays_inside_group_scope_and_repairs_invalid_flags():
|
||||
result = run_node(
|
||||
"""
|
||||
const layers=['root','group-base','group-clip','after'].map(id=>({id,clipped:id!=='root'}));
|
||||
const state={layers,layerGroups:[{id:'g',layerIds:['group-base','group-clip']}]};
|
||||
const before={
|
||||
groupBase:clippingBaseForLayer(state,'group-clip')?.id || null,
|
||||
afterBase:clippingBaseForLayer(state,'after')?.id || null,
|
||||
canRoot:canToggleLayerClipping(state,'root'),
|
||||
};
|
||||
const cleared=normalizeLayerClipping(state);
|
||||
console.log(JSON.stringify({before,cleared,clipped:layers.map(layer=>layer.clipped)}));
|
||||
"""
|
||||
)
|
||||
assert result["before"] == {"groupBase": None, "afterBase": None, "canRoot": False}
|
||||
assert result["cleared"] == ["group-base", "after"]
|
||||
assert result["clipped"] == [False, False, True, False]
|
||||
|
||||
|
||||
def test_clipped_layer_is_masked_by_base_alpha_before_its_opacity_and_blend():
|
||||
result = run_node(
|
||||
"""
|
||||
const operations=[];
|
||||
const makeCtx=tag=>({
|
||||
tag,_alpha:1,_gco:'source-over',
|
||||
clearRect(){operations.push([tag,'clear']);},
|
||||
drawImage(image,x=0,y=0){operations.push([tag,'draw',image.tag,x,y,this._alpha,this._gco]);},
|
||||
set globalAlpha(value){this._alpha=value;},get globalAlpha(){return this._alpha;},
|
||||
set globalCompositeOperation(value){this._gco=value;},get globalCompositeOperation(){return this._gco;},
|
||||
});
|
||||
const scratch={tag:'clip-scratch',width:0,height:0,getContext:()=>scratchCtx};
|
||||
const scratchCtx=makeCtx('clip-scratch');
|
||||
globalThis.document={createElement:()=>scratch};
|
||||
const target=makeCtx('target');
|
||||
const layers=[
|
||||
{id:'base',visible:true,opacity:.4,blendMode:'source-over',clipped:false},
|
||||
{id:'color',visible:true,opacity:.7,blendMode:'multiply',clipped:true},
|
||||
];
|
||||
const state={imgWidth:100,imgHeight:80,layers,layerGroups:[],layerOffsets:new Map([['base',{x:3,y:4}],['color',{x:8,y:9}]])};
|
||||
drawLayerStack(target,state,layers,layer=>({tag:layer.id}));
|
||||
console.log(JSON.stringify(operations));
|
||||
"""
|
||||
)
|
||||
assert ["target", "draw", "base", 3, 4, 0.4, "source-over"] in result
|
||||
assert ["clip-scratch", "draw", "color", 8, 9, 1, "source-over"] in result
|
||||
assert ["clip-scratch", "draw", "base", 3, 4, 1, "destination-in"] in result
|
||||
assert ["target", "draw", "clip-scratch", 0, 0, 0.7, "multiply"] in result
|
||||
Reference in New Issue
Block a user