fe2c89a55c7ea063e0a70adc4f9b623c2b1c9c65
[mono.git] / mcs / class / System.Data / Test / System.Data / ConstraintCollectionTest.cs
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
35
36 using NUnit.Framework;
37 using System;
38 using System.Data;
39
40 namespace MonoTests.System.Data
41 {
42         [TestFixture]
43         public class ConstraintCollectionTest : Assertion {
44                 private DataTable _table;
45                 private DataTable _table2;
46                 private Constraint _constraint1;
47                 private Constraint _constraint2;
48
49                 [SetUp]
50                 public void GetReady() 
51                 {
52                         //Setup DataTable
53                         _table = new DataTable("TestTable");
54                         _table.Columns.Add("Col1",typeof(int));
55                         _table.Columns.Add("Col2",typeof(int));
56                         _table.Columns.Add("Col3",typeof(int));
57
58                         _table2 = new DataTable("TestTable");
59                         _table2.Columns.Add("Col1",typeof(int));
60                         _table2.Columns.Add("Col2",typeof(int));
61
62                         //Use UniqueConstraint to test Constraint Base Class
63                         _constraint1 = new UniqueConstraint(_table.Columns[0],false); 
64                         _constraint2 = new UniqueConstraint(_table.Columns[1],false); 
65
66                         // not sure why this is needed since a new _table was just created
67                         // for us, but this Clear() keeps the tests from throwing
68                         // an exception when the Add() is called.
69                         _table.Constraints.Clear();
70                 }
71
72                 [Test]
73                 public void Add()
74                 {
75                         ConstraintCollection col = _table.Constraints;
76                         col.Add(_constraint1);
77                         col.Add(_constraint2);
78
79                         AssertEquals("Count doesn't equal added.",2, col.Count);
80                 }
81
82                 [Test]
83                 public void AddExceptions()
84                 {
85                         ConstraintCollection col = _table.Constraints;
86                         
87                         //null
88                         try 
89                         {
90                                 col.Add(null);
91                                 Fail("B1: Failed to throw ArgumentNullException.");
92                         }
93                         catch (ArgumentNullException) {}
94                         catch (AssertionException exc) {throw exc;}
95                         catch 
96                         {
97                                 Fail("A1: Wrong exception type");
98                         }
99
100                         //duplicate name
101                         try 
102                         {
103                                 _constraint1.ConstraintName = "Dog";
104                                 _constraint2.ConstraintName = "dog"; //case insensitive
105                                 col.Add(_constraint1);
106                                 col.Add(_constraint2);
107 #if NET_1_1
108 #else
109                                 Fail("Failed to throw Duplicate name exception.");
110 #endif
111                                 col.Remove (_constraint2); // only for !1.0
112                                 col.Remove (_constraint1);
113                         }
114 #if ! NET_1_1
115                         catch (DuplicateNameException) {
116                         }
117 #endif
118                         catch (AssertionException exc) {throw exc;}
119 /* Don't use such catch. They cover our eyes from the exact exception location.
120                         catch (Exception exc)
121                         {
122                                 Fail("A2: Wrong exception type. " + exc.ToString());
123                         }
124 */
125                         //Constraint Already exists
126                         try 
127                         {
128                                 col.Add(_constraint1);
129 #if NET_1_1
130 #else
131                                 Fail("B2: Failed to throw ArgumentException.");
132 #endif
133                                 col.Remove (_constraint1);
134                         }
135                         catch (ArgumentException) {
136 #if NET_1_1
137 #else
138                                 throw;
139 #endif
140                         }
141                         catch (AssertionException exc) {throw exc;}
142                         catch 
143                         {
144                                 Fail("A3: Wrong exception type");
145                         }
146                 }
147
148                 [Test]
149                 public void Indexer()
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
158                         _table.Constraints.Add(c1);
159                         _table.Constraints.Add(c2);
160
161                         AssertSame("A1", c1, _table.Constraints[0]); 
162                         AssertSame("A2", c2, _table.Constraints[1]);
163
164                         AssertSame("A3", c1, _table.Constraints["first"]);
165                         AssertSame("A4", c2, _table.Constraints["sEcond"]); //case insensitive
166
167                 }
168
169                 [Test]
170                 public void IndexOf()
171                 {
172                         Constraint c1 = new UniqueConstraint(_table.Columns[0]);
173                         Constraint c2 = new UniqueConstraint(_table.Columns[1]);
174
175                         c1.ConstraintName = "first";
176                         c2.ConstraintName = "second";
177
178                         _table.Constraints.Add(c1);
179                         _table.Constraints.Add(c2);
180
181                         AssertEquals("A1", 0, _table.Constraints.IndexOf(c1));
182                         AssertEquals("A2", 1, _table.Constraints.IndexOf(c2));
183                         AssertEquals("A3", 0, _table.Constraints.IndexOf("first"));
184                         AssertEquals("A4", 1, _table.Constraints.IndexOf("second"));
185                 }
186
187                 [Test]
188                 public void Contains()
189                 {
190                         Constraint c1 = new UniqueConstraint(_table.Columns[0]);
191                         Constraint c2 = new UniqueConstraint(_table.Columns[1]);
192
193                         c1.ConstraintName = "first";
194                         c2.ConstraintName = "second";
195
196                         _table.Constraints.Add(c1);
197
198                         Assert("A1", _table.Constraints.Contains(c1.ConstraintName)); //true
199                         Assert("A2", _table.Constraints.Contains(c2.ConstraintName) == false); //doesn't contain
200                 }
201
202                 [Test]
203                 public void IndexerFailures()
204                 {
205                         _table.Constraints.Add(new UniqueConstraint(_table.Columns[0]));
206
207                         //This doesn't throw
208                         AssertNull(_table.Constraints["notInCollection"]);
209                         
210                         //Index too high
211                         try 
212                         {
213                                 Constraint c = _table.Constraints[_table.Constraints.Count];
214                                 Fail("B1: Failed to throw IndexOutOfRangeException.");
215                         }
216                         catch (IndexOutOfRangeException) {}
217                         catch (AssertionException exc) {throw exc;}
218                         catch 
219                         {
220                                 Fail("A1: Wrong exception type");
221                         }
222
223                         //Index too low
224                         try 
225                         {
226                                 Constraint c = _table.Constraints[-1];
227                                 Fail("B2: Failed to throw IndexOutOfRangeException.");
228                         }
229                         catch (IndexOutOfRangeException) {}
230                         catch (AssertionException exc) {throw exc;}
231                         catch 
232                         {
233                                 Fail("A2: Wrong exception type");
234                         }       
235
236                 }
237
238                 [Test]
239                 public void AddFkException1()
240                 {
241                         DataSet ds = new DataSet();
242                         ds.Tables.Add(_table);
243                         _table2.TableName = "TestTable2";
244                         ds.Tables.Add(_table2);
245
246                         _table.Rows.Add(new object [] {1});
247                         _table.Rows.Add(new object [] {1});
248
249                         //FKC: can't create unique constraint because duplicate values already exist
250                         try
251                         {
252                                 ForeignKeyConstraint fkc = new ForeignKeyConstraint( _table.Columns[0],
253                                                                                         _table2.Columns[0]);
254                                 
255                                 _table2.Constraints.Add(fkc);   //should throw                  
256                                 Fail("B1: Failed to throw ArgumentException.");
257                         }
258                         catch (ArgumentException) {}
259                         catch (AssertionException exc) {throw exc;}
260                         catch (Exception exc)
261                         {
262                                 Fail("A1: Wrong Exception type. " + exc.ToString());
263                         }
264
265
266                 }
267
268
269                 [Test]
270                 public void AddFkException2()
271                 {
272                         //Foreign key rules only work when the tables
273                         //are apart of the dataset
274                         DataSet ds = new DataSet();
275                         ds.Tables.Add(_table);
276                         _table2.TableName = "TestTable2";
277                         ds.Tables.Add(_table2);
278
279                         _table.Rows.Add(new object [] {1});
280                         
281                         // will need a matching parent value in 
282                         // _table
283                         _table2.Rows.Add(new object [] {3}); 
284                                                                 
285
286                         //FKC: no matching parent value
287                         try
288                         {
289                                 ForeignKeyConstraint fkc = new ForeignKeyConstraint( _table.Columns[0],
290                                         _table2.Columns[0]);
291                                 
292                                 _table2.Constraints.Add(fkc);   //should throw                  
293                                 Fail("B1: Failed to throw ArgumentException.");
294                         }
295                         catch (ArgumentException) {}
296                         catch (AssertionException exc) {throw exc;}
297                         catch (Exception exc)
298                         {
299                                 Fail("A1: Wrong Exception type. " + exc.ToString());
300                         }
301
302
303                 }
304
305
306                 [Test]
307                 public void AddUniqueExceptions()
308                 {
309                         
310
311                         //UC: can't create unique constraint because duplicate values already exist
312                         try
313                         {
314                                 _table.Rows.Add(new object [] {1});
315                                 _table.Rows.Add(new object [] {1});
316                                 UniqueConstraint uc = new UniqueConstraint( _table.Columns[0]);
317                                 
318                                 _table.Constraints.Add(uc);     //should throw                  
319                                 Fail("B1: Failed to throw ArgumentException.");
320                         }
321                         catch (ArgumentException) {}
322                         catch (AssertionException exc) {throw exc;}
323                         catch (Exception exc)
324                         {
325                                 Fail("A1: Wrong Exception type. " + exc.ToString());
326                         }
327                 }
328
329                 [Test]
330                 //Tests AddRange (), CanRemove (), RemoveAt (), Remove (), Exceptions of  Remove(), and Clear ()
331                 public void AddRemoveTest ()
332                 {
333                         AddRange ();
334 //                      CanRemove (); This test is ignored
335                         Remove ();
336 //                      RemoveAt (); This test is ignored
337
338                         // This test is expected to be failed, so don't reuse it.
339 //                        RemoveExceptions ();
340                         _table.Constraints.Remove (_table.Constraints [0]);
341
342                         Clear ();
343                 }
344
345                 [Test]
346                 public void AddRange()
347                 {
348                         _constraint1.ConstraintName = "UK1";
349                         _constraint2.ConstraintName = "UK12";
350                                                                                                     
351                         ForeignKeyConstraint _constraint3 = new ForeignKeyConstraint ("FK2", _table.Columns [0],
352                                         _table2.Columns [0]);
353                         UniqueConstraint _constraint4=new UniqueConstraint("UK2", _table2.Columns [1]);
354                                                                                                     
355                         // Add the constraints.
356                         Constraint [] constraints = {_constraint1, _constraint2};
357                         _table.Constraints.AddRange (constraints);
358                                                                                                                                                                                                          
359                         Constraint [] constraints1 = {_constraint3, _constraint4};
360                         _table2.Constraints.AddRange (constraints1);
361                                                                                                     
362                         AssertEquals ("A1", "UK1", _table.Constraints [0].ConstraintName);
363                         AssertEquals ("A2", "UK12", _table.Constraints [1].ConstraintName);
364                                                                                                     
365                         AssertEquals ("A3", "FK2", _table2.Constraints [0].ConstraintName);
366                         AssertEquals ("A4", "UK2", _table2.Constraints [1].ConstraintName);
367
368                 }
369                 
370                 [Test]
371                 [Category ("NotDotNet")]
372                 // Even after EndInit(), MS.NET does not fill Table property
373                 // on UniqueConstraint.
374                 public void TestAddRange2()
375                 {
376                         DataTable table = new DataTable ("Table");
377                         DataColumn column1 = new DataColumn ("col1");
378                         DataColumn column2 = new DataColumn ("col2");
379                         DataColumn column3 = new DataColumn ("col3");
380                         table.Columns.Add (column1);
381                         table.Columns.Add (column2);
382                         table.Columns.Add (column3);
383                         string []columnNames = {"col1", "col2", "col3"};
384                                                                                                     
385                         Constraint []constraints = new Constraint[3];
386                         constraints [0] = new UniqueConstraint ("Unique1",column1);
387                         constraints [1] = new UniqueConstraint ("Unique2",column2);
388                         constraints [2] = new UniqueConstraint ("Unique3", columnNames, true);
389                                                                                                     
390                         table.BeginInit();
391                         //Console.WriteLine(table.InitStatus == DataTable.initStatus.BeginInit);
392                         table.Constraints.AddRange (constraints);
393                                                                                                     
394                         //Check the table property of UniqueConstraint Object
395                         try{
396                                 Assertion.AssertNull ("#01", constraints [2].Table);
397                         }
398                         catch (Exception e) {
399                                 Assertion.Assert ("#A02", "System.NullReferenceException".Equals (e.GetType().ToString()));
400                         }
401
402                         table.EndInit();
403
404                         // After EndInit is called the constraints associated with most recent call to AddRange() must be
405                         // added to the ConstraintCollection
406                         Assertion.Assert ("#A03", constraints [2].Table.ToString().Equals ("Table"));
407                         Assertion.Assert ("#A04", table.Constraints.Contains ("Unique1"));
408                         Assertion.Assert ("#A05", table.Constraints.Contains ("Unique2"));
409                         Assertion.Assert ("#A06", table.Constraints.Contains ("Unique3"));
410
411                 }
412         
413
414
415                 [Test]
416                 public void Clear()
417                 {
418                         try {
419                                _table.Constraints.Clear (); //Clear all constraints
420                                 AssertEquals ("A1", 0, _table.Constraints.Count); //No constraints should remain
421                                 _table2.Constraints.Clear ();
422                                 AssertEquals ("A2", 0, _table2.Constraints.Count);
423                         }
424                         catch (Exception e) {
425                                 Console.WriteLine (e);
426                         }
427
428                 }
429
430                 [Test]
431                 [Ignore ("This never works on MS.NET (and it should not)")]
432                 public void CanRemove()
433                 {
434                         AssertEquals ("A1", false, _table.Constraints.CanRemove (_table.Constraints [0]));
435
436                 }
437
438                 [Test]
439                 public void CollectionChanged()
440                 {
441                 }
442 #if false
443                 //
444                 // If this fails on MS.NET and its supposed to fail, why do we have this as Ignore?
445                 //
446                 [Test]
447                 [Ignore ("MS.NET fails this test (and it should fail)")]
448                 public void RemoveAt()
449                 {
450                          _table2.Constraints.RemoveAt (1); //Remove constraint and again add it
451                          AssertEquals ("A1", 1, _table2.Constraints.Count);                                                  UniqueConstraint _constraint4  = new UniqueConstraint ("UK2", _table2.Columns [1]);
452                          // Add the constraints.
453                          Constraint [] constraints = {_constraint4};
454                          _table.Constraints.AddRange (constraints);
455
456                 }
457 #endif
458
459                 //[Test]
460                 [Ignore ("MS.NET fails this test (and it should fail)")]
461                 public void Remove()
462                 {
463                         _table2.Constraints.Remove (_table2.Constraints [1]); //Remove constraint and again add it
464                         AssertEquals ("A1", 1, _table2.Constraints.Count);                      
465                         UniqueConstraint _constraint4 = new UniqueConstraint ("UK2", _table2.Columns [1]);                                                                               
466                         // Add the constraints.
467                         Constraint [] constraints = {_constraint4};
468                         _table2.Constraints.AddRange (constraints);
469                 }
470
471                 [Test]
472                 public void RemoveExceptions()
473                 {
474                         try {
475                                 //Remove constraint that cannot be removed
476                                 _table.Constraints.Remove (_table.Constraints [0]);
477                                 Fail ("A1");
478                         } catch (Exception e) {
479                                 AssertEquals ("A2", typeof (IndexOutOfRangeException), e.GetType ());
480                         }
481                 }
482
483         }
484         
485 }