BindingFlags.Public needed here as Exception.HResult is now public in .NET 4.5. This...
[mono.git] / mcs / class / System.Data / Test / System.Data / DataTableTest2.cs
1 // Authors:
2 //   Rafael Mizrahi   <rafim@mainsoft.com>
3 //   Erez Lotan       <erezl@mainsoft.com>
4 //   Oren Gurfinkel   <oreng@mainsoft.com>
5 //   Ofer Borstein
6 // 
7 // Copyright (c) 2004 Mainsoft Co.
8 // 
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System;
30 using System.Collections;
31 using System.Data;
32 using System.Globalization;
33
34 using MonoTests.System.Data.Utils;
35
36 using NUnit.Framework;
37
38 namespace MonoTests_System.Data
39 {
40         [TestFixture]
41         public class DataTableTest2
42         {
43                 private bool _EventTriggered;
44                 private bool EventRaised;
45                 private bool EventValues;
46
47                 class ProtectedTestClass : DataTable
48                 {
49                         public ProtectedTestClass ()
50                         {
51                                 this.Columns.Add ("Id", typeof (int));
52                                 this.Columns.Add ("Value", typeof (string));
53                                 this.Rows.Add (new object[] {1, "one"});
54                                 this.Rows.Add (new object[] {2, "two"});
55                                 this.AcceptChanges ();
56                         }
57
58                         public void OnColumnChanged_Test ()
59                         {
60                                 OnColumnChanged (new DataColumnChangeEventArgs (
61                                         this.Rows [0], this.Columns ["Value"],
62                                         "NewValue"));
63                         }
64
65                         public void OnColumnChanging_Test ()
66                         {
67                                 OnColumnChanging (new DataColumnChangeEventArgs (
68                                         this.Rows [0], this.Columns ["Value"],
69                                         "NewValue"));
70                         }
71
72                         public void OnRemoveColumn_Test ()
73                         {
74                                 OnRemoveColumn (this.Columns [0]);
75                         }
76
77                         public DataTable CreateInstance_Test ()
78                         {
79                                 return CreateInstance ();
80                         }
81
82                         public void OnRowChanged_Test (DataRowAction drAction)
83                         {
84                                 base.OnRowChanged (new DataRowChangeEventArgs (this.Rows [0], drAction));
85                         }
86
87                         public void OnRowChanging_Test (DataRowAction drAction)
88                         {
89                                 base.OnRowChanging (new DataRowChangeEventArgs (this.Rows [0], drAction));
90                         }
91
92                         public void OnRowDeleted_Test (DataRowAction drAction)
93                         {
94                                 base.OnRowDeleted (new DataRowChangeEventArgs (this.Rows [0], drAction));
95                         }
96
97                         public void OnRowDeleting_Test (DataRowAction drAction)
98                         {
99                                 base.OnRowDeleting (new DataRowChangeEventArgs (this.Rows [0], drAction));
100                         }
101                 }
102
103                 [Test]
104                 public void AcceptChanges ()
105                 {
106                         String sNewValue = "NewValue";
107                         DataRow drModified,drDeleted,drAdded;
108                         DataTable dt = DataProvider.CreateParentDataTable();
109
110                         drModified = dt.Rows[0];
111                         drModified[1] = sNewValue; //DataRowState = Modified, DataRowVersion = Proposed
112
113                         drDeleted = dt.Rows[1];
114                         drDeleted.Delete(); //DataRowState =  Deleted
115
116                         drAdded = dt.NewRow();
117                         dt.Rows.Add(drAdded); //DataRowState =  Added
118
119                         dt.AcceptChanges();
120
121                         // AcceptChanges - Unchanged1
122                         Assert.AreEqual(DataRowState.Unchanged, drModified.RowState, "DT1");
123
124                         // AcceptChanges - Current
125                         Assert.AreEqual(sNewValue, drModified[1,DataRowVersion.Current], "DT2");
126
127                         // AcceptChanges - Unchanged2
128                         Assert.AreEqual(DataRowState.Unchanged, drAdded.RowState, "DT3");
129
130                         // AcceptChanges - Detached
131                         Assert.AreEqual(DataRowState.Detached, drDeleted.RowState, "DT4");
132                 }
133
134                 [Test]
135                 public void ChildRelations ()
136                 {
137                         DataTable dtChild,dtParent;
138                         DataSet ds = new DataSet();
139                         //Create tables
140                         dtChild = DataProvider.CreateChildDataTable();
141                         dtParent= DataProvider.CreateParentDataTable();
142                         //Add tables to dataset
143                         ds.Tables.Add(dtChild);
144                         ds.Tables.Add(dtParent);
145
146                         DataRelationCollection drlCollection;
147                         DataRelation drl = new DataRelation("Parent-Child",dtParent.Columns["ParentId"],dtChild.Columns["ParentId"]);
148
149                         // Checking ChildRelations - default value
150                         //Check default
151                         drlCollection = dtParent.ChildRelations;
152                         Assert.AreEqual(0, drlCollection.Count, "DT5");
153
154                         ds.Relations.Add(drl);
155                         drlCollection = dtParent.ChildRelations;
156
157                         // Checking ChildRelations Count
158                         Assert.AreEqual(1, drlCollection.Count, "DT6");
159
160                         // Checking ChildRelations Value
161                         Assert.AreEqual(drl, drlCollection [0], "DT7");
162                 }
163
164                 [Test]
165                 public void Clear ()
166                 {
167                         DataTable dt = DataProvider.CreateParentDataTable();
168                         dt.Clear();
169                         Assert.AreEqual(0, dt.Rows.Count, "DT8");
170                 }
171
172                 [Test]
173                 public void Clone ()
174                 {
175                         DataTable dt1,dt2 = DataProvider.CreateParentDataTable();
176                         dt2.Constraints.Add ("Unique", dt2.Columns[0], true);
177                         dt2.Columns[0].DefaultValue = 7;
178
179                         dt1 = dt2.Clone ();
180
181                         for (int i = 0; i < dt2.Constraints.Count; i++) {
182                                 // Clone - Constraints[{0}],i)
183                                 Assert.AreEqual (dt2.Constraints [i].ConstraintName,
184                                         dt1.Constraints[i].ConstraintName, "DT9");
185                         }
186
187                         for (int i = 0; i < dt2.Columns.Count; i++) {
188                                 // Clone - Columns[{0}].ColumnName,i)
189                                 Assert.AreEqual(dt2.Columns[i].ColumnName, dt1.Columns[i].ColumnName, "DT10");
190
191                                 // Clone - Columns[{0}].DataType,i)
192                                 Assert.AreEqual(dt2.Columns[i].DataType, dt1.Columns[i].DataType, "DT11");
193                         }
194                 }
195
196                 [Test]
197                 public void ColumnChanged ()
198                 {
199                         DataTable dt = DataProvider.CreateParentDataTable();
200
201                         dt.ColumnChanged += new DataColumnChangeEventHandler (Column_Changed);
202
203                         _EventTriggered = false;
204                         // ColumnChanged - EventTriggered
205                         dt.Rows[0][1] = "NewValue";
206                         Assert.IsTrue (_EventTriggered, "DT12");
207
208                         _EventTriggered = false;
209                         dt.ColumnChanged -= new DataColumnChangeEventHandler (Column_Changed);
210                         // ColumnChanged - NO EventTriggered
211                         dt.Rows[0][1] = "VeryNewValue";
212                         Assert.IsFalse (_EventTriggered, "DT13");
213                 }
214
215                 private void Column_Changed (object sender, DataColumnChangeEventArgs e)
216                 {
217                         _EventTriggered = true;
218                 }
219
220                 [Test]
221                 public void ColumnChanging ()
222                 {
223                         DataTable dt = DataProvider.CreateParentDataTable();
224
225                         dt.ColumnChanging += new DataColumnChangeEventHandler (Column_Changeding);
226
227                         _EventTriggered = false;
228                         // ColumnChanged - EventTriggered
229                         dt.Rows[0][1] = "NewValue";
230                         Assert.IsTrue (_EventTriggered, "DT14");
231
232                         _EventTriggered = false;
233                         dt.ColumnChanging  -= new DataColumnChangeEventHandler (Column_Changeding);
234                         // ColumnChanged - NO EventTriggered
235                         dt.Rows[0][1] = "VeryNewValue";
236                         Assert.IsFalse (_EventTriggered, "DT15");
237                 }
238
239                 private void Column_Changeding (object sender, DataColumnChangeEventArgs e)
240                 {
241                         _EventTriggered = true;
242                 }
243
244                 [Test]
245                 public void Columns ()
246                 {
247                         DataTable dtParent = DataProvider.CreateParentDataTable();
248                         DataColumnCollection dcl = dtParent.Columns;
249
250                         Assert.IsNotNull (dcl, "#A1");
251                         Assert.AreEqual(6, dcl.Count, "#A2");
252                         dtParent.Columns.Add(new DataColumn("Test"));
253                         Assert.AreEqual(7, dcl.Count, "#A3");
254                         DataColumn tmp = dtParent.Columns["TEST"];
255                         Assert.AreEqual(dtParent.Columns["Test"], tmp, "#A4");
256                         dtParent.Columns.Add(new DataColumn("test"));
257                         Assert.AreEqual(8, dcl.Count, "#A5");
258
259                         try {
260                                 tmp = dtParent.Columns ["TEST"];
261                                 Assert.Fail("#B1");
262                         } catch (ArgumentException ex) {
263                                 // The given name 'TEST' matches at least two
264                                 // names in the collection object with different
265                                 // cases, but does not match either of them with
266                                 // the same case
267                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
268                                 Assert.IsNull (ex.InnerException, "#B3");
269                                 Assert.IsNotNull (ex.Message, "#B4");
270                                 Assert.IsTrue (ex.Message.IndexOf ("'TEST'") != -1, "#B5");
271                                 Assert.IsNull (ex.ParamName, "#B6");
272                         }
273                 }
274
275                 [Test]
276                 public void Compute ()
277                 {
278                         DataTable dt = DataProvider.CreateChildDataTable();
279
280                         //Get expected
281                         DataRow[] drArr = dt.Select("ParentId=1");
282                         Int64 iExSum = 0;
283                         foreach (DataRow dr in drArr)
284                                 iExSum += (int)dr["ChildId"];
285                         object objCompute = null;
286                         // Compute - sum values
287                         objCompute = dt.Compute ("Sum(ChildId)", "ParentId=1");
288                         Assert.AreEqual(Int64.Parse (objCompute.ToString()), Int64.Parse(iExSum.ToString()), "DT23");
289
290                         // Compute - sum type
291                         Assert.AreEqual(typeof (Int64), objCompute.GetType (), "DT24");
292
293                         //get expected
294                         double iExAvg = 0;
295                         drArr = dt.Select("ParentId=5");
296                         foreach (DataRow dr in drArr)
297                                 iExAvg += (double)dr["ChildDouble"];
298                         iExAvg = iExAvg / drArr.Length;
299
300                         // Compute - Avg value
301                         objCompute = dt.Compute("Avg(ChildDouble)", "ParentId=5");
302                         Assert.AreEqual(double.Parse(objCompute.ToString()), double.Parse(iExAvg.ToString()), "DT25");
303
304                         // Compute - Avg type
305                         Assert.AreEqual(typeof(double), objCompute.GetType(), "DT26");
306                 }
307
308                 [Test]
309                 public void Constraints ()
310                 {
311                         DataTable dtParent;
312                         ConstraintCollection consColl;
313                         dtParent= DataProvider.CreateParentDataTable();
314
315                         consColl = dtParent.Constraints;
316                         // Checking Constraints  != null 
317                         Assert.IsNotNull (consColl, "DT27");
318
319                         // Checking Constraints Count
320                         Assert.AreEqual (0, consColl.Count, "DT28");
321
322                         // Checking Constraints Count
323                         //Add primary key
324                         dtParent.PrimaryKey = new DataColumn[] {dtParent.Columns[0]};
325                         Assert.AreEqual (1, consColl.Count, "DT29");
326                 }
327
328                 [Test]
329                 public void Copy ()
330                 {
331                         DataTable dt1,dt2 = DataProvider.CreateParentDataTable();
332                         dt2.Constraints.Add("Unique",dt2.Columns[0],true);
333                         dt2.Columns[0].DefaultValue=7;
334
335                         dt1 = dt2.Copy();
336
337                         for (int i = 0; i < dt2.Constraints.Count; i++) {
338                                 // Copy - Constraints[{0}],i)
339                                 Assert.AreEqual (dt2.Constraints[i].ConstraintName,
340                                         dt1.Constraints[i].ConstraintName, "DT30");
341                         }
342
343                         for (int i = 0; i < dt2.Columns.Count; i++) {
344                                 // Copy - Columns[{0}].ColumnName,i)
345                                 Assert.AreEqual (dt2.Columns [i].ColumnName, dt1.Columns [i].ColumnName, "DT31");
346
347                                 // Copy - Columns[{0}].DataType,i)
348                                 Assert.AreEqual (dt2.Columns [i].DataType, dt1.Columns[i].DataType, "DT32");
349                         }
350
351                         DataRow[] drArr1,drArr2;
352                         drArr1 = dt1.Select (string.Empty);
353                         drArr2 = dt2.Select (string.Empty);
354                         for (int i = 0; i < drArr1.Length; i++) {
355                                 // Copy - Data [ParentId]{0} ,i)
356                                 Assert.AreEqual (drArr2[i]["ParentId"], drArr1[i]["ParentId"], "DT33");
357                                 // Copy - Data [String1]{0} ,i)
358                                 Assert.AreEqual (drArr2[i]["String1"], drArr1[i]["String1"], "DT34");
359                                 // Copy - Data [String2]{0} ,i)
360                                 Assert.AreEqual (drArr2[i]["String2"], drArr1[i]["String2"], "DT35");
361                         }
362                 }
363
364                 [Test]
365                 public void CreateInstance ()
366                 {
367                         // CreateInstance
368                         ProtectedTestClass C = new ProtectedTestClass();
369                         DataTable dt = C.CreateInstance_Test();
370                         Assert.IsNotNull(dt, "DT36");
371                 }
372
373                 [Test]
374                 public void DataSet ()
375                 {
376                         DataTable dtParent;
377                         DataSet ds;
378                         dtParent= DataProvider.CreateParentDataTable();
379
380                         ds = dtParent.DataSet;
381
382                         // Checking DataSet == null
383                         Assert.IsNull(ds, "DT37");
384
385                         // Checking DataSet != null
386                         ds = new DataSet("MyDataSet");
387                         ds.Tables.Add(dtParent);
388                         Assert.IsNotNull(dtParent.DataSet, "DT38");
389
390                         // Checking DataSet Name
391                         Assert.AreEqual("MyDataSet", dtParent.DataSet.DataSetName, "DT39");
392                 }
393
394                 [Test]
395                 public void DefaultView ()
396                 {
397                         DataTable dtParent;
398                         DataView dv;
399                         dtParent= DataProvider.CreateParentDataTable();
400                         dv = dtParent.DefaultView;
401                         Assert.IsNotNull (dv, "DT40");
402                 }
403
404                 [Test]
405                 public void EndLoadData ()
406                 {
407                         DataTable dt = DataProvider.CreateParentDataTable();
408                         dt.Columns[0].AllowDBNull = false;
409
410                         // EndLoadData
411                         dt.BeginLoadData();
412                         dt.LoadDataRow(new object [] { null, "A", "B" }, false);
413
414                         try {
415                                 dt.EndLoadData ();
416                                 Assert.Fail ("#1");
417                         } catch (ConstraintException ex) {
418                                 // Failed to enable constraints. One or more rows
419                                 // contain values violating non-null, unique, or
420                                 // foreign-key constraints
421                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#2");
422                                 Assert.IsNull (ex.InnerException, "#3");
423                                 Assert.IsNotNull (ex.Message, "#4");
424                         }
425                 }
426
427                 [Test] // LoadDataRow (Object [], Boolean)
428                 public void LoadDataRow1_Column_ReadOnly ()
429                 {
430                         DataTable dt = new DataTable ("myTable");
431                         DataColumn dcId = new DataColumn ("Id", typeof (int));
432                         dcId.ReadOnly = true;
433                         dt.Columns.Add (dcId);
434                         DataColumn dcName = new DataColumn ("Name", typeof (string));
435                         dcName.ReadOnly = true;
436                         dt.Columns.Add (dcName);
437                         DataColumn dcPassword = new DataColumn ("Password", typeof (string));
438                         dt.Columns.Add (dcPassword);
439                         dt.PrimaryKey = new DataColumn [] { dcId };
440
441                         dt.Rows.Add (new object [] { 5, "Mono", "guess" });
442                         dt.AcceptChanges ();
443                         dt.LoadDataRow (new object [] { 5, "SysData", "what" }, true);
444
445                         Assert.AreEqual (1, dt.Rows.Count, "#1");
446                         DataRow row = dt.Rows.Find (5);
447                         Assert.IsNotNull (row, "#2");
448                         Assert.AreEqual (5, row [dcId], "#3");
449                         Assert.AreEqual ("SysData", row [dcName], "#4");
450                         Assert.AreEqual ("what", row [dcPassword], "#5");
451                         Assert.AreEqual (DataRowState.Unchanged, row.RowState, "#6");
452                 }
453
454                 [Test]
455                 public void LoadDataRow_DuplicateValues ()
456                 {
457                         DataTable table = new DataTable ();
458                         table.Columns.Add ("col1", typeof (int));
459                         table.Columns.Add ("col2", typeof (int));
460
461                         table.PrimaryKey = new DataColumn[] {table.Columns [0]};
462
463                         table.BeginLoadData ();
464                         table.LoadDataRow (new object[] {1, 1}, false);
465                         table.LoadDataRow (new object[] {1, 10}, false);
466
467                         try {
468                                 table.EndLoadData ();
469                                 Assert.Fail ("#1");
470                         } catch (ConstraintException ex) {
471                                  // Failed to enable constraints. One or more rows
472                                 // contain values violating non-null, unique, or
473                                 // foreign-key constraints
474                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#2");
475                                 Assert.IsNull (ex.InnerException, "#3");
476                                 Assert.IsNotNull (ex.Message, "#4");
477                         }
478                 }
479
480                 [Test]
481                 public void LoadDataRow_WithoutBeginLoadData ()
482                 {
483                         DataTable table = new DataTable ();
484                         table.Columns.Add ("col1", typeof (int));
485                         table.Columns.Add ("col2", typeof (int));
486
487                         table.PrimaryKey = new DataColumn[] {table.Columns [0]};
488                         table.Rows.Add (new object[] {1,1});
489                         table.AcceptChanges ();
490
491                         table.LoadDataRow (new object[] {10,1}, false);
492                         DataRow row = table.Rows.Find (10);
493                         Assert.IsNotNull (row, "#1");
494                         Assert.AreEqual (1, row [1], "#2");
495                         Assert.AreEqual (DataRowState.Added, row.RowState, "#3");
496                         table.AcceptChanges ();
497
498                         table.LoadDataRow (new object[] {10,2}, true);
499                         row = table.Rows.Find (10);
500                         Assert.IsNotNull (row, "#4");
501                         Assert.AreEqual (2, row [1], "#5");
502                         Assert.AreEqual (DataRowState.Unchanged, row.RowState, "#6");
503
504                         table.LoadDataRow (new object[] {1,2}, false);
505                         row = table.Rows.Find (1);
506                         Assert.IsNotNull (row, "#7");
507                         Assert.AreEqual (2, row [1], "#8");
508                         Assert.AreEqual (DataRowState.Modified, table.Rows.Find (1).RowState, "#9");
509
510                         table.LoadDataRow (new object[] {1,3}, true);
511                         row = table.Rows.Find (1);
512                         Assert.IsNotNull (row, "#10");
513                         Assert.AreEqual (3, row [1], "#11");
514                         Assert.AreEqual (DataRowState.Unchanged, table.Rows.Find (1).RowState, "#12");
515                 }
516
517                 [Test]
518                 public void EndLoadData_MergeDuplcateValues ()
519                 {
520                         DataTable table = new DataTable ();
521                         table.Columns.Add ("col1", typeof (int));
522                         table.Columns.Add ("col2", typeof (int));
523
524                         table.PrimaryKey = new DataColumn[] {table.Columns [0]};
525                         table.Rows.Add (new object[] {1, 500});
526                         table.AcceptChanges ();
527
528                         table.BeginLoadData ();
529                         table.LoadDataRow (new object[] {1, 1}, false);
530                         table.LoadDataRow (new object[] {1, 10}, false);
531                         table.LoadDataRow (new object[] {1, 100}, false);
532                         table.EndLoadData ();
533
534                         Assert.AreEqual (1, table.Rows.Count, "#1");
535                         Assert.AreEqual (100, table.Rows [0][1], "#2");
536                 }
537
538                 [Test]
539                 public void GetChanges ()
540                 {
541                         DataTable dt1,dt2 = DataProvider.CreateParentDataTable();
542                         dt2.Constraints.Add("Unique",dt2.Columns[0],true);
543                         dt2.Columns[0].DefaultValue=7;
544
545                         //make some changes
546                         dt2.Rows[0].Delete();
547                         dt2.Rows[1].Delete();
548                         dt2.Rows[2].Delete();
549                         dt2.Rows[3].Delete();
550
551                         dt1 = dt2.GetChanges();
552
553                         for (int i = 0; i < dt2.Constraints.Count; i++) {
554                                 // GetChanges - Constraints[{0}],i)
555                                 Assert.AreEqual (dt2.Constraints[i].ConstraintName,
556                                         dt1.Constraints[i].ConstraintName, "DT43");
557                         }
558
559                         for (int i = 0; i < dt2.Columns.Count; i++) {
560                                 // GetChanges - Columns[{0}].ColumnName,i)
561                                 Assert.AreEqual (dt2.Columns [i].ColumnName, dt1.Columns [i].ColumnName, "DT44");
562
563                                 // GetChanges - Columns[{0}].DataType,i)
564                                 Assert.AreEqual (dt2.Columns [i].DataType, dt1.Columns [i].DataType, "DT45");
565                         }
566
567                         DataRow [] drArr1,drArr2;
568
569                         drArr1 = dt1.Select (string.Empty, string.Empty,DataViewRowState.Deleted);
570                         drArr2 = dt2.Select (string.Empty, string.Empty,DataViewRowState.Deleted);
571
572                         for (int i = 0; i < drArr1.Length; i++) {
573                                 // GetChanges - Data [ParentId]{0} ,i)
574                                 Assert.AreEqual (drArr1 [i] ["ParentId",DataRowVersion.Original ],drArr2[i]["ParentId",DataRowVersion.Original], "DT46");
575                                 // GetChanges - Data [String1]{0} ,i)
576                                 Assert.AreEqual (drArr1 [i] ["String1", DataRowVersion.Original],drArr2[i]["String1",DataRowVersion.Original], "DT47");
577                                 // GetChanges - Data [String2]{0} ,i)
578                                 Assert.AreEqual (drArr1 [i] ["String2", DataRowVersion.Original],drArr2[i]["String2",DataRowVersion.Original], "DT48");
579                         }
580                 }
581
582                 [Test]
583                 public void GetChanges_ByDataRowState ()
584                 {
585                         DataTable dt1,dt2 = DataProvider.CreateParentDataTable();
586                         dt2.Constraints.Add("Unique",dt2.Columns[0],true);
587                         dt2.Columns[0].DefaultValue=7;
588
589                         //make some changes
590                         dt2.Rows[0].Delete(); //DataRowState.Deleted
591                         dt2.Rows[1].Delete(); //DataRowState.Deleted
592                         dt2.Rows[2].BeginEdit();
593                         dt2.Rows[2]["String1"] = "Changed"; //DataRowState.Modified
594                         dt2.Rows[2].EndEdit();
595
596                         dt2.Rows.Add(new object[] {"99", "Temp1", "Temp2"}); //DataRowState.Added
597
598                         // *********** Checking GetChanges - DataRowState.Deleted ************
599                         dt1 = null;
600                         dt1 = dt2.GetChanges(DataRowState.Deleted);
601                         CheckTableSchema (dt1,dt2,DataRowState.Deleted.ToString());
602                         DataRow[] drArr1,drArr2;
603                         drArr1 = dt1.Select (string.Empty, string.Empty, DataViewRowState.Deleted);
604                         drArr2 = dt2.Select (string.Empty, string.Empty, DataViewRowState.Deleted);
605
606                         for (int i = 0; i < drArr1.Length; i++) {
607                                 // GetChanges(Deleted) - Data [ParentId]{0} ,i)
608                                 Assert.AreEqual (drArr1 [i] ["ParentId", DataRowVersion.Original], drArr2 [i] ["ParentId", DataRowVersion.Original], "DT49");
609                                 // GetChanges(Deleted) - Data [String1]{0} ,i)
610                                 Assert.AreEqual (drArr1 [i] ["String1", DataRowVersion.Original], drArr2 [i] ["String1", DataRowVersion.Original], "DT50");
611                                 // GetChanges(Deleted) - Data [String2]{0} ,i)
612                                 Assert.AreEqual (drArr1 [i] ["String2", DataRowVersion.Original],drArr2 [i] ["String2", DataRowVersion.Original], "DT51");
613                         }
614
615                         // *********** Checking GetChanges - DataRowState.Modified ************
616                         dt1 = null;
617                         dt1 = dt2.GetChanges(DataRowState.Modified);
618                         CheckTableSchema (dt1,dt2,DataRowState.Modified.ToString());
619                         drArr1 = dt1.Select (string.Empty, string.Empty);
620                         drArr2 = dt2.Select (string.Empty, string.Empty, DataViewRowState.ModifiedCurrent);
621
622                         for (int i = 0; i < drArr1.Length; i++) {
623                                 // GetChanges(Modified) - Data [ParentId]{0} ,i)
624                                 Assert.AreEqual (drArr2 [i] ["ParentId"], drArr1 [i] ["ParentId"], "DT52");
625                                 // GetChanges(Modified) - Data [String1]{0} ,i)
626                                 Assert.AreEqual (drArr2 [i] ["String1"], drArr1 [i] ["String1"], "DT53");
627                                 // GetChanges(Modified) - Data [String2]{0} ,i)
628                                 Assert.AreEqual (drArr2 [i] ["String2"], drArr1 [i] ["String2"], "DT54");
629                         }
630
631                         // *********** Checking GetChanges - DataRowState.Added ************
632                         dt1 = null;
633                         dt1 = dt2.GetChanges(DataRowState.Added);
634                         CheckTableSchema (dt1,dt2,DataRowState.Added.ToString());
635                         drArr1 = dt1.Select (string.Empty, string.Empty);
636                         drArr2 = dt2.Select (string.Empty, string.Empty, DataViewRowState.Added);
637
638                         for (int i = 0; i < drArr1.Length; i++) {
639                                 // GetChanges(Added) - Data [ParentId]{0} ,i)
640                                 Assert.AreEqual (drArr2 [i] ["ParentId"], drArr1 [i] ["ParentId"], "DT55");
641                                 // GetChanges(Added) - Data [String1]{0} ,i)
642                                 Assert.AreEqual (drArr2 [i] ["String1"], drArr1 [i] ["String1"], "DT56");
643                                 // GetChanges(Added) - Data [String2]{0} ,i)
644                                 Assert.AreEqual (drArr2 [i] ["String2"], drArr1 [i] ["String2" ], "DT57");
645                         }
646
647                         // *********** Checking GetChanges - DataRowState.Unchanged  ************
648                         dt1 = null;
649                         dt1 = dt2.GetChanges(DataRowState.Unchanged);
650                         CheckTableSchema (dt1,dt2,DataRowState.Unchanged .ToString());
651                         drArr1 = dt1.Select (string.Empty, string.Empty);
652                         drArr2 = dt2.Select (string.Empty, string.Empty, DataViewRowState.Unchanged);
653
654                         for (int i = 0; i < drArr1.Length; i++) {
655                                 // GetChanges(Unchanged) - Data [ParentId]{0} ,i)
656                                 Assert.AreEqual (drArr2 [i] ["ParentId"], drArr1 [i] ["ParentId"], "DT58");
657                                 // GetChanges(Unchanged) - Data [String1]{0} ,i)
658                                 Assert.AreEqual (drArr2 [i] ["String1"], drArr1 [i] ["String1"], "DT59");
659                                 // GetChanges(Unchanged) - Data [String2]{0} ,i)
660                                 Assert.AreEqual (drArr2 [i] ["String2"], drArr1 [i] ["String2" ], "DT60");
661                         }
662                 }
663
664                 private void CheckTableSchema (DataTable dt1, DataTable dt2, string Description)
665                 {
666                         for (int i = 0; i < dt2.Constraints.Count; i++) {
667                                 // GetChanges - Constraints[{0}] - {1},i,Description)
668                                 Assert.AreEqual (dt2.Constraints [i].ConstraintName,
669                                         dt1.Constraints [i].ConstraintName, "DT61");
670                         }
671
672                         for (int i = 0; i < dt2.Columns.Count; i++) {
673                                 // GetChanges - Columns[{0}].ColumnName - {1},i,Description)
674                                 Assert.AreEqual (dt2.Columns [i].ColumnName, dt1.Columns [i].ColumnName, "DT62");
675
676                                 // GetChanges - Columns[{0}].DataType {1},i,Description)
677                                 Assert.AreEqual (dt2.Columns [i].DataType, dt1.Columns [i].DataType, "DT63");
678                         }
679                 }
680
681                 [Test]
682                 public void GetErrors()
683                 {
684                         DataTable dt = DataProvider.CreateParentDataTable();
685                         DataRow[] drArr = new DataRow[3];
686                         drArr[0] = dt.Rows[0];
687                         drArr[1] = dt.Rows[2];
688                         drArr[2] = dt.Rows[5];
689
690                         drArr[0].RowError = "Error1";
691                         drArr[1].RowError = "Error2";
692                         drArr[2].RowError = "Error3";
693
694                         // GetErrors
695                         Assert.AreEqual(dt.GetErrors(), drArr, "DT64");
696                 }
697
698                 [Test]
699                 public new void GetHashCode ()
700                 {
701                         DataTable dt = DataProvider.CreateParentDataTable();
702                         int iHashCode;
703                         iHashCode = dt.GetHashCode();
704
705                         for (int i = 0; i < 10; i++) {
706                                 // HashCode - i= + i.ToString()
707                                 Assert.AreEqual(dt.GetHashCode (), iHashCode, "DT65");
708                         }
709                 }
710
711                 [Test]
712                 public new void GetType ()
713                 {
714                         DataTable dt = DataProvider.CreateParentDataTable ();
715                         Type tmpType = typeof (DataTable);
716
717                         // GetType
718                         Assert.AreEqual (tmpType, dt.GetType(), "DT66");
719                 }
720
721                 [Test]
722                 public void HasErrors ()
723                 {
724                         DataTable dtParent;
725                         dtParent= DataProvider.CreateParentDataTable();
726
727                         // Checking HasErrors default 
728                         Assert.AreEqual(false, dtParent.HasErrors, "DT67");
729
730                         // Checking HasErrors Get 
731                         dtParent.Rows[0].RowError = "Error on row 0";
732                         dtParent.Rows[2].RowError = "Error on row 2";
733                         Assert.AreEqual(true, dtParent.HasErrors, "DT68");
734                 }
735
736                 [Test]
737                 public void ImportRow ()
738                 {
739                         DataTable dt1, dt2;
740                         dt1 = DataProvider.CreateParentDataTable ();
741                         dt2 = DataProvider.CreateParentDataTable ();
742                         DataRow dr = dt2.NewRow ();
743                         dr.ItemArray = new object [] { 99, string.Empty, string.Empty };
744                         dt2.Rows.Add (dr);
745
746                         // ImportRow - Values
747                         dt1.ImportRow (dr);
748                         Assert.AreEqual (dr.ItemArray, dt1.Rows [dt1.Rows.Count - 1].ItemArray, "DT69");
749
750                         // ImportRow - DataRowState
751                         Assert.AreEqual (dr.RowState, dt1.Rows [dt1.Rows.Count - 1].RowState, "DT70");
752                 }
753
754                 [Test]
755                 public void LoadDataRow ()
756                 {
757                         DataTable dt;
758                         DataRow dr;
759                         dt = DataProvider.CreateParentDataTable();
760                         dt.PrimaryKey= new DataColumn[] {dt.Columns[0]}; //add ParentId as Primary Key
761                         dt.Columns["String1"].DefaultValue = "Default";
762
763                         dr = dt.Select("ParentId=1")[0];
764
765                         //Update existing row without accept changes
766                         dt.BeginLoadData ();
767                         dt.LoadDataRow (new object [] { 1, null, "Changed" }, false);
768                         dt.EndLoadData ();
769
770                         // LoadDataRow(update1) - check column String1
771                         Assert.AreEqual (dr ["String1"], dt.Columns ["String1"].DefaultValue, "DT71");
772
773                         // LoadDataRow(update1) - check column String2
774                         Assert.AreEqual (dr ["String2"], "Changed", "DT72");
775
776                         // LoadDataRow(update1) - check row state
777                         Assert.AreEqual (DataRowState.Modified, dr.RowState, "DT73");
778
779                         //Update existing row with accept changes
780                         dr = dt.Select ("ParentId=2") [0];
781
782                         dt.BeginLoadData ();
783                         dt.LoadDataRow (new object [] { 2, null, "Changed"}, true);
784                         dt.EndLoadData ();
785
786                         // LoadDataRow(update2) - check row state
787                         Assert.AreEqual (DataRowState.Unchanged, dr.RowState, "DT74");
788
789                         //Add New row without accept changes
790                         dt.BeginLoadData();
791                         dt.LoadDataRow(new object [] { 99, null, "Changed" }, false);
792                         dt.EndLoadData();
793
794                         // LoadDataRow(insert1) - check column String2
795                         dr = dt.Select("ParentId=99")[0];
796                         Assert.AreEqual("Changed", dr ["String2"], "DT75");
797
798                         // LoadDataRow(insert1) - check row state
799                         Assert.AreEqual(DataRowState.Added, dr.RowState, "DT76");
800
801                         //Add New row with accept changes
802                         dt.BeginLoadData ();
803                         dt.LoadDataRow (new object [] { 100, null, "Changed" }, true);
804                         dt.EndLoadData ();
805
806                         // LoadDataRow(insert2) - check row and values
807                         dr = dt.Select ("ParentId=100") [0];
808                         Assert.AreEqual("Changed", dr ["String2"], "DT77");
809
810                         // LoadDataRow(insert2) - check row state
811                         Assert.AreEqual (DataRowState.Unchanged, dr.RowState, "DT78");
812                 }
813
814                 [Test]
815                 public void Locale ()
816                 {
817                         DataTable dtParent;
818                         DataSet ds = new DataSet ("MyDataSet");
819
820                         dtParent= DataProvider.CreateParentDataTable ();
821                         ds.Tables.Add (dtParent);
822                         CultureInfo culInfo = CultureInfo.CurrentCulture;
823
824                         // Checking Locale default from system
825                         Assert.AreEqual (culInfo, dtParent.Locale, "DT79");
826
827                         // Checking Locale default from dataset
828                         culInfo = new CultureInfo ("fr");
829                         ds.Locale = culInfo;
830                         Assert.AreEqual (culInfo, dtParent.Locale, "DT80");
831
832                         // Checking Locale get/set
833                         culInfo = new CultureInfo ("nl-BE");
834                         dtParent.Locale = culInfo;
835                         Assert.AreEqual(culInfo, dtParent.Locale, "DT81");
836                 }
837
838                 [Test]
839                 public void MinimumCapacity ()
840                 {
841                         //                              i get default=50, according to MSDN the value should be 25 
842                         //                              // Checking MinimumCapacity default = 25 
843                         //                              Assert.AreEqual(25, dtParent.MinimumCapacity, "DT82");
844                         //                              EndCase(null);
845                         DataTable dt = new DataTable ();
846
847                         // Checking MinimumCapacity get/set int.MaxValue 
848                         dt.MinimumCapacity = int.MaxValue;
849                         Assert.AreEqual (int.MaxValue, dt.MinimumCapacity, "DT83");
850
851                         // Checking MinimumCapacity get/set 0
852                         dt.MinimumCapacity = 0;
853                         Assert.AreEqual (0, dt.MinimumCapacity, "DT84");
854
855                         //                              // Checking MinimumCapacity get/set int.MinValue 
856                         //                              dtParent.MinimumCapacity = int.MinValue;
857                         //                              Assert.AreEqual(int.MinValue, dtParent.MinimumCapacity, "DT85");
858                         //                              EndCase(null);
859                 }
860
861                 [Test]
862                 public void Namespace ()
863                 {
864                         DataTable dtParent = new DataTable ();
865
866                         // Checking Namespace default
867                         Assert.AreEqual (String.Empty, dtParent.Namespace, "DT86");
868
869                         // Checking Namespace set/get
870                         String s = "MyNamespace";
871                         dtParent.Namespace = s;
872                         Assert.AreEqual (s, dtParent.Namespace, "DT87");
873                 }
874
875                 [Test]
876                 public void NewRow ()
877                 {
878                         DataTable dt;
879                         DataRow dr;
880                         dt = DataProvider.CreateParentDataTable();
881
882                         // NewRow
883                         dr = dt.NewRow();
884                         Assert.IsNotNull (dr, "DT88");
885                 }
886
887                 [Test]
888                 public void OnColumnChanged ()
889                 {
890                         ProtectedTestClass dt = new ProtectedTestClass();
891
892                         EventRaised = false;
893                         dt.OnColumnChanged_Test ();
894                         // OnColumnChanged Event 1
895                         Assert.AreEqual (false, EventRaised, "DT89");
896                         EventRaised = false;
897                         EventValues = false;
898                         dt.ColumnChanged += new DataColumnChangeEventHandler (OnColumnChanged_Handler);
899                         dt.OnColumnChanged_Test();
900                         // OnColumnChanged Event 2
901                         Assert.AreEqual (true, EventRaised, "DT90");
902                         // OnColumnChanged Values
903                         Assert.AreEqual (true, EventValues, "DT91");
904                         dt.ColumnChanged -= new DataColumnChangeEventHandler (OnColumnChanged_Handler);
905                 }
906
907                 private void OnColumnChanged_Handler(Object sender,DataColumnChangeEventArgs e)
908                 {
909                         DataTable dt = (DataTable)sender;
910                         if ((e.Column.Equals(dt.Columns["Value"])) && (e.Row.Equals(dt.Rows[0])) && (e.ProposedValue.Equals("NewValue"))) {
911                                 EventValues = true;
912                         } else {
913                                 EventValues = false;
914                         }
915                         EventRaised = true;
916                 }
917
918                 [Test]
919                 public void OnColumnChanging ()
920                 {
921                         ProtectedTestClass dt = new ProtectedTestClass ();
922
923                         EventRaised = false;
924                         dt.OnColumnChanging_Test ();
925                         // OnColumnChanging Event 1
926                         Assert.AreEqual (false, EventRaised, "DT92");
927                         EventRaised = false;
928                         EventValues = false;
929                         dt.ColumnChanging  += new DataColumnChangeEventHandler(OnColumnChanging_Handler);
930                         dt.OnColumnChanging_Test();
931                         // OnColumnChanging Event 2
932                         Assert.AreEqual (true, EventRaised, "DT93");
933                         // OnColumnChanging Values
934                         Assert.AreEqual (true, EventValues, "DT94");
935                         dt.ColumnChanging -= new DataColumnChangeEventHandler (OnColumnChanging_Handler);
936                 }
937
938                 private void OnColumnChanging_Handler (Object sender, DataColumnChangeEventArgs e)
939                 {
940                         DataTable dt = (DataTable)sender;
941                         if ((e.Column.Equals(dt.Columns["Value"])) && (e.Row.Equals(dt.Rows[0])) && (e.ProposedValue.Equals("NewValue"))) {
942                                 EventValues = true;
943                         } else {
944                                 EventValues = false;
945                         }
946                         EventRaised = true;
947                 }
948
949                 [Test]
950                 public void OnRemoveColumn ()
951                 {
952                         ProtectedTestClass dt = new ProtectedTestClass();
953                         dt.OnRemoveColumn_Test();
954                 }
955
956                 [Test]
957                 public void ParentRelations ()
958                 {
959                         DataTable dtChild,dtParent;
960                         DataSet ds = new DataSet();
961                         //Create tables
962                         dtChild = DataProvider.CreateChildDataTable();
963                         dtParent= DataProvider.CreateParentDataTable();
964                         //Add tables to dataset
965                         ds.Tables.Add(dtChild);
966                         ds.Tables.Add(dtParent);
967
968                         DataRelationCollection drlCollection;
969                         DataRelation drl = new DataRelation("Parent-Child",dtParent.Columns["ParentId"],dtChild.Columns["ParentId"]);
970
971                         // Checking ParentRelations - default value
972                         //Check default
973                         drlCollection = dtChild.ParentRelations;
974                         Assert.AreEqual(0, drlCollection.Count, "DT96");
975
976                         ds.Relations.Add(drl);
977                         drlCollection = dtChild.ParentRelations;
978
979                         // Checking ParentRelations Count
980                         Assert.AreEqual(1, drlCollection.Count, "DT97");
981
982                         // Checking ParentRelations Value
983                         Assert.AreEqual(drl, drlCollection[0], "DT98");
984                 }
985
986                 [Test]
987                 public void Prefix ()
988                 {
989                         DataTable dtParent = new DataTable();
990
991                         // Checking Prefix default
992                         Assert.AreEqual(String.Empty, dtParent.Prefix, "DT99");
993
994                         // Checking Prefix set/get
995                         String s = "MyPrefix";
996                         dtParent.Prefix=s;
997                         Assert.AreEqual(s, dtParent.Prefix, "DT100");
998                 }
999
1000                 [Test]
1001                 public void RejectChanges ()
1002                 {
1003                         String sNewValue = "NewValue";
1004                         DataRow drModified, drDeleted, drAdded;
1005                         DataTable dt = DataProvider.CreateParentDataTable ();
1006
1007                         drModified = dt.Rows [0];
1008                         drModified [1] = sNewValue; //DataRowState = Modified, DataRowVersion = Proposed
1009
1010                         drDeleted = dt.Rows [1];
1011                         drDeleted.Delete (); //DataRowState =  Deleted
1012
1013                         drAdded = dt.NewRow ();
1014                         dt.Rows.Add (drAdded); //DataRowState =  Added
1015
1016                         dt.RejectChanges ();
1017
1018                         // RejectChanges - Unchanged1
1019                         Assert.AreEqual (DataRowState.Unchanged, drModified.RowState, "DT101");
1020
1021                         // RejectChanges - Unchanged2
1022                         Assert.AreEqual (DataRowState.Detached, drAdded.RowState, "DT102");
1023
1024                         // RejectChanges - Detached
1025                         Assert.AreEqual (DataRowState.Unchanged, drDeleted.RowState, "DT103");
1026                 }
1027
1028                 [Test]
1029                 public void Reset ()
1030                 {
1031                         DataTable dt1 = DataProvider.CreateParentDataTable ();
1032                         DataTable dt2 = DataProvider.CreateChildDataTable ();
1033                         dt1.PrimaryKey = new DataColumn [] { dt1.Columns [0] };
1034                         dt2.PrimaryKey = new DataColumn [] {dt2.Columns [0], dt2.Columns [1]};
1035                         DataRelation rel = new DataRelation ("Rel", dt1.Columns ["ParentId"], dt2.Columns ["ParentId"]);
1036                         DataSet ds = new DataSet ();
1037                         ds.Tables.AddRange (new DataTable [] { dt1, dt2 });
1038                         ds.Relations.Add (rel);
1039
1040                         dt2.Reset ();
1041
1042                         // Reset - ParentRelations
1043                         Assert.AreEqual (0, dt2.ParentRelations.Count, "DT104");
1044                         // Reset - Constraints
1045                         Assert.AreEqual (0, dt2.Constraints.Count, "DT105");
1046                         // Reset - Rows
1047                         Assert.AreEqual (0, dt2.Rows.Count, "DT106");
1048                         // Reset - Columns
1049                         Assert.AreEqual (0, dt2.Columns.Count, "DT107");
1050                 }
1051
1052                 [Test]
1053                 public void RowChanged ()
1054                 {
1055                         DataTable dt = DataProvider.CreateParentDataTable();
1056
1057                         dt.RowChanged += new DataRowChangeEventHandler (Row_Changed);
1058
1059                         _EventTriggered = false;
1060                         // RowChanged - 1
1061                         dt.Rows[0][1] = "NewValue";
1062                         Assert.AreEqual (true, _EventTriggered, "DT108");
1063
1064                         _EventTriggered = false;
1065                         // RowChanged - 2
1066                         dt.Rows[0].BeginEdit ();
1067                         dt.Rows[0][1] = "NewValue";
1068                         Assert.AreEqual (false, _EventTriggered, "DT109");
1069
1070                         _EventTriggered = false;
1071                         // RowChanged - 3
1072                         dt.Rows[0].EndEdit ();
1073                         Assert.AreEqual (true, _EventTriggered, "DT110");
1074
1075                         _EventTriggered = false;
1076                         dt.RowChanged -= new DataRowChangeEventHandler (Row_Changed);
1077                         // RowChanged - 4
1078                         dt.Rows[0][1] = "NewValue A";
1079                         Assert.AreEqual (false, _EventTriggered, "DT111");
1080                 }
1081
1082                 private void Row_Changed (object sender, DataRowChangeEventArgs e)
1083                 {
1084                         _EventTriggered = true;
1085                 }
1086
1087                 [Test]
1088                 public void RowChanging ()
1089                 {
1090                         DataTable dt = DataProvider.CreateParentDataTable();
1091
1092                         dt.RowChanging  += new DataRowChangeEventHandler (Row_Changing);
1093
1094                         _EventTriggered = false;
1095                         // RowChanging - 1
1096                         dt.Rows[0][1] = "NewValue";
1097                         Assert.AreEqual (true, _EventTriggered, "DT112");
1098
1099                         _EventTriggered = false;
1100                         // RowChanging - 2
1101                         dt.Rows[0].BeginEdit ();
1102                         dt.Rows[0][1] = "NewValue";
1103                         Assert.AreEqual(false, _EventTriggered, "DT113");
1104
1105                         _EventTriggered = false;
1106                         // RowChanging - 3
1107                         dt.Rows[0].EndEdit ();
1108                         Assert.AreEqual (true, _EventTriggered, "DT114");
1109
1110                         _EventTriggered = false;
1111                         dt.RowChanging  -= new DataRowChangeEventHandler (Row_Changing);
1112                         // RowChanging - 4
1113                         dt.Rows[0][1] = "NewValue A";
1114                         Assert.AreEqual (false, _EventTriggered, "DT115");
1115                 }
1116
1117                 private void Row_Changing (object sender, DataRowChangeEventArgs e)
1118                 {
1119                         _EventTriggered = true;
1120                 }
1121
1122                 [Test]
1123                 public void RowDeleted ()
1124                 {
1125                         DataTable dt = DataProvider.CreateParentDataTable();
1126
1127                         dt.RowDeleted += new DataRowChangeEventHandler (Row_Deleted);
1128
1129                         _EventTriggered = false;
1130                         // RowDeleted - 1
1131                         dt.Rows[0].Delete();
1132                         Assert.IsTrue (_EventTriggered, "DT116");
1133
1134                         _EventTriggered = false;
1135                         dt.RowDeleted -= new DataRowChangeEventHandler (Row_Deleted);
1136                         // RowDeleted - 2
1137                         dt.Rows[1].Delete ();
1138                         Assert.IsFalse (_EventTriggered, "DT117");
1139                 }
1140
1141                 private void Row_Deleted (object sender, DataRowChangeEventArgs e)
1142                 {
1143                         _EventTriggered = true;
1144                 }
1145
1146                 [Test]
1147                 public void RowDeleting ()
1148                 {
1149                         DataTable dt = DataProvider.CreateParentDataTable();
1150
1151                         dt.RowDeleting += new DataRowChangeEventHandler (Row_Deleting);
1152
1153                         _EventTriggered = false;
1154                         // RowDeleting - 1
1155                         dt.Rows [0].Delete ();
1156                         Assert.IsTrue (_EventTriggered, "DT118");
1157
1158                         _EventTriggered = false;
1159                         dt.RowDeleting  -= new DataRowChangeEventHandler (Row_Deleting);
1160                         // RowDeleting - 2
1161                         dt.Rows [1].Delete ();
1162                         Assert.IsFalse (_EventTriggered, "DT119");
1163                 }
1164
1165                 private void Row_Deleting (object sender, DataRowChangeEventArgs e)
1166                 {
1167                         _EventTriggered = true;
1168                 }
1169
1170                 [Test]
1171                 public void Rows ()
1172                 {
1173                         DataTable dtParent;
1174                         dtParent = DataProvider.CreateParentDataTable();
1175
1176                         // Checking Rows
1177                         Assert.IsNotNull (dtParent.Rows, "DT120");
1178
1179                         // Checking rows count
1180                         Assert.IsTrue (dtParent.Rows.Count > 0, "DT121");
1181                 }
1182
1183                 [Test]
1184                 public void Select ()
1185                 {
1186                         DataTable dt = DataProvider.CreateParentDataTable();
1187
1188                         DataRow[] drSelect = dt.Select ();
1189                         DataRow[] drResult = new DataRow [dt.Rows.Count];
1190                         dt.Rows.CopyTo (drResult, 0);
1191
1192                         // Select
1193                         Assert.AreEqual(drResult, drSelect, "DT122");
1194                 }
1195
1196                 [Test]
1197                 public void Select_ByFilter ()
1198                 {
1199                         DataSet ds = new DataSet();
1200                         ds.Tables.Add(DataProvider.CreateParentDataTable ());
1201
1202                         DataTable dt = DataProvider.CreateChildDataTable ();
1203                         ds.Tables.Add (dt);
1204                         DataRow[] drSelect = null;
1205                         ArrayList al = new ArrayList ();
1206
1207                         //add column with special name
1208                         DataColumn dc = new DataColumn("Column#",typeof(int));
1209                         dc.DefaultValue=-1;
1210                         dt.Columns.Add(dc);
1211                         //put some values
1212                         dt.Rows[0][dc] = 100;
1213                         dt.Rows[1][dc] = 200;
1214                         dt.Rows[2][dc] = 300;
1215                         dt.Rows[4][dc] = -400;
1216
1217                         //for trim function
1218                         dt.Rows[0]["String1"] = dt.Rows[0]["String1"] + "   \t\n ";
1219                         dt.Rows[0]["String1"] = "   \t\n " + dt.Rows[0]["String1"];
1220                         dt.Rows[0]["String1"] = dt.Rows[0]["String1"] + "    ";
1221
1222                         ds.Tables[0].Rows[0]["ParentBool"] = DBNull.Value;
1223                         ds.Tables[0].Rows[2]["ParentBool"] = DBNull.Value;
1224                         ds.Tables[0].Rows[3]["ParentBool"] = DBNull.Value;
1225
1226                         //-------------------------------------------------------------
1227                         al.Clear();
1228                         foreach (DataRow dr in dt.Rows) {
1229                                 if ((int)dr["ChildId"] == 1)
1230                                         al.Add(dr);
1231                         }
1232                         // Select_S - ChildId=1
1233                         drSelect = dt.Select ("ChildId=1");
1234                         Assert.AreEqual (al.ToArray(), drSelect, "DT123");
1235
1236                         //-------------------------------------------------------------
1237                         al.Clear();
1238                         foreach (DataRow dr in dt.Rows) {
1239                                 if ((int)dr["ChildId"] == 1)
1240                                         al.Add(dr);
1241                         }
1242                         // Select_S - ChildId='1'
1243                         drSelect = dt.Select ("ChildId='1'");
1244                         Assert.AreEqual (al.ToArray(), drSelect, "DT124");
1245                         //-------------------------------------------------------------
1246                         // Select_S - ChildId= '1'  (whitespace in filter string.
1247                         drSelect = dt.Select("ChildId= '1'");
1248                         Assert.AreEqual (al.ToArray(), drSelect, "DT125");
1249                         //-------------------------------------------------------------
1250                         al.Clear();
1251                         foreach (DataRow dr in dt.Rows)
1252                                 if (dr["String1"].ToString() == "1-String1")
1253                                         al.Add(dr);
1254                         // Select_S - String1='1-String1'
1255                         drSelect = dt.Select ("String1='1-String1'");
1256                         Assert.AreEqual (al.ToArray(), drSelect, "DT126");
1257
1258                         //-------------------------------------------------------------
1259                         al.Clear();
1260                         foreach (DataRow dr in dt.Rows)
1261                                 if ((int)dr["ChildId"] == 1 && dr["String1"].ToString() == "1-String1")
1262                                         al.Add(dr);
1263                         // Select_S - ChildId=1 and String1='1-String1'
1264                         drSelect = dt.Select ("ChildId=1 and String1='1-String1'");
1265                         Assert.AreEqual (al.ToArray(), drSelect, "DT127");
1266
1267                         //-------------------------------------------------------------
1268                         al.Clear();
1269                         foreach (DataRow dr in dt.Rows)
1270                                 if ((int)dr["ChildId"] + (int)dr["ParentId"] >= 4)
1271                                         al.Add(dr);
1272                         // Select_S - ChildId+ParentId >= 4
1273                         drSelect = dt.Select ("ChildId+ParentId >= 4");
1274                         CompareUnSorted(drSelect, al.ToArray());
1275
1276                         //-------------------------------------------------------------
1277                         al.Clear();
1278                         foreach (DataRow dr in dt.Rows) {
1279                                 if ((((int)dr["ChildId"] - (int)dr["ParentId"]) * -1) != 0)
1280                                         al.Add(dr);
1281                         }
1282                         // Select_S - ChildId-ParentId) * -1  <> 0
1283                         drSelect = dt.Select ("(ChildId-ParentId) * -1  <> 0");
1284                         CompareUnSorted(drSelect, al.ToArray());
1285
1286                         //-------------------------------------------------------------
1287                         al.Clear();
1288                         foreach (DataRow dr in dt.Rows)
1289                                 if ((double)dr["ChildDouble"] < ((int)dr["ParentId"]) % 4)
1290                                         al.Add(dr);
1291                         // Select_S - ChildDouble < ParentId % 4
1292                         drSelect = dt.Select ("ChildDouble < ParentId % 4");
1293                         CompareUnSorted(drSelect, al.ToArray());
1294
1295                         //-------------------------------------------------------------
1296                         al.Clear();
1297                         foreach (DataRow dr in dt.Rows)
1298                                 if ((double)dr["ChildDouble"] == 10 || (double)dr["ChildDouble"] == 20 || (double)dr["ChildDouble"] == 25)
1299                                         al.Add (dr);
1300                         // Select_S - ChildDouble in (10,20,25)
1301                         drSelect = dt.Select("ChildDouble in (10,20,25)");
1302                         CompareUnSorted(drSelect, al.ToArray());
1303
1304                         //-------------------------------------------------------------
1305                         al.Clear();
1306                         foreach (DataRow dr in dt.Rows)
1307                                 if (dr["String2"].ToString().IndexOf("1-S") >= 0)
1308                                         al.Add (dr);
1309                         // Select_S - String2 like '%1-S%'
1310                         drSelect = dt.Select ("String2 like '%1-S%'");
1311                         Assert.AreEqual (al.ToArray (), drSelect, "DT128");
1312
1313                         //-------------------------------------------------------------
1314                         //If a column name contains one of the above characters,(ex. #\/=><+-*%&|^'" and so on) the name must be wrapped in brackets. For example to use a column named "Column#" in an expression, you would write "[Column#]":
1315                         al.Clear();
1316                         foreach (DataRow dr in dt.Rows)
1317                                 if ((int)dr["Column#"] <= 0)
1318                                         al.Add (dr);
1319                         // Select_S - [Column#] <= 0 
1320                         drSelect = dt.Select ("[Column#] <= 0 ");
1321                         CompareUnSorted (drSelect, al.ToArray());
1322                         //-------------------------------------------------------------
1323                         al.Clear();
1324                         foreach (DataRow dr in dt.Rows)
1325                                 if ((int)dr["Column#"] <= 0)
1326                                         al.Add (dr);
1327                         // Select_S - [Column#] <= 0
1328                         drSelect = dt.Select ("[Column#] <= 0");
1329                         CompareUnSorted (drSelect, al.ToArray());
1330
1331                         //-------------------------------------------------------------
1332                         al.Clear();
1333                         foreach (DataRow dr in dt.Rows)
1334                                 if (((DateTime)dr["ChildDateTime"]).CompareTo(new DateTime(2000,12,12)) > 0)
1335                                         al.Add(dr);
1336                         // Select_S - ChildDateTime > #12/12/2000# 
1337                         drSelect = dt.Select("ChildDateTime > #12/12/2000# ");
1338                         CompareUnSorted (drSelect, al.ToArray ());
1339
1340                         //-------------------------------------------------------------
1341
1342                         al.Clear();
1343                         foreach (DataRow dr in dt.Rows)
1344                                 if (((DateTime)dr["ChildDateTime"]).CompareTo(new DateTime(1999,1,12,12,06,30)) > 0)
1345                                         al.Add(dr);
1346                         // Select_S - ChildDateTime > #1/12/1999 12:06:30 PM#  
1347                         drSelect = dt.Select ("ChildDateTime > #1/12/1999 12:06:30 PM#  ");
1348                         CompareUnSorted (drSelect, al.ToArray ());
1349
1350                         //-------------------------------------------------------------
1351
1352                         al.Clear();
1353                         foreach (DataRow dr in dt.Rows)
1354                                 if (((DateTime) dr ["ChildDateTime"]).CompareTo (new DateTime (2005, 12, 03, 17, 06, 30)) >= 0  || ((DateTime) dr ["ChildDateTime"]).CompareTo (new DateTime (1980, 11, 03)) <= 0)
1355                                         al.Add (dr);
1356                         // Select_S - ChildDateTime >= #12/3/2005 5:06:30 PM# or ChildDateTime <= #11/3/1980#  
1357                         drSelect = dt.Select ("ChildDateTime >= #12/3/2005 5:06:30 PM# or ChildDateTime <= #11/3/1980#  ");
1358                         CompareUnSorted (drSelect, al.ToArray());
1359
1360 #if LATER
1361                         //-------------------------------------------------------------
1362                         al.Clear();
1363                         foreach (DataRow dr in dt.Rows)
1364                                 if (dr["ChildDouble"].ToString().Length > 10)
1365                                         al.Add(dr);
1366                                 // Select_S - Len(Convert(ChildDouble,'System.String')) > 10
1367                                 drSelect = dt.Select ("Len(Convert(ChildDouble,'System.String')) > 10");
1368                                 Assert.AreEqual (al.ToArray(), drSelect, "DT129");
1369 #endif
1370                         //-------------------------------------------------------------
1371                         al.Clear();
1372                         foreach (DataRow dr in dt.Rows)
1373                                 if (dr["String1"].ToString().Trim().Substring(0,2) == "1-")
1374                                         al.Add(dr);
1375                         // Select_S - SubString(Trim(String1),1,2) = '1-'
1376                         drSelect = dt.Select ("SubString(Trim(String1),1,2) = '1-'");
1377                         Assert.AreEqual (al.ToArray(), drSelect, "DT130");
1378                         //-------------------------------------------------------------
1379                         /*
1380                         al.Clear();
1381                         foreach (DataRow dr in ds.Tables[0].Rows)
1382                                 if (dr.IsNull("ParentBool") || (bool)dr["ParentBool"])
1383                                         al.Add(dr);
1384                                 // Select_S - IsNull(ParentBool,true)
1385                                 drSelect = ds.Tables[0].Select("IsNull(ParentBool,true) ");
1386                                 Assert.AreEqual (al.ToArray(), drSelect, "DT131");
1387                         */
1388                         //-------------------------------------------------------------
1389                         al.Clear();
1390                         // Select_S - Relation not exists, Exception
1391                         try {
1392                                 drSelect = dt.Select ("Parent.ParentId = ChildId");
1393                                 Assert.Fail ("#A1");
1394                         } catch (IndexOutOfRangeException ex) {
1395                                 // Cannot find relation 0
1396                                 Assert.AreEqual (typeof (IndexOutOfRangeException), ex.GetType (), "#A2");
1397                                 Assert.IsNull (ex.InnerException, "#A3");
1398                                 Assert.IsNotNull (ex.Message, "#A4");
1399                         }
1400                         //-------------------------------------------------------------
1401                         al.Clear();
1402                         ds.Relations.Add(new DataRelation("ParentChild",ds.Tables[0].Columns[0],ds.Tables[1].Columns[0]));
1403                         foreach (DataRow dr in dt.Rows)
1404                                 if ((int)dr["ChildId"] == (int)dr.GetParentRow("ParentChild")["ParentId"])
1405                                         al.Add(dr);
1406                         // Select_S - Parent.ParentId = ChildId
1407                         drSelect = dt.Select ("Parent.ParentId = ChildId");
1408                         Assert.AreEqual (al.ToArray(), drSelect, "DT134");
1409                 }
1410
1411                 private void CompareUnSorted(Array a, Array b)
1412                 {
1413                         string msg = string.Format("Failed while comparing(Array a ={0} ({1}), Array b = {2} ({3}))]", a.ToString(), a.GetType().FullName, b.ToString(), b.GetType().FullName);
1414                         foreach (object item in a) {
1415                                 if (Array.IndexOf(b, item) < 0) //b does not contain the current item.
1416                                         Assert.Fail(msg);
1417                         }
1418
1419                         foreach (object item in b) {
1420                                 if (Array.IndexOf(a, item) < 0) //a does not contain the current item.
1421                                         Assert.Fail(msg);
1422                         }
1423                 }
1424
1425                 [Test]
1426                 public void Select_ByFilterDataViewRowState ()
1427                 {
1428                         DataTable dt = DataProvider.CreateParentDataTable();
1429                         DataRow[] drSelect, drResult;
1430
1431                         dt.Rows[0].Delete();
1432                         dt.Rows[1]["ParentId"] = 1;
1433                         dt.Rows[2]["ParentId"] = 1;
1434                         dt.Rows[3].Delete();
1435                         dt.Rows.Add(new object[] {1, "A", "B"});
1436                         dt.Rows.Add(new object[] {1, "C", "D"});
1437                         dt.Rows.Add(new object[] {1, "E", "F"});
1438
1439                         drSelect = dt.Select ("ParentId=1", string.Empty, DataViewRowState.Added);
1440                         drResult = GetResultRows(dt,DataRowState.Added);
1441                         // Select_SSD DataViewRowState.Added
1442                         Assert.AreEqual (drResult, drSelect, "DT135");
1443
1444                         drSelect = dt.Select ("ParentId=1", string.Empty, DataViewRowState.CurrentRows);
1445                         drResult = GetResultRows (dt, DataRowState.Unchanged | DataRowState.Added  | DataRowState.Modified);
1446                         // Select_SSD DataViewRowState.CurrentRows
1447                         Assert.AreEqual (drResult, drSelect, "DT136");
1448
1449                         drSelect = dt.Select ("ParentId=1", string.Empty, DataViewRowState.Deleted);
1450                         drResult = GetResultRows (dt, DataRowState.Deleted);
1451                         // Select_SSD DataViewRowState.Deleted
1452                         Assert.AreEqual (drResult, drSelect, "DT137");
1453
1454                         drSelect = dt.Select ("ParentId=1", string.Empty, DataViewRowState.ModifiedCurrent | DataViewRowState.ModifiedOriginal);
1455                         drResult = GetResultRows (dt,DataRowState.Modified);
1456                         // Select_SSD ModifiedCurrent or ModifiedOriginal
1457                         Assert.AreEqual (drResult, drSelect, "DT138");
1458                 }
1459
1460                 private DataRow [] GetResultRows (DataTable dt, DataRowState State)
1461                 {
1462                         ArrayList al = new ArrayList ();
1463                         DataRowVersion drVer = DataRowVersion.Current;
1464
1465                         //From MSDN -   The row the default version for the current DataRowState.
1466                         //                              For a DataRowState value of Added, Modified or Current, 
1467                         //                              the default version is Current. 
1468                         //                              For a DataRowState of Deleted, the version is Original.
1469                         //                              For a DataRowState value of Detached, the version is Proposed.
1470
1471                         if (    ((State & DataRowState.Added)           > 0)
1472                                 | ((State & DataRowState.Modified)      > 0)
1473                                 | ((State & DataRowState.Unchanged)     > 0))
1474                                 drVer = DataRowVersion.Current;
1475                         if ( (State & DataRowState.Deleted)             > 0
1476                                 | (State & DataRowState.Detached)       > 0)
1477                                 drVer = DataRowVersion.Original;
1478
1479                         foreach (DataRow dr in dt.Rows) {
1480                                 if (dr.HasVersion(drVer) && ((int)dr["ParentId", drVer] == 1) && ((dr.RowState & State) > 0))
1481                                         al.Add(dr);
1482                         }
1483                         DataRow[] result = (DataRow[])al.ToArray((typeof(DataRow)));
1484                         return result;
1485                 }
1486
1487                 [Test]
1488                 public void TableName ()
1489                 {
1490                         DataTable dtParent = new DataTable();
1491
1492                         // Checking TableName default
1493                         Assert.AreEqual(String.Empty, dtParent.TableName, "DT139");
1494
1495                         // Checking TableName set/get
1496                         String s = "MyTable";
1497                         dtParent.TableName=s;
1498                         Assert.AreEqual(s, dtParent.TableName, "DT140");
1499                 }
1500
1501                 [Test]
1502                 public new void ToString ()
1503                 {
1504                         DataTable dt = DataProvider.CreateParentDataTable();
1505                         dt.DisplayExpression = dt.Columns[0].ColumnName;
1506
1507                         string sToString = dt.TableName + " + " + dt.DisplayExpression;
1508                         Assert.AreEqual (sToString, dt.ToString (), "DT141");
1509                 }
1510
1511                 [Test]
1512                 public void CaseSensitive ()
1513                 {
1514                         DataTable dtParent = new DataTable();
1515
1516                         // Checking default
1517                         Assert.IsFalse (dtParent.CaseSensitive, "DT142");
1518
1519                         // Checking set/get
1520                         dtParent.CaseSensitive = true;
1521                         Assert.IsTrue (dtParent.CaseSensitive, "DT143");
1522                 }
1523
1524                 [Test]
1525                 public void ctor ()
1526                 {
1527                         DataTable dt = new DataTable ();
1528                         Assert.IsNotNull(dt, "DT144");
1529                 }
1530
1531                 [Test]
1532                 public void ctor_ByName ()
1533                 {
1534                         string sName = "MyName";
1535
1536                         DataTable dt = new DataTable (sName);
1537
1538                         Assert.IsNotNull (dt, "DT145");
1539                         Assert.AreEqual(sName, dt.TableName, "DT146");
1540                 }
1541
1542                 [Test]
1543                 public void DisplayExpression ()
1544                 {
1545                         DataTable dtParent;
1546                         dtParent= DataProvider.CreateParentDataTable ();
1547
1548                         // Checking DisplayExpression default 
1549                         Assert.AreEqual (String.Empty, dtParent.DisplayExpression, "DT147");
1550
1551                         // Checking DisplayExpression Set/Get 
1552                         dtParent.DisplayExpression = dtParent.Columns[0].ColumnName;
1553                         Assert.AreEqual (dtParent.Columns[0].ColumnName, dtParent.DisplayExpression, "DT148");
1554                 }
1555
1556                 [Test]
1557                 public void ExtendedProperties ()
1558                 {
1559                         DataTable dtParent;
1560                         PropertyCollection pc;
1561                         dtParent= DataProvider.CreateParentDataTable ();
1562
1563                         pc = dtParent.ExtendedProperties;
1564
1565                         // Checking ExtendedProperties default
1566                         Assert.IsNotNull (pc, "DT149");
1567
1568                         // Checking ExtendedProperties count
1569                         Assert.AreEqual (0, pc.Count, "DT150");
1570                 }
1571
1572                 [Test]
1573                 [Category ("NotWorking")]
1574                 public void PrimaryKey()
1575                 {
1576                         DataTable dtParent;
1577                         dtParent = DataProvider.CreateParentDataTable();
1578
1579                         // Checking PrimaryKey default
1580                         Assert.AreEqual (0, dtParent.PrimaryKey.Length, "DT151");
1581
1582                         // Checking PrimaryKey set/get
1583                         DataColumn[] dcArr = new DataColumn[] {dtParent.Columns[0]};
1584                         dtParent.PrimaryKey = new DataColumn[] {dtParent.Columns[0]};
1585                         Assert.AreEqual (dcArr, dtParent.PrimaryKey, "DT152");
1586
1587                         dtParent.PrimaryKey=null;
1588                         DataSet ds = new DataSet();
1589                         DataRow dr = null;
1590                         ds.Tables.Add(dtParent);
1591
1592                         //check primary key - ColumnType String, ds.CaseSensitive = false;
1593                         ds.CaseSensitive = false;
1594                         dtParent.PrimaryKey = new DataColumn[] {dtParent.Columns["String1"]};
1595                         // check primary key - ColumnType String, ds.CaseSensitive = false;
1596                         dr = dtParent.NewRow();
1597                         dr.ItemArray = dtParent.Rows[0].ItemArray;
1598                         dr["String1"] = dr["String1"].ToString().ToUpper();
1599                         try {
1600                                 dtParent.Rows.Add(dr);
1601                                 Assert.Fail("#A1");
1602                         } catch (ConstraintException ex) {
1603                                 // Column 'String1' is constrained to be unique.
1604                                 // Value '1-STRING1' is already present
1605                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#A2");
1606                                 Assert.IsNull (ex.InnerException, "#A3");
1607                                 Assert.IsNotNull (ex.Message, "#A4");
1608                                 Assert.IsTrue (ex.Message.IndexOf ("'String1'") != -1, "#A5");
1609                                 Assert.IsTrue (ex.Message.IndexOf ("'1-STRING1'") != -1, "#A6");
1610                         }
1611                         if (dr.RowState != DataRowState.Detached)
1612                                 dtParent.Rows.Remove(dr);
1613
1614                         //check primary key - ColumnType String, ds.CaseSensitive = true;
1615                         ds.CaseSensitive = true;
1616                         // check primary key ConstraintException - ColumnType String, ds.CaseSensitive = true;
1617                         dr = dtParent.NewRow();
1618                         dr.ItemArray = dtParent.Rows[0].ItemArray;
1619                         dr["String1"] = dr["String1"].ToString();
1620                         try {
1621                                 dtParent.Rows.Add(dr);
1622                                 Assert.Fail("#B1");
1623                         } catch (ConstraintException ex) {
1624                                 // Column 'String1' is constrained to be unique.
1625                                 // Value '1-String1' is already present
1626                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#B2");
1627                                 Assert.IsNull (ex.InnerException, "#B3");
1628                                 Assert.IsNotNull (ex.Message, "#B4");
1629                                 Assert.IsTrue (ex.Message.IndexOf ("'String1'") != -1, "#B5");
1630                                 Assert.IsTrue (ex.Message.IndexOf ("'1-String1'") != -1, "#B6");
1631                         }
1632                         if (dr.RowState != DataRowState.Detached)
1633                                 dtParent.Rows.Remove(dr);
1634
1635                         //check primary key - ColumnType String, ds.CaseSensitive = true;
1636                         ds.CaseSensitive = true;
1637
1638                         // check primary key - ColumnType String, ds.CaseSensitive = true;
1639                         dr = dtParent.NewRow();
1640                         dr.ItemArray = dtParent.Rows[0].ItemArray;
1641                         dr["String1"] = dr["String1"].ToString().ToUpper();
1642                         dtParent.Rows.Add(dr);
1643                         Assert.AreEqual(true, dtParent.Rows.Contains(dr["String1"]), "DT157");
1644
1645                         if (dr.RowState != DataRowState.Detached)
1646                                 dtParent.Rows.Remove(dr);
1647
1648                         dtParent.PrimaryKey=null;
1649                         dtParent.PrimaryKey = new DataColumn[] {dtParent.Columns["ParentDateTime"]};
1650                         // check primary key - ColumnType DateTime
1651                         dr = dtParent.NewRow();
1652                         dr.ItemArray = dtParent.Rows[0].ItemArray;
1653                         dr["ParentDateTime"] = DateTime.Now;
1654                         dtParent.Rows.Add(dr);
1655                         Assert.AreEqual(true, dtParent.Rows.Contains(dr["ParentDateTime"]), "DT158");
1656                         if (dr.RowState != DataRowState.Detached) dtParent.Rows.Remove(dr);
1657
1658                         // check primary key ConstraintException- ColumnType DateTime
1659                         dr = dtParent.NewRow();
1660                         dr.ItemArray = dtParent.Rows[0].ItemArray;
1661                         dr["ParentDateTime"] = dtParent.Rows[0]["ParentDateTime"];
1662                         try {
1663                                 dtParent.Rows.Add(dr);
1664                                 Assert.Fail("#C1");
1665                         } catch (ConstraintException ex) {
1666                                 // Column 'ParentDateTime' is constrained to be
1667                                 // unique.  Value '1/1/2005 12:00:00 AM' is
1668                                 // already present
1669                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#C2");
1670                                 Assert.IsNull (ex.InnerException, "#C3");
1671                                 Assert.IsNotNull (ex.Message, "#C4");
1672                                 Assert.IsTrue (ex.Message.IndexOf ("'ParentDateTime'") != -1, "#C5");
1673                                 Assert.IsTrue (ex.Message.IndexOf ("'1/1/2005 12:00:00 AM'") != -1, "#C6");
1674                         }
1675                         if (dr.RowState != DataRowState.Detached)
1676                                 dtParent.Rows.Remove(dr);
1677
1678                         dtParent.PrimaryKey=null;
1679                         dtParent.PrimaryKey = new DataColumn[] {dtParent.Columns["ParentDouble"]};
1680                         // check primary key - ColumnType ParentDouble, value=Epsilon
1681                         dr = dtParent.NewRow();
1682                         dr.ItemArray = dtParent.Rows[0].ItemArray;
1683                         dr["ParentDouble"] = Double.Epsilon;
1684                         dtParent.Rows.Add(dr);
1685                         Assert.AreEqual(true, dtParent.Rows.Contains(dr["ParentDouble"]), "DT161");
1686                         if (dr.RowState != DataRowState.Detached) dtParent.Rows.Remove(dr);
1687
1688                         // check primary key ConstraintException - ColumnType ParentDouble
1689                         dr = dtParent.NewRow();
1690                         dr.ItemArray = dtParent.Rows[0].ItemArray;
1691                         dr["ParentDouble"] = dtParent.Rows[0]["ParentDouble"];
1692                         try {
1693                                 dtParent.Rows.Add(dr);
1694                                 Assert.Fail("#D1");
1695                         } catch (ConstraintException ex) {
1696                                 // Column 'ParentDouble' is constrained to be
1697                                 // unique.  Value '1.534' is already present
1698                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#D2");
1699                                 Assert.IsNull (ex.InnerException, "#D3");
1700                                 Assert.IsNotNull (ex.Message, "#D4");
1701                                 Assert.IsTrue (ex.Message.IndexOf ("'ParentDouble'") != -1, "#D5");
1702                                 Assert.IsTrue (ex.Message.IndexOf ("'1.534'") != -1, "#D6");
1703                         }
1704                         if (dr.RowState != DataRowState.Detached)
1705                                 dtParent.Rows.Remove(dr);
1706
1707                         //
1708                         // SubTest
1709                         //
1710                         dtParent.PrimaryKey = null;
1711                         // check primary key ConstraintException - ColumnType ParentBool 
1712                         try {
1713                                 dtParent.PrimaryKey = new DataColumn[] {dtParent.Columns["ParentBool"]};
1714                                 Assert.Fail("#E1");
1715                         } catch (ArgumentException ex) {
1716                                 // These columns don't currently have unique values
1717                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#E2");
1718                                 Assert.IsNull (ex.InnerException, "#E3");
1719                                 Assert.IsNotNull (ex.Message, "#A4");
1720                                 Assert.IsNull (ex.ParamName, "#A5");
1721                         }
1722                         if (dr.RowState != DataRowState.Detached)
1723                                 dtParent.Rows.Remove(dr);
1724
1725                         //
1726                         // SubTest
1727                         //
1728                         dtParent.PrimaryKey=null;
1729                         dtParent.PrimaryKey = new DataColumn[] {dtParent.Columns["ParentDouble"],dtParent.Columns["ParentDateTime"]};
1730                         // check primary key - ColumnType Double,DateTime test1
1731                         dr = dtParent.NewRow();
1732                         dr.ItemArray = dtParent.Rows[0].ItemArray;
1733                         dr["ParentDouble"] = dtParent.Rows[0]["ParentDouble"];
1734                         dr["ParentDateTime"] = DateTime.Now;
1735                         dtParent.Rows.Add(dr);
1736                         Assert.AreEqual(true, dtParent.Rows.Contains(new object[] {dr["ParentDouble"],dr["ParentDateTime"]}), "DT166");
1737                         if (dr.RowState != DataRowState.Detached)
1738                                 dtParent.Rows.Remove(dr);
1739
1740                         // check primary key - ColumnType Double,DateTime test2
1741                         dr = dtParent.NewRow();
1742                         dr.ItemArray = dtParent.Rows[0].ItemArray;
1743                         dr["ParentDateTime"] = dtParent.Rows[0]["ParentDateTime"];
1744                         dr["ParentDouble"] = 99.399;
1745                         dtParent.Rows.Add(dr);
1746                         Assert.AreEqual(true, dtParent.Rows.Contains(new object[] {dr["ParentDouble"],dr["ParentDateTime"]}), "DT167");
1747                         if (dr.RowState != DataRowState.Detached) dtParent.Rows.Remove(dr);
1748
1749                         // check primary key ConstraintException - ColumnType Double,DateTime 
1750                         dr = dtParent.NewRow();
1751                         dr.ItemArray = dtParent.Rows[0].ItemArray;
1752                         dr["ParentDouble"] = dtParent.Rows[0]["ParentDouble"];
1753                         dr["ParentDateTime"] = dtParent.Rows[0]["ParentDateTime"];
1754                         try {
1755                                 dtParent.Rows.Add (dr);
1756                                 Assert.Fail("#F1");
1757                         } catch (ConstraintException ex) {
1758                                 // Column 'ParentDouble, ParentDateTime' is
1759                                 // constrained to be unique.  Value '1.534,
1760                                 // 1/1/2005 12:00:00 AM' is already present
1761                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#F2");
1762                                 Assert.IsNull (ex.InnerException, "#F3");
1763                                 Assert.IsNotNull (ex.Message, "#F4");
1764                                 Assert.IsTrue (ex.Message.IndexOf ("'ParentDouble, ParentDateTime'") != -1, "#F5");
1765                                 Assert.IsTrue (ex.Message.IndexOf ("'1.534, 1/1/2005 12:00:00 AM'") != -1, "#F6");
1766                         }
1767                         if (dr.RowState != DataRowState.Detached)
1768                                 dtParent.Rows.Remove(dr);
1769
1770                         DataTable dtChild = DataProvider.CreateChildDataTable();
1771                         ds.Tables.Add(dtChild);
1772                         dtParent.PrimaryKey = null;
1773                         //this test was addedd to check java exception: 
1774                         //System.ArgumentException: Cannot remove UniqueConstraint because the ForeignKeyConstraint myRelation exists.
1775                         // check add primary key with relation 
1776                         ds.Relations.Add(new DataRelation("myRelation",ds.Tables[0].Columns[0],ds.Tables[1].Columns[0]));
1777                         //the following line will cause java to fail
1778                         ds.Tables[0].PrimaryKey = new DataColumn[] {ds.Tables[0].Columns[0],ds.Tables[0].Columns[1]};
1779                         Assert.AreEqual (2, ds.Tables[0].PrimaryKey.Length, "DT170");
1780                 }
1781         
1782                 [Test] // bug #319089
1783                 public void Compute_WithoutSchemaData_Test ()
1784                 {
1785                         DataSet ds = new DataSet ("TestData");
1786                         DataTable table = ds.Tables.Add ("TestTable");
1787
1788                         table.Columns.Add ("Id");
1789                         table.Columns.Add ("Value");
1790
1791                         table.Rows.Add (new object[] {"1", "4.5"});
1792                         table.Rows.Add (new object[] {"2", "7.5"});
1793                         table.Rows.Add (new object[] {"3", "2.5"});
1794                         table.Rows.Add (new object[] {"4", "3.5"});
1795                         
1796                         Assert.AreEqual ("1",
1797                                 table.Compute ("Min(Id)", String.Empty), "#1");
1798                         Assert.AreEqual ("4",
1799                                 table.Compute ("Max(Id)", String.Empty), "#2");
1800                         Assert.AreEqual ("2.5",
1801                                 table.Compute ("Min(Value)", String.Empty), "#3");
1802                         Assert.AreEqual ("7.5",
1803                                 table.Compute ("Max(Value)", String.Empty), "#4");
1804                 }
1805
1806                 [Test]
1807                 public void BeginLoadData ()
1808                 {
1809                         DataTable dt = DataProvider.CreateParentDataTable ();
1810                         dt.Columns [0].AllowDBNull = false;
1811
1812                         try {
1813                                 //if BeginLoadData has not been called, an exception will be throw
1814                                 dt.LoadDataRow (new object [] {null, "A", "B"}, false);
1815                                 Assert.Fail ("#A1");
1816                         } catch (NoNullAllowedException ex) {
1817                                 // Column 'ParentId' does not allow nulls
1818                                 Assert.AreEqual (typeof (NoNullAllowedException), ex.GetType (), "#A2");
1819                                 Assert.IsNull (ex.InnerException, "#A3");
1820                                 Assert.IsNotNull (ex.Message, "#A4");
1821                                 Assert.IsTrue (ex.Message.IndexOf ("'ParentId'") != -1, "#A5");
1822                         }
1823
1824                         DataTable dt1 = DataProvider.CreateUniqueConstraint();
1825
1826                         dt1.BeginLoadData ();
1827
1828                         DataRow dr = dt1.NewRow ();
1829                         dr [0] = 3;
1830                         dt1.Rows.Add (dr);
1831
1832                         try {
1833                                 dt1.EndLoadData ();
1834                                 Assert.Fail ("#B1");
1835                         } catch (ConstraintException ex) {
1836                                 // Failed to enable constraints. One or more rows
1837                                 // contain values violating non-null, unique, or
1838                                 // foreign-key constraints
1839                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#B2");
1840                                 Assert.IsNull (ex.InnerException, "#B3");
1841                                 Assert.IsNotNull (ex.Message, "#B4");
1842
1843                                 Assert.AreEqual (2, dt1.GetErrors().Length, "#B5");
1844                                 Assert.IsTrue (dt1.GetErrors () [0].RowError.Length > 10, "#B6");
1845                                 Assert.IsTrue (dt1.GetErrors () [1].RowError.Length > 10, "#B7");
1846                         }
1847
1848                         DataSet ds = DataProvider.CreateForigenConstraint ();
1849                         ds.Tables [0].BeginLoadData ();
1850                         ds.Tables [0].Rows [0] [0] = 10; //Forigen constraint violation
1851
1852                         try {
1853                                 ds.Tables [0].EndLoadData ();
1854                                 Assert.Fail ("#C1");
1855                         } catch (ConstraintException ex) {
1856                                 // Failed to enable constraints. One or more
1857                                 // rows contain values violating non-null,
1858                                 // unique, or foreign-key constraints
1859                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#C2");
1860                                 Assert.IsNull (ex.InnerException, "#C3");
1861                                 Assert.IsNotNull (ex.Message, "#C4");
1862
1863                                 Assert.AreEqual(3,ds.Tables[1].GetErrors().Length, "#C5");
1864                                 for (int index =0; index < 3; index++)
1865                                         Assert.IsTrue (ds.Tables [1].GetErrors () [index].RowError.Length > 10, "#C6");
1866                         }
1867                 }
1868
1869                 private DataRowAction drExpectedAction;
1870                 
1871                 [Test]
1872                 public void OnRowChanged ()
1873                 {
1874                         ProtectedTestClass dt = new ProtectedTestClass ();
1875
1876                         EventRaised = false;
1877                         dt.OnRowChanged_Test (DataRowAction.Nothing);
1878                         
1879                         Assert.IsFalse (EventRaised, "DT181");
1880
1881                         dt.RowChanged += new DataRowChangeEventHandler(OnRowChanged_Handler);
1882                         foreach (int i in Enum.GetValues (typeof (DataRowAction))) {
1883                                 EventRaised = false;
1884                                 EventValues = false;
1885                                 drExpectedAction = (DataRowAction) i;
1886                                 dt.OnRowChanged_Test (drExpectedAction);
1887
1888                                 Assert.IsTrue (EventRaised, "DT182");
1889                                 Assert.IsTrue (EventValues, "DT183");
1890                         }
1891                         dt.RowChanged -= new DataRowChangeEventHandler(OnRowChanged_Handler);
1892                 }
1893
1894                 private void OnRowChanged_Handler (Object sender, DataRowChangeEventArgs e)
1895                 {
1896                         DataTable dt = (DataTable)sender;
1897                         if (dt.Rows [0].Equals (e.Row) && e.Action == drExpectedAction)
1898                                 EventValues = true;
1899                         EventRaised = true;
1900                 }
1901
1902                 [Test]
1903                 public void OnRowChanging ()
1904                 {
1905                         ProtectedTestClass dt = new ProtectedTestClass();
1906
1907                         EventRaised = false;
1908                         dt.OnRowChanging_Test (DataRowAction.Nothing);
1909                         
1910                         Assert.IsFalse (EventRaised, "DT184");
1911
1912                         dt.RowChanging += new DataRowChangeEventHandler(OnRowChanging_Handler);
1913                         foreach (int i in Enum.GetValues (typeof (DataRowAction))) {
1914                                 EventRaised = false;
1915                                 EventValues = false;
1916                                 drExpectedAction = (DataRowAction) i;
1917                                 dt.OnRowChanging_Test (drExpectedAction);
1918
1919                                 Assert.IsTrue (EventRaised, "DT185");
1920                                 Assert.IsTrue (EventValues, "DT186");
1921                         }
1922                         dt.RowChanging -= new DataRowChangeEventHandler(OnRowChanging_Handler);
1923                 }
1924
1925                 private void OnRowChanging_Handler (Object sender,DataRowChangeEventArgs e)
1926                 {
1927                         DataTable dt = (DataTable) sender;
1928                         if (dt.Rows [0].Equals (e.Row) && e.Action == drExpectedAction)
1929                                 EventValues = true;
1930                         EventRaised = true;
1931                 }
1932
1933                 [Test]
1934                 public void OnRowDeleted ()
1935                 {
1936                         ProtectedTestClass dt = new ProtectedTestClass();
1937
1938                         EventRaised = false;
1939                         dt.OnRowDeleted_Test (DataRowAction.Nothing);
1940
1941                         Assert.IsFalse (EventRaised, "DT187");
1942
1943                         dt.RowDeleted += new DataRowChangeEventHandler(OnRowDeleted_Handler);
1944                         foreach (int i in Enum.GetValues (typeof (DataRowAction))) {
1945                                 EventRaised = false;
1946                                 EventValues = false;
1947                                 drExpectedAction = (DataRowAction) i;
1948                                 dt.OnRowDeleted_Test (drExpectedAction);
1949
1950                                 Assert.IsTrue (EventRaised, "DT188");
1951                                 Assert.IsTrue (EventValues, "DT189");
1952                         }
1953                         dt.RowDeleted -= new DataRowChangeEventHandler (OnRowDeleted_Handler);
1954                 }
1955
1956                 private void OnRowDeleted_Handler (Object sender,DataRowChangeEventArgs e)
1957                 {
1958                         DataTable dt = (DataTable)sender;
1959                         if (dt.Rows [0].Equals (e.Row) && e.Action == drExpectedAction)
1960                                 EventValues = true;
1961                         EventRaised = true;
1962                 }
1963
1964                 [Test]
1965                 public void OnRowDeleting ()
1966                 {
1967                         ProtectedTestClass dt = new ProtectedTestClass();
1968
1969                         EventRaised = false;
1970                         dt.OnRowDeleting_Test (DataRowAction.Nothing);
1971
1972                         Assert.IsFalse (EventRaised, "DT190");
1973
1974                         dt.RowDeleting += new DataRowChangeEventHandler(OnRowDeleting_Handler);
1975                         foreach (int i in Enum.GetValues (typeof(DataRowAction))) {
1976                                 EventRaised = false;
1977                                 EventValues = false;
1978                                 drExpectedAction = (DataRowAction) i;
1979                                 dt.OnRowDeleting_Test (drExpectedAction);
1980
1981                                 Assert.IsTrue (EventRaised, "DT191");
1982                                 Assert.IsTrue (EventValues, "DT192");
1983                         }
1984                         dt.RowDeleting -= new DataRowChangeEventHandler(OnRowDeleting_Handler);
1985                 }
1986
1987                 [Test]
1988                 public void BeginInit_PrimaryKey_1 ()
1989                 {
1990                         DataTable table = new DataTable ();
1991                         DataColumn col = table.Columns.Add ("col", typeof (int));
1992                         table.PrimaryKey = new DataColumn[] {col};
1993                         table.AcceptChanges ();
1994                         Assert.AreEqual (1, table.PrimaryKey.Length, "#1");
1995                 
1996                         table.BeginInit ();
1997                         DataColumn col2 = new DataColumn ("col2", typeof (int));
1998                         table.Columns.AddRange (new DataColumn[] {col2});
1999                         table.PrimaryKey = new DataColumn[] {col2};
2000                         table.EndInit ();
2001                         Assert.AreEqual (1, table.PrimaryKey.Length, "#2");
2002                         Assert.AreEqual ("col2", table.PrimaryKey[0].ColumnName, "#3");
2003                 }
2004
2005                 [Test]
2006                 public void BeginInit_PrimaryKey_2()
2007                 {
2008                         DataTable table = new DataTable ();
2009                         DataColumn col = table.Columns.Add ("col", typeof (int));
2010                         table.PrimaryKey = new DataColumn[] {col};
2011                         table.AcceptChanges ();
2012         
2013                         // ms.net behavior.     
2014                         table.BeginInit ();
2015                         DataColumn col1 = new DataColumn ("col1", typeof (int));
2016                         table.Columns.AddRange (new DataColumn[] {col1});
2017                         UniqueConstraint uc = new UniqueConstraint (string.Empty, new String[] {"col1"}, true);
2018                         table.Constraints.AddRange (new Constraint[] {uc});
2019
2020                         try {
2021                                 table.EndInit ();
2022                                 Assert.Fail ("#1");
2023                         } catch (ArgumentException ex) {
2024                                 // Cannot add primary key constraint since primary
2025                                 // key is already set for the table
2026                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
2027                                 Assert.IsNull (ex.InnerException, "#3");
2028                                 Assert.IsNotNull (ex.Message, "#4");
2029                                 Assert.IsNull (ex.ParamName, "#5");
2030                         }
2031                 }
2032
2033                 [Test]
2034                 public void BeginInit_PrimaryKey_3 ()
2035                 {
2036                         DataTable table = new DataTable ();
2037                         DataColumn col1 = table.Columns.Add ("col1", typeof (int));
2038                         DataColumn col2 = table.Columns.Add ("col2", typeof (int));
2039                 
2040                         // ms.net behavior
2041                         table.BeginInit ();
2042                         UniqueConstraint uc = new UniqueConstraint (string.Empty, new String[] {"col1"}, true);
2043                         table.Constraints.AddRange (new Constraint[] {uc});
2044                         table.PrimaryKey = new DataColumn [] {col2};
2045                         table.EndInit ();
2046
2047                         Assert.AreEqual ("col1", table.PrimaryKey[0].ColumnName, "#1");
2048                 }
2049                 
2050                 [Test]
2051                 public void PrimaryKey_OnFailing ()
2052                 {
2053                         DataTable table = new DataTable ();
2054                         DataColumn col1 = table.Columns.Add ("col1", typeof (int));
2055                         table.PrimaryKey = new DataColumn[] {col1};
2056
2057                         try {
2058                                 table.PrimaryKey = new DataColumn [] { new DataColumn ("col2", typeof (int)) };
2059                                 Assert.Fail ("#1");
2060                         } catch (ArgumentException ex) {
2061                                 //  Column must belong to a table
2062                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
2063                                 Assert.IsNull (ex.InnerException, "#3");
2064                                 Assert.IsNotNull (ex.Message, "#4");
2065                                 Assert.IsNull (ex.ParamName, "#5");
2066                         }
2067
2068                         Assert.AreEqual ("col1", table.PrimaryKey [0].ColumnName, "#6");
2069                 }
2070
2071                 [Test]
2072                 public void BeginInit_Cols_Constraints ()
2073                 {
2074                         DataTable table = new DataTable ();
2075
2076                         // if both cols and constraints are added after BeginInit, the cols
2077                         // should be added, before the constraints are added/validated
2078                         table.BeginInit ();
2079                         DataColumn col1 = new DataColumn ("col1", typeof (int));
2080                         table.Columns.AddRange (new DataColumn[] {col1});
2081                         UniqueConstraint uc = new UniqueConstraint (string.Empty, new String[] {"col1"}, false);
2082                         table.Constraints.AddRange (new Constraint[] {uc});
2083                         // no exception shud be thrown
2084                         table.EndInit ();
2085
2086                         Assert.AreEqual (1, table.Constraints.Count, "#1");
2087                 }
2088
2089                 [Test]
2090                 public void LoadDataRow_ExistingData ()
2091                 {
2092                         DataSet ds = new DataSet ();
2093                         DataTable table = ds.Tables.Add ();
2094                         
2095                         table.Columns.Add ("col1", typeof (int));
2096                         table.Columns.Add ("col2", typeof (int));
2097                         table.PrimaryKey = new DataColumn[] {table.Columns [0]};
2098
2099                         table.BeginLoadData ();
2100                         table.LoadDataRow (new object[] {1,10}, true);
2101                         table.LoadDataRow (new object[] {2,10}, true);
2102                         table.LoadDataRow (new object[] {3,10}, true);
2103                         table.LoadDataRow (new object[] {4,10}, true);
2104                         table.EndLoadData ();
2105
2106                         Assert.AreEqual (4, table.Rows.Count, "#1");
2107                         Assert.AreEqual (10, table.Rows [0][1], "#2");
2108                         Assert.AreEqual (10, table.Rows [1][1], "#3");
2109                         Assert.AreEqual (10, table.Rows [2][1], "#4");
2110                         Assert.AreEqual (10, table.Rows [3][1], "#5");
2111
2112                         table.BeginLoadData ();
2113                         table.LoadDataRow (new object[] {1,100}, true);
2114                         table.LoadDataRow (new object[] {2,100}, true);
2115                         table.LoadDataRow (new object[] {3,100}, true);
2116                         table.LoadDataRow (new object[] {4,100}, true);
2117                         table.EndLoadData ();
2118
2119                         Assert.AreEqual (4, table.Rows.Count, "#6");
2120                         Assert.AreEqual (100, table.Rows [0][1], "#7");
2121                         Assert.AreEqual (100, table.Rows [1][1], "#8");
2122                         Assert.AreEqual (100, table.Rows [2][1], "#7");
2123                         Assert.AreEqual (100, table.Rows [3][1], "#10");
2124                 }
2125
2126                 [Test]
2127                 public void LoadDataRow_DefaultValueError ()
2128                 {
2129                         DataTable table = new DataTable ();
2130                         table.Columns.Add ("col1", typeof (int));
2131                         table.Columns.Add ("col2", typeof (int));
2132                         table.PrimaryKey = new DataColumn[] {table.Columns [0]};
2133
2134                         table.BeginLoadData ();
2135                         // should not throw exception
2136                         table.LoadDataRow (new object[] {1}, true);
2137                         table.EndLoadData ();
2138
2139                         Assert.AreEqual (1, table.Rows [0][0], "#1");
2140                         Assert.AreEqual (DBNull.Value, table.Rows [0][1], "#2");
2141                 }
2142
2143                 [Test]
2144                 public void RejectChanges_CheckIndex ()
2145                 {
2146                         DataTable table = new DataTable ();
2147                         table.Columns.Add ("col1", typeof (int));
2148                         table.PrimaryKey = new DataColumn[] {table.Columns [0]};
2149
2150                         table.Rows.Add (new object[] {1});
2151                         table.AcceptChanges ();
2152
2153                         table.Rows [0][0] = 10;
2154                         table.RejectChanges ();
2155
2156                         Assert.IsNotNull (table.Rows.Find (1));
2157                 }
2158
2159                 private void OnRowDeleting_Handler (Object sender,DataRowChangeEventArgs e)
2160                 {
2161                         DataTable dt = (DataTable)sender;
2162                         if (dt.Rows [0].Equals (e.Row) && e.Action == drExpectedAction)
2163                                 EventValues = true;
2164                         EventRaised = true;
2165                 }
2166
2167                 [Test]
2168                 public void Select_StringString ()
2169                 {
2170                         DataTable dt = DataProvider.CreateChildDataTable ();
2171
2172                         DataRow [] drSelect;
2173                         ArrayList al;
2174
2175                         //add some rows
2176                         dt.Rows.Add (new object[] {99,88, "bla", "wowww"});
2177                         dt.Rows.Add (new object[] {999,888, string.Empty, "woowww"});
2178
2179                         //get excepted resault
2180                         al = new ArrayList ();
2181                         foreach (DataRow dr in dt.Rows) {
2182                                 if ((int) dr["ChildId"] == 1)
2183                                         al.Add (dr);
2184                         }
2185                         //al.Reverse();
2186                         al.Sort (new DataRowsComparer ("ParentId", "Desc"));
2187
2188                         drSelect = dt.Select ("ChildId=1", "ParentId Desc");
2189                         Assert.AreEqual (al.ToArray (), drSelect, "DT193");
2190
2191                         //get excepted resault
2192                         al = new ArrayList();
2193                         foreach (DataRow dr in dt.Rows) {
2194                                 if (dr ["String1"].ToString () == "1-String1")
2195                                         al.Add (dr);
2196                         }
2197                         //al.Reverse();
2198                         al.Sort (new DataRowsComparer ("ParentId", "Desc"));
2199
2200                         drSelect = dt.Select("String1='1-String1'", "ParentId Desc");
2201                         Assert.AreEqual (al.ToArray(),drSelect, "DT194");
2202
2203                         //get excepted resault
2204                         al = new ArrayList ();
2205                         foreach (DataRow dr in dt.Rows) {
2206                                 if ((int) dr["ChildId"] == 1 && dr["String1"].ToString() == "1-String1")
2207                                         al.Add (dr);
2208                         }
2209                         //al.Reverse();
2210                         al.Sort (new DataRowsComparer ("ParentId", "Desc"));
2211
2212                         drSelect = dt.Select ("ChildId=1 and String1='1-String1'", "ParentId Desc");
2213                         Assert.AreEqual(al.ToArray (), drSelect, "DT195");
2214                         
2215
2216                         //get excepted resault
2217                         al = new ArrayList ();
2218                         foreach (DataRow dr in dt.Rows) {
2219                                 if (dr ["String1"].ToString ().Length < 4)
2220                                         al.Add (dr);
2221                         }
2222                         //al.Reverse();
2223                         al.Sort(new DataRowsComparer("ParentId", "Desc"));
2224
2225                         drSelect = dt.Select("Len(String1) < 4 ", "ParentId Desc");
2226                         Assert.AreEqual(al.ToArray(),drSelect, "DT196");
2227
2228                         //get excepted resault
2229                         al = new ArrayList ();
2230                         foreach (DataRow dr in dt.Rows) {
2231                                 if (dr ["String1"].ToString ().IndexOf ("String") > 0)
2232                                         al.Add (dr);
2233                         }
2234                         //al.Reverse();
2235                         al.Sort (new DataRowsComparer ("ParentId", "Desc"));
2236
2237                         drSelect = dt.Select ("String1 like '%%String*'  ", "ParentId Desc");
2238                         Assert.AreEqual (al.ToArray (), drSelect, "DT197");
2239                         
2240                         //get excepted resault
2241                         al = new ArrayList ();
2242                         foreach (DataRow dr in dt.Rows) {
2243                                 if (((int) dr ["ChildId"] == 2) || ((int) dr ["ChildId"] == 3))
2244                                         al.Add (dr);
2245                         }
2246                         //al.Reverse();
2247                         al.Sort (new DataRowsComparer ("ParentId", "Desc"));
2248
2249                         drSelect = dt.Select ("ChildId in (2,3)  ", "ParentId Desc");
2250                         Assert.AreEqual (al.ToArray (), drSelect, "DT198");
2251
2252                         //get excepted resault
2253                         al = new ArrayList ();
2254                         foreach (DataRow dr in dt.Rows) {
2255                                 if ((((int) dr ["ChildId"] * (int) dr ["ParentId"]) > 5))
2256                                         al.Add (dr);
2257                         }
2258                         al.Sort (new DataRowsComparer ("ChildId", "Asc"));
2259
2260                         drSelect = dt.Select ("ChildId * ParentId > 5 ", "ChildId Asc");
2261                         // Cannot check this way as ArrayList.Sort uses unstable sort and 
2262                         // so the Order of the elements is not preserved when elements are equal
2263                         //Assert.AreEqual (al.ToArray(),drSelect, "DT199");
2264                         Assert.AreEqual (al.Count, drSelect.Length, "#DT199");
2265                         for (int i = 0; i < al.Count; ++i){
2266                                 // check the datarow is present and that the sort order is correct
2267                                 Assert.IsTrue (Array.IndexOf (drSelect, al[i]) != -1, "#DT_199_2_"+i);
2268                                 Assert.AreEqual (((DataRow)al[i])["ChildId"], drSelect[i]["ChildId"], "#DT_199_1" +i);
2269                         }
2270
2271                         //get excepted resault
2272                         al = new ArrayList ();
2273                         foreach (DataRow dr in dt.Rows) {
2274                                 if (dr ["String2"].ToString ().Substring (2, 3) == "Str")
2275                                         al.Add (dr);
2276                         }
2277                         al.Sort (new DataRowsComparer ("ParentId", "Desc"));
2278
2279                         drSelect = dt.Select ("SubString(String2,3,3) like 'Str' ", "ParentId Desc");
2280                         Assert.AreEqual (al.ToArray (), drSelect, "DT200");
2281                 }
2282
2283                 [Test]
2284                 [Category ("NotWorking")]
2285                 public void Select_StringString_2 ()
2286                 {
2287                         DataTable dt = DataProvider.CreateParentDataTable ();
2288
2289                         try {
2290                                 dt.Select (dt.Columns [0].ColumnName + "=1", "[x");
2291                                 Assert.Fail ("#1");
2292                         } catch (ArgumentException ex) {
2293                                 // [x isn't a valid Sort string entry
2294                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
2295                                 Assert.IsNull (ex.InnerException, "#3");
2296                                 Assert.IsNotNull (ex.Message, "#4");
2297                                 Assert.IsTrue (ex.Message.IndexOf ("[x") != -1, "#5");
2298                                 Assert.IsNull (ex.ParamName, "#6");
2299                         }
2300                 }
2301
2302                 [Test]
2303                 public void Select_StringString_3 ()
2304                 {       
2305                         DataTable dt = DataProvider.CreateParentDataTable ();
2306                         //Select - parse sort string checking 1");
2307                         try {
2308                                 dt.Select (dt.Columns [0].ColumnName, dt.Columns [0].ColumnName + "1");
2309                                 Assert.Fail ("#1");
2310                         } catch (IndexOutOfRangeException ex) {
2311                                 // Cannot find column ParentId1
2312                                 Assert.AreEqual (typeof (IndexOutOfRangeException), ex.GetType (), "#2");
2313                                 Assert.IsNull (ex.InnerException, "#3");
2314                                 Assert.IsNotNull (ex.Message, "#4");
2315                                 Assert.IsTrue (ex.Message.IndexOf ("ParentId1") != -1, "#5");
2316                         }
2317                 }
2318
2319                 [Test]
2320                 public void Select_NonBooleanFilter ()
2321                 {
2322                         DataTable table = new DataTable ();
2323                         table.Columns.Add ("col1", typeof (int));
2324                         
2325                         DataRow[] row = table.Select ("col1*10");
2326                         Assert.AreEqual (0, row.Length, "#A");
2327
2328                         // No exception shud be thrown 
2329                         // The filter created earlier (if cached), will raise an EvaluateException
2330                         // and so shouldnt be cached
2331                         for (int i=0; i < 5; ++i)
2332                                 table.Rows.Add (new object [] { i });
2333
2334                         try {
2335                                 table.Select ("col1*10");
2336                                 Assert.Fail ("#B1");
2337                         } catch (EvaluateException ex) {
2338                                 // Filter expression 'col1*10' does not evaluate
2339                                 // to a Boolean term
2340                                 Assert.AreEqual (typeof (EvaluateException), ex.GetType (), "#B2");
2341                                 Assert.IsNull (ex.InnerException, "#B3");
2342                                 Assert.IsNotNull (ex.Message, "#B4");
2343                                 //Assert.IsTrue (ex.Message.IndexOf ("'col1*10'") != -1, "#B5");
2344                                 //Assert.IsTrue (ex.Message.IndexOf ("Boolean") != -1, "#B6");
2345                         }
2346                 }
2347
2348                 [Test]
2349                 public void Select_BoolColumn ()
2350                 {
2351                         DataTable table = new DataTable ();
2352                         table.Columns.Add ("col1", typeof (int));
2353                         table.Columns.Add ("col2", typeof (bool));
2354
2355                         for (int i = 0; i < 5; i++)
2356                                 table.Rows.Add (new object [] { i });
2357
2358                         DataRow [] result;
2359                         try {
2360                                 result = table.Select ("col1");
2361                                 Assert.Fail ("#1");
2362                         } catch (EvaluateException ex) {
2363                                 // Filter expression 'col1' does not evaluate to
2364                                 // a Boolean term
2365                                 Assert.AreEqual (typeof (EvaluateException), ex.GetType (), "#2");
2366                                 Assert.IsNull (ex.InnerException, "#3");
2367                                 Assert.IsNotNull (ex.Message, "#4");
2368                                 //Assert.IsTrue (ex.Message.IndexOf ("'col1'") != -1, "#5");
2369                                 //Assert.IsTrue (ex.Message.IndexOf ("Boolean") != -1, "#6");
2370                         }
2371
2372                         //col2 is a boolean expression, and a null value translates to
2373                         //false.
2374                         result = table.Select ("col2");
2375                         Assert.AreEqual (0, result.Length);
2376                 }
2377
2378                 [Test]
2379                 public void Select_OrderOfRows ()
2380                 {
2381                         DataTable table = new DataTable ();
2382                         table.Columns.Add ("col1", typeof (int));
2383                         table.Columns.Add ("col2", typeof (int));
2384                 
2385                         for (int i = 0; i < 10; i++)
2386                                 table.Rows.Add (new object [] { 10 - i, i });
2387                         DataRow[] result = table.Select ("col1 > 5");
2388
2389                         Assert.AreEqual (6, result [0][0], "# incorrect sorting order");
2390                 }
2391
2392 #if NET_2_0
2393                 [Test]
2394                 public void DataTable_Clone ()
2395                 {
2396                         DataTable table = new DataTable ();
2397                         table.Columns.Add ("col1", typeof (DateTime));
2398                         table.Columns [0].DateTimeMode = DataSetDateTime.Local;
2399                         DataTable table1 = table.Clone ();
2400                         Assert.AreEqual (DataSetDateTime.Local, table1.Columns [0].DateTimeMode, "#1");
2401
2402                         //Test any other new prop in 2.0
2403                 }
2404
2405                 [Test]
2406                 public void Merge_SchemaTest ()
2407                 {
2408                         DataTable table1 = new DataTable ("t1");
2409                         table1.Columns.Add ("col1", typeof (int));
2410
2411                         DataTable table2 = new DataTable ("t2");
2412                         table2.Columns.Add ("col2", typeof (int));
2413
2414                         DataTable table3;
2415
2416                         table3 = table1.Clone ();
2417                         table3.Merge (table2);
2418                         Assert.AreEqual (2, table3.Columns.Count, "#1");
2419                         table3 = table1.Clone ();
2420                         table3.Merge (table2, false, MissingSchemaAction.Ignore);
2421                         Assert.AreEqual (1, table3.Columns.Count, "#2");
2422
2423                         // source constraints are ignored
2424                         table2.Constraints.Add ("uc", table2.Columns [0], false);
2425                         table3 = table1.Clone ();
2426                         table3.Merge (table2);
2427                         Assert.AreEqual (0, table3.Constraints.Count, "#3");
2428
2429                         // source PK is merged depending on MissingSchemaAction
2430                         table2.PrimaryKey = new DataColumn[] {table2.Columns[0]};
2431                         table3 = table1.Clone ();
2432                         table3.Merge (table2);
2433                         Assert.AreEqual (1, table3.Constraints.Count, "#4");
2434                         table3 = table1.Clone ();
2435                         table3.Merge (table2, false, MissingSchemaAction.Ignore);
2436                         Assert.AreEqual (0, table3.Constraints.Count, "#5");
2437
2438                         //FIXME : If both source and target have PK, then 
2439                         // shud be the exception raised when schema is merged? 
2440                         // ms.net throws a nullreference exception.
2441                         // If any data is merged, exception is anyways raised.
2442                         /*
2443                         table1.PrimaryKey = new DataColumn[] {table1.Columns[0]};
2444                         table3 = table1.Clone ();
2445                         try {
2446                                 table3.Merge(table2);
2447                                 Assert.Fail("#6");
2448                         } catch (DataException e) {}
2449                         */
2450
2451                         table3.Merge (table2,false,MissingSchemaAction.Ignore);
2452                         table1.PrimaryKey = null;
2453
2454                         // DateTime columns, DataType match only if DateTimeMode matches
2455                         table1.Columns.Add ("col_datetime", typeof (DateTime));
2456                         table2.Columns.Add ("col_datetime", typeof (DateTime));
2457                         table1.Columns ["col_datetime"].DateTimeMode = DataSetDateTime.Local;
2458                         table2.Columns ["col_datetime"].DateTimeMode = DataSetDateTime.Unspecified;
2459
2460                         table3 = table1.Clone ();
2461                         try {
2462                                 table3.Merge (table2);
2463                                 Assert.Fail ("#7");
2464                         } catch (DataException) {
2465                                 // <target>.col_datetime and <source>.col_datetime
2466                                 // have conflicting properties: DataType property mismatch.
2467                         }
2468
2469                         table1.Columns ["col_datetime"].DateTimeMode = DataSetDateTime.Unspecified;
2470                         table2.Columns ["col_datetime"].DateTimeMode = DataSetDateTime.UnspecifiedLocal;
2471                         table3 = table1.Clone ();
2472                         table3.Merge (table2);
2473                         Assert.AreEqual (DataSetDateTime.Unspecified, table3.Columns ["col_datetime"].DateTimeMode, "#9");
2474                 }
2475
2476                 [Test]
2477                 public void Merge_TestData ()
2478                 {
2479                         DataTable t1 = new DataTable ("t1");
2480                         DataTable t2 = new DataTable ("t2");
2481
2482                         t1.Columns.Add ("c1", typeof (int));
2483                         t1.Columns.Add ("c2", typeof (int));
2484                         t2.Columns.Add ("c1", typeof (int));
2485                         t2.Columns.Add ("c2", typeof (int));
2486
2487                         t1.Rows.Add (new object[] {1, 1});
2488                         t1.Rows.Add (new object[] {2, 2});
2489
2490                         t2.Rows.Add (new object[] {1, 5});
2491                         t2.Rows.Add (new object[] {1, 10});
2492
2493                         DataTable t3 = t1.Copy ();
2494                         // When primary key is not defined, rows are not merged.
2495                         t3.Merge (t2);
2496                         Assert.AreEqual (4, t3.Rows.Count, "#1");
2497
2498                         t1.PrimaryKey = new DataColumn[] {t1.Columns[0]};
2499                         t3 = t1.Copy ();
2500                         t3.Merge (t2);
2501                         Assert.AreEqual (2, t3.Rows.Count, "#2");
2502                         Assert.AreEqual (10, t3.Rows [0][1], "#3");
2503
2504                         t3 = t1.Copy ();
2505                         t3.Merge (t2, true);
2506                         Assert.AreEqual (2, t3.Rows.Count, "#4");
2507                         Assert.AreEqual (1, t3.Rows [0][1], "#5");
2508                 }
2509 #endif
2510
2511                 internal class DataRowsComparer : IComparer
2512                 {
2513                         private string _columnName;
2514                         private string _direction;
2515
2516                         public DataRowsComparer(string columnName, string direction)
2517                         {
2518                                 _columnName = columnName;
2519                                 if (direction.ToLower() != "asc" && direction.ToLower() != "desc")
2520                                         throw new ArgumentException("Direction can only be one of: 'asc' or 'desc'");
2521                                 _direction = direction;
2522                         }
2523
2524                         public int Compare(object x, object y)
2525                         {
2526                                 DataRow drX = (DataRow)x;
2527                                 DataRow drY = (DataRow)y;
2528
2529                                 object objX = drX[_columnName];
2530                                 object objY = drY[_columnName];
2531
2532                                 int compareResult = Comparer.Default.Compare(objX, objY);
2533
2534                                 //If we are comparing desc we need to reverse the result.
2535                                 if (_direction.ToLower() == "desc")
2536                                         compareResult = -compareResult;
2537
2538                                 return compareResult;
2539                         }
2540                 }
2541         }
2542 }