A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

189 lines
5.5 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Data.Core.ExpressionNodes;
using Avalonia.Data.Core.ExpressionNodes.Reflection;
using Avalonia.Data.Core.Parsers;
using Avalonia.UnitTests;
using Avalonia.Utilities;
using Xunit;
namespace Avalonia.Markup.UnitTests.Parsers
{
public class ExpressionNodeFactoryTests : ScopedTestBase
{
[Fact]
public void Should_Build_Single_Property()
{
var result = Parse("Foo");
Assert.NotNull(result);
AssertIsProperty(result[0], "Foo");
}
[Fact]
public void Should_Build_Underscored_Property()
{
var result = Parse("_Foo");
Assert.NotNull(result);
AssertIsProperty(result[0], "_Foo");
}
[Fact]
public void Should_Build_Property_With_Digits()
{
var result = Parse("F0o");
Assert.NotNull(result);
AssertIsProperty(result[0], "F0o");
}
[Fact]
public void Should_Build_Dot()
{
var result = Parse(".");
Assert.Null(result);
}
[Fact]
public void Should_Build_Property_Chain()
{
var result = Parse("Foo.Bar.Baz");
Assert.NotNull(result);
Assert.Equal(3, result.Count);
AssertIsProperty(result[0], "Foo");
AssertIsProperty(result[1], "Bar");
AssertIsProperty(result[2], "Baz");
}
[Fact]
public void Should_Build_Negated_Property_Chain()
{
var result = Parse("!Foo.Bar.Baz");
Assert.NotNull(result);
Assert.Equal(4, result.Count);
AssertIsProperty(result[0], "Foo");
AssertIsProperty(result[1], "Bar");
AssertIsProperty(result[2], "Baz");
Assert.IsType<LogicalNotNode>(result[3]);
}
[Fact]
public void Should_Build_Double_Negated_Property_Chain()
{
var result = Parse("!!Foo.Bar.Baz");
Assert.NotNull(result);
Assert.Equal(5, result.Count);
AssertIsProperty(result[0], "Foo");
AssertIsProperty(result[1], "Bar");
AssertIsProperty(result[2], "Baz");
Assert.IsType<LogicalNotNode>(result[3]);
Assert.IsType<LogicalNotNode>(result[4]);
}
[Fact]
public void Should_Build_Indexed_Property()
{
var result = Parse("Foo[15]");
Assert.NotNull(result);
Assert.Equal(2, result.Count);
AssertIsProperty(result[0], "Foo");
AssertIsIndexer(result[1], "15");
Assert.IsType<ReflectionIndexerNode>(result[1]);
}
[Fact]
public void Should_Build_Indexed_Property_StringIndex()
{
var result = Parse("Foo[Key]");
Assert.NotNull(result);
Assert.Equal(2, result.Count);
AssertIsProperty(result[0], "Foo");
AssertIsIndexer(result[1], "Key");
Assert.IsType<ReflectionIndexerNode>(result[1]);
}
[Fact]
public void Should_Build_Multiple_Indexed_Property()
{
var result = Parse("Foo[15,6]");
Assert.NotNull(result);
Assert.Equal(2, result.Count);
AssertIsProperty(result[0], "Foo");
AssertIsIndexer(result[1], "15", "6");
}
[Fact]
public void Should_Build_Multiple_Indexed_Property_With_Space()
{
var result = Parse("Foo[5, 16]");
Assert.NotNull(result);
Assert.Equal(2, result.Count);
AssertIsProperty(result[0], "Foo");
AssertIsIndexer(result[1], "5", "16");
}
[Fact]
public void Should_Build_Consecutive_Indexers()
{
var result = Parse("Foo[15][16]");
Assert.NotNull(result);
Assert.Equal(3, result.Count);
AssertIsProperty(result[0], "Foo");
AssertIsIndexer(result[1], "15");
AssertIsIndexer(result[2], "16");
}
[Fact]
public void Should_Build_Indexed_Property_In_Chain()
{
var result = Parse("Foo.Bar[5, 6].Baz");
Assert.NotNull(result);
Assert.Equal(4, result.Count);
AssertIsProperty(result[0], "Foo");
AssertIsProperty(result[1], "Bar");
AssertIsIndexer(result[2], "5", "6");
AssertIsProperty(result[3], "Baz");
}
[Fact]
public void Should_Build_Stream_Node()
{
var result = Parse("Foo^");
Assert.NotNull(result);
Assert.Equal(2, result.Count);
Assert.IsType<DynamicPluginStreamNode>(result[1]);
}
private static void AssertIsProperty(ExpressionNode node, string name)
{
var p = Assert.IsType<DynamicPluginPropertyAccessorNode>(node);
Assert.Equal(name, p.PropertyName);
}
private static void AssertIsIndexer(ExpressionNode node, params string[] args)
{
var e = Assert.IsType<ReflectionIndexerNode>(node);
Assert.Equal(e.Arguments.Cast<string>().ToArray(), args);
}
private static List<ExpressionNode>? Parse(string path)
{
var reader = new CharacterReader(path.AsSpan());
var (astNodes, sourceMode) = BindingExpressionGrammar.Parse(ref reader);
return ExpressionNodeFactory.CreateFromAst(astNodes, null, null, out _);
}
}
}