// -----------------------------------------------------------------------
//
// Copyright 2013 MIT Licence. See licence.md for more information.
//
// -----------------------------------------------------------------------
namespace Perspex.Controls.UnitTests.Primitives
{
using System;
using System.Collections.Specialized;
using System.Linq;
using Layout;
using Moq;
using Perspex.Controls.Presenters;
using Perspex.Controls.Primitives;
using Perspex.LogicalTree;
using Perspex.Platform;
using Perspex.Styling;
using Perspex.VisualTree;
using Splat;
using Templates;
using Xunit;
public class PopupTests
{
[Fact]
public void Setting_Child_Should_Set_Child_Controls_LogicalParent()
{
var target = new Popup();
var child = new Control();
target.Child = child;
Assert.Equal(child.Parent, target);
Assert.Equal(((ILogical)child).LogicalParent, target);
}
[Fact]
public void Clearing_Child_Should_Clear_Child_Controls_Parent()
{
var target = new Popup();
var child = new Control();
target.Child = child;
target.Child = null;
Assert.Null(child.Parent);
Assert.Null(((ILogical)child).LogicalParent);
}
[Fact]
public void Child_Control_Should_Appear_In_LogicalChildren()
{
var target = new Popup();
var child = new Control();
target.Child = child;
Assert.Equal(new[] { child }, target.GetLogicalChildren());
}
[Fact]
public void Clearing_Child_Should_Remove_From_LogicalChildren()
{
var target = new Popup();
var child = new Control();
target.Child = child;
target.Child = null;
Assert.Equal(new ILogical[0], ((ILogical)target).LogicalChildren.ToList());
}
[Fact]
public void Setting_Child_Should_Fire_LogicalChildren_CollectionChanged()
{
var target = new Popup();
var child = new Control();
var called = false;
((ILogical)target).LogicalChildren.CollectionChanged += (s, e) =>
called = e.Action == NotifyCollectionChangedAction.Add;
target.Child = child;
Assert.True(called);
}
[Fact]
public void Clearing_Child_Should_Fire_LogicalChildren_CollectionChanged()
{
var target = new Popup();
var child = new Control();
var called = false;
target.Child = child;
((ILogical)target).LogicalChildren.CollectionChanged += (s, e) =>
called = e.Action == NotifyCollectionChangedAction.Remove;
target.Child = null;
Assert.True(called);
}
[Fact]
public void Changing_Child_Should_Fire_LogicalChildren_CollectionChanged()
{
var target = new Popup();
var child1 = new Control();
var child2 = new Control();
var called = false;
target.Child = child1;
((ILogical)target).LogicalChildren.CollectionChanged += (s, e) => called = true;
target.Child = child2;
Assert.True(called);
}
[Fact]
public void Setting_Child_Should_Not_Set_Childs_VisualParent()
{
var target = new Popup();
var child = new Control();
target.Child = child;
Assert.Null(((IVisual)child).VisualParent);
}
[Fact]
public void PopupRoot_Should_Initially_Be_Null()
{
using (CreateServices())
{
var target = new Popup();
Assert.Null(target.PopupRoot);
}
}
[Fact]
public void PopupRoot_Should_Have_Null_VisualParent()
{
using (CreateServices())
{
var target = new Popup();
target.Open();
Assert.Null(target.PopupRoot.GetVisualParent());
}
}
[Fact]
public void PopupRoot_Should_Have_Popup_As_LogicalParent()
{
using (CreateServices())
{
var target = new Popup();
target.Open();
Assert.Equal(target, target.PopupRoot.Parent);
Assert.Equal(target, target.PopupRoot.GetLogicalParent());
}
}
[Fact]
public void PopupRoot_Should_Have_Template_Applied()
{
using (CreateServices())
{
var target = new Popup();
var child = new Control();
target.Open();
Assert.Equal(1, target.PopupRoot.GetVisualChildren().Count());
var templatedChild = target.PopupRoot.GetVisualChildren().Single();
Assert.IsType(templatedChild);
Assert.Equal(target.PopupRoot, ((IControl)templatedChild).TemplatedParent);
}
}
[Fact]
public void PopupRoot_Should_Have_Child_As_LogicalChild()
{
using (CreateServices())
{
var target = new Popup();
var child = new Control();
target.Child = child;
target.Open();
Assert.Equal(new[] { child }, target.PopupRoot.GetLogicalChildren());
}
}
[Fact]
public void Templated_Control_With_Popup_In_Template_Should_Set_TemplatedParent()
{
using (CreateServices())
{
PopupContentControl target;
var root = new TestRoot
{
Child = target = new PopupContentControl
{
Content = new Border(),
Template = new ControlTemplate(PopupContentControlTemplate),
}
};
target.ApplyTemplate();
var popup = target.GetTemplateChild("popup");
popup.Open();
var popupRoot = popup.PopupRoot;
var children = popupRoot.GetVisualDescendents().ToList();
var types = children.Select(x => x.GetType().Name).ToList();
Assert.Equal(
new[]
{
"ContentPresenter",
"ContentPresenter",
"Border",
},
types);
var templatedParents = children
.OfType()
.Select(x => x.TemplatedParent).ToList();
Assert.Equal(
new object[]
{
popupRoot,
target,
null,
},
templatedParents);
}
}
private static IDisposable CreateServices()
{
var result = Locator.Current.WithResolver();
var styles = new Styles
{
new Style(x => x.OfType())
{
Setters = new[]
{
new Setter(TemplatedControl.TemplateProperty, new ControlTemplate(PopupRootTemplate)),
}
},
};
var globalStyles = new Mock();
globalStyles.Setup(x => x.Styles).Returns(styles);
Locator.CurrentMutable.Register(() => globalStyles.Object, typeof(IGlobalStyles));
Locator.CurrentMutable.Register(() => new LayoutManager(), typeof(ILayoutManager));
Locator.CurrentMutable.Register(() => new Mock().Object, typeof(IPlatformThreadingInterface));
Locator.CurrentMutable.Register(() => new Mock().Object, typeof(IPopupImpl));
Locator.CurrentMutable.Register(() => new Styler(), typeof(IStyler));
return result;
}
private static IControl PopupRootTemplate(PopupRoot control)
{
return new ContentPresenter
{
Name = "contentPresenter",
[~ContentPresenter.ContentProperty] = control[~PopupRoot.ContentProperty],
};
}
private static IControl PopupContentControlTemplate(PopupContentControl control)
{
return new Popup
{
Name = "popup",
Child = new ContentPresenter
{
[~ContentPresenter.ContentProperty] = control[~PopupRoot.ContentProperty],
}
};
}
private class PopupContentControl : ContentControl
{
}
}
}