ContentControlTests.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. // Copyright (c) The Perspex Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using System.Collections.Specialized;
  5. using System.Linq;
  6. using Moq;
  7. using Perspex.Controls.Presenters;
  8. using Perspex.Controls.Templates;
  9. using Perspex.LogicalTree;
  10. using Perspex.Platform;
  11. using Perspex.Styling;
  12. using Perspex.VisualTree;
  13. using Ploeh.AutoFixture;
  14. using Ploeh.AutoFixture.AutoMoq;
  15. using Xunit;
  16. namespace Perspex.Controls.UnitTests
  17. {
  18. public class ContentControlTests
  19. {
  20. [Fact]
  21. public void Template_Should_Be_Instantiated()
  22. {
  23. using (var ctx = RegisterServices())
  24. {
  25. var target = new ContentControl();
  26. target.Content = "Foo";
  27. target.Template = GetTemplate();
  28. target.ApplyTemplate();
  29. ((ContentPresenter)target.Presenter).UpdateChild();
  30. var child = ((IVisual)target).VisualChildren.Single();
  31. Assert.IsType<Border>(child);
  32. child = child.VisualChildren.Single();
  33. Assert.IsType<ContentPresenter>(child);
  34. child = child.VisualChildren.Single();
  35. Assert.IsType<TextBlock>(child);
  36. }
  37. }
  38. [Fact]
  39. public void Templated_Children_Should_Be_Styled()
  40. {
  41. using (var ctx = RegisterServices())
  42. {
  43. var root = new TestRoot();
  44. var target = new ContentControl();
  45. var styler = new Mock<IStyler>();
  46. PerspexLocator.CurrentMutable.Bind<IStyler>().ToConstant(styler.Object);
  47. target.Content = "Foo";
  48. target.Template = GetTemplate();
  49. root.Child = target;
  50. target.ApplyTemplate();
  51. styler.Verify(x => x.ApplyStyles(It.IsAny<ContentControl>()), Times.Once());
  52. styler.Verify(x => x.ApplyStyles(It.IsAny<Border>()), Times.Once());
  53. styler.Verify(x => x.ApplyStyles(It.IsAny<ContentPresenter>()), Times.Once());
  54. styler.Verify(x => x.ApplyStyles(It.IsAny<TextBlock>()), Times.Once());
  55. }
  56. }
  57. [Fact]
  58. public void ContentPresenter_Should_Have_TemplatedParent_Set()
  59. {
  60. var target = new ContentControl();
  61. var child = new Border();
  62. target.Template = GetTemplate();
  63. target.Content = child;
  64. target.ApplyTemplate();
  65. ((ContentPresenter)target.Presenter).UpdateChild();
  66. var contentPresenter = child.GetVisualParent<ContentPresenter>();
  67. Assert.Equal(target, contentPresenter.TemplatedParent);
  68. }
  69. [Fact]
  70. public void Content_Should_Have_TemplatedParent_Set_To_Null()
  71. {
  72. var target = new ContentControl();
  73. var child = new Border();
  74. target.Template = GetTemplate();
  75. target.Content = child;
  76. target.ApplyTemplate();
  77. ((ContentPresenter)target.Presenter).UpdateChild();
  78. Assert.Null(child.TemplatedParent);
  79. }
  80. [Fact]
  81. public void Control_Content_Should_Be_Logical_Child_Before_ApplyTemplate()
  82. {
  83. var target = new ContentControl
  84. {
  85. Template = GetTemplate(),
  86. };
  87. var child = new Control();
  88. target.Content = child;
  89. Assert.Equal(child.Parent, target);
  90. Assert.Equal(child.GetLogicalParent(), target);
  91. Assert.Equal(new[] { child }, target.GetLogicalChildren());
  92. }
  93. [Fact]
  94. public void DataTemplate_Created_Control_Should_Be_Logical_Child_After_ApplyTemplate()
  95. {
  96. var target = new ContentControl
  97. {
  98. Template = GetTemplate(),
  99. };
  100. target.Content = "Foo";
  101. target.ApplyTemplate();
  102. ((ContentPresenter)target.Presenter).UpdateChild();
  103. var child = target.Presenter.Child;
  104. Assert.NotNull(child);
  105. Assert.Equal(target, child.Parent);
  106. Assert.Equal(target, child.GetLogicalParent());
  107. Assert.Equal(new[] { child }, target.GetLogicalChildren());
  108. }
  109. [Fact]
  110. public void Clearing_Content_Should_Clear_Logical_Child()
  111. {
  112. var target = new ContentControl();
  113. var child = new Control();
  114. target.Content = child;
  115. Assert.Equal(new[] { child }, target.GetLogicalChildren());
  116. target.Content = null;
  117. Assert.Null(child.Parent);
  118. Assert.Null(child.GetLogicalParent());
  119. Assert.Empty(target.GetLogicalChildren());
  120. }
  121. [Fact]
  122. public void Setting_Content_Should_Fire_LogicalChildren_CollectionChanged()
  123. {
  124. var target = new ContentControl();
  125. var child = new Control();
  126. var called = false;
  127. ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) =>
  128. called = e.Action == NotifyCollectionChangedAction.Add;
  129. target.Template = GetTemplate();
  130. target.Content = child;
  131. target.ApplyTemplate();
  132. ((ContentPresenter)target.Presenter).UpdateChild();
  133. Assert.True(called);
  134. }
  135. [Fact]
  136. public void Clearing_Content_Should_Fire_LogicalChildren_CollectionChanged()
  137. {
  138. var target = new ContentControl();
  139. var child = new Control();
  140. var called = false;
  141. target.Template = GetTemplate();
  142. target.Content = child;
  143. target.ApplyTemplate();
  144. ((ContentPresenter)target.Presenter).UpdateChild();
  145. ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) => called = true;
  146. target.Content = null;
  147. ((ContentPresenter)target.Presenter).UpdateChild();
  148. Assert.True(called);
  149. }
  150. [Fact]
  151. public void Changing_Content_Should_Fire_LogicalChildren_CollectionChanged()
  152. {
  153. var target = new ContentControl();
  154. var child1 = new Control();
  155. var child2 = new Control();
  156. var called = false;
  157. target.Template = GetTemplate();
  158. target.Content = child1;
  159. target.ApplyTemplate();
  160. ((ContentPresenter)target.Presenter).UpdateChild();
  161. ((ILogical)target).LogicalChildren.CollectionChanged += (s, e) => called = true;
  162. target.Content = child2;
  163. target.Presenter.ApplyTemplate();
  164. Assert.True(called);
  165. }
  166. [Fact]
  167. public void Changing_Content_Should_Update_Presenter()
  168. {
  169. var target = new ContentControl();
  170. target.Template = GetTemplate();
  171. target.ApplyTemplate();
  172. ((ContentPresenter)target.Presenter).UpdateChild();
  173. target.Content = "Foo";
  174. ((ContentPresenter)target.Presenter).UpdateChild();
  175. Assert.Equal("Foo", ((TextBlock)target.Presenter.Child).Text);
  176. target.Content = "Bar";
  177. ((ContentPresenter)target.Presenter).UpdateChild();
  178. Assert.Equal("Bar", ((TextBlock)target.Presenter.Child).Text);
  179. }
  180. [Fact]
  181. public void DataContext_Should_Be_Set_For_DataTemplate_Created_Content()
  182. {
  183. var target = new ContentControl();
  184. target.Template = GetTemplate();
  185. target.Content = "Foo";
  186. target.ApplyTemplate();
  187. ((ContentPresenter)target.Presenter).UpdateChild();
  188. Assert.Equal("Foo", target.Presenter.Child.DataContext);
  189. }
  190. [Fact]
  191. public void DataContext_Should_Not_Be_Set_For_Control_Content()
  192. {
  193. var target = new ContentControl();
  194. target.Template = GetTemplate();
  195. target.Content = new TextBlock();
  196. target.ApplyTemplate();
  197. ((ContentPresenter)target.Presenter).UpdateChild();
  198. Assert.Null(target.Presenter.Child.DataContext);
  199. }
  200. private FuncControlTemplate GetTemplate()
  201. {
  202. return new FuncControlTemplate<ContentControl>(parent =>
  203. {
  204. return new Border
  205. {
  206. Background = new Media.SolidColorBrush(0xffffffff),
  207. Child = new ContentPresenter
  208. {
  209. Name = "PART_ContentPresenter",
  210. [~ContentPresenter.ContentProperty] = parent[~ContentControl.ContentProperty],
  211. }
  212. };
  213. });
  214. }
  215. private IDisposable RegisterServices()
  216. {
  217. var result = PerspexLocator.EnterScope();
  218. var fixture = new Fixture().Customize(new AutoMoqCustomization());
  219. var renderInterface = fixture.Create<IPlatformRenderInterface>();
  220. PerspexLocator.CurrentMutable
  221. .Bind<IPlatformRenderInterface>().ToConstant(renderInterface);
  222. return result;
  223. }
  224. }
  225. }