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