public void Should_Build_Stream_Node() { var result = ToList(ExpressionObserverBuilder.Parse("Foo^")); Assert.Equal(2, result.Count); Assert.IsType <StreamNode>(result[1]); }
public void Should_Build_Dot() { var result = ToList(ExpressionObserverBuilder.Parse(".")); Assert.Equal(1, result.Count); Assert.IsType <EmptyExpressionNode>(result[0]); }
public void Should_Build_Multiple_Indexed_Property_With_Space() { var result = ToList(ExpressionObserverBuilder.Parse("Foo[5, 16]")); Assert.Equal(2, result.Count); AssertIsProperty(result[0], "Foo"); AssertIsIndexer(result[1], "5", "16"); }
public void Should_Build_Indexed_Property_StringIndex() { var result = ToList(ExpressionObserverBuilder.Parse("Foo[Key]")); Assert.Equal(2, result.Count); AssertIsProperty(result[0], "Foo"); AssertIsIndexer(result[1], "Key"); Assert.IsType <StringIndexerNode>(result[1]); }
public void Should_Build_Consecutive_Indexers() { var result = ToList(ExpressionObserverBuilder.Parse("Foo[15][16]")); Assert.Equal(3, result.Count); AssertIsProperty(result[0], "Foo"); AssertIsIndexer(result[1], "15"); AssertIsIndexer(result[2], "16"); }
public void Should_Build_Property_Chain() { var result = ToList(ExpressionObserverBuilder.Parse("Foo.Bar.Baz")); Assert.Equal(3, result.Count); AssertIsProperty(result[0], "Foo"); AssertIsProperty(result[1], "Bar"); AssertIsProperty(result[2], "Baz"); }
public void Should_Build_Negated_Property_Chain() { var result = ToList(ExpressionObserverBuilder.Parse("!Foo.Bar.Baz")); Assert.Equal(4, result.Count); Assert.IsType <LogicalNotNode>(result[0]); AssertIsProperty(result[1], "Foo"); AssertIsProperty(result[2], "Bar"); AssertIsProperty(result[3], "Baz"); }
public void Should_Build_Indexed_Property_In_Chain() { var result = ToList(ExpressionObserverBuilder.Parse("Foo.Bar[5, 6].Baz")); Assert.Equal(4, result.Count); AssertIsProperty(result[0], "Foo"); AssertIsProperty(result[1], "Bar"); AssertIsIndexer(result[2], "5", "6"); AssertIsProperty(result[3], "Baz"); }
protected override ExpressionObserver CreateExpressionObserver(IAvaloniaObject target, AvaloniaProperty targetProperty, object?anchor, bool enableDataValidation) { _ = target ?? throw new ArgumentNullException(nameof(target)); anchor ??= DefaultAnchor?.Target; enableDataValidation = enableDataValidation && Priority == BindingPriority.LocalValue; INameScope?nameScope = null; NameScope?.TryGetTarget(out nameScope); var(node, mode) = ExpressionObserverBuilder.Parse(Path, enableDataValidation, TypeResolver, nameScope); if (node is null) { throw new InvalidOperationException("Could not parse binding expression."); } IStyledElement GetSource() { return(target as IStyledElement ?? anchor as IStyledElement ?? throw new ArgumentException("Could not find binding source: either target or anchor must be an IStyledElement.")); } if (ElementName != null) { return(CreateElementObserver( GetSource(), ElementName, node)); } else if (Source != null) { return(CreateSourceObserver(Source, node)); } else if (RelativeSource == null) { if (mode == SourceMode.Data) { return(CreateDataContextObserver( target, node, targetProperty == StyledElement.DataContextProperty, anchor)); } else { return(CreateSourceObserver(GetSource(), node)); } } else if (RelativeSource.Mode == RelativeSourceMode.DataContext) { return(CreateDataContextObserver( target, node, targetProperty == StyledElement.DataContextProperty, anchor)); } else if (RelativeSource.Mode == RelativeSourceMode.Self) { return(CreateSourceObserver(GetSource(), node)); } else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent) { return(CreateTemplatedParentObserver(GetSource(), node)); } else if (RelativeSource.Mode == RelativeSourceMode.FindAncestor) { if (RelativeSource.Tree == TreeType.Visual && RelativeSource.AncestorType == null) { throw new InvalidOperationException("AncestorType must be set for RelativeSourceMode.FindAncestor when searching the visual tree."); } return(CreateFindAncestorObserver(GetSource(), RelativeSource, node)); } else { throw new NotSupportedException(); } }
public void Should_Build_Property_With_Digits() { var result = ToList(ExpressionObserverBuilder.Parse("F0o")); AssertIsProperty(result[0], "F0o"); }
public void Should_Build_Underscored_Property() { var result = ToList(ExpressionObserverBuilder.Parse("_Foo")); AssertIsProperty(result[0], "_Foo"); }
public void Should_Build_Single_Property() { var result = ToList(ExpressionObserverBuilder.Parse("Foo")); AssertIsProperty(result[0], "Foo"); }
/// <inheritdoc/> public InstancedBinding Initiate( IAvaloniaObject target, AvaloniaProperty targetProperty, object anchor = null, bool enableDataValidation = false) { Contract.Requires <ArgumentNullException>(target != null); anchor = anchor ?? DefaultAnchor?.Target; enableDataValidation = enableDataValidation && Priority == BindingPriority.LocalValue; ExpressionObserver observer; var(node, mode) = ExpressionObserverBuilder.Parse(Path, enableDataValidation, TypeResolver); if (ElementName != null) { observer = CreateElementObserver( (target as IStyledElement) ?? (anchor as IStyledElement), ElementName, node); } else if (Source != null) { observer = CreateSourceObserver(Source, node); } else if (RelativeSource == null) { if (mode == SourceMode.Data) { observer = CreateDataContextObserver( target, node, targetProperty == StyledElement.DataContextProperty, anchor); } else { observer = new ExpressionObserver( (target as IStyledElement) ?? (anchor as IStyledElement), node); } } else if (RelativeSource.Mode == RelativeSourceMode.DataContext) { observer = CreateDataContextObserver( target, node, targetProperty == StyledElement.DataContextProperty, anchor); } else if (RelativeSource.Mode == RelativeSourceMode.Self) { observer = CreateSourceObserver( (target as IStyledElement) ?? (anchor as IStyledElement), node); } else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent) { observer = CreateTemplatedParentObserver( (target as IStyledElement) ?? (anchor as IStyledElement), node); } else if (RelativeSource.Mode == RelativeSourceMode.FindAncestor) { if (RelativeSource.Tree == TreeType.Visual && RelativeSource.AncestorType == null) { throw new InvalidOperationException("AncestorType must be set for RelativeSourceMode.FindAncestor when searching the visual tree."); } observer = CreateFindAncestorObserver( (target as IStyledElement) ?? (anchor as IStyledElement), RelativeSource, node); } else { throw new NotSupportedException(); } var fallback = FallbackValue; // If we're binding to DataContext and our fallback is UnsetValue then override // the fallback value to null, as broken bindings to DataContext must reset the // DataContext in order to not propagate incorrect DataContexts to child controls. // See Avalonia.Markup.UnitTests.Data.DataContext_Binding_Should_Produce_Correct_Results. if (targetProperty == StyledElement.DataContextProperty && fallback == AvaloniaProperty.UnsetValue) { fallback = null; } var converter = Converter; var targetType = targetProperty?.PropertyType ?? typeof(object); // We only respect `StringFormat` if the type of the property we're assigning to will // accept a string. Note that this is slightly different to WPF in that WPF only applies // `StringFormat` for target type `string` (not `object`). if (!string.IsNullOrWhiteSpace(StringFormat) && (targetType == typeof(string) || targetType == typeof(object))) { converter = new StringFormatValueConverter(StringFormat, converter); } var subject = new BindingExpression( observer, targetType, fallback, converter ?? DefaultValueConverter.Instance, ConverterParameter, Priority); return(new InstancedBinding(subject, Mode, Priority)); }
public void Identifier_Cannot_Start_With_Symbol() { Assert.Throws <ExpressionParseException>( () => ExpressionObserverBuilder.Parse("Foo.%Bar")); }
public void Expression_Cannot_Start_With_Period_Then_Token() { Assert.Throws <ExpressionParseException>( () => ExpressionObserverBuilder.Parse(".Bar")); }
public void Expression_Cannot_Have_Letter_After_Indexer() { Assert.Throws <ExpressionParseException>( () => ExpressionObserverBuilder.Parse("Foo.Bar[3,4]A")); }
public void Expression_Cannot_Have_Extra_Comma_At_End_Of_Indexer() { Assert.Throws <ExpressionParseException>( () => ExpressionObserverBuilder.Parse("Foo.Bar[3,4,]")); }
public void Expression_Cannot_Have_Empty_Indexer() { Assert.Throws <ExpressionParseException>( () => ExpressionObserverBuilder.Parse("Foo.Bar[]")); }
public void Expression_Cannot_End_With_Period() { Assert.Throws <ExpressionParseException>( () => ExpressionObserverBuilder.Parse("Foo.Bar.")); }
protected override ExpressionObserver CreateExpressionObserver(IAvaloniaObject target, AvaloniaProperty targetProperty, object anchor, bool enableDataValidation) { Contract.Requires <ArgumentNullException>(target != null); anchor = anchor ?? DefaultAnchor?.Target; enableDataValidation = enableDataValidation && Priority == BindingPriority.LocalValue; INameScope nameScope = null; NameScope?.TryGetTarget(out nameScope); var(node, mode) = ExpressionObserverBuilder.Parse(Path, enableDataValidation, TypeResolver, nameScope); if (ElementName != null) { return(CreateElementObserver( (target as IStyledElement) ?? (anchor as IStyledElement), ElementName, node)); } else if (Source != null) { return(CreateSourceObserver(Source, node)); } else if (RelativeSource == null) { if (mode == SourceMode.Data) { return(CreateDataContextObserver( target, node, targetProperty == StyledElement.DataContextProperty, anchor)); } else { return(CreateSourceObserver( (target as IStyledElement) ?? (anchor as IStyledElement), node)); } } else if (RelativeSource.Mode == RelativeSourceMode.DataContext) { return(CreateDataContextObserver( target, node, targetProperty == StyledElement.DataContextProperty, anchor)); } else if (RelativeSource.Mode == RelativeSourceMode.Self) { return(CreateSourceObserver( (target as IStyledElement) ?? (anchor as IStyledElement), node)); } else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent) { return(CreateTemplatedParentObserver( (target as IStyledElement) ?? (anchor as IStyledElement), node)); } else if (RelativeSource.Mode == RelativeSourceMode.FindAncestor) { if (RelativeSource.Tree == TreeType.Visual && RelativeSource.AncestorType == null) { throw new InvalidOperationException("AncestorType must be set for RelativeSourceMode.FindAncestor when searching the visual tree."); } return(CreateFindAncestorObserver( (target as IStyledElement) ?? (anchor as IStyledElement), RelativeSource, node)); } else { throw new NotSupportedException(); } }
public void Identifier_Cannot_Start_With_Digit() { Assert.Throws <ExpressionParseException>( () => ExpressionObserverBuilder.Parse("1Foo")); }