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