1 // ConstraintCollection.cs - NUnit Test Cases for testing the ConstraintCollection
2 //	class.
3 //
4 // Authors:
5 //   Franklin Wise (gracenote@earthlink.net)
6 //   Martin Willemoes Hansen (mwh@sysrq.dk)
7 //   Roopa Wilson (rowilson@novell.com)
8 //
9 // (C) Franklin Wise
10 // (C) 2003 Martin Willemoes Hansen
11 
12 //
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 //
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 //
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34 using NUnit.Framework;
35 using System;
36 using System.Data;
37 
38 namespace MonoTests.System.Data
39 {
40 	[TestFixture]
41 	public class ConstraintCollectionTest
42 	{
43 		private DataTable _table;
44 		private DataTable _table2;
45 		private Constraint _constraint1;
46 		private Constraint _constraint2;
47 
48 		[SetUp]
GetReady()49 		public void GetReady ()
50 		{
51 			//Setup DataTable
52 			_table = new DataTable ("TestTable");
53 			_table.Columns.Add ("Col1", typeof(int));
54 			_table.Columns.Add ("Col2", typeof(int));
55 			_table.Columns.Add ("Col3", typeof(int));
56 
57 			_table2 = new DataTable ("TestTable");
58 			_table2.Columns.Add ("Col1", typeof(int));
59 			_table2.Columns.Add ("Col2", typeof(int));
60 
61 			//Use UniqueConstraint to test Constraint Base Class
62 			_constraint1 = new UniqueConstraint (_table.Columns [0], false);
63 			_constraint2 = new UniqueConstraint (_table.Columns [1], false);
64 
65 			// not sure why this is needed since a new _table was just created
66 			// for us, but this Clear() keeps the tests from throwing
67 			// an exception when the Add() is called.
68 			_table.Constraints.Clear ();
69 		}
70 
71 		[Test]
Add()72 		public void Add ()
73 		{
74 			ConstraintCollection col = _table.Constraints;
75 			col.Add (_constraint1);
76 			col.Add (_constraint2);
77 
78 			Assert.That (col.Count, Is.EqualTo (2), "Count doesn't equal added.");
79 		}
80 
81 		[Test]
AddExceptions()82 		public void AddExceptions ()
83 		{
84 			ConstraintCollection col = _table.Constraints;
85 
86 			//null
87 			try {
88 				col.Add (null);
89 				Assert.Fail ("B1: Failed to throw ArgumentNullException.");
90 			} catch (ArgumentNullException) {
91 			} catch (AssertionException exc) {
92 				throw exc;
93 			} catch {
94 				Assert.Fail ("A1: Wrong exception type");
95 			}
96 
97 			//duplicate name
98 			try {
99 				_constraint1.ConstraintName = "Dog";
100 				_constraint2.ConstraintName = "dog"; //case insensitive
101 				col.Add (_constraint1);
102 				col.Add (_constraint2);
103 				col.Remove (_constraint2); // only for !1.0
104 				col.Remove (_constraint1);
105 			}
106 			catch (AssertionException exc) {
107 				throw exc;
108 			}
109 /* Don't use such catch. They cover our eyes from the exact exception location.
110 			catch (Exception exc)
111 			{
112 				Assert.Fail("A2: Wrong exception type. " + exc.ToString());
113 			}
114 */
115 			//Constraint Already exists
116 			try {
117 				col.Add (_constraint1);
118 				col.Remove (_constraint1);
119 			} catch (ArgumentException) {
120 			} catch (AssertionException exc) {
121 				throw exc;
122 			} catch {
123 				Assert.Fail ("A3: Wrong exception type");
124 			}
125 		}
126 
127 		[Test]
Indexer()128 		public void Indexer ()
129 		{
130 			Constraint c1 = new UniqueConstraint (_table.Columns [0]);
131 			Constraint c2 = new UniqueConstraint (_table.Columns [1]);
132 
133 			c1.ConstraintName = "first";
134 			c2.ConstraintName = "second";
135 
136 
137 			_table.Constraints.Add (c1);
138 			_table.Constraints.Add (c2);
139 
140 			Assert.AreSame (c1, _table.Constraints [0], "A1");
141 			Assert.AreSame (c2, _table.Constraints [1], "A2");
142 
143 			Assert.AreSame (c1, _table.Constraints ["first"], "A3");
144 			Assert.AreSame (c2, _table.Constraints ["sEcond"], "A4"); //case insensitive
145 
146 		}
147 
148 		[Test]
IndexOf()149 		public void IndexOf ()
150 		{
151 			Constraint c1 = new UniqueConstraint (_table.Columns [0]);
152 			Constraint c2 = new UniqueConstraint (_table.Columns [1]);
153 
154 			c1.ConstraintName = "first";
155 			c2.ConstraintName = "second";
156 
157 			_table.Constraints.Add (c1);
158 			_table.Constraints.Add (c2);
159 
160 			Assert.AreEqual (0, _table.Constraints.IndexOf (c1), "A1");
161 			Assert.AreEqual (1, _table.Constraints.IndexOf (c2), "A2");
162 			Assert.AreEqual (0, _table.Constraints.IndexOf ("first"), "A3");
163 			Assert.AreEqual (1, _table.Constraints.IndexOf ("second"), "A4");
164 		}
165 
166 		[Test]
Contains()167 		public void Contains ()
168 		{
169 			Constraint c1 = new UniqueConstraint (_table.Columns [0]);
170 			Constraint c2 = new UniqueConstraint (_table.Columns [1]);
171 
172 			c1.ConstraintName = "first";
173 			c2.ConstraintName = "second";
174 
175 			_table.Constraints.Add (c1);
176 
177 			Assert.That (_table.Constraints.Contains (c1.ConstraintName), Is.True);
178 			Assert.That (_table.Constraints.Contains (c2.ConstraintName), Is.False);
179 		}
180 
181 		[Test]
IndexerFailures()182 		public void IndexerFailures ()
183 		{
184 			_table.Constraints.Add (new UniqueConstraint (_table.Columns [0]));
185 
186 			//This doesn't throw
187 			Assert.That (_table.Constraints ["notInCollection"], Is.Null);
188 
189 			//Index too high
190 			try {
191 				Constraint c = _table.Constraints [_table.Constraints.Count];
192 				Assert.Fail ("B1: Failed to throw IndexOutOfRangeException.");
193 			} catch (IndexOutOfRangeException) {
194 			} catch (AssertionException exc) {
195 				throw exc;
196 			} catch {
197 				Assert.Fail ("A1: Wrong exception type");
198 			}
199 
200 			//Index too low
201 			try {
202 				Constraint c = _table.Constraints [-1];
203 				Assert.Fail ("B2: Failed to throw IndexOutOfRangeException.");
204 			} catch (IndexOutOfRangeException) {
205 			} catch (AssertionException exc) {
206 				throw exc;
207 			} catch {
208 				Assert.Fail ("A2: Wrong exception type");
209 			}
210 		}
211 
212 		[Test]
AddFkException1()213 		public void AddFkException1 ()
214 		{
215 			DataSet ds = new DataSet ();
216 			ds.Tables.Add (_table);
217 			_table2.TableName = "TestTable2";
218 			ds.Tables.Add (_table2);
219 
220 			_table.Rows.Add (new object [] {1});
221 			_table.Rows.Add (new object [] {1});
222 
223 			//FKC: can't create unique constraint because duplicate values already exist
224 			try {
225 				ForeignKeyConstraint fkc = new ForeignKeyConstraint (_table.Columns [0],
226 											_table2.Columns [0]);
227 
228 				_table2.Constraints.Add (fkc);	//should throw
229 				Assert.Fail ("B1: Failed to throw ArgumentException.");
230 			} catch (ArgumentException) {
231 			} catch (AssertionException exc) {
232 				throw exc;
233 			} catch (Exception exc) {
234 				Assert.Fail ("A1: Wrong Exception type. " + exc.ToString ());
235 			}
236 		}
237 
238 		[Test]
AddFkException2()239 		public void AddFkException2 ()
240 		{
241 			//Foreign key rules only work when the tables
242 			//are apart of the dataset
243 			DataSet ds = new DataSet ();
244 			ds.Tables.Add (_table);
245 			_table2.TableName = "TestTable2";
246 			ds.Tables.Add (_table2);
247 
248 			_table.Rows.Add (new object [] {1});
249 
250 			// will need a matching parent value in
251 			// _table
252 			_table2.Rows.Add (new object [] {3});
253 
254 
255 			//FKC: no matching parent value
256 			try {
257 				ForeignKeyConstraint fkc = new ForeignKeyConstraint (_table.Columns [0],
258 					_table2.Columns [0]);
259 
260 				_table2.Constraints.Add (fkc);	//should throw
261 				Assert.Fail ("B1: Failed to throw ArgumentException.");
262 			} catch (ArgumentException) {
263 			} catch (AssertionException exc) {
264 				throw exc;
265 			} catch (Exception exc) {
266 				Assert.Fail ("A1: Wrong Exception type. " + exc.ToString ());
267 			}
268 		}
269 
270 		[Test]
AddUniqueExceptions()271 		public void AddUniqueExceptions ()
272 		{
273 
274 
275 			//UC: can't create unique constraint because duplicate values already exist
276 			try {
277 				_table.Rows.Add (new object [] {1});
278 				_table.Rows.Add (new object [] {1});
279 				UniqueConstraint uc = new UniqueConstraint (_table.Columns [0]);
280 
281 				_table.Constraints.Add (uc);	//should throw
282 				Assert.Fail ("B1: Failed to throw ArgumentException.");
283 			} catch (ArgumentException) {
284 			} catch (AssertionException exc) {
285 				throw exc;
286 			} catch (Exception exc) {
287 				Assert.Fail ("A1: Wrong Exception type. " + exc.ToString ());
288 			}
289 		}
290 
291 		[Test]
292 		//Tests AddRange (), CanRemove (), RemoveAt (), Remove (), Exceptions of  Remove(), and Clear ()
AddRemoveTest()293 		public void AddRemoveTest ()
294 		{
295 			AddRange ();
296 			//CanRemove (); This test is ignored
297 			Remove ();
298 			//RemoveAt (); This test is ignored
299 
300 			// This test is expected to be failed, so don't reuse it.
301 			//RemoveExceptions ();
302 			_table.Constraints.Remove (_table.Constraints [0]);
303 
304 			Clear ();
305 		}
306 
307 		[Test]
AddRange()308 		public void AddRange ()
309 		{
310 			_constraint1.ConstraintName = "UK1";
311 			_constraint2.ConstraintName = "UK12";
312 
313 			ForeignKeyConstraint _constraint3 = new ForeignKeyConstraint ("FK2", _table.Columns [0],
314                                         _table2.Columns [0]);
315 			UniqueConstraint _constraint4 = new UniqueConstraint ("UK2", _table2.Columns [1]);
316 
317 			// Add the constraints.
318 			Constraint [] constraints = {_constraint1, _constraint2};
319 			_table.Constraints.AddRange (constraints);
320 
321 			Constraint [] constraints1 = {_constraint3, _constraint4};
322 			_table2.Constraints.AddRange (constraints1);
323 
324 			Assert.AreEqual ("UK1", _table.Constraints [0].ConstraintName, "A1");
325 			Assert.AreEqual ("UK12", _table.Constraints [1].ConstraintName, "A2");
326 
327 			Assert.AreEqual ("FK2", _table2.Constraints [0].ConstraintName, "A3");
328 			Assert.AreEqual ("UK2", _table2.Constraints [1].ConstraintName, "A4");
329 		}
330 
331 		[Test]
332 		[Ignore ("Even after EndInit(), .NET does not fill Table property on UniqueConstraint.")]
TestAddRange2()333 		public void TestAddRange2 ()
334 		{
335 			DataTable table = new DataTable ("Table");
336 			DataColumn column1 = new DataColumn ("col1");
337 			DataColumn column2 = new DataColumn ("col2");
338 			DataColumn column3 = new DataColumn ("col3");
339 			table.Columns.Add (column1);
340 			table.Columns.Add (column2);
341 			table.Columns.Add (column3);
342 			string [] columnNames = {"col1", "col2", "col3"};
343 
344 			Constraint [] constraints = new Constraint[3];
345 			constraints [0] = new UniqueConstraint ("Unique1", column1);
346 			constraints [1] = new UniqueConstraint ("Unique2", column2);
347 			constraints [2] = new UniqueConstraint ("Unique3", columnNames, true);
348 
349 			table.BeginInit ();
350 			//Console.WriteLine(table.InitStatus == DataTable.initStatus.BeginInit);
351 			table.Constraints.AddRange (constraints);
352 
353 			//Check the table property of UniqueConstraint Object
354 			try {
355 				Assert.That (constraints [2].Table, Is.Null, "#A01");
356 			} catch (Exception e) {
357 				Assert.That (e, Is.TypeOf (typeof(NullReferenceException)), "#A02");
358 			}
359 
360 			table.EndInit ();
361 
362 			// After EndInit is called the constraints associated with most recent call to AddRange() must be
363 			// added to the ConstraintCollection
364 			/* dunno if the above is true, but it crashes on .NET either. Disabling.
365 			Assert.That (constraints [2].Table.ToString (), Is.EqualTo ("Table"), "#A03");
366 			Assert.That (table.Constraints.Contains ("Unique1"), Is.True, "#A04");
367 			Assert.That (table.Constraints.Contains ("Unique3"), Is.True, "#A06");
368 			Assert.That (table.Constraints.Contains ("Unique2"), Is.True, "#A05");
369 			*/
370 		}
371 
372 		[Test]
Clear()373 		public void Clear ()
374 		{
375 			try {
376 				_table.Constraints.Clear (); //Clear all constraints
377 				Assert.That (_table.Constraints.Count, Is.EqualTo (0), "A1"); //No constraints should remain
378 				_table2.Constraints.Clear ();
379 				Assert.That (_table2.Constraints.Count, Is.EqualTo (0), "A2"); //No constraints should remain
380 			} catch (Exception e) {
381 				Console.WriteLine (e);
382 			}
383 		}
384 
385 		[Test]
386 		[Ignore ("This never works on MS.NET (and it should not)")]
CanRemove()387 		public void CanRemove ()
388 		{
389 			Assert.That (_table.Constraints.CanRemove (_table.Constraints [0]), Is.False, "A1");
390 		}
391 
392 		[Test]
CollectionChanged()393 		public void CollectionChanged ()
394 		{
395 		}
396 #if false
397 		//
398 		// If this fails on MS.NET and its supposed to fail, why do we have this as Ignore?
399 		//
400 		[Test]
401 		[Ignore ("MS.NET fails this test (and it should fail)")]
RemoveAt()402 		public void RemoveAt()
403 		{
404 			 _table2.Constraints.RemoveAt (1); //Remove constraint and again add it
405                          AssertEquals ("A1", 1, _table2.Constraints.Count);                                                  UniqueConstraint _constraint4  = new UniqueConstraint ("UK2", _table2.Columns [1]);
406                          // Add the constraints.
407                          Constraint [] constraints = {_constraint4};
408                          _table.Constraints.AddRange (constraints);
409 
410 		}
411 #endif
412 
413 		//[Test]
414 		[Ignore ("MS.NET fails this test (and it should fail)")]
Remove()415 		public void Remove ()
416 		{
417 			_table2.Constraints.Remove (_table2.Constraints [1]); //Remove constraint and again add it
418 			Assert.That (_table2.Constraints.Count, Is.EqualTo (1), "A1");
419 			UniqueConstraint _constraint4 = new UniqueConstraint ("UK2", _table2.Columns [1]);
420 			// Add the constraints.
421 			Constraint [] constraints = {_constraint4};
422 			_table2.Constraints.AddRange (constraints);
423 		}
424 
425 		[Test]
RemoveExceptions()426 		public void RemoveExceptions ()
427 		{
428 			try {
429 				//Remove constraint that cannot be removed
430 				_table.Constraints.Remove (_table.Constraints [0]);
431 				Assert.Fail ("A1");
432 			} catch (Exception e) {
433 				Assert.That (e, Is.TypeOf (typeof(IndexOutOfRangeException)), "A2");
434 			}
435 		}
436 	}
437 }
438