"""Actual Stinger feedback and parsing, against a failure-injectable settings boundary.""" from pathlib import Path import os from policy_harness import ROOT,body,run P=Path(os.environ.get('ERR_HQ_ADMIN_SOURCE',str(ROOT/'addons/core/Scripts/Game/ERR/10_AI/ERR_HQAdminProvider.c'))) S=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_Settings.c' valid=body(S,'static bool Valid(').replace('string key','std::string key') integer=body(ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminService.c','static bool Integer(') integer=(integer.replace('string text','std::string text').replace('out int value','int& value').replace('text.IsEmpty()','text.empty()').replace('text.Length()','int(text.size())').replace('text.Substring(','text.substr(').replace('"0123456789".IndexOf(', 'std::string("0123456789").find(').replace('< 0) return false;','== std::string::npos) return false;').replace('text.ToInt()','std::stoi(text)')) method=body(P,'protected void StingerSetting(') method=(method.replace('protected ','').replace('ERR_GameMode mode','ERR_GameMode* mode').replace('array','Array&').replace('mode.Settings().','mode->Settings()->').replace('ERR_CommandArguments.Integer','Integer').replace('mode->Settings()->Get(key).ToString()','std::to_string(mode->Settings()->Get(key))').replace('value.ToString()','std::to_string(value)').replace('int value;','int value=0;')) run(r''' #include #include #include using string=std::string; templatestruct Array:std::vector{using std::vector::vector;int Count(){return this->size();}void Insert(T x){this->push_back(x);}}; '''+valid+integer+r''' struct Settings{int chance=15,writes=0;bool fail=false; int Get(string key){assert(key=="stingerChanceOneIn");return chance;} bool Set(string key,int value){writes++;if(fail||!Valid(key,value))return false;chance=value;return true;}}; struct ERR_GameMode{struct Settings settings;struct Settings* Settings(){return &settings;}}; struct Provider{ '''+method+r''' }; void Effect(const Array& r){assert(r.back().find("have not rolled yet")!=string::npos&&r.back().find("no reroll, removal or replenishment")!=string::npos);} int main(){ ERR_GameMode mode;Provider p;Array replies; Array show{"hq","stinger","show"};p.StingerSetting(&mode,show,replies); assert(mode.settings.writes==0&&replies.back().find("stingerChanceOneIn=15")!=string::npos);Effect(replies); Array help{"hq","stinger","help"};p.StingerSetting(&mode,help,replies); assert(mode.settings.writes==0&&replies.back().find("0 off, 1 every eligible soldier, 2..10000 one in N")!=string::npos);Effect(replies); Array setting{"hq","stinger","set","0"}; for(int n:{0,1,2,15,10000}){ setting[3]=std::to_string(n);p.StingerSetting(&mode,setting,replies); assert(mode.settings.chance==n&&replies.back().find(" saved.")!=string::npos);Effect(replies); } for(string invalid:{"-1","1.0","1junk","10000000","10001","1e1","+1"}){ setting[3]=invalid;p.StingerSetting(&mode,setting,replies); assert(mode.settings.chance==10000&&replies.back().find("previous setting retained")!=string::npos&&replies.back().find(" saved.")==string::npos);Effect(replies); } setting[3]="0";mode.settings.fail=true;p.StingerSetting(&mode,setting,replies); assert(mode.settings.chance==10000&&replies.back().find("previous setting retained")!=string::npos);Effect(replies); int writes=mode.settings.writes; for(Array malformed: {Array{"hq","stinger"},Array{"hq","stinger","set"},Array{"hq","stinger","show","extra"}}){ p.StingerSetting(&mode,malformed,replies);assert(mode.settings.writes==writes&&replies.back().find("previous setting retained")!=string::npos); } } ''') execute=body(P,'override bool Execute(') assert execute.index('arguments.IndexOf("hq stinger ") == 0')