1 //
2 // System.Collections.CollectionBase
3 // Test suite for System.Collections.CollectionBase
4 //
5 // Authors:
6 //    Nick D. Drochak II
7 //    Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 //
9 // (C) 2001 Nick D. Drochak II
10 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
11 //
12 
13 
14 using System;
15 using System.Collections;
16 using NUnit.Framework;
17 
18 namespace MonoTests.System.Collections
19 {
20 
21 [TestFixture]
22 public class CollectionBaseTest
23 {
24 	// We need a concrete class to test the abstract base class
25 	public class ConcreteCollection : CollectionBase
26 	{
27 		// These fields are used as markers to test the On* hooks.
28 		public bool onClearFired;
29 		public bool onClearCompleteFired;
30 
31 		public bool onInsertFired;
32 		public int onInsertIndex;
33 		public bool onInsertCompleteFired;
34 		public int onInsertCompleteIndex;
35 
36 		public bool onRemoveFired;
37 		public int onRemoveIndex;
38 		public bool onRemoveCompleteFired;
39 		public int onRemoveCompleteIndex;
40 
41 		public bool onSetFired;
42 		public int onSetOldValue;
43 		public int onSetNewValue;
44 		public bool onSetCompleteFired;
45 		public int onSetCompleteOldValue;
46 		public int onSetCompleteNewValue;
47 		public int mustThrowException;
48 		public bool onValidateFired;
49 
50 		// This constructor is used to test OnValid()
ConcreteCollection()51 		public ConcreteCollection()
52 		{
53 			IList listObj;
54 			listObj = this;
55 			listObj.Add(null);
56 		}
57 
58 		// This constructor puts consecutive integers into the list
ConcreteCollection(int i)59 		public ConcreteCollection(int i) {
60 			IList listObj;
61 			listObj = this;
62 
63 			int j;
64 			for (j = 0; j< i; j++) {
65 				listObj.Add(j);
66 			}
67 		}
68 
CheckIfThrow()69 		void CheckIfThrow ()
70 		{
71 			if (mustThrowException > 0) {
72 				mustThrowException--;
73 				if (mustThrowException == 0)
74 					throw new Exception ();
75 			}
76 		}
77 
78 		// A helper method to look at a value in the list at a specific index
PeekAt(int index)79 		public int PeekAt(int index)
80 		{
81 			IList listObj;
82 			listObj = this;
83 			return (int) listObj[index];
84 		}
85 
OnValidate(object value)86 		protected override void OnValidate (object value) {
87 			this.onValidateFired = true;
88 			CheckIfThrow ();
89 			base.OnValidate (value);
90 		}
91 
92 		// Mark the flag if this hook is fired
OnClear()93 		protected override void OnClear() {
94 			this.onClearFired = true;
95 			CheckIfThrow ();
96 		}
97 
98 		// Mark the flag if this hook is fired
OnClearComplete()99 		protected override void OnClearComplete()
100 		{
101 			this.onClearCompleteFired = true;
102 			CheckIfThrow ();
103 		}
104 
105 		// Mark the flag, and save the paramter if this hook is fired
OnInsert(int index, object value)106 		protected override void OnInsert(int index, object value)
107 		{
108 			this.onInsertFired = true;
109 			this.onInsertIndex = index;
110 			CheckIfThrow ();
111 		}
112 
113 		// Mark the flag, and save the paramter if this hook is fired
OnInsertComplete(int index, object value)114 		protected override void OnInsertComplete(int index, object value)
115 		{
116 			this.onInsertCompleteFired = true;
117 			this.onInsertCompleteIndex = index;
118 			CheckIfThrow ();
119 		}
120 
121 		// Mark the flag, and save the paramter if this hook is fired
OnRemove(int index, object value)122 		protected override void OnRemove(int index, object value)
123 		{
124 			this.onRemoveFired = true;
125 			this.onRemoveIndex = index;
126 			CheckIfThrow ();
127 		}
128 
129 		// Mark the flag, and save the paramter if this hook is fired
OnRemoveComplete(int index, object value)130 		protected override void OnRemoveComplete(int index, object value)
131 		{
132 			this.onRemoveCompleteFired = true;
133 			this.onRemoveCompleteIndex = index;
134 			CheckIfThrow ();
135 		}
136 
137 		// Mark the flag, and save the paramters if this hook is fired
OnSet(int index, object oldValue, object newValue)138 		protected override void OnSet(int index, object oldValue, object newValue)
139 		{
140 			this.onSetFired = true;
141 			this.onSetOldValue = (int) oldValue;
142 			this.onSetNewValue = (int) newValue;
143 			CheckIfThrow ();
144 		}
145 
146 		// Mark the flag, and save the paramters if this hook is fired
OnSetComplete(int index, object oldValue, object newValue)147 		protected override void OnSetComplete(int index, object oldValue, object newValue)
148 		{
149 			this.onSetCompleteFired = true;
150 			this.onSetCompleteOldValue = (int) oldValue;
151 			this.onSetCompleteNewValue = (int) newValue;
152 			CheckIfThrow ();
153 		}
154 
155 		public IList BaseList {
156 			get { return base.List; }
157 		}
158 	}  // public class ConcreteCollection
159 
160 	// Check the count property
161 	[Test]
Count()162 	public void Count() {
163 		ConcreteCollection myCollection;
164 		myCollection = new ConcreteCollection(4);
165 		Assert.IsTrue (4 == myCollection.Count);
166 	}
167 
168 	// Make sure GetEnumerator returns an object
169 	[Test]
GetEnumerator()170 	public void GetEnumerator() {
171 		ConcreteCollection myCollection;
172 		myCollection = new ConcreteCollection(4);
173 		Assert.IsTrue (null != myCollection.GetEnumerator());
174 	}
175 
176 	// OnValid disallows nulls
177 	[Test]
178 	[ExpectedException(typeof(ArgumentNullException))]
OnValid()179 	public void OnValid() {
180 		ConcreteCollection myCollection;
181 		myCollection = new ConcreteCollection();
182 	}
183 
184 	// Test various Insert paths
185 	[Test]
Insert()186 	public void Insert() {
187 		ConcreteCollection myCollection;
188 		int numberOfItems;
189 		numberOfItems = 3;
190 		// The constructor inserts
191 		myCollection = new ConcreteCollection(numberOfItems);
192 		Assert.IsTrue (myCollection.onInsertFired);
193 		Assert.IsTrue (myCollection.onInsertCompleteFired);
194 
195 		// Using the IList interface, check inserts in the middle
196 		IList listObj = myCollection;
197 		listObj.Insert(1, 9);
198 		Assert.IsTrue (myCollection.onInsertIndex == 1);
199 		Assert.IsTrue (myCollection.onInsertCompleteIndex == 1);
200 		Assert.IsTrue (myCollection.PeekAt(1) == 9);
201 	}
202 
203 	// Test Clear and it's hooks
204 	[Test]
Clear()205 	public void Clear()
206 	{
207 		ConcreteCollection myCollection;
208 		int numberOfItems;
209 		numberOfItems = 1;
210 		myCollection = new ConcreteCollection(numberOfItems);
211 		myCollection.Clear();
212 		Assert.IsTrue (myCollection.Count == 0);
213 		Assert.IsTrue (myCollection.onClearFired);
214 		Assert.IsTrue (myCollection.onClearCompleteFired);
215 	}
216 
217 	// Test RemoveAt, other removes and the hooks
218 	[Test]
Remove()219 	public void Remove()
220 	{
221 		ConcreteCollection myCollection;
222 		int numberOfItems;
223 		numberOfItems = 3;
224 		// Set up a test collection
225 		myCollection = new ConcreteCollection(numberOfItems);
226 
227 		// The list is 0-based.  So if we remove the second one
228 		myCollection.RemoveAt(1);
229 
230 		// We should see the original third one in it's place
231 		Assert.IsTrue (myCollection.PeekAt(1) == 2);
232 		Assert.IsTrue (myCollection.onRemoveFired);
233 		Assert.IsTrue (myCollection.onRemoveIndex == 1);
234 		Assert.IsTrue (myCollection.onRemoveCompleteFired);
235 		Assert.IsTrue (myCollection.onRemoveCompleteIndex == 1);
236 		IList listObj = myCollection;
237 		listObj.Remove(0);
238 		// Confirm parameters are being passed to the hooks
239 		Assert.IsTrue (myCollection.onRemoveIndex == 0);
240 		Assert.IsTrue (myCollection.onRemoveCompleteIndex == 0);
241 	}
242 
243 	// Test the random access feature
244 	[Test]
Set()245 	public void Set()
246 	{
247 		ConcreteCollection myCollection;
248 		int numberOfItems;
249 		numberOfItems = 3;
250 		myCollection = new ConcreteCollection(numberOfItems);
251 		IList listObj = myCollection;
252 		listObj[0] = 99;
253 		Assert.IsTrue ((int) listObj[0] == 99);
254 		Assert.IsTrue (myCollection.onSetFired);
255 		Assert.IsTrue (myCollection.onSetCompleteFired);
256 		Assert.IsTrue (myCollection.onSetOldValue == 0);
257 		Assert.IsTrue (myCollection.onSetCompleteOldValue == 0);
258 		Assert.IsTrue (myCollection.onSetNewValue == 99);
259 		Assert.IsTrue (myCollection.onSetCompleteNewValue == 99);
260 	}
261 
262 	[Test]
InsertComplete_Add()263 	public void InsertComplete_Add ()
264 	{
265 		ConcreteCollection coll = new ConcreteCollection (0);
266 		coll.mustThrowException = 1;
267 
268 		try {
269 			coll.BaseList.Add (0);
270 		} catch {
271 		}
272 		Assert.AreEqual (0, coll.Count);
273 	}
274 
275 	[Test]
276 	[ExpectedException (typeof (ArgumentOutOfRangeException))]
ValidateCalled()277 	public void ValidateCalled ()
278 	{
279 		ConcreteCollection coll = new ConcreteCollection (0);
280 		coll.mustThrowException = 1;
281 
282 		try {
283 			coll.BaseList [5] = 8888;
284 		} catch (ArgumentOutOfRangeException) {
285 			throw;
286 		} finally {
287 			Assert.AreEqual (false, coll.onValidateFired);
288 		}
289 	}
290 
291 	[Test]
SetCompleteCalled()292 	public void SetCompleteCalled ()
293 	{
294 		ConcreteCollection coll = new ConcreteCollection (0);
295 
296 		coll.BaseList.Add (88);
297 		coll.mustThrowException = 1;
298 		try {
299 			coll.BaseList [0] = 11;
300 		} catch {
301 		} finally {
302 			Assert.AreEqual (false, coll.onSetCompleteFired);
303 		}
304 	}
305 
306 	[Test]
SetCompleteUndo()307 	public void SetCompleteUndo ()
308 	{
309 		ConcreteCollection coll = new ConcreteCollection (0);
310 
311 		bool throwsException = true;
312 
313 		coll.BaseList.Add (88);
314 		coll.onValidateFired = false;
315 		coll.onInsertFired = false;
316 		coll.onSetCompleteFired = false;
317 		coll.mustThrowException = 3;
318 		try {
319 			coll.BaseList [0] = 11;
320 			throwsException = false;
321 		} catch {
322 		} finally {
323 			Assert.IsTrue (throwsException);
324 			Assert.IsTrue (coll.onValidateFired);
325 			Assert.IsTrue (coll.onSetFired);
326 			Assert.IsTrue (coll.onSetCompleteFired);
327 			Assert.AreEqual (88, coll.BaseList [0]);
328 		}
329 	}
330 
331 	[Test]
332 	[ExpectedException (typeof (ArgumentException))]
InvalidRemove()333 	public void InvalidRemove ()
334 	{
335 		ConcreteCollection coll = new ConcreteCollection (0);
336 		coll.BaseList.Remove (10);
337 	}
338 }
339 
340 }
341