CarouselTests.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. using System.Collections.ObjectModel;
  2. using System.Linq;
  3. using System.Reactive.Subjects;
  4. using Avalonia.Controls.Presenters;
  5. using Avalonia.Controls.Primitives;
  6. using Avalonia.Controls.Templates;
  7. using Avalonia.Data;
  8. using Avalonia.LogicalTree;
  9. using Avalonia.Threading;
  10. using Avalonia.VisualTree;
  11. using Avalonia.UnitTests;
  12. using Xunit;
  13. namespace Avalonia.Controls.UnitTests
  14. {
  15. public class CarouselTests
  16. {
  17. [Fact]
  18. public void First_Item_Should_Be_Selected_By_Default()
  19. {
  20. var target = new Carousel
  21. {
  22. Template = new FuncControlTemplate<Carousel>(CreateTemplate),
  23. Items = new[]
  24. {
  25. "Foo",
  26. "Bar"
  27. }
  28. };
  29. target.ApplyTemplate();
  30. Assert.Equal(0, target.SelectedIndex);
  31. Assert.Equal("Foo", target.SelectedItem);
  32. }
  33. [Fact]
  34. public void LogicalChild_Should_Be_Selected_Item()
  35. {
  36. var target = new Carousel
  37. {
  38. Template = new FuncControlTemplate<Carousel>(CreateTemplate),
  39. Items = new[]
  40. {
  41. "Foo",
  42. "Bar"
  43. }
  44. };
  45. target.ApplyTemplate();
  46. target.Presenter.ApplyTemplate();
  47. Assert.Single(target.GetLogicalChildren());
  48. var child = GetContainerTextBlock(target.GetLogicalChildren().Single());
  49. Assert.Equal("Foo", child.Text);
  50. }
  51. [Fact]
  52. public void Should_Remove_NonCurrent_Page_When_IsVirtualized_True()
  53. {
  54. var target = new Carousel
  55. {
  56. Template = new FuncControlTemplate<Carousel>(CreateTemplate),
  57. Items = new[] { "foo", "bar" },
  58. IsVirtualized = true,
  59. SelectedIndex = 0,
  60. };
  61. target.ApplyTemplate();
  62. target.Presenter.ApplyTemplate();
  63. Assert.Single(target.ItemContainerGenerator.Containers);
  64. target.SelectedIndex = 1;
  65. Assert.Single(target.ItemContainerGenerator.Containers);
  66. }
  67. [Fact]
  68. public void Selected_Item_Changes_To_First_Item_When_Items_Property_Changes()
  69. {
  70. var items = new ObservableCollection<string>
  71. {
  72. "Foo",
  73. "Bar",
  74. "FooBar"
  75. };
  76. var target = new Carousel
  77. {
  78. Template = new FuncControlTemplate<Carousel>(CreateTemplate),
  79. Items = items,
  80. IsVirtualized = false
  81. };
  82. target.ApplyTemplate();
  83. target.Presenter.ApplyTemplate();
  84. Assert.Equal(3, target.GetLogicalChildren().Count());
  85. var child = GetContainerTextBlock(target.GetLogicalChildren().First());
  86. Assert.Equal("Foo", child.Text);
  87. var newItems = items.ToList();
  88. newItems.RemoveAt(0);
  89. target.Items = newItems;
  90. child = GetContainerTextBlock(target.GetLogicalChildren().First());
  91. Assert.Equal("Bar", child.Text);
  92. }
  93. [Fact]
  94. public void Selected_Item_Changes_To_First_Item_When_Items_Property_Changes_And_Virtualized()
  95. {
  96. var items = new ObservableCollection<string>
  97. {
  98. "Foo",
  99. "Bar",
  100. "FooBar"
  101. };
  102. var target = new Carousel
  103. {
  104. Template = new FuncControlTemplate<Carousel>(CreateTemplate),
  105. Items = items,
  106. IsVirtualized = true,
  107. };
  108. target.ApplyTemplate();
  109. target.Presenter.ApplyTemplate();
  110. Assert.Single(target.GetLogicalChildren());
  111. var child = GetContainerTextBlock(target.GetLogicalChildren().Single());
  112. Assert.Equal("Foo", child.Text);
  113. var newItems = items.ToList();
  114. newItems.RemoveAt(0);
  115. target.Items = newItems;
  116. child = GetContainerTextBlock(target.GetLogicalChildren().Single());
  117. Assert.Equal("Bar", child.Text);
  118. }
  119. [Fact]
  120. public void Selected_Item_Changes_To_First_Item_When_Item_Added()
  121. {
  122. var items = new ObservableCollection<string>();
  123. var target = new Carousel
  124. {
  125. Template = new FuncControlTemplate<Carousel>(CreateTemplate),
  126. Items = items,
  127. IsVirtualized = false
  128. };
  129. target.ApplyTemplate();
  130. target.Presenter.ApplyTemplate();
  131. Assert.Equal(-1, target.SelectedIndex);
  132. Assert.Empty(target.GetLogicalChildren());
  133. items.Add("Foo");
  134. Assert.Equal(0, target.SelectedIndex);
  135. Assert.Single(target.GetLogicalChildren());
  136. }
  137. [Fact]
  138. public void Selected_Index_Changes_To_None_When_Items_Assigned_Null()
  139. {
  140. var items = new ObservableCollection<string>
  141. {
  142. "Foo",
  143. "Bar",
  144. "FooBar"
  145. };
  146. var target = new Carousel
  147. {
  148. Template = new FuncControlTemplate<Carousel>(CreateTemplate),
  149. Items = items,
  150. IsVirtualized = false
  151. };
  152. target.ApplyTemplate();
  153. target.Presenter.ApplyTemplate();
  154. Assert.Equal(3, target.GetLogicalChildren().Count());
  155. var child = GetContainerTextBlock(target.GetLogicalChildren().First());
  156. Assert.Equal("Foo", child.Text);
  157. target.Items = null;
  158. var numChildren = target.GetLogicalChildren().Count();
  159. Assert.Equal(0, numChildren);
  160. Assert.Equal(-1, target.SelectedIndex);
  161. }
  162. [Fact]
  163. public void Selected_Index_Is_Maintained_Carousel_Created_With_Non_Zero_SelectedIndex()
  164. {
  165. var items = new ObservableCollection<string>
  166. {
  167. "Foo",
  168. "Bar",
  169. "FooBar"
  170. };
  171. var target = new Carousel
  172. {
  173. Template = new FuncControlTemplate<Carousel>(CreateTemplate),
  174. Items = items,
  175. IsVirtualized = false,
  176. SelectedIndex = 2
  177. };
  178. target.ApplyTemplate();
  179. target.Presenter.ApplyTemplate();
  180. Assert.Equal("FooBar", target.SelectedItem);
  181. var child = GetContainerTextBlock(target.GetVisualDescendants().LastOrDefault());
  182. Assert.IsType<TextBlock>(child);
  183. Assert.Equal("FooBar", ((TextBlock)child).Text);
  184. }
  185. [Fact]
  186. public void Selected_Item_Changes_To_Next_First_Item_When_Item_Removed_From_Beggining_Of_List()
  187. {
  188. var items = new ObservableCollection<string>
  189. {
  190. "Foo",
  191. "Bar",
  192. "FooBar"
  193. };
  194. var target = new Carousel
  195. {
  196. Template = new FuncControlTemplate<Carousel>(CreateTemplate),
  197. Items = items,
  198. IsVirtualized = false
  199. };
  200. target.ApplyTemplate();
  201. target.Presenter.ApplyTemplate();
  202. Assert.Equal(3, target.GetLogicalChildren().Count());
  203. var child = GetContainerTextBlock(target.GetLogicalChildren().First());
  204. Assert.Equal("Foo", child.Text);
  205. items.RemoveAt(0);
  206. child = GetContainerTextBlock(target.GetLogicalChildren().First());
  207. Assert.IsType<TextBlock>(child);
  208. Assert.Equal("Bar", ((TextBlock)child).Text);
  209. }
  210. [Fact]
  211. public void Selected_Item_Changes_To_First_Item_If_SelectedItem_Is_Removed_From_Middle()
  212. {
  213. var items = new ObservableCollection<string>
  214. {
  215. "Foo",
  216. "Bar",
  217. "FooBar"
  218. };
  219. var target = new Carousel
  220. {
  221. Template = new FuncControlTemplate<Carousel>(CreateTemplate),
  222. Items = items,
  223. IsVirtualized = false
  224. };
  225. target.ApplyTemplate();
  226. target.Presenter.ApplyTemplate();
  227. target.SelectedIndex = 1;
  228. items.RemoveAt(1);
  229. Assert.Equal(0, target.SelectedIndex);
  230. Assert.Equal("Foo", target.SelectedItem);
  231. }
  232. private Control CreateTemplate(Carousel control, INameScope scope)
  233. {
  234. return new CarouselPresenter
  235. {
  236. Name = "PART_ItemsPresenter",
  237. [~CarouselPresenter.IsVirtualizedProperty] = control[~Carousel.IsVirtualizedProperty],
  238. [~CarouselPresenter.ItemsProperty] = control[~Carousel.ItemsProperty],
  239. [~CarouselPresenter.ItemsPanelProperty] = control[~Carousel.ItemsPanelProperty],
  240. [~CarouselPresenter.SelectedIndexProperty] = control[~Carousel.SelectedIndexProperty],
  241. [~CarouselPresenter.PageTransitionProperty] = control[~Carousel.PageTransitionProperty],
  242. }.RegisterInNameScope(scope);
  243. }
  244. private static TextBlock GetContainerTextBlock(object control)
  245. {
  246. var contentPresenter = Assert.IsType<ContentPresenter>(control);
  247. contentPresenter.UpdateChild();
  248. return Assert.IsType<TextBlock>(contentPresenter.Child);
  249. }
  250. [Fact]
  251. public void SelectedItem_Validation()
  252. {
  253. using (UnitTestApplication.Start(TestServices.MockThreadingInterface))
  254. {
  255. var target = new Carousel
  256. {
  257. Template = new FuncControlTemplate<Carousel>(CreateTemplate), IsVirtualized = false
  258. };
  259. target.ApplyTemplate();
  260. target.Presenter.ApplyTemplate();
  261. var exception = new System.InvalidCastException("failed validation");
  262. var textObservable =
  263. new BehaviorSubject<BindingNotification>(new BindingNotification(exception,
  264. BindingErrorType.DataValidationError));
  265. target.Bind(ComboBox.SelectedItemProperty, textObservable);
  266. Assert.True(DataValidationErrors.GetHasErrors(target));
  267. Assert.True(DataValidationErrors.GetErrors(target).SequenceEqual(new[] { exception }));
  268. }
  269. }
  270. }
  271. }