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

XFESystem

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

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

namespace XFESystem.Browser.Tests;

public sealed class BrowserDatasetTests
{
    [Fact]
    public void ConsoleCallbacksAreCallableWithStandardFunctionBindAndCall()
    {
        Run("console.log.bind(console)('bound');console.warn.call(console,'called');");
    }
    [Fact]
    public void BoundJavaScriptMethodsCanBeBoundAgain()
    {
        Run("class C { constructor(){this.value=42;this.method=this.method.bind(this);this.second=this.method.bind(this);}method(){return this.value;}} if(new C().second()!==42)throw Error('bind twice');");
    }
    [Fact]
    public void DatasetReflectsExistingAttributesAndStaysTheSameObject()
    {
        Run("""
            const element=document.querySelector('div'),data=element.dataset;
            if(data!==element.dataset||!(data instanceof DOMStringMap)||Object.prototype.toString.call(data)!=='[object DOMStringMap]')throw Error('identity');
            if(data.fooBar!=='one'||data.empty!==''||data.missing!==undefined)throw Error('values');
            element.setAttribute('data-foo-bar','two');if(data.fooBar!=='two')throw Error('attribute reflection');
            """);
    }

    [Fact]
    public void DatasetWritesAndDeletesActualCamelCaseAttributes()
    {
        var doc = Run("""
            const element=document.querySelector('div');element.dataset.codeToolsApplied=true;element.dataset.fooBar=null;
            if(element.getAttribute('data-code-tools-applied')!=='true'||element.getAttribute('data-foo-bar')!=='null')throw Error('set');
            delete element.dataset.fooBar;if(element.hasAttribute('data-foo-bar')||'fooBar' in element.dataset)throw Error('delete');
            element.dataset['number-1']='ok';element.dataset['foo-Bar']='dash';
            if(element.getAttribute('data-number-1')!=='ok'||element.getAttribute('data-foo--bar')!=='dash')throw Error('special');
            """);
        Assert.Equal("true", doc.QuerySelector("div")!.GetAttribute("data-code-tools-applied"));
    }

    [Fact]
    public void DatasetOwnKeysDescriptorsAndJsonReflectTheLiveAttributeCollection()
    {
        Run("""
            const element=document.querySelector('div'),data=element.dataset;
            if(Object.keys(data).join(',')!=='fooBar,empty')throw Error('keys');
            const descriptor=Object.getOwnPropertyDescriptor(data,'fooBar');
            if(!descriptor.enumerable||!descriptor.configurable||!descriptor.writable||descriptor.value!=='one')throw Error('descriptor');
            element.setAttribute('data-new-key','three');if(Object.entries(data).length!==3||JSON.parse(JSON.stringify(data)).newKey!=='three')throw Error('live keys');
            delete data.empty;if(Object.keys(data).join(',')!=='fooBar,newKey')throw Error('removed keys');
            """);
    }

    [Fact]
    public void DatasetPrototypeNamedPropertiesCannotChangeTheActualPrototype()
    {
        Run("""
            const data=document.querySelector('div').dataset,prototype=Object.getPrototypeOf(data);
            data.__proto__='safe';if(data.__proto__!=='safe'||Object.getPrototypeOf(data)!==prototype)throw Error('prototype');
            if(!Object.hasOwn(data,'__proto__'))throw Error('own');delete data.__proto__;
            data.constructor='text';if(data.constructor!=='text')throw Error('constructor');delete data.constructor;
            if(data.constructor!==DOMStringMap)throw Error('prototype restoration');
            """);
    }

    [Fact]
    public void DatasetRejectsAmbiguousHyphenLowercaseNames()
    {
        Run("""
            const element=document.querySelector('div');let name='';try{element.dataset['foo-bar']='bad';}catch(error){name=error.name;}
            if(name!=='SyntaxError'||element.getAttribute('data-foo-bar')!=='one')throw Error('invalid name');
            Object.defineProperty(element.dataset,'definedKey',{value:'defined',configurable:true,enumerable:true,writable:true});
            if(element.getAttribute('data-defined-key')!=='defined')throw Error('define');
            """);
    }

    private static AngleSharp.Dom.IDocument Run(string code)
    {
        var runtime = new JavaScriptRuntime();
        var doc = new HtmlParser().ParseDocument("<div data-foo-bar='one' data-empty=''></div>");
        _ = new DomBridge(runtime, doc, new("http://xfesystem.local/"), new());
        var result = runtime.Evaluate(code);
        Assert.True(result.Success, result.Error);
        return doc;
    }
}