1 // Licensed to the .NET Foundation under one or more agreements. 2 // See the LICENSE file in the project root for more information. 3 4 // Copyright (c) 2004 Mainsoft Co. 5 // 6 // Permission is hereby granted, free of charge, to any person obtaining 7 // a copy of this software and associated documentation files (the 8 // "Software"), to deal in the Software without restriction, including 9 // without limitation the rights to use, copy, modify, merge, publish, 10 // distribute, sublicense, and/or sell copies of the Software, and to 11 // permit persons to whom the Software is furnished to do so, subject to 12 // the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be 15 // included in all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 using System.Collections; 26 using System.ComponentModel; 27 using Xunit; 28 29 namespace System.Data.Tests 30 { 31 public class ConstraintCollectionTest2 32 { 33 private bool _collectionChangedFlag = false; 34 35 [Fact] CanRemove_ParentForeign()36 public void CanRemove_ParentForeign() 37 { 38 DataSet ds = DataProvider.CreateForigenConstraint(); 39 Assert.False(ds.Tables["parent"].Constraints.CanRemove(ds.Tables["parent"].Constraints[0])); 40 } 41 42 [Fact] CanRemove_ChildForeign()43 public void CanRemove_ChildForeign() 44 { 45 DataSet ds = DataProvider.CreateForigenConstraint(); 46 Assert.True(ds.Tables["child"].Constraints.CanRemove(ds.Tables["child"].Constraints[0])); 47 } 48 49 [Fact] CanRemove_ParentAndChildForeign()50 public void CanRemove_ParentAndChildForeign() 51 { 52 DataSet ds = DataProvider.CreateForigenConstraint(); 53 //remove the forigen and ask about the unique 54 ds.Tables["child"].Constraints.Remove(ds.Tables["child"].Constraints[0]); 55 Assert.True(ds.Tables["parent"].Constraints.CanRemove(ds.Tables["parent"].Constraints[0])); 56 } 57 58 [Fact] Clear_Foreign()59 public void Clear_Foreign() 60 { 61 DataSet ds = DataProvider.CreateForigenConstraint(); 62 foreach (DataTable dt in ds.Tables) 63 { 64 dt.Constraints.Clear(); 65 } 66 Assert.Equal(0, ds.Tables[0].Constraints.Count); 67 Assert.Equal(0, ds.Tables[0].Constraints.Count); 68 } 69 70 [Fact] Clear_Unique()71 public void Clear_Unique() 72 { 73 DataTable dt = DataProvider.CreateUniqueConstraint(); 74 int rowsCount = dt.Rows.Count; 75 dt.Constraints.Clear(); 76 DataRow dr = dt.NewRow(); 77 dr[0] = 1; 78 dt.Rows.Add(dr); 79 Assert.Equal(rowsCount + 1, dt.Rows.Count); // verifying no exception as well 80 } 81 82 [Fact] CollectionChanged()83 public void CollectionChanged() 84 { 85 DataTable dt = DataProvider.CreateParentDataTable(); 86 _collectionChangedFlag = false; 87 dt.Constraints.CollectionChanged += new CollectionChangeEventHandler(Constraints_CollectionChangedHandler); 88 dt = DataProvider.CreateUniqueConstraint(dt); 89 Assert.True(_collectionChangedFlag); 90 } 91 92 [Fact] Contains_ByName()93 public void Contains_ByName() 94 { 95 DataSet ds = DataProvider.CreateForigenConstraint(); 96 97 //changing the constraints's name 98 99 ds.Tables["child"].Constraints[0].ConstraintName = "name1"; 100 ds.Tables["parent"].Constraints[0].ConstraintName = "name2"; 101 102 103 Assert.True(ds.Tables["child"].Constraints.Contains("name1")); 104 Assert.False(ds.Tables["child"].Constraints.Contains("xxx")); 105 Assert.True(ds.Tables["parent"].Constraints.Contains("name2")); 106 Assert.False(ds.Tables["parent"].Constraints.Contains("xxx")); 107 } 108 109 [Fact] CopyTo()110 public void CopyTo() 111 { 112 DataTable dt = DataProvider.CreateUniqueConstraint(); 113 dt.Constraints.Add("constraint2", dt.Columns["String1"], true); 114 115 var ar = new object[2]; 116 117 dt.Constraints.CopyTo(ar, 0); 118 Assert.Equal(2, ar.Length); 119 } 120 121 [Fact] Count()122 public void Count() 123 { 124 DataTable dt = DataProvider.CreateUniqueConstraint(); 125 Assert.Equal(1, dt.Constraints.Count); 126 127 //Add 128 129 dt.Constraints.Add("constraint2", dt.Columns["String1"], false); 130 Assert.Equal(2, dt.Constraints.Count); 131 132 //Remove 133 134 dt.Constraints.Remove("constraint2"); 135 Assert.Equal(1, dt.Constraints.Count); 136 } 137 138 [Fact] GetEnumerator()139 public void GetEnumerator() 140 { 141 DataTable dt = DataProvider.CreateUniqueConstraint(); 142 dt.Constraints.Add("constraint2", dt.Columns["String1"], false); 143 144 int counter = 0; 145 IEnumerator myEnumerator = dt.Constraints.GetEnumerator(); 146 while (myEnumerator.MoveNext()) 147 { 148 counter++; 149 } 150 Assert.Equal(2, counter); 151 } 152 153 [Fact] IndexOf()154 public void IndexOf() 155 { 156 DataTable dt = DataProvider.CreateUniqueConstraint(); 157 Assert.Equal(0, dt.Constraints.IndexOf(dt.Constraints[0])); 158 159 //Add new constraint 160 Constraint con = new UniqueConstraint(dt.Columns["String1"], false); 161 162 dt.Constraints.Add(con); 163 Assert.Equal(1, dt.Constraints.IndexOf(con)); 164 165 //Remove it and try to look for it 166 167 dt.Constraints.Remove(con); 168 Assert.Equal(-1, dt.Constraints.IndexOf(con)); 169 } 170 171 [Fact] IndexOf_ByName()172 public void IndexOf_ByName() 173 { 174 DataTable dt = DataProvider.CreateUniqueConstraint(); 175 dt.Constraints[0].ConstraintName = "name1"; 176 Assert.Equal(0, dt.Constraints.IndexOf("name1")); 177 178 //Add new constraint 179 Constraint con = new UniqueConstraint(dt.Columns["String1"], false); 180 con.ConstraintName = "name2"; 181 182 dt.Constraints.Add(con); 183 Assert.Equal(1, dt.Constraints.IndexOf("name2")); 184 185 //Remove it and try to look for it 186 187 dt.Constraints.Remove(con); 188 Assert.Equal(-1, dt.Constraints.IndexOf("name2")); 189 } 190 191 [Fact] IndexOf_SameColumns()192 public void IndexOf_SameColumns() 193 { 194 var ds = new DataSet(); 195 DataTable table1 = ds.Tables.Add("table1"); 196 DataTable table2 = ds.Tables.Add("table2"); 197 DataColumn pcol = table1.Columns.Add("col1"); 198 DataColumn ccol = table2.Columns.Add("col1"); 199 200 ds.Relations.Add("fk_rel", pcol, ccol); 201 202 var fk = new ForeignKeyConstraint("fk", pcol, ccol); 203 Assert.Equal(-1, ds.Tables[1].Constraints.IndexOf(fk)); 204 } 205 206 [Fact] Add_RelationFirst_ConstraintNext()207 public void Add_RelationFirst_ConstraintNext() 208 { 209 var ds = new DataSet(); 210 DataTable table1 = ds.Tables.Add("table1"); 211 DataTable table2 = ds.Tables.Add("table2"); 212 DataColumn pcol = table1.Columns.Add("col1"); 213 DataColumn ccol = table2.Columns.Add("col1"); 214 215 ds.Relations.Add("fk_rel", pcol, ccol); 216 217 Assert.Throws<DataException>(() => table2.Constraints.Add("fk_cons", pcol, ccol)); 218 Assert.Throws<DataException>(() => table1.Constraints.Add("pk_cons", pcol, false)); 219 } 220 221 [Fact] Add_ConstraintFirst_RelationNext()222 public void Add_ConstraintFirst_RelationNext() 223 { 224 DataSet ds = new DataSet(); 225 DataTable table1 = ds.Tables.Add("table1"); 226 DataTable table2 = ds.Tables.Add("table2"); 227 DataColumn pcol = table1.Columns.Add("col1"); 228 DataColumn ccol = table2.Columns.Add("col1"); 229 230 table2.Constraints.Add("fk_cons", pcol, ccol); 231 232 // Should not throw DataException 233 ds.Relations.Add("fk_rel", pcol, ccol); 234 235 Assert.Equal(1, table2.Constraints.Count); 236 Assert.Equal(1, table1.Constraints.Count); 237 Assert.Equal("fk_cons", table2.Constraints[0].ConstraintName); 238 Assert.Equal("Constraint1", table1.Constraints[0].ConstraintName); 239 } 240 241 [Fact] IsReadOnly()242 public void IsReadOnly() 243 { 244 DataTable dt = DataProvider.CreateUniqueConstraint(); 245 Assert.False(dt.Constraints.IsReadOnly); 246 } 247 248 [Fact] IsSynchronized()249 public void IsSynchronized() 250 { 251 DataTable dt = DataProvider.CreateUniqueConstraint(); 252 Assert.False(dt.Constraints.IsSynchronized); 253 } 254 255 [Fact] Remove()256 public void Remove() 257 { 258 DataTable dt = DataProvider.CreateUniqueConstraint(); 259 dt.Constraints.Remove(dt.Constraints[0]); 260 Assert.Equal(0, dt.Constraints.Count); 261 } 262 263 [Fact] Remove_CheckUnique()264 public void Remove_CheckUnique() 265 { 266 DataTable table = new DataTable(); 267 DataColumn col1 = table.Columns.Add("col1"); 268 DataColumn col2 = table.Columns.Add("col2"); 269 270 Assert.False(col1.Unique); 271 272 Constraint uc = table.Constraints.Add("", col1, false); 273 Assert.True(col1.Unique); 274 275 table.Constraints.Remove(uc); 276 Assert.False(col1.Unique); 277 278 table.PrimaryKey = new DataColumn[] { col2 }; 279 AssertExtensions.Throws<ArgumentException>(null, () => table.Constraints.Remove(table.Constraints[0])); 280 } 281 282 [Fact] Remove_ByNameSimple()283 public void Remove_ByNameSimple() 284 { 285 DataTable dt = DataProvider.CreateUniqueConstraint(); 286 dt.Constraints[0].ConstraintName = "constraint1"; 287 dt.Constraints.Remove("constraint1"); 288 Assert.Equal(0, dt.Constraints.Count); 289 } 290 291 [Fact] Remove_ByNameWithAdd()292 public void Remove_ByNameWithAdd() 293 { 294 DataTable dt = DataProvider.CreateUniqueConstraint(); 295 dt.Constraints[0].ConstraintName = "constraint1"; 296 Constraint con = new UniqueConstraint(dt.Columns["String1"], false); 297 dt.Constraints.Add(con); 298 dt.Constraints.Remove(con); 299 300 Assert.Equal(1, dt.Constraints.Count); 301 Assert.Equal("constraint1", dt.Constraints[0].ConstraintName); 302 } 303 304 [Fact] Remove_CollectionChangedEvent()305 public void Remove_CollectionChangedEvent() 306 { 307 DataTable dt = DataProvider.CreateUniqueConstraint(); 308 _collectionChangedFlag = false; 309 dt.Constraints.CollectionChanged += new CollectionChangeEventHandler(Constraints_CollectionChangedHandler); 310 dt.Constraints.Remove(dt.Constraints[0]); 311 Assert.True(_collectionChangedFlag); 312 } 313 314 [Fact] Remove_ByNameCollectionChangedEvent()315 public void Remove_ByNameCollectionChangedEvent() 316 { 317 DataTable dt = DataProvider.CreateUniqueConstraint(); 318 _collectionChangedFlag = false; 319 dt.Constraints.CollectionChanged += new CollectionChangeEventHandler(Constraints_CollectionChangedHandler); 320 dt.Constraints.Remove("constraint1"); 321 Assert.True(_collectionChangedFlag); 322 } 323 324 [Fact] add_CollectionChanged()325 public void add_CollectionChanged() 326 { 327 DataTable dt = DataProvider.CreateParentDataTable(); 328 _collectionChangedFlag = false; 329 dt.Constraints.CollectionChanged += new CollectionChangeEventHandler(Constraints_CollectionChangedHandler); 330 dt = DataProvider.CreateUniqueConstraint(dt); 331 Assert.True(_collectionChangedFlag); 332 } 333 Constraints_CollectionChangedHandler(object sender, CollectionChangeEventArgs e)334 private void Constraints_CollectionChangedHandler(object sender, CollectionChangeEventArgs e) => _collectionChangedFlag = true; 335 336 [Fact] Remove_Constraint()337 public void Remove_Constraint() 338 { 339 DataTable table1 = new DataTable("table1"); 340 DataTable table2 = new DataTable("table2"); 341 342 DataColumn col1 = table1.Columns.Add("col1", typeof(int)); 343 DataColumn col2 = table1.Columns.Add("col2", typeof(int)); 344 DataColumn col3 = table2.Columns.Add("col1", typeof(int)); 345 346 Constraint c1 = table1.Constraints.Add("unique1", col1, false); 347 Constraint c2 = table1.Constraints.Add("unique2", col2, false); 348 Constraint c3 = table2.Constraints.Add("fk", col1, col3); 349 350 table1.Constraints.Remove(c1); 351 table1.Constraints.Remove(c2); 352 table2.Constraints.Remove(c3); 353 354 Assert.Equal(0, table1.Constraints.Count); 355 Assert.Equal(0, table2.Constraints.Count); 356 357 DataSet ds = new DataSet(); 358 ds.Tables.Add(table1); 359 ds.Tables.Add(table2); 360 361 c1 = table1.Constraints.Add("unique1", col1, false); 362 c2 = table1.Constraints.Add("unique2", col2, false); 363 c3 = table2.Constraints.Add("fk", col1, col3); 364 365 AssertExtensions.Throws<ArgumentException>(null, () => table1.Constraints.Remove(c1)); 366 367 Assert.Equal(2, table1.Constraints.Count); 368 369 table1.Constraints.Remove(c2); 370 Assert.Equal(1, table1.Constraints.Count); 371 372 table2.Constraints.Remove(c3); 373 Assert.Equal(1, table1.Constraints.Count); 374 Assert.Equal(0, table2.Constraints.Count); 375 376 table1.Constraints.Remove(c1); 377 Assert.Equal(0, table1.Constraints.Count); 378 } 379 testExceptionMethodCallback()380 public delegate void testExceptionMethodCallback(); 381 382 [Fact] Add_Constraint()383 public void Add_Constraint() 384 { 385 DataTable dt = DataProvider.CreateUniqueConstraint(); 386 Assert.Equal(1, dt.Constraints.Count); 387 Assert.Equal("Constraint1", dt.Constraints[0].ConstraintName); 388 389 DataSet ds = DataProvider.CreateForigenConstraint(); 390 Assert.Equal(1, ds.Tables[1].Constraints.Count); 391 Assert.Equal(1, ds.Tables[0].Constraints.Count); 392 393 var arr = new ArrayList(1); 394 arr.Add(new ConstraintException()); 395 TestException(new testExceptionMethodCallback(DataProvider.TryToBreakUniqueConstraint), arr); 396 397 arr = new ArrayList(1); 398 arr.Add(new InvalidConstraintException()); 399 TestException(new testExceptionMethodCallback(DataProvider.TryToBreakForigenConstraint), arr); 400 } 401 TestException(testExceptionMethodCallback dlg, IList exceptionList)402 public void TestException(testExceptionMethodCallback dlg, IList exceptionList) 403 { 404 Exception ex = Assert.ThrowsAny<Exception>(() => dlg()); 405 foreach (Exception expectedEx in exceptionList) 406 if ((expectedEx.GetType()) == (ex.GetType())) 407 return; 408 Assert.True(false); 409 } 410 411 [Fact] Add_SDB1()412 public void Add_SDB1() 413 { 414 DataTable dt = DataProvider.CreateParentDataTable(); 415 dt.Constraints.Add("UniqueConstraint", dt.Columns["ParentId"], true); 416 Assert.Equal(1, (double)dt.Constraints.Count); ; 417 Assert.Equal("UniqueConstraint", dt.Constraints[0].ConstraintName); 418 } 419 420 [Fact] Add_SDB2()421 public void Add_SDB2() 422 { 423 DataTable dt = DataProvider.CreateParentDataTable(); 424 dt.Constraints.Add("UniqueConstraint", dt.Columns["ParentId"], false); 425 Assert.Equal(1, dt.Constraints.Count); 426 Assert.Equal("UniqueConstraint", dt.Constraints[0].ConstraintName); 427 } 428 429 [Fact] Add_SDB3()430 public void Add_SDB3() 431 { 432 DataTable dt = DataProvider.CreateParentDataTable(); 433 dt.Constraints.Add("UniqueConstraint", dt.Columns["ParentId"], true); 434 //Break the constraint 435 436 ArrayList arr = new ArrayList(1); 437 arr.Add(new ConstraintException()); 438 TestException(new testExceptionMethodCallback(DataProvider.TryToBreakUniqueConstraint), arr); 439 } 440 441 [Fact] Add_SDB4()442 public void Add_SDB4() 443 { 444 Assert.Throws<ConstraintException>(() => 445 { 446 DataTable dt = DataProvider.CreateParentDataTable(); 447 dt.Constraints.Add("UniqueConstraint", dt.Columns["ParentId"], false); 448 DataProvider.TryToBreakUniqueConstraint(); 449 Assert.Equal(2, dt.Select("ParentId=1").Length); 450 }); 451 } 452 453 [Fact] Add_Constraint_Column_Column()454 public void Add_Constraint_Column_Column() 455 { 456 DataTable parent = DataProvider.CreateParentDataTable(); 457 DataTable child = DataProvider.CreateChildDataTable(); 458 459 child.Constraints.Add("ForigenConstraint", parent.Columns[0], child.Columns[0]); 460 461 Assert.Equal(1, parent.Constraints.Count); 462 Assert.Equal(1, child.Constraints.Count); 463 Assert.Equal("ForigenConstraint", child.Constraints[0].ConstraintName); 464 465 parent = DataProvider.CreateParentDataTable(); 466 child = DataProvider.CreateChildDataTable(); 467 468 child.Constraints.Add("ForigenConstraint", parent.Columns[0], child.Columns[0]); 469 470 ArrayList arr = new ArrayList(1); 471 arr.Add(new InvalidConstraintException()); 472 TestException(new testExceptionMethodCallback(DataProvider.TryToBreakForigenConstraint), arr); 473 474 Assert.Equal(1, parent.Constraints.Count); 475 Assert.Equal(1, child.Constraints.Count); 476 } 477 478 [Fact] AddRange_C1()479 public void AddRange_C1() 480 { 481 DataTable dt = new DataTable(); 482 dt.Constraints.AddRange(null); 483 Assert.Equal(0, dt.Constraints.Count); 484 } 485 486 [Fact] AddRange_C2()487 public void AddRange_C2() 488 { 489 var ds = new DataSet(); 490 ds.Tables.Add(DataProvider.CreateParentDataTable()); 491 ds.Tables.Add(DataProvider.CreateChildDataTable()); 492 ds.Tables[1].Constraints.AddRange(GetConstraintArray(ds)); //Cuz foreign key belongs to child table 493 Assert.Equal(2, ds.Tables[1].Constraints.Count); 494 Assert.Equal(1, ds.Tables[0].Constraints.Count); 495 } 496 497 [Fact] AddRange_C3()498 public void AddRange_C3() 499 { 500 AssertExtensions.Throws<ArgumentException>(null, () => 501 { 502 var ds = new DataSet(); 503 ds.Tables.Add(DataProvider.CreateParentDataTable()); 504 ds.Tables.Add(DataProvider.CreateChildDataTable()); 505 Constraint badConstraint = new UniqueConstraint(ds.Tables[0].Columns[0]); 506 507 ds.Tables[1].Constraints.AddRange(new Constraint[] { badConstraint }); //Cuz foreign key belongs to child table 508 }); 509 } 510 GetConstraintArray(DataSet ds)511 private Constraint[] GetConstraintArray(DataSet ds) 512 { 513 DataTable parent = ds.Tables[0]; 514 DataTable child = ds.Tables[1]; 515 Constraint[] constArray = new Constraint[2]; 516 517 //Create unique 518 constArray[0] = new UniqueConstraint("Unique1", child.Columns["ChildDouble"]); 519 //Create foreign 520 constArray[1] = new ForeignKeyConstraint(parent.Columns[0], child.Columns[1]); 521 522 return constArray; 523 } 524 525 [Fact] Item()526 public void Item() 527 { 528 DataTable dt = DataProvider.CreateUniqueConstraint(); 529 dt.Constraints[0].ConstraintName = "constraint1"; 530 Assert.Equal("constraint1", dt.Constraints[0].ConstraintName); 531 Assert.Equal("constraint1", dt.Constraints["constraint1"].ConstraintName); 532 533 ArrayList arr = new ArrayList(1); 534 arr.Add(new IndexOutOfRangeException()); 535 TestException(new testExceptionMethodCallback(Item2), arr); 536 } 537 Item2()538 private void Item2() 539 { 540 DataTable dt = DataProvider.CreateUniqueConstraint(); 541 dt.Constraints[1].ConstraintName = "error"; 542 } 543 544 private bool _collectionChanged = false; 545 546 [Fact] RemoveAt_Integer()547 public void RemoveAt_Integer() 548 { 549 DataTable dt = DataProvider.CreateUniqueConstraint(); 550 dt.Constraints.RemoveAt(0); 551 Assert.Equal(0, dt.Constraints.Count); 552 553 dt = DataProvider.CreateUniqueConstraint(); 554 Constraint con = new UniqueConstraint(dt.Columns["String1"], false); 555 dt.Constraints[0].ConstraintName = "constraint1"; 556 con.ConstraintName = "constraint2"; 557 dt.Constraints.Add(con); 558 dt.Constraints.RemoveAt(0); 559 Assert.Equal(1, dt.Constraints.Count); 560 Assert.Equal("constraint2", dt.Constraints[0].ConstraintName); 561 562 dt = DataProvider.CreateUniqueConstraint(); 563 dt.Constraints.CollectionChanged += new CollectionChangeEventHandler(Constraints_CollectionChanged); 564 dt.Constraints.RemoveAt(0); 565 Assert.Equal(true, _collectionChanged); 566 567 ArrayList arr = new ArrayList(1); 568 arr.Add(new IndexOutOfRangeException()); 569 TestException(new testExceptionMethodCallback(RemoveAt_I), arr); 570 } 571 Constraints_CollectionChanged(object sender, CollectionChangeEventArgs e)572 private void Constraints_CollectionChanged(object sender, CollectionChangeEventArgs e) 573 { 574 _collectionChanged = true; 575 } 576 RemoveAt_I()577 private void RemoveAt_I() 578 { 579 DataTable dt = DataProvider.CreateUniqueConstraint(); 580 dt.Constraints.RemoveAt(2); 581 } 582 583 [Fact] RemoveTest()584 public void RemoveTest() 585 { 586 DataTable table = new DataTable(); 587 table.Columns.Add("col1"); 588 Constraint c = table.Constraints.Add("c", table.Columns[0], false); 589 AssertExtensions.Throws<ArgumentException>(null, () => table.Constraints.Remove("sdfs")); 590 591 table.Constraints.Remove(c); 592 Assert.Equal(0, table.Constraints.Count); 593 594 // No exception shud be raised 595 table.Constraints.Add(c); 596 Assert.Equal(1, table.Constraints.Count); 597 } 598 } 599 } 600