ContentControlTests.cs 9.7 KB

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