PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/System/Test/System.Collections.ObjectModel/ObservableCollectionTest.cs

https://bitbucket.org/danipen/mono
C# | 352 lines | 252 code | 61 blank | 39 comment | 0 complexity | e424242fa7443061eaa03f122c25b1c2 MD5 | raw file
Possible License(s): Unlicense, Apache-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
  21. // Copyright 2011 Xamarin Inc.
  22. //
  23. // Authors:
  24. // Chris Toshok (toshok@ximian.com)
  25. // Brian O'Keefe (zer0keefie@gmail.com)
  26. // Marek Safar (marek.safar@gmail.com)
  27. //
  28. #if NET_4_0
  29. using System.Collections.ObjectModel;
  30. using System.Collections.Specialized;
  31. using NUnit.Framework;
  32. using System.ComponentModel;
  33. using System.Collections.Generic;
  34. using System;
  35. using System.Collections;
  36. using MonoTests.System.Collections.Specialized;
  37. namespace MonoTests.System.Collections.ObjectModel {
  38. [TestFixture]
  39. public class ObservableCollectionTest
  40. {
  41. [Test]
  42. public void Constructor ()
  43. {
  44. var list = new List<int> { 3 };
  45. var col = new ObservableCollection<int> (list);
  46. col.Add (5);
  47. Assert.AreEqual (1, list.Count, "#1");
  48. col = new ObservableCollection<int> ((IEnumerable<int>) list);
  49. col.Add (5);
  50. Assert.AreEqual (1, list.Count, "#2");
  51. }
  52. [Test]
  53. public void Constructor_Invalid ()
  54. {
  55. try {
  56. new ObservableCollection<int> ((List<int>) null);
  57. Assert.Fail ("#1");
  58. } catch (ArgumentNullException) {
  59. }
  60. try {
  61. new ObservableCollection<int> ((IEnumerable<int>) null);
  62. Assert.Fail ("#2");
  63. } catch (ArgumentNullException) {
  64. }
  65. }
  66. [Test]
  67. public void Insert()
  68. {
  69. bool reached = false;
  70. ObservableCollection<int> col = new ObservableCollection<int> ();
  71. col.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  72. reached = true;
  73. Assert.AreEqual (NotifyCollectionChangedAction.Add, e.Action, "INS_1");
  74. Assert.AreEqual (0, e.NewStartingIndex, "INS_2");
  75. Assert.AreEqual (-1, e.OldStartingIndex, "INS_3");
  76. Assert.AreEqual (1, e.NewItems.Count, "INS_4");
  77. Assert.AreEqual (5, (int)e.NewItems [0], "INS_5");
  78. Assert.AreEqual (null, e.OldItems, "INS_6");
  79. };
  80. col.Insert (0, 5);
  81. Assert.IsTrue (reached, "INS_5");
  82. }
  83. [Test]
  84. public void RemoveAt()
  85. {
  86. bool reached = false;
  87. ObservableCollection<int> col = new ObservableCollection<int> ();
  88. col.Insert (0, 5);
  89. col.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  90. reached = true;
  91. Assert.AreEqual (NotifyCollectionChangedAction.Remove, e.Action, "REMAT_1");
  92. Assert.AreEqual (-1, e.NewStartingIndex, "REMAT_2");
  93. Assert.AreEqual (0, e.OldStartingIndex, "REMAT_3");
  94. Assert.AreEqual (null, e.NewItems, "REMAT_4");
  95. Assert.AreEqual (1, e.OldItems.Count, "REMAT_5");
  96. Assert.AreEqual (5, (int)e.OldItems [0], "REMAT_6");
  97. };
  98. col.RemoveAt (0);
  99. Assert.IsTrue (reached, "REMAT_7");
  100. }
  101. [Test]
  102. public void Move()
  103. {
  104. bool reached = false;
  105. ObservableCollection<int> col = new ObservableCollection<int> ();
  106. col.Insert (0, 0);
  107. col.Insert (1, 1);
  108. col.Insert (2, 2);
  109. col.Insert (3, 3);
  110. col.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  111. reached = true;
  112. Assert.AreEqual (NotifyCollectionChangedAction.Move, e.Action, "MOVE_1");
  113. Assert.AreEqual (3, e.NewStartingIndex, "MOVE_2");
  114. Assert.AreEqual (1, e.OldStartingIndex, "MOVE_3");
  115. Assert.AreEqual (1, e.NewItems.Count, "MOVE_4");
  116. Assert.AreEqual (1, e.NewItems [0], "MOVE_5");
  117. Assert.AreEqual (1, e.OldItems.Count, "MOVE_6");
  118. Assert.AreEqual (1, e.OldItems [0], "MOVE_7");
  119. };
  120. col.Move (1, 3);
  121. Assert.IsTrue (reached, "MOVE_8");
  122. }
  123. [Test]
  124. public void Add()
  125. {
  126. ObservableCollection<char> collection = new ObservableCollection<char> ();
  127. bool propertyChanged = false;
  128. List<string> changedProps = new List<string> ();
  129. NotifyCollectionChangedEventArgs args = null;
  130. ((INotifyPropertyChanged)collection).PropertyChanged += delegate (object sender, PropertyChangedEventArgs e) {
  131. propertyChanged = true;
  132. changedProps.Add (e.PropertyName);
  133. };
  134. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  135. args = e;
  136. };
  137. collection.Add ('A');
  138. Assert.IsTrue (propertyChanged, "ADD_1");
  139. Assert.IsTrue (changedProps.Contains ("Count"), "ADD_2");
  140. Assert.IsTrue (changedProps.Contains ("Item[]"), "ADD_3");
  141. CollectionChangedEventValidators.ValidateAddOperation (args, new char [] { 'A' }, 0, "ADD_4");
  142. }
  143. [Test]
  144. public void Remove()
  145. {
  146. ObservableCollection<char> collection = new ObservableCollection<char> ();
  147. bool propertyChanged = false;
  148. List<string> changedProps = new List<string> ();
  149. NotifyCollectionChangedEventArgs args = null;
  150. collection.Add ('A');
  151. collection.Add ('B');
  152. collection.Add ('C');
  153. ((INotifyPropertyChanged)collection).PropertyChanged += delegate (object sender, PropertyChangedEventArgs e) {
  154. propertyChanged = true;
  155. changedProps.Add (e.PropertyName);
  156. };
  157. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  158. args = e;
  159. };
  160. collection.Remove ('B');
  161. Assert.IsTrue (propertyChanged, "REM_1");
  162. Assert.IsTrue (changedProps.Contains ("Count"), "REM_2");
  163. Assert.IsTrue (changedProps.Contains ("Item[]"), "REM_3");
  164. CollectionChangedEventValidators.ValidateRemoveOperation (args, new char [] { 'B' }, 1, "REM_4");
  165. }
  166. [Test]
  167. public void Set()
  168. {
  169. ObservableCollection<char> collection = new ObservableCollection<char> ();
  170. bool propertyChanged = false;
  171. List<string> changedProps = new List<string> ();
  172. NotifyCollectionChangedEventArgs args = null;
  173. collection.Add ('A');
  174. collection.Add ('B');
  175. collection.Add ('C');
  176. ((INotifyPropertyChanged)collection).PropertyChanged += delegate (object sender, PropertyChangedEventArgs e) {
  177. propertyChanged = true;
  178. changedProps.Add (e.PropertyName);
  179. };
  180. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  181. args = e;
  182. };
  183. collection [2] = 'I';
  184. Assert.IsTrue (propertyChanged, "SET_1");
  185. Assert.IsTrue (changedProps.Contains ("Item[]"), "SET_2");
  186. CollectionChangedEventValidators.ValidateReplaceOperation (args, new char [] { 'C' }, new char [] { 'I' }, 2, "SET_3");
  187. }
  188. [Test]
  189. public void Reentrant()
  190. {
  191. ObservableCollection<char> collection = new ObservableCollection<char> ();
  192. bool propertyChanged = false;
  193. List<string> changedProps = new List<string> ();
  194. NotifyCollectionChangedEventArgs args = null;
  195. collection.Add ('A');
  196. collection.Add ('B');
  197. collection.Add ('C');
  198. PropertyChangedEventHandler pceh = delegate (object sender, PropertyChangedEventArgs e) {
  199. propertyChanged = true;
  200. changedProps.Add (e.PropertyName);
  201. };
  202. // Adding a PropertyChanged event handler
  203. ((INotifyPropertyChanged)collection).PropertyChanged += pceh;
  204. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  205. args = e;
  206. };
  207. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  208. // This one will attempt to break reentrancy
  209. try {
  210. collection.Add ('X');
  211. Assert.Fail ("Reentrancy should not be allowed.");
  212. } catch (InvalidOperationException) {
  213. }
  214. };
  215. collection [2] = 'I';
  216. Assert.IsTrue (propertyChanged, "REENT_1");
  217. Assert.IsTrue (changedProps.Contains ("Item[]"), "REENT_2");
  218. CollectionChangedEventValidators.ValidateReplaceOperation (args, new char [] { 'C' }, new char [] { 'I' }, 2, "REENT_3");
  219. // Removing the PropertyChanged event handler should work as well:
  220. ((INotifyPropertyChanged)collection).PropertyChanged -= pceh;
  221. }
  222. //Private test class for protected members of ObservableCollection
  223. private class ObservableCollectionTestHelper : ObservableCollection<char> {
  224. internal void DoubleEnterReentrant()
  225. {
  226. IDisposable object1 = BlockReentrancy ();
  227. IDisposable object2 = BlockReentrancy ();
  228. Assert.AreSame (object1, object2);
  229. //With double block, try the reentrant:
  230. NotifyCollectionChangedEventArgs args = null;
  231. CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  232. args = e;
  233. };
  234. // We need a second callback for reentrancy to matter
  235. CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  236. // Doesn't need to do anything; just needs more than one callback registered.
  237. };
  238. // Try adding - this should cause reentrancy, and fail
  239. try {
  240. Add ('I');
  241. Assert.Fail ("Reentrancy should not be allowed. -- #2");
  242. } catch (InvalidOperationException) {
  243. }
  244. // Release the first reentrant
  245. object1.Dispose ();
  246. // Try adding again - this should cause reentrancy, and fail again
  247. try {
  248. Add ('J');
  249. Assert.Fail ("Reentrancy should not be allowed. -- #3");
  250. } catch (InvalidOperationException) {
  251. }
  252. // Release the reentrant a second time
  253. object1.Dispose ();
  254. // This last add should work fine.
  255. Add ('K');
  256. CollectionChangedEventValidators.ValidateAddOperation (args, new char [] { 'K' }, 0, "REENTHELP_1");
  257. }
  258. }
  259. [Test]
  260. public void ReentrantReuseObject()
  261. {
  262. ObservableCollectionTestHelper helper = new ObservableCollectionTestHelper ();
  263. helper.DoubleEnterReentrant ();
  264. }
  265. [Test]
  266. public void Clear()
  267. {
  268. List<char> initial = new List<char> ();
  269. initial.Add ('A');
  270. initial.Add ('B');
  271. initial.Add ('C');
  272. ObservableCollection<char> collection = new ObservableCollection<char> (initial);
  273. bool propertyChanged = false;
  274. List<string> changedProps = new List<string> ();
  275. NotifyCollectionChangedEventArgs args = null;
  276. ((INotifyPropertyChanged)collection).PropertyChanged += delegate (object sender, PropertyChangedEventArgs e) {
  277. propertyChanged = true;
  278. changedProps.Add (e.PropertyName);
  279. };
  280. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  281. args = e;
  282. };
  283. collection.Clear ();
  284. Assert.IsTrue (propertyChanged, "CLEAR_1");
  285. Assert.IsTrue (changedProps.Contains ("Count"), "CLEAR_2");
  286. Assert.IsTrue (changedProps.Contains ("Item[]"), "CLEAR_3");
  287. CollectionChangedEventValidators.ValidateResetOperation (args, "CLEAR_4");
  288. }
  289. }
  290. }
  291. #endif