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