XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using AngleSharp.Html.Parser;
using XFESystem.Browser;

namespace XFESystem.Kernel;

/// <summary>Same code is run on the guest: reports actual JavaScript/host identity and dispatch results.</summary>
public static class BrowserNativeEventRegression
{
    public static bool Run(BrowserService browser, Action<string> log)
    {
        var passed = true;
        void Stage(string name, string actual, string expected)
        {
            var ok = actual == expected; passed &= ok;
            log("XFE_BROWSER_EVENT_REGRESSION|" + name + "|" + (ok ? "PASS" : "FAIL") + "|" + actual.Replace('\r', ' ').Replace('\n', ' ') + "\n");
        }
        string Page(string source) => browser.ExecuteJavaScript(source);
        try
        {
            Stage("WeakMapPlainSameEval", Page("var __xfeRegKey={},__xfeRegWeak=new WeakMap();__xfeRegWeak.set(__xfeRegKey,42);__xfeRegWeak.has(__xfeRegKey)+':'+__xfeRegWeak.get(__xfeRegKey)"), "true:42");
            Stage("WeakMapPlainCrossEval", Page("__xfeRegWeak.has(__xfeRegKey)+':'+__xfeRegWeak.get(__xfeRegKey)"), "true:42");
            Stage("WeakMapHostSameEval", Page("var __xfeRegBody=document.body,__xfeRegHostWeak=new WeakMap();__xfeRegHostWeak.set(__xfeRegBody,43);__xfeRegHostWeak.has(document.body)+':'+__xfeRegHostWeak.get(document.body)+':'+(__xfeRegBody===document.body)"), "true:43:true");
            Stage("WeakMapHostCrossEval", Page("__xfeRegHostWeak.has(document.body)+':'+__xfeRegHostWeak.get(document.body)+':'+(__xfeRegBody===document.body)"), "true:43:true");
            Stage("PlainEventTargetSameEval", Page("var __xfeRegCount=0,__xfeRegTarget=new EventTarget();__xfeRegTarget.addEventListener('xfe-test',()=>++__xfeRegCount);__xfeRegTarget.dispatchEvent(new Event('xfe-test'));__xfeRegCount"), "1");
            Stage("PlainEventTargetCrossEval", Page("__xfeRegTarget.dispatchEvent(new Event('xfe-test'));__xfeRegCount"), "2");
            Stage("HostEventSameEval", Page("var __xfeRegButton=document.createElement('button');__xfeRegButton.id='XfeNativeEventRegression';document.body.appendChild(__xfeRegButton);var __xfeRegButtonCount=0;__xfeRegButton.addEventListener('click',()=>{++__xfeRegButtonCount;__xfeRegButton.textContent='clicked '+__xfeRegButtonCount;});__xfeRegButton.dispatchEvent(new Event('click'));__xfeRegButtonCount+':'+__xfeRegButton.textContent"), "1:clicked 1");
            Stage("HostEventCrossEval", Page("document.getElementById('XfeNativeEventRegression').dispatchEvent(new Event('click'));__xfeRegButtonCount+':'+__xfeRegButton.textContent"), "2:clicked 2");
            Stage("HostClickMethodCrossEval", Page("document.getElementById('XfeNativeEventRegression').click();__xfeRegButtonCount+':'+__xfeRegButton.textContent"), "3:clicked 3");
            Stage("HostListenerReceiver", Page("var __xfeRegSameReceiver=false;__xfeRegButton.addEventListener('receiver',function(e){__xfeRegSameReceiver=this===__xfeRegButton&&e.target===this;});__xfeRegButton.dispatchEvent(new Event('receiver'));__xfeRegSameReceiver"), "true");
            Page("__xfeRegButton.remove()");
        }
        catch (Exception error) { passed = false; log("XFE_BROWSER_EVENT_REGRESSION|PageException|FAIL|" + error.Message + "\n"); }
        try
        {
            var limits = new BrowserLimits(); var runtime = new JavaScriptRuntime(limits);
            var document = new HtmlParser().ParseDocument("<button id='Button'>Before</button>"); var mutations = 0;
            var dom = new DomBridge(runtime, document, new Uri("http://xfe.test/Regression"), limits, new() { Mutated = () => ++mutations });
            Stage("BridgeSetup", runtime.Evaluate("var count=0;var button=document.getElementById('Button');button.addEventListener('click',()=>{++count;button.textContent='clicked '+count;});'ready'").Text, "ready");
            Stage("BridgeCrossCSharpAllowed", dom.DispatchEvent(document.GetElementById("Button"), "click").ToString(), "True");
            Stage("BridgeCrossCSharpMutation", runtime.Evaluate("count+':'+document.getElementById('Button').textContent").Text, "1:clicked 1");
            Stage("BridgeMutationCallback", mutations.ToString(), "1");
            Stage("BridgeWeakMapIdentity", runtime.Evaluate("var weak=new WeakMap();weak.set(button,44);weak.get(document.getElementById('Button'))+':'+weak.has(button)").Text, "44:true");
            Stage("BridgeSecondCSharpAllowed", dom.DispatchEvent(document.GetElementById("Button"), "click").ToString(), "True");
            Stage("BridgeSecondCSharpMutation", runtime.Evaluate("count+':'+button.textContent").Text, "2:clicked 2");
            Stage("BridgeEventErrorVisible", runtime.Evaluate("var afterError=0;button.addEventListener('error-probe',()=>{throw Error('NativeEventErrorVisible');});button.addEventListener('error-probe',()=>++afterError);'ready'").Text, "ready");
            dom.DispatchEvent(document.GetElementById("Button"), "error-probe");
            Stage("BridgeErrorConsole", runtime.DrainConsoleOutput().Contains("NativeEventErrorVisible", StringComparison.Ordinal).ToString(), "True");
            Stage("BridgeAfterErrorListener", runtime.Evaluate("afterError").Text, "1");
            Stage("BridgeAfterErrorLexicalScope", runtime.Evaluate("function outer(){const value=21;try{(()=>{throw Error('scope')})()}catch(error){return (()=>value*2)()}}outer()").Text, "42");
        }
        catch (Exception error) { passed = false; log("XFE_BROWSER_EVENT_REGRESSION|BridgeException|FAIL|" + error.Message + "\n"); }
        log("XFE_BROWSER_EVENT_REGRESSION|Complete|" + (passed ? "PASS" : "FAIL") + "\n");
        return passed;
    }
}