committed by
GitHub
5 changed files with 431 additions and 193 deletions
@ -0,0 +1,291 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using System.Linq; |
|||
using Avalonia.Controls.Presenters; |
|||
using Avalonia.Controls.Templates; |
|||
using Avalonia.LogicalTree; |
|||
using Avalonia.UnitTests; |
|||
using Avalonia.VisualTree; |
|||
using Moq; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Controls.UnitTests.Presenters |
|||
{ |
|||
/// <summary>
|
|||
/// Tests for ContentControls that are hosted in a control template.
|
|||
/// </summary>
|
|||
public class ContentPresenterTests_InTemplate |
|||
{ |
|||
[Fact] |
|||
public void Should_Register_With_Host_When_TemplatedParent_Set() |
|||
{ |
|||
var host = new Mock<IContentPresenterHost>(); |
|||
var target = new ContentPresenter(); |
|||
|
|||
target.SetValue(Control.TemplatedParentProperty, host.Object); |
|||
|
|||
host.Verify(x => x.RegisterContentPresenter(target)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Setting_Content_To_Control_Should_Set_Child() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
var child = new Border(); |
|||
|
|||
target.Content = child; |
|||
|
|||
Assert.Equal(child, target.Child); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Setting_Content_To_Control_Should_Update_Logical_Tree() |
|||
{ |
|||
var (target, parent) = CreateTarget(); |
|||
var child = new Border(); |
|||
|
|||
target.Content = child; |
|||
|
|||
Assert.Equal(parent, child.GetLogicalParent()); |
|||
Assert.Equal(new[] { child }, parent.GetLogicalChildren()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Setting_Content_To_Control_Should_Update_Visual_Tree() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
var child = new Border(); |
|||
|
|||
target.Content = child; |
|||
|
|||
Assert.Equal(target, child.GetVisualParent()); |
|||
Assert.Equal(new[] { child }, target.GetVisualChildren()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Setting_Content_To_String_Should_Create_TextBlock() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
|
|||
target.Content = "Foo"; |
|||
|
|||
Assert.IsType<TextBlock>(target.Child); |
|||
Assert.Equal("Foo", ((TextBlock)target.Child).Text); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Setting_Content_To_String_Should_Update_Logical_Tree() |
|||
{ |
|||
var (target, parent) = CreateTarget(); |
|||
|
|||
target.Content = "Foo"; |
|||
|
|||
var child = target.Child; |
|||
Assert.Equal(parent, child.GetLogicalParent()); |
|||
Assert.Equal(new[] { child }, parent.GetLogicalChildren()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Setting_Content_To_String_Should_Update_Visual_Tree() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
|
|||
target.Content = "Foo"; |
|||
|
|||
var child = target.Child; |
|||
Assert.Equal(target, child.GetVisualParent()); |
|||
Assert.Equal(new[] { child }, target.GetVisualChildren()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Clearing_Control_Content_Should_Update_Logical_Tree() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
var child = new Border(); |
|||
|
|||
target.Content = child; |
|||
target.Content = null; |
|||
|
|||
Assert.Equal(null, child.GetLogicalParent()); |
|||
Assert.Empty(target.GetLogicalChildren()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Clearing_Control_Content_Should_Update_Visual_Tree() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
var child = new Border(); |
|||
|
|||
target.Content = child; |
|||
target.Content = null; |
|||
|
|||
Assert.Equal(null, child.GetVisualParent()); |
|||
Assert.Empty(target.GetVisualChildren()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Control_Content_Should_Not_Be_NameScope() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
|
|||
target.Content = new TextBlock(); |
|||
|
|||
Assert.IsType<TextBlock>(target.Child); |
|||
Assert.Null(NameScope.GetNameScope((Control)target.Child)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void DataTemplate_Created_Control_Should_Be_NameScope() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
|
|||
target.Content = "Foo"; |
|||
|
|||
Assert.IsType<TextBlock>(target.Child); |
|||
Assert.NotNull(NameScope.GetNameScope((Control)target.Child)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Assigning_Control_To_Content_Should_Not_Set_DataContext() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
target.Content = new Border(); |
|||
|
|||
Assert.False(target.IsSet(Control.DataContextProperty)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Assigning_NonControl_To_Content_Should_Set_DataContext_On_UpdateChild() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
target.Content = "foo"; |
|||
|
|||
Assert.Equal("foo", target.DataContext); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Use_ContentTemplate_If_Specified() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
|
|||
target.ContentTemplate = new FuncDataTemplate<string>(_ => new Canvas()); |
|||
target.Content = "Foo"; |
|||
|
|||
Assert.IsType<Canvas>(target.Child); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Update_If_ContentTemplate_Changed() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
|
|||
target.Content = "Foo"; |
|||
Assert.IsType<TextBlock>(target.Child); |
|||
|
|||
target.ContentTemplate = new FuncDataTemplate<string>(_ => new Canvas()); |
|||
Assert.IsType<Canvas>(target.Child); |
|||
|
|||
target.ContentTemplate = null; |
|||
Assert.IsType<TextBlock>(target.Child); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Assigning_Control_To_Content_After_NonControl_Should_Clear_DataContext() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
|
|||
target.Content = "foo"; |
|||
|
|||
Assert.True(target.IsSet(Control.DataContextProperty)); |
|||
|
|||
target.Content = new Border(); |
|||
|
|||
Assert.False(target.IsSet(Control.DataContextProperty)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Recycles_DataTemplate() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
target.DataTemplates.Add(new FuncDataTemplate<string>(_ => new Border(), true)); |
|||
|
|||
target.Content = "foo"; |
|||
|
|||
var control = target.Child; |
|||
Assert.IsType<Border>(control); |
|||
|
|||
target.Content = "bar"; |
|||
Assert.Same(control, target.Child); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Detects_DataTemplate_Doesnt_Match_And_Doesnt_Recycle() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
target.DataTemplates.Add(new FuncDataTemplate<string>(x => x == "foo", _ => new Border(), true)); |
|||
|
|||
target.Content = "foo"; |
|||
|
|||
var control = target.Child; |
|||
Assert.IsType<Border>(control); |
|||
|
|||
target.Content = "bar"; |
|||
Assert.IsType<TextBlock>(target.Child); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Detects_DataTemplate_Doesnt_Support_Recycling() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
target.DataTemplates.Add(new FuncDataTemplate<string>(_ => new Border(), false)); |
|||
|
|||
target.Content = "foo"; |
|||
|
|||
var control = target.Child; |
|||
Assert.IsType<Border>(control); |
|||
|
|||
target.Content = "bar"; |
|||
Assert.NotSame(control, target.Child); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Reevaluates_DataTemplates_When_Recycling() |
|||
{ |
|||
var (target, _) = CreateTarget(); |
|||
|
|||
target.DataTemplates.Add(new FuncDataTemplate<string>(x => x == "bar", _ => new Canvas(), true)); |
|||
target.DataTemplates.Add(new FuncDataTemplate<string>(_ => new Border(), true)); |
|||
|
|||
target.Content = "foo"; |
|||
|
|||
var control = target.Child; |
|||
Assert.IsType<Border>(control); |
|||
|
|||
target.Content = "bar"; |
|||
Assert.IsType<Canvas>(target.Child); |
|||
} |
|||
|
|||
(ContentPresenter presenter, ContentControl templatedParent) CreateTarget() |
|||
{ |
|||
var templatedParent = new ContentControl |
|||
{ |
|||
Template = new FuncControlTemplate<ContentControl>(x => |
|||
new ContentPresenter |
|||
{ |
|||
Name = "PART_ContentPresenter", |
|||
}), |
|||
}; |
|||
var root = new TestRoot { Child = templatedParent }; |
|||
|
|||
templatedParent.ApplyTemplate(); |
|||
|
|||
return ((ContentPresenter)templatedParent.Presenter, templatedParent); |
|||
} |
|||
|
|||
private class TestContentControl : ContentControl |
|||
{ |
|||
public IControl Child { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,102 @@ |
|||
// Copyright (c) The Avalonia Project. All rights reserved.
|
|||
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
|||
|
|||
using Avalonia.Controls.Presenters; |
|||
using Avalonia.Controls.Templates; |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Controls.UnitTests.Presenters |
|||
{ |
|||
/// <summary>
|
|||
/// Tests for ContentControls that are not attached to a logical tree.
|
|||
/// </summary>
|
|||
public class ContentPresenterTests_Unrooted |
|||
{ |
|||
[Fact] |
|||
public void Setting_Content_To_Control_Should_Not_Set_Child_Unless_UpdateChild_Called() |
|||
{ |
|||
var target = new ContentPresenter(); |
|||
var child = new Border(); |
|||
|
|||
target.Content = child; |
|||
Assert.Null(target.Child); |
|||
|
|||
target.ApplyTemplate(); |
|||
Assert.Null(target.Child); |
|||
|
|||
target.UpdateChild(); |
|||
Assert.Equal(child, target.Child); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Setting_Content_To_String_Should_Not_Create_TextBlock_Unless_UpdateChild_Called() |
|||
{ |
|||
var target = new ContentPresenter(); |
|||
|
|||
target.Content = "Foo"; |
|||
Assert.Null(target.Child); |
|||
|
|||
target.ApplyTemplate(); |
|||
Assert.Null(target.Child); |
|||
|
|||
target.UpdateChild(); |
|||
Assert.IsType<TextBlock>(target.Child); |
|||
Assert.Equal("Foo", ((TextBlock)target.Child).Text); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Clearing_Control_Content_Should_Remove_Child_Immediately() |
|||
{ |
|||
var target = new ContentPresenter(); |
|||
var child = new Border(); |
|||
|
|||
target.Content = child; |
|||
target.UpdateChild(); |
|||
Assert.Equal(child, target.Child); |
|||
|
|||
target.Content = null; |
|||
Assert.Null(target.Child); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Clearing_String_Content_Should_Remove_Child_Immediately() |
|||
{ |
|||
var target = new ContentPresenter(); |
|||
|
|||
target.Content = "Foo"; |
|||
target.UpdateChild(); |
|||
Assert.IsType<TextBlock>(target.Child); |
|||
|
|||
target.Content = null; |
|||
Assert.Null(target.Child); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Adding_To_Logical_Tree_Should_Reevaluate_DataTemplates() |
|||
{ |
|||
var root = new TestRoot(); |
|||
var target = new ContentPresenter(); |
|||
|
|||
target.Content = "Foo"; |
|||
Assert.Null(target.Child); |
|||
|
|||
root.Child = target; |
|||
target.ApplyTemplate(); |
|||
Assert.IsType<TextBlock>(target.Child); |
|||
|
|||
root.Child = null; |
|||
root = new TestRoot |
|||
{ |
|||
DataTemplates = new DataTemplates |
|||
{ |
|||
new FuncDataTemplate<string>(x => new Decorator()), |
|||
}, |
|||
}; |
|||
|
|||
root.Child = target; |
|||
target.ApplyTemplate(); |
|||
Assert.IsType<Decorator>(target.Child); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue