Merge pull request #3913 from omwok/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 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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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 ()
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]
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.")]
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]
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)")]
387                 public void CanRemove ()
388                 {
389                         Assert.That (_table.Constraints.CanRemove (_table.Constraints [0]), Is.False, "A1");
390                 }
391
392                 [Test]
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)")]
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)")]
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]
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 }