PageRenderTime 50ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/danipen/mono
C# | 321 lines | 227 code | 57 blank | 37 comment | 0 complexity | 1bb9c23d8185ba951529ddf878978d63 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. //
  22. // Authors:
  23. // Chris Toshok (toshok@ximian.com)
  24. // Brian O'Keefe (zer0keefie@gmail.com)
  25. //
  26. using System.Collections.ObjectModel;
  27. using System.Collections.Specialized;
  28. using NUnit.Framework;
  29. using System.ComponentModel;
  30. using System.Collections.Generic;
  31. using System;
  32. using System.Collections;
  33. using MonoTests.System.Collections.Specialized;
  34. namespace MonoTests.System.Collections.ObjectModel {
  35. [TestFixture]
  36. public class ObservableCollectionTest {
  37. public ObservableCollectionTest()
  38. {
  39. }
  40. [Test]
  41. public void Insert()
  42. {
  43. bool reached = false;
  44. ObservableCollection<int> col = new ObservableCollection<int> ();
  45. col.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  46. reached = true;
  47. Assert.AreEqual (NotifyCollectionChangedAction.Add, e.Action, "INS_1");
  48. Assert.AreEqual (0, e.NewStartingIndex, "INS_2");
  49. Assert.AreEqual (-1, e.OldStartingIndex, "INS_3");
  50. Assert.AreEqual (1, e.NewItems.Count, "INS_4");
  51. Assert.AreEqual (5, (int)e.NewItems [0], "INS_5");
  52. Assert.AreEqual (null, e.OldItems, "INS_6");
  53. };
  54. col.Insert (0, 5);
  55. Assert.IsTrue (reached, "INS_5");
  56. }
  57. [Test]
  58. public void RemoveAt()
  59. {
  60. bool reached = false;
  61. ObservableCollection<int> col = new ObservableCollection<int> ();
  62. col.Insert (0, 5);
  63. col.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  64. reached = true;
  65. Assert.AreEqual (NotifyCollectionChangedAction.Remove, e.Action, "REMAT_1");
  66. Assert.AreEqual (-1, e.NewStartingIndex, "REMAT_2");
  67. Assert.AreEqual (0, e.OldStartingIndex, "REMAT_3");
  68. Assert.AreEqual (null, e.NewItems, "REMAT_4");
  69. Assert.AreEqual (1, e.OldItems.Count, "REMAT_5");
  70. Assert.AreEqual (5, (int)e.OldItems [0], "REMAT_6");
  71. };
  72. col.RemoveAt (0);
  73. Assert.IsTrue (reached, "REMAT_7");
  74. }
  75. [Test]
  76. public void Move()
  77. {
  78. bool reached = false;
  79. ObservableCollection<int> col = new ObservableCollection<int> ();
  80. col.Insert (0, 0);
  81. col.Insert (1, 1);
  82. col.Insert (2, 2);
  83. col.Insert (3, 3);
  84. col.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  85. reached = true;
  86. Assert.AreEqual (NotifyCollectionChangedAction.Move, e.Action, "MOVE_1");
  87. Assert.AreEqual (3, e.NewStartingIndex, "MOVE_2");
  88. Assert.AreEqual (1, e.OldStartingIndex, "MOVE_3");
  89. Assert.AreEqual (1, e.NewItems.Count, "MOVE_4");
  90. Assert.AreEqual (1, e.NewItems [0], "MOVE_5");
  91. Assert.AreEqual (1, e.OldItems.Count, "MOVE_6");
  92. Assert.AreEqual (1, e.OldItems [0], "MOVE_7");
  93. };
  94. col.Move (1, 3);
  95. Assert.IsTrue (reached, "MOVE_8");
  96. }
  97. [Test]
  98. public void Add()
  99. {
  100. ObservableCollection<char> collection = new ObservableCollection<char> ();
  101. bool propertyChanged = false;
  102. List<string> changedProps = new List<string> ();
  103. NotifyCollectionChangedEventArgs args = null;
  104. ((INotifyPropertyChanged)collection).PropertyChanged += delegate (object sender, PropertyChangedEventArgs e) {
  105. propertyChanged = true;
  106. changedProps.Add (e.PropertyName);
  107. };
  108. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  109. args = e;
  110. };
  111. collection.Add ('A');
  112. Assert.IsTrue (propertyChanged, "ADD_1");
  113. Assert.IsTrue (changedProps.Contains ("Count"), "ADD_2");
  114. Assert.IsTrue (changedProps.Contains ("Item[]"), "ADD_3");
  115. CollectionChangedEventValidators.ValidateAddOperation (args, new char [] { 'A' }, 0, "ADD_4");
  116. }
  117. [Test]
  118. public void Remove()
  119. {
  120. ObservableCollection<char> collection = new ObservableCollection<char> ();
  121. bool propertyChanged = false;
  122. List<string> changedProps = new List<string> ();
  123. NotifyCollectionChangedEventArgs args = null;
  124. collection.Add ('A');
  125. collection.Add ('B');
  126. collection.Add ('C');
  127. ((INotifyPropertyChanged)collection).PropertyChanged += delegate (object sender, PropertyChangedEventArgs e) {
  128. propertyChanged = true;
  129. changedProps.Add (e.PropertyName);
  130. };
  131. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  132. args = e;
  133. };
  134. collection.Remove ('B');
  135. Assert.IsTrue (propertyChanged, "REM_1");
  136. Assert.IsTrue (changedProps.Contains ("Count"), "REM_2");
  137. Assert.IsTrue (changedProps.Contains ("Item[]"), "REM_3");
  138. CollectionChangedEventValidators.ValidateRemoveOperation (args, new char [] { 'B' }, 1, "REM_4");
  139. }
  140. [Test]
  141. public void Set()
  142. {
  143. ObservableCollection<char> collection = new ObservableCollection<char> ();
  144. bool propertyChanged = false;
  145. List<string> changedProps = new List<string> ();
  146. NotifyCollectionChangedEventArgs args = null;
  147. collection.Add ('A');
  148. collection.Add ('B');
  149. collection.Add ('C');
  150. ((INotifyPropertyChanged)collection).PropertyChanged += delegate (object sender, PropertyChangedEventArgs e) {
  151. propertyChanged = true;
  152. changedProps.Add (e.PropertyName);
  153. };
  154. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  155. args = e;
  156. };
  157. collection [2] = 'I';
  158. Assert.IsTrue (propertyChanged, "SET_1");
  159. Assert.IsTrue (changedProps.Contains ("Item[]"), "SET_2");
  160. CollectionChangedEventValidators.ValidateReplaceOperation (args, new char [] { 'C' }, new char [] { 'I' }, 2, "SET_3");
  161. }
  162. [Test]
  163. public void Reentrant()
  164. {
  165. ObservableCollection<char> collection = new ObservableCollection<char> ();
  166. bool propertyChanged = false;
  167. List<string> changedProps = new List<string> ();
  168. NotifyCollectionChangedEventArgs args = null;
  169. collection.Add ('A');
  170. collection.Add ('B');
  171. collection.Add ('C');
  172. PropertyChangedEventHandler pceh = delegate (object sender, PropertyChangedEventArgs e) {
  173. propertyChanged = true;
  174. changedProps.Add (e.PropertyName);
  175. };
  176. // Adding a PropertyChanged event handler
  177. ((INotifyPropertyChanged)collection).PropertyChanged += pceh;
  178. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  179. args = e;
  180. };
  181. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  182. // This one will attempt to break reentrancy
  183. try {
  184. collection.Add ('X');
  185. Assert.Fail ("Reentrancy should not be allowed.");
  186. } catch (InvalidOperationException) {
  187. }
  188. };
  189. collection [2] = 'I';
  190. Assert.IsTrue (propertyChanged, "REENT_1");
  191. Assert.IsTrue (changedProps.Contains ("Item[]"), "REENT_2");
  192. CollectionChangedEventValidators.ValidateReplaceOperation (args, new char [] { 'C' }, new char [] { 'I' }, 2, "REENT_3");
  193. // Removing the PropertyChanged event handler should work as well:
  194. ((INotifyPropertyChanged)collection).PropertyChanged -= pceh;
  195. }
  196. //Private test class for protected members of ObservableCollection
  197. private class ObservableCollectionTestHelper : ObservableCollection<char> {
  198. internal void DoubleEnterReentrant()
  199. {
  200. IDisposable object1 = BlockReentrancy ();
  201. IDisposable object2 = BlockReentrancy ();
  202. Assert.AreSame (object1, object2);
  203. //With double block, try the reentrant:
  204. NotifyCollectionChangedEventArgs args = null;
  205. CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  206. args = e;
  207. };
  208. // We need a second callback for reentrancy to matter
  209. CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  210. // Doesn't need to do anything; just needs more than one callback registered.
  211. };
  212. // Try adding - this should cause reentrancy, and fail
  213. try {
  214. Add ('I');
  215. Assert.Fail ("Reentrancy should not be allowed. -- #2");
  216. } catch (InvalidOperationException) {
  217. }
  218. // Release the first reentrant
  219. object1.Dispose ();
  220. // Try adding again - this should cause reentrancy, and fail again
  221. try {
  222. Add ('J');
  223. Assert.Fail ("Reentrancy should not be allowed. -- #3");
  224. } catch (InvalidOperationException) {
  225. }
  226. // Release the reentrant a second time
  227. object1.Dispose ();
  228. // This last add should work fine.
  229. Add ('K');
  230. CollectionChangedEventValidators.ValidateAddOperation (args, new char [] { 'K' }, 0, "REENTHELP_1");
  231. }
  232. }
  233. [Test]
  234. public void ReentrantReuseObject()
  235. {
  236. ObservableCollectionTestHelper helper = new ObservableCollectionTestHelper ();
  237. helper.DoubleEnterReentrant ();
  238. }
  239. [Test]
  240. public void Clear()
  241. {
  242. List<char> initial = new List<char> ();
  243. initial.Add ('A');
  244. initial.Add ('B');
  245. initial.Add ('C');
  246. ObservableCollection<char> collection = new ObservableCollection<char> (initial);
  247. bool propertyChanged = false;
  248. List<string> changedProps = new List<string> ();
  249. NotifyCollectionChangedEventArgs args = null;
  250. ((INotifyPropertyChanged)collection).PropertyChanged += delegate (object sender, PropertyChangedEventArgs e) {
  251. propertyChanged = true;
  252. changedProps.Add (e.PropertyName);
  253. };
  254. collection.CollectionChanged += delegate (object sender, NotifyCollectionChangedEventArgs e) {
  255. args = e;
  256. };
  257. collection.Clear ();
  258. Assert.IsTrue (propertyChanged, "CLEAR_1");
  259. Assert.IsTrue (changedProps.Contains ("Count"), "CLEAR_2");
  260. Assert.IsTrue (changedProps.Contains ("Item[]"), "CLEAR_3");
  261. CollectionChangedEventValidators.ValidateResetOperation (args, "CLEAR_4");
  262. }
  263. }
  264. }