Files
EscapistsReintroduced/tests/test_objective_map_element.py
T
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

59 lines
4.2 KiB
Python

"""Actual authored map element updates avoid repeated text/texture loads while panning."""
from pathlib import Path
import os
from policy_harness import ROOT, body, run
root=Path(os.environ.get('ERR_OBJECTIVE_MAP_ROOT',ROOT))
p=root/'addons/core/Scripts/Game/ERR/00_Core/ERR_ObjectiveMapPresentation.c'
# Native Enforce requires the inherited override argument name, not only its type.
assert 'override void HandlerAttached(Widget w)' in p.read_text()
assert 'super.HandlerAttached(w);' in body(p,'override void HandlerAttached(')
s=body(p,'void SetObjective(').replace('ResourceName','string')
for n in ['m_ERRText','m_ERRImage']:s=s.replace(n+'.',n+'->')
run(r'''
#include <cassert>
#include <string>
using string=std::string;
struct vector{int x=0,z=0;};
struct TextWidget{string text;int sets=0;void SetText(string t){text=t;sets++;}};
struct ImageWidget{string source,icon;int loads=0;bool succeeds=true,visible=true;bool LoadImageFromSet(int,string s,string i){source=s;icon=i;loads++;return succeeds;}void SetVisible(bool v){visible=v;}};
struct Element{vector m_ERRPosition;TextWidget*m_ERRText=nullptr;ImageWidget*m_ERRImage=nullptr;bool m_ERRTextReady=false,m_ERRImageReady=false;string m_ERRLastText,m_ERRLastIcon;
'''+s+r'''
};
int main(){
TextWidget text;ImageWidget image;Element e;e.m_ERRText=&text;e.m_ERRImage=&image;
e.SetObjective({250,750},"Unknown location (500 m area)","mark-question");assert(text.sets==1&&image.loads==1&&image.source.find("UI/Textures/ERR/SiteMarkers.imageset")!=string::npos);
for(int i=0;i<500;i++)e.SetObjective({i,750},"Unknown location (500 m area)","mark-question");
assert(text.sets==1&&image.loads==1&&e.m_ERRPosition.x==499);
e.SetObjective({612,734},"Radio station","radio");assert(text.sets==2&&image.loads==2&&image.icon=="radio"&&image.source.find("UI/Textures/ERR/SiteMarkers.imageset")!=string::npos);
e.SetObjective({612,734},"Changed label","radio");assert(text.sets==3&&image.loads==2);
e.SetObjective({612,734},"Changed label","supplies");assert(text.sets==3&&image.loads==3);
// Failed lookup hides the untextured rectangle and retries the same icon next update.
image.succeeds=false;e.SetObjective({612,734},"Unknown", "mark-question");
assert(!e.m_ERRImageReady&&!image.visible&&image.loads==4);
image.succeeds=true;e.SetObjective({612,734},"Unknown", "mark-question");
assert(e.m_ERRImageReady&&image.visible&&image.loads==5&&image.icon=="mark-question");
// Each new widget initializes even for the same data; caches are instance-owned.
TextWidget nextText;ImageWidget nextImage;Element next;next.m_ERRText=&nextText;next.m_ERRImage=&nextImage;
next.SetObjective({612,734},"Changed label","supplies");assert(nextText.sets==1&&nextImage.loads==1&&text.sets==4);
Element delayed;delayed.SetObjective({1,2},"", "mark-question");assert(!delayed.m_ERRTextReady&&!delayed.m_ERRImageReady&&delayed.m_ERRPosition.z==2);
delayed.m_ERRText=&nextText;delayed.SetObjective({3,4},"", "mark-question");assert(nextText.text.empty()&&delayed.m_ERRTextReady&&!delayed.m_ERRImageReady);
int sets=nextText.sets;delayed.m_ERRImage=&nextImage;delayed.SetObjective({5,6},"", "mark-question");assert(nextText.sets==sets&&delayed.m_ERRImageReady&&nextImage.loads==2);
}
''')
print('PASS: actual map element initializes each widget, retries missing widgets, updates position and changes only stale text/icon data; no native image-load claim')
# All generated marker names must survive resource tokenization unchanged. A
# hyphenated bare identifier can lose the suffix while other atlas entries work.
import ast, re
atlas=(root/'addons/core/UI/Textures/ERR/SiteMarkers.imageset').read_text()
names=[]
for token in re.findall(r'ImageSetDefClass\s+([^\n{]+)\s*\{', atlas):
token=token.strip()
assert re.fullmatch(r'"[^"\n]+"|[A-Za-z_][A-Za-z_0-9]*', token), token
names.append(token.strip('"'))
module=ast.parse((root/'tools/generate_map_icons.py').read_text())
symbols=next(ast.literal_eval(n.value) for n in module.body if isinstance(n,ast.Assign) and any(isinstance(t,ast.Name) and t.id=='SYMBOLS' for t in n.targets))
assert names==[symbol[2] for symbol in symbols]
assert 'mark-question' in names
print('PASS: all atlas identifiers, including the quoted question mark, match the generator')