Merge pull request #1668 from alexanderkyte/bug1856
[mono.git] / mcs / class / System.Data / Test / System.Data / DataTableTest.cs
1 // DataTableTest.cs - NUnit Test Cases for testing the DataTable 
2 //
3 // Authors:
4 //   Franklin Wise (gracenote@earthlink.net)
5 //   Martin Willemoes Hansen (mwh@sysrq.dk)
6 //   Hagit Yidov (hagity@mainsoft.com)
7 // 
8 // (C) Franklin Wise
9 // (C) 2003 Martin Willemoes Hansen
10 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
11
12 //
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 // Copyright (C) 2011 Xamarin Inc. (http://www.xamarin.com)
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 using System;
37 using System.Collections;
38 using System.Collections.Generic;
39 using System.Data;
40 using System.Data.SqlTypes;
41 using System.Globalization;
42 using System.IO;
43 using System.Runtime.Serialization.Formatters.Binary;
44 using System.Threading;
45 using System.Xml;
46 using System.Text;
47
48 using MonoTests.System.Data.Utils;
49
50 using NUnit.Framework;
51
52 namespace MonoTests.System.Data
53 {
54         [TestFixture]
55         public class DataTableTest :  DataSetAssertion
56         {
57                 [SetUp]
58                 public void Setup ()
59                 {
60                         MyDataTable.count = 0;
61                 }
62
63                 string EOL = Environment.NewLine;
64
65                 [Test]
66                 public void Ctor()
67                 {
68                         DataTable dt = new DataTable();
69
70                         Assert.IsFalse (dt.CaseSensitive, "CaseSensitive must be false.");
71                         Assert.IsNotNull (dt.Columns, "Col");
72                         //Assert.IsTrue (dt.ChildRelations != null);
73                         Assert.IsNotNull (dt.Constraints, "Const");
74                         Assert.IsNull (dt.DataSet, "ds");
75                         Assert.IsNotNull (dt.DefaultView, "dv");
76                         Assert.AreEqual (string.Empty, dt.DisplayExpression, "de");
77                         Assert.IsNotNull (dt.ExtendedProperties, "ep");
78                         Assert.IsFalse (dt.HasErrors, "he");
79                         Assert.IsNotNull (dt.Locale, "lc");
80                         Assert.AreEqual (50, dt.MinimumCapacity, "mc"); //LAMESPEC:
81                         Assert.AreEqual (string.Empty, dt.Namespace, "ns");
82                         //Assert.IsTrue (dt.ParentRelations != null);
83                         Assert.AreEqual (string.Empty, dt.Prefix, "pf");
84                         Assert.IsNotNull (dt.PrimaryKey, "pk");
85                         Assert.IsNotNull (dt.Rows, "rows");
86                         Assert.IsNull (dt.Site, "Site");
87                         Assert.AreEqual (string.Empty, dt.TableName, "tname");
88                 }
89
90                 [Test]
91                 public void Select ()
92                 {
93                         DataSet Set = new DataSet ();
94                         DataTable Mom = new DataTable ("Mom");
95                         DataTable Child = new DataTable ("Child");
96                         Set.Tables.Add (Mom);
97                         Set.Tables.Add (Child);
98                         
99                         DataColumn Col = new DataColumn ("Name");
100                         DataColumn Col2 = new DataColumn ("ChildName");
101                         Mom.Columns.Add (Col);
102                         Mom.Columns.Add (Col2);
103                         
104                         DataColumn Col3 = new DataColumn ("Name");
105                         DataColumn Col4 = new DataColumn ("Age");
106                         Col4.DataType = typeof (short);
107                         Child.Columns.Add (Col3);
108                         Child.Columns.Add (Col4);
109
110                         DataRelation Relation = new DataRelation ("Rel", Mom.Columns [1], Child.Columns [0]);
111                         Set.Relations.Add (Relation);
112
113                         DataRow Row = Mom.NewRow ();
114                         Row [0] = "Laura";
115                         Row [1] = "Nick";
116                         Mom.Rows.Add (Row);
117
118                         Row = Mom.NewRow ();
119                         Row [0] = "Laura";
120                         Row [1] = "Dick";
121                         Mom.Rows.Add (Row);
122
123                         Row = Mom.NewRow ();
124                         Row [0] = "Laura";
125                         Row [1] = "Mick";
126                         Mom.Rows.Add (Row);
127
128                         Row = Mom.NewRow ();
129                         Row [0] = "Teresa";
130                         Row [1] = "Jack";
131                         Mom.Rows.Add (Row);
132
133                         Row = Mom.NewRow ();
134                         Row [0] = "Teresa";
135                         Row [1] = "Mack";
136                         Mom.Rows.Add (Row);
137
138                         Row = Mom.NewRow ();
139                         Row [0] = "'Jhon O'' Collenal'";
140                         Row [1] = "Pack";
141                         Mom.Rows.Add (Row);
142
143                         Row = Child.NewRow ();
144                         Row [0] = "Nick";
145                         Row [1] = 15;
146                         Child.Rows.Add (Row);
147
148                         Row = Child.NewRow ();
149                         Row [0] = "Dick";
150                         Row [1] = 25;
151                         Child.Rows.Add (Row);
152
153                         Row = Child.NewRow ();
154                         Row [0] = "Mick";
155                         Row [1] = 35;
156                         Child.Rows.Add (Row);
157
158                         Row = Child.NewRow ();
159                         Row [0] = "Jack";
160                         Row [1] = 10;
161                         Child.Rows.Add (Row);
162
163                         Row = Child.NewRow ();
164                         Row [0] = "Mack";
165                         Row [1] = 19;
166                         Child.Rows.Add (Row);
167
168                         Row = Child.NewRow ();
169                         Row [0] = "Mack";
170                         Row [1] = 99;
171                         Child.Rows.Add (Row);
172
173                         Row = Child.NewRow ();
174                         Row [0] = "Pack";
175                         Row [1] = 66;
176                         Child.Rows.Add (Row);
177
178                         DataRow [] Rows = Mom.Select ("Name = 'Teresa'");
179                         Assert.AreEqual (2, Rows.Length, "test#01");
180
181                         // test with apos escaped
182                         Rows = Mom.Select ("Name = '''Jhon O'''' Collenal'''");
183                         Assert.AreEqual (1, Rows.Length, "test#01.1");
184
185                         Rows = Mom.Select ("Name = 'Teresa' and ChildName = 'Nick'");
186                         Assert.AreEqual (0, Rows.Length, "test#02");
187
188                         Rows = Mom.Select ("Name = 'Teresa' and ChildName = 'Jack'");
189                         Assert.AreEqual (1, Rows.Length, "test#03");
190
191                         Rows = Mom.Select ("Name = 'Teresa' and ChildName <> 'Jack'");
192                         Assert.AreEqual ("Mack", Rows [0] [1], "test#04");
193
194                         Rows = Mom.Select ("Name = 'Teresa' or ChildName <> 'Jack'");
195                         Assert.AreEqual (6, Rows.Length, "test#05");
196
197                         Rows = Child.Select ("age = 20 - 1");
198                         Assert.AreEqual (1, Rows.Length, "test#06");
199
200                         Rows = Child.Select ("age <= 20");
201                         Assert.AreEqual (3, Rows.Length, "test#07");
202
203                         Rows = Child.Select ("age >= 20");
204                         Assert.AreEqual (4, Rows.Length, "test#08");
205
206                         Rows = Child.Select ("age >= 20 and name = 'Mack' or name = 'Nick'");
207                         Assert.AreEqual (2, Rows.Length, "test#09");
208
209                         Rows = Child.Select ("age >= 20 and (name = 'Mack' or name = 'Nick')");
210                         Assert.AreEqual (1, Rows.Length, "test#10");
211                         Assert.AreEqual ("Mack", Rows [0] [0], "test#11");
212
213                         Rows = Child.Select ("not (Name = 'Jack')");
214                         Assert.AreEqual (6, Rows.Length, "test#12");
215                 }
216
217                 [Test]
218                 public void Select2 ()
219                 {
220                         DataSet Set = new DataSet ();
221                         DataTable Child = new DataTable ("Child");
222
223                         Set.Tables.Add (Child);
224
225                         DataColumn Col3 = new DataColumn ("Name");
226                         DataColumn Col4 = new DataColumn ("Age");
227                         Col4.DataType = typeof (short);
228                         Child.Columns.Add (Col3);
229                         Child.Columns.Add (Col4);
230
231                         DataRow Row = Child.NewRow ();
232                         Row [0] = "Nick";
233                         Row [1] = 15;
234                         Child.Rows.Add (Row);
235
236                         Row = Child.NewRow ();
237                         Row [0] = "Dick";
238                         Row [1] = 25;
239                         Child.Rows.Add (Row);
240
241                         Row = Child.NewRow ();
242                         Row [0] = "Mick";
243                         Row [1] = 35;
244                         Child.Rows.Add (Row);
245
246                         Row = Child.NewRow ();
247                         Row [0] = "Jack";
248                         Row [1] = 10;
249                         Child.Rows.Add (Row);
250
251                         Row = Child.NewRow ();
252                         Row [0] = "Mack";
253                         Row [1] = 19;
254                         Child.Rows.Add (Row);
255
256                         Row = Child.NewRow ();
257                         Row [0] = "Mack";
258                         Row [1] = 99;
259                         Child.Rows.Add (Row);
260
261                         DataRow [] Rows = Child.Select ("age >= 20", "age DESC");
262                         Assert.AreEqual (3, Rows.Length, "test#01");
263                         Assert.AreEqual ("Mack", Rows [0] [0], "test#02");
264                         Assert.AreEqual ("Mick", Rows [1] [0], "test#03");
265                         Assert.AreEqual ("Dick", Rows [2] [0], "test#04");
266
267                         Rows = Child.Select ("age >= 20", "age asc");
268                         Assert.AreEqual (3, Rows.Length, "test#05");
269                         Assert.AreEqual ("Dick", Rows [0] [0], "test#06");
270                         Assert.AreEqual ("Mick", Rows [1] [0], "test#07");
271                         Assert.AreEqual ("Mack", Rows [2] [0], "test#08");
272
273                         Rows = Child.Select ("age >= 20", "name asc");
274                         Assert.AreEqual (3, Rows.Length, "test#09");
275                         Assert.AreEqual ("Dick", Rows [0] [0], "test#10");
276                         Assert.AreEqual ("Mack", Rows [1] [0], "test#11");
277                         Assert.AreEqual ("Mick", Rows [2] [0], "test#12");
278
279                         Rows = Child.Select ("age >= 20", "name desc");
280                         Assert.AreEqual (3, Rows.Length, "test#09");
281                         Assert.AreEqual ("Mick", Rows [0] [0], "test#10");
282                         Assert.AreEqual ("Mack", Rows [1] [0], "test#11");
283                         Assert.AreEqual ("Dick", Rows [2] [0], "test#12");
284                 }
285
286                 [Test]
287                 public void SelectParsing ()
288                 {
289                         DataTable T = new DataTable ("test");
290                         DataColumn C = new DataColumn ("name");
291                         T.Columns.Add (C);
292                         C = new DataColumn ("age");
293                         C.DataType = typeof (int);
294                         T.Columns.Add (C);
295                         C = new DataColumn ("id");
296                         T.Columns.Add (C);
297                         
298                         DataSet Set = new DataSet ("TestSet");
299                         Set.Tables.Add (T);
300                         
301                         DataRow Row = null;
302                         for (int i = 0; i < 100; i++) {
303                                 Row = T.NewRow ();
304                                 Row [0] = "human" + i;
305                                 Row [1] = i;
306                                 Row [2] = i;
307                                 T.Rows.Add (Row);
308                         }
309                         
310                         Row = T.NewRow ();
311                         Row [0] = "h*an";
312                         Row [1] = 1;
313                         Row [2] = 1;
314                         T.Rows.Add (Row);
315
316                         Assert.AreEqual (12, T.Select ("age<=10").Length, "test#01");
317                         
318                         Assert.AreEqual (12, T.Select ("age\n\t<\n\t=\t\n10").Length, "test#02");
319
320                         try {
321                                 T.Select ("name = 1human ");
322                                 Assert.Fail ("test#03");
323                         } catch (SyntaxErrorException e) {
324                                 // missing operand after 'human' operand 
325                                 Assert.AreEqual (typeof (SyntaxErrorException), e.GetType (), "test#04");
326                         }
327                         
328                         try {
329                                 T.Select ("name = 1");
330                                 Assert.Fail ("test#05");
331                         } catch (EvaluateException e) {
332                                 // Cannot perform '=' operation between string and Int32
333                                 Assert.AreEqual (typeof (EvaluateException), e.GetType (), "test#06");
334                         }
335                         
336                         Assert.AreEqual (1, T.Select ("age = '13'").Length, "test#07");
337                 }
338
339                 [Test]
340                 public void SelectEscaping ()
341                 {
342                         DataTable dt = new DataTable ();
343                         dt.Columns.Add ("SomeCol");
344                         dt.Rows.Add (new object [] {"\t"});
345                         dt.Rows.Add (new object [] {"\\"});
346                         
347                         Assert.AreEqual (0, dt.Select (@"SomeCol='\t'").Length, "test#01");
348                         Assert.AreEqual (0, dt.Select (@"SomeCol='\\'").Length, "test#02");
349                         
350                         Assert.AreEqual (0, dt.Select (@"SomeCol='\x'").Length, "test#03");
351                 }
352
353                 [Test]
354                 public void SelectOperators ()
355                 {
356                         DataTable T = new DataTable ("test");
357                         DataColumn C = new DataColumn ("name");
358                         T.Columns.Add (C);
359                         C = new DataColumn ("age");
360                         C.DataType = typeof (int);
361                         T.Columns.Add (C);
362                         C = new DataColumn ("id");
363                         T.Columns.Add (C);
364                         
365                         DataSet Set = new DataSet ("TestSet");
366                         Set.Tables.Add (T);
367                         
368                         DataRow Row = null;
369                         for (int i = 0; i < 100; i++) {
370                                 Row = T.NewRow ();
371                                 Row [0] = "human" + i;
372                                 Row [1] = i;
373                                 Row [2] = i;
374                                 T.Rows.Add (Row);
375                         }
376                         
377                         Row = T.NewRow ();
378                         Row [0] = "h*an";
379                         Row [1] = 1;
380                         Row [2] = 1;
381                         T.Rows.Add (Row);
382                         
383                         Assert.AreEqual (11, T.Select ("age < 10").Length, "test#01");
384                         Assert.AreEqual (12, T.Select ("age <= 10").Length, "test#02");
385                         Assert.AreEqual (12, T.Select ("age< =10").Length, "test#03");
386                         Assert.AreEqual (89, T.Select ("age > 10").Length, "test#04");
387                         Assert.AreEqual (90, T.Select ("age >= 10").Length, "test#05");
388                         Assert.AreEqual (100, T.Select ("age <> 10").Length, "test#06");
389                         Assert.AreEqual (3, T.Select ("name < 'human10'").Length, "test#07");
390                         Assert.AreEqual (3, T.Select ("id < '10'").Length, "test#08");
391                         // FIXME: Somebody explain how this can be possible.
392                         // it seems that it is no matter between 10 - 30. The
393                         // result is allways 25 :-P
394                         //Assert.AreEqual (25, T.Select ("id < 10").Length, "test#09");
395                         
396                 }
397
398                 [Test]
399                 public void SelectExceptions ()
400                 {
401                         DataTable T = new DataTable ("test");
402                         DataColumn C = new DataColumn ("name");
403                         T.Columns.Add (C);
404                         C = new DataColumn ("age");
405                         C.DataType = typeof (int);
406                         T.Columns.Add (C);
407                         C = new DataColumn ("id");
408                         T.Columns.Add (C);
409                         
410                         for (int i = 0; i < 100; i++) {
411                                 DataRow Row = T.NewRow ();
412                                 Row [0] = "human" + i;
413                                 Row [1] = i;
414                                 Row [2] = i;
415                                 T.Rows.Add (Row);
416                         }
417                         
418                         try {
419                                 T.Select ("name = human1");
420                                 Assert.Fail ("test#01");
421                         } catch (EvaluateException e) {
422                                 // column name human not found
423                                 Assert.AreEqual (typeof (EvaluateException), e.GetType (), "test#02");
424                         }
425                         
426                         Assert.AreEqual (1, T.Select ("id = '12'").Length, "test#04");
427                         Assert.AreEqual (1, T.Select ("id = 12").Length, "test#05");
428                         
429                         try {
430                                 T.Select ("id = 1k3");
431                                 Assert.Fail ("test#06");
432                         } catch (SyntaxErrorException e) {
433                                 // no operands after k3 operator
434                                 Assert.AreEqual (typeof (SyntaxErrorException), e.GetType (), "test#07");
435                         }
436                 }
437                 
438                 [Test]
439                 public void SelectStringOperators ()
440                 {
441                         DataTable T = new DataTable ("test");
442                         DataColumn C = new DataColumn ("name");
443                         T.Columns.Add (C);
444                         C = new DataColumn ("age");
445                         C.DataType = typeof (int);
446                         T.Columns.Add (C);
447                         C = new DataColumn ("id");
448                         T.Columns.Add (C);
449                         
450                         DataSet Set = new DataSet ("TestSet");
451                         Set.Tables.Add (T);
452                         
453                         DataRow Row = null;
454                         for (int i = 0; i < 100; i++) {
455                                 Row = T.NewRow ();
456                                 Row [0] = "human" + i;
457                                 Row [1] = i;
458                                 Row [2] = i;
459                                 T.Rows.Add (Row);
460                         }
461                         Row = T.NewRow ();
462                         Row [0] = "h*an";
463                         Row [1] = 1;
464                         Row [2] = 1;
465                         T.Rows.Add (Row);
466
467                         Assert.AreEqual (1, T.Select ("name = 'human' + 1").Length, "test#01");
468                         
469                         Assert.AreEqual ("human1", T.Select ("name = 'human' + 1") [0] ["name"], "test#02");
470                         Assert.AreEqual (1, T.Select ("name = 'human' + '1'").Length, "test#03");
471                         Assert.AreEqual ("human1", T.Select ("name = 'human' + '1'") [0] ["name"], "test#04");
472                         Assert.AreEqual (1, T.Select ("name = 'human' + 1 + 2").Length, "test#05");
473                         Assert.AreEqual ("human12", T.Select ("name = 'human' + '1' + '2'") [0] ["name"], "test#06");
474                         
475                         Assert.AreEqual (1, T.Select ("name = 'huMAn' + 1").Length, "test#07");
476                         
477                         Set.CaseSensitive = true;
478                         Assert.AreEqual (0, T.Select ("name = 'huMAn' + 1").Length, "test#08");
479                         
480                         T.CaseSensitive = false;
481                         Assert.AreEqual (1, T.Select ("name = 'huMAn' + 1").Length, "test#09");
482                         
483                         T.CaseSensitive = true;
484                         Assert.AreEqual (0, T.Select ("name = 'huMAn' + 1").Length, "test#10");
485                         
486                         Set.CaseSensitive = false;
487                         Assert.AreEqual (0, T.Select ("name = 'huMAn' + 1").Length, "test#11");
488                         
489                         T.CaseSensitive = false;
490                         Assert.AreEqual (1, T.Select ("name = 'huMAn' + 1").Length, "test#12");
491                         
492                         Assert.AreEqual (0, T.Select ("name = 'human1*'").Length, "test#13");
493                         Assert.AreEqual (11, T.Select ("name like 'human1*'").Length, "test#14");
494                         Assert.AreEqual (11, T.Select ("name like 'human1%'").Length, "test#15");
495                         
496                         try {
497                                 Assert.AreEqual (11, T.Select ("name like 'h*an1'").Length, "test#16");
498                                 Assert.Fail ("test#16");
499                         } catch (EvaluateException e) {
500                                 // 'h*an1' is invalid
501                                 Assert.AreEqual (typeof (EvaluateException), e.GetType (), "test#17");
502                         }
503                         
504                         try {
505                                 Assert.AreEqual (11, T.Select ("name like 'h%an1'").Length, "test#18");
506                                 Assert.Fail ("test#19");
507                         } catch (EvaluateException e) {
508                                 // 'h%an1' is invalid
509                                 Assert.AreEqual (typeof (EvaluateException), e.GetType (), "test#20");
510                         }
511                         
512                         Assert.AreEqual (0, T.Select ("name like 'h[%]an'").Length, "test#21");
513                         Assert.AreEqual (1, T.Select ("name like 'h[*]an'").Length, "test#22");
514                 }
515
516                 [Test]
517                 public void SelectAggregates ()
518                 {
519                         DataTable T = new DataTable ("test");
520                         DataColumn C = new DataColumn ("name");
521                         T.Columns.Add (C);
522                         C = new DataColumn ("age");
523                         C.DataType = typeof (int);
524                         T.Columns.Add (C);
525                         C = new DataColumn ("id");
526                         T.Columns.Add (C);
527                         DataRow Row = null;
528                         
529                         for (int i = 0; i < 1000; i++) {
530                                 Row = T.NewRow ();
531                                 Row [0] = "human" + i;
532                                 Row [1] = i;
533                                 Row [2] = i;
534                                 T.Rows.Add (Row);
535                         }
536                         
537                         Assert.AreEqual (1000, T.Select ("Sum(age) > 10").Length, "test#01");
538                         Assert.AreEqual (1000, T.Select ("avg(age) = 499").Length, "test#02");
539                         Assert.AreEqual (1000, T.Select ("min(age) = 0").Length, "test#03");
540                         Assert.AreEqual (1000, T.Select ("max(age) = 999").Length, "test#04");
541                         Assert.AreEqual (1000, T.Select ("count(age) = 1000").Length, "test#05");
542                         Assert.AreEqual (1000, T.Select ("stdev(age) > 287 and stdev(age) < 289").Length, "test#06");
543                         Assert.AreEqual (1000, T.Select ("var(age) < 83417 and var(age) > 83416").Length, "test#07");
544                 }
545                 
546                 [Test]
547                 public void SelectFunctions ()
548                 {
549                         DataTable T = new DataTable ("test");
550                         DataColumn C = new DataColumn ("name");
551                         T.Columns.Add (C);
552                         C = new DataColumn ("age");
553                         C.DataType = typeof (int);
554                         T.Columns.Add (C);
555                         C = new DataColumn ("id");
556                         T.Columns.Add (C);
557                         DataRow Row = null;
558                         
559                         for (int i = 0; i < 1000; i++) {
560                                 Row = T.NewRow ();
561                                 Row [0] = "human" + i;
562                                 Row [1] = i;
563                                 Row [2] = i;
564                                 T.Rows.Add (Row);
565                         }
566                         
567                         Row = T.NewRow ();
568                         Row [0] = "human" + "test";
569                         Row [1] = DBNull.Value;
570                         Row [2] = DBNull.Value;
571                         T.Rows.Add (Row);
572
573                         //TODO: How to test Convert-function
574                         Assert.AreEqual (25, T.Select ("age = 5*5") [0]["age"], "test#01");
575                         Assert.AreEqual (901, T.Select ("len(name) > 7").Length, "test#02");
576                         Assert.AreEqual (125, T.Select ("age = 5*5*5 AND len(name)>7") [0]["age"], "test#03");
577                         Assert.AreEqual (1, T.Select ("isnull(id, 'test') = 'test'").Length, "test#04");
578                         Assert.AreEqual (1000, T.Select ("iif(id = '56', 'test', 'false') = 'false'").Length, "test#05");
579                         Assert.AreEqual (1, T.Select ("iif(id = '56', 'test', 'false') = 'test'").Length, "test#06");
580                         Assert.AreEqual (9, T.Select ("substring(id, 2, 3) = '23'").Length, "test#07");
581                         Assert.AreEqual ("123", T.Select ("substring(id, 2, 3) = '23'") [0] ["id"], "test#08");
582                         Assert.AreEqual ("423", T.Select ("substring(id, 2, 3) = '23'") [3] ["id"], "test#09");
583                         Assert.AreEqual ("923", T.Select ("substring(id, 2, 3) = '23'") [8] ["id"], "test#10");
584                 }
585
586                 [Test]
587                 public void SelectRelations ()
588                 {
589                         DataSet Set = new DataSet ();
590                         DataTable Mom = new DataTable ("Mom");
591                         DataTable Child = new DataTable ("Child");
592
593                         Set.Tables.Add (Mom);
594                         Set.Tables.Add (Child);
595
596                         DataColumn Col = new DataColumn ("Name");
597                         DataColumn Col2 = new DataColumn ("ChildName");
598                         Mom.Columns.Add (Col);
599                         Mom.Columns.Add (Col2);
600
601                         DataColumn Col3 = new DataColumn ("Name");
602                         DataColumn Col4 = new DataColumn ("Age");
603                         Col4.DataType = typeof (short);
604                         Child.Columns.Add (Col3);
605                         Child.Columns.Add (Col4);
606
607                         DataRelation Relation = new DataRelation ("Rel", Mom.Columns [1], Child.Columns [0]);
608                         Set.Relations.Add (Relation);
609
610                         DataRow Row = Mom.NewRow ();
611                         Row [0] = "Laura";
612                         Row [1] = "Nick";
613                         Mom.Rows.Add (Row);
614
615                         Row = Mom.NewRow ();
616                         Row [0] = "Laura";
617                         Row [1] = "Dick";
618                         Mom.Rows.Add (Row);
619
620                         Row = Mom.NewRow ();
621                         Row [0] = "Laura";
622                         Row [1] = "Mick";
623                         Mom.Rows.Add (Row);
624
625                         Row = Mom.NewRow ();
626                         Row [0] = "Teresa";
627                         Row [1] = "Jack";
628                         Mom.Rows.Add (Row);
629
630                         Row = Mom.NewRow ();
631                         Row [0] = "Teresa";
632                         Row [1] = "Mack";
633                         Mom.Rows.Add (Row);
634
635                         Row = Child.NewRow ();
636                         Row [0] = "Nick";
637                         Row [1] = 15;
638                         Child.Rows.Add (Row);
639
640                         Row = Child.NewRow ();
641                         Row [0] = "Dick";
642                         Row [1] = 25;
643                         Child.Rows.Add (Row);
644
645                         Row = Child.NewRow ();
646                         Row [0] = "Mick";
647                         Row [1] = 35;
648                         Child.Rows.Add (Row);
649
650                         Row = Child.NewRow ();
651                         Row [0] = "Jack";
652                         Row [1] = 10;
653                         Child.Rows.Add (Row);
654
655                         Row = Child.NewRow ();
656                         Row [0] = "Mack";
657                         Row [1] = 19;
658                         Child.Rows.Add (Row);
659
660                         Row = Child.NewRow ();
661                         Row [0] = "Mack";
662                         Row [1] = 99;
663                         Child.Rows.Add (Row);
664                         
665                         DataRow [] Rows = Child.Select ("name = Parent.Childname");
666                         Assert.AreEqual (6, Rows.Length, "test#01");
667                         Rows = Child.Select ("Parent.childname = 'Jack'");
668                         Assert.AreEqual (1, Rows.Length, "test#02");
669                         
670                         /*
671                         try {
672                                 // FIXME: LAMESPEC: Why the exception is thrown why... why... 
673                                 Mom.Select ("Child.Name = 'Jack'");
674                                 Assert.Fail ("test#03");
675                         } catch (Exception e) {
676                                 Assert.AreEqual (typeof (SyntaxErrorException), e.GetType (), "test#04");
677                                 Assert.AreEqual ("Cannot interpret token 'Child' at position 1.", e.Message, "test#05");
678                         }
679                         */
680                         
681                         Rows = Child.Select ("Parent.name = 'Laura'");
682                         Assert.AreEqual (3, Rows.Length, "test#06");
683                         
684                         DataTable Parent2 = new DataTable ("Parent2");
685                         Col = new DataColumn ("Name");
686                         Col2 = new DataColumn ("ChildName");
687
688                         Parent2.Columns.Add (Col);
689                         Parent2.Columns.Add (Col2);
690                         Set.Tables.Add (Parent2);
691
692                         Row = Parent2.NewRow ();
693                         Row [0] = "Laura";
694                         Row [1] = "Nick";
695                         Parent2.Rows.Add (Row);
696
697                         Row = Parent2.NewRow ();
698                         Row [0] = "Laura";
699                         Row [1] = "Dick";
700                         Parent2.Rows.Add (Row);
701
702                         Row = Parent2.NewRow ();
703                         Row [0] = "Laura";
704                         Row [1] = "Mick";
705                         Parent2.Rows.Add (Row);
706
707                         Row = Parent2.NewRow ();
708                         Row [0] = "Teresa";
709                         Row [1] = "Jack";
710                         Parent2.Rows.Add (Row);
711
712                         Row = Parent2.NewRow ();
713                         Row [0] = "Teresa";
714                         Row [1] = "Mack";
715                         Parent2.Rows.Add (Row);
716
717                         Relation = new DataRelation ("Rel2", Parent2.Columns [1], Child.Columns [0]);
718                         Set.Relations.Add (Relation);
719
720                         try {
721                                 Rows = Child.Select ("Parent.ChildName = 'Jack'");
722                                 Assert.Fail ("test#07");
723                         } catch (EvaluateException e) {
724                                 Assert.AreEqual (typeof (EvaluateException), e.GetType (), "test#08");
725                                 // Do not compare exception messages!
726                                 //Assert.AreEqual ("The table [Child] involved in more than one relation. You must explicitly mention a relation name in the expression 'parent.[ChildName]'.", e.Message, "test#09");
727                         }
728                         
729                         Rows = Child.Select ("Parent(rel).ChildName = 'Jack'");
730                         Assert.AreEqual (1, Rows.Length, "test#10");
731
732                         Rows = Child.Select ("Parent(Rel2).ChildName = 'Jack'");
733                         Assert.AreEqual (1, Rows.Length, "test#10");
734                         
735                         try {
736                                 Mom.Select ("Parent.name  = 'John'");
737                         } catch (IndexOutOfRangeException e) {
738                                 Assert.AreEqual (typeof (IndexOutOfRangeException), e.GetType (), "test#11");
739                                 // Do not compare exception messages!
740                                 //Assert.AreEqual ("Cannot find relation 0.", e.Message, "test#12");
741                         }
742                 }
743
744                 [Test]
745                 public void SelectRowState()
746                 {
747                         DataTable d = new DataTable();
748                         d.Columns.Add (new DataColumn ("aaa"));
749                         DataRow [] rows = d.Select (null, null, DataViewRowState.Deleted);
750                         Assert.AreEqual (0, rows.Length);
751                         d.Rows.Add (new object [] {"bbb"});
752                         d.Rows.Add (new object [] {"bbb"});
753                         rows = d.Select (null, null, DataViewRowState.Deleted);
754                         Assert.AreEqual (0, rows.Length);
755                 }
756
757                 [Test]
758                 public void ToStringTest()
759                 {
760                         DataTable dt = new DataTable();
761                         dt.Columns.Add("Col1", typeof(int));
762
763                         dt.TableName = "Mytable";
764                         dt.DisplayExpression = "Col1";
765
766                         string cmpr = dt.TableName + " + " + dt.DisplayExpression;
767                         Assert.AreEqual (cmpr, dt.ToString());
768                 }
769
770                 [Test]
771                 public void PrimaryKey ()
772                 {
773                         DataTable dt = new DataTable ();
774                         DataColumn Col = new DataColumn ();
775                         Col.AllowDBNull = false;
776                         Col.DataType = typeof (int);
777                         dt.Columns.Add (Col);
778                         dt.Columns.Add ();
779                         dt.Columns.Add ();
780                         dt.Columns.Add ();
781
782                         Assert.AreEqual (0, dt.PrimaryKey.Length, "test#01");
783
784                         dt.PrimaryKey = new DataColumn [] {dt.Columns [0]};
785                         Assert.AreEqual (1, dt.PrimaryKey.Length, "test#02");
786                         Assert.AreEqual ("Column1", dt.PrimaryKey [0].ColumnName, "test#03");
787
788                         dt.PrimaryKey = null;
789                         Assert.AreEqual (0, dt.PrimaryKey.Length, "test#04");
790
791                         Col = new DataColumn ("failed");
792
793                         try {
794                                 dt.PrimaryKey = new DataColumn [] {Col};
795                                 Assert.Fail ("test#05");
796                         } catch (ArgumentException e) {
797                                 Assert.AreEqual (typeof (ArgumentException), e.GetType (), "test#06");
798                                 // Never expect English message
799                                 // Assert.AreEqual ("Column must belong to a table.", e.Message, "test#07");
800                         }
801
802                         DataTable dt2 = new DataTable ();
803                         dt2.Columns.Add ();
804
805                         try {
806                                 dt.PrimaryKey = new DataColumn [] {dt2.Columns [0]};
807                                 Assert.Fail ("test#08");
808                         } catch (ArgumentException e) {
809                                 Assert.AreEqual (typeof (ArgumentException), e.GetType (), "test#09");
810                                 // Never expect English message
811                                 // Assert.AreEqual ("PrimaryKey columns do not belong to this table.", e.Message, "test#10");
812                         }
813
814                         Assert.AreEqual (0, dt.Constraints.Count, "test#11");
815
816                         dt.PrimaryKey = new DataColumn [] {dt.Columns [0], dt.Columns [1]};
817                         Assert.AreEqual (2, dt.PrimaryKey.Length, "test#12");
818                         Assert.AreEqual (1, dt.Constraints.Count, "test#13");
819                         Assert.IsTrue (dt.Constraints [0] is UniqueConstraint, "test#14");
820                         Assert.AreEqual ("Column1", dt.PrimaryKey [0].ColumnName, "test#15");
821                         Assert.AreEqual ("Column2", dt.PrimaryKey [1].ColumnName, "test#16");
822                 }
823                 
824                 [Test]
825                 [SetCulture("en-US")]
826                 public void PropertyExceptions ()
827                 {
828                         DataSet set = new DataSet ();
829                         DataTable table = new DataTable ();
830                         DataTable table1 =  new DataTable ();
831                         set.Tables.Add (table);
832                         set.Tables.Add (table1);
833
834                         DataColumn col = new DataColumn ();
835                         col.ColumnName = "Id";
836                         col.DataType = typeof (int);
837                         table.Columns.Add (col);
838                         UniqueConstraint uc = new UniqueConstraint ("UK1", table.Columns[0] );
839                         table.Constraints.Add (uc);
840                         table.CaseSensitive = false;
841
842                         col = new DataColumn ();
843                         col.ColumnName = "Name";
844                         col.DataType = typeof (string);
845                         table.Columns.Add (col);
846
847                         col = new DataColumn ();
848                         col.ColumnName = "Id";
849                         col.DataType = typeof (int);
850                         table1.Columns.Add (col);
851                         col = new DataColumn ();
852                         col.ColumnName = "Name";
853                         col.DataType = typeof (string);
854                         table1.Columns.Add (col);
855
856                         DataRelation dr = new DataRelation ("DR", table.Columns[0], table1.Columns[0]);
857                         set.Relations.Add (dr);
858
859                         try {
860                                 table.CaseSensitive = true;
861                                 table1.CaseSensitive = true;
862                                 Assert.Fail ("#A01");
863                         } catch (ArgumentException) {
864                         }
865
866                         try {
867                                 CultureInfo cultureInfo = new CultureInfo ("en-gb");
868                                 table.Locale = cultureInfo;
869                                 table1.Locale = cultureInfo;
870                                 Assert.Fail ("#A03");
871                         } catch (ArgumentException) {
872                         }
873
874                         try {
875                                 table.Prefix = "Prefix#1";
876                                 Assert.Fail ("#A05");
877                         } catch (DataException) {
878                         }
879                 }
880
881                 [Test]
882                 public void GetErrors ()
883                 {
884                         DataTable table = new DataTable ();
885
886                         DataColumn col = new DataColumn ();
887                         col.ColumnName = "Id";
888                         col.DataType = typeof (int);
889                         table.Columns.Add (col);
890
891                         col = new DataColumn ();
892                         col.ColumnName = "Name";
893                         col.DataType = typeof (string);
894                         table.Columns.Add (col);
895                         
896                         DataRow row = table.NewRow ();
897                         row ["Id"] = 147;
898                         row ["name"] = "Abc";
899                         row.RowError = "Error#1";
900                         table.Rows.Add (row);
901
902                         Assert.AreEqual (1, table.GetErrors ().Length, "#A01");
903                         Assert.AreEqual ("Error#1", (table.GetErrors ())[0].RowError, "#A02");
904                 }
905
906                 [Test]
907                 public void NewRowAddedTest ()
908                 {
909                         DataTable table = new DataTable ();
910
911                         DataColumn col = new DataColumn ();
912                         col.ColumnName = "Id";
913                         col.DataType = typeof (int);
914                         table.Columns.Add (col);
915
916                         col = new DataColumn ();
917                         col.ColumnName = "Name";
918                         col.DataType = typeof (string);
919                         table.Columns.Add (col);
920                         
921                         _tableNewRowAddedEventFired = false;
922                         table.TableNewRow += new DataTableNewRowEventHandler (OnTableNewRowAdded);
923                         DataRow row = table.NewRow ();
924                         row ["Id"] = 147;
925                         row ["name"] = "Abc";
926                         table.Rows.Add (row);
927
928                         Assert.IsTrue (_tableNewRowAddedEventFired, "#NewRowAdded Event #01");
929                 }
930
931                 [Test]
932                 public void CloneCopyTest ()
933                 {
934                         DataTable table = new DataTable ();
935                         table.TableName = "Table#1";
936                         DataTable table1 = new DataTable ();
937                         table1.TableName = "Table#2";
938
939                         table.AcceptChanges ();
940
941                         DataSet set = new DataSet ("Data Set#1");
942                         set.DataSetName = "Dataset#1";
943                         set.Tables.Add (table);
944                         set.Tables.Add (table1);
945
946                         DataColumn col = new DataColumn ();
947                         col.ColumnName = "Id";
948                         col.DataType = typeof (int);
949                         table.Columns.Add (col);
950                         UniqueConstraint uc = new UniqueConstraint ("UK1", table.Columns[0] );
951                         table.Constraints.Add (uc);
952
953                         col = new DataColumn ();
954                         col.ColumnName = "Id";
955                         col.DataType = typeof (int);
956                         table1.Columns.Add (col);
957
958                         col = new DataColumn ();
959                         col.ColumnName = "Name";
960                         col.DataType = typeof (string);
961                         table.Columns.Add (col);
962                         
963                         col = new DataColumn ();
964                         col.ColumnName = "Name";
965                         col.DataType = typeof (string);
966                         table1.Columns.Add (col);
967                         DataRow row = table.NewRow ();
968                         row ["Id"] = 147;
969                         row ["name"] = "Abc";
970                         row.RowError = "Error#1";
971                         table.Rows.Add (row);
972
973                         row = table.NewRow ();
974                         row ["Id"] = 47;
975                         row ["name"] = "Efg";
976                         table.Rows.Add (row);
977                         table.AcceptChanges ();
978
979                         table.CaseSensitive = true;
980                         table1.CaseSensitive = true;
981                         table.MinimumCapacity = 100;
982                         table.Prefix = "PrefixNo:1";
983                         table.Namespace = "Namespace#1";
984                         table.DisplayExpression = "Id / Name + (Id * Id)";
985                         DataColumn[] colArray = {table.Columns[0]};
986                         table.PrimaryKey = colArray;
987                         table.ExtendedProperties.Add ("TimeStamp", DateTime.Now);
988
989                         row = table1.NewRow ();
990                         row ["Name"] = "Abc";
991                         row ["Id"] = 147;
992                         table1.Rows.Add (row);
993
994                         row = table1.NewRow ();
995                         row ["Id"] = 47;
996                         row ["Name"] = "Efg";
997                         table1.Rows.Add (row);
998
999                         DataRelation dr = new DataRelation ("DR", table.Columns[0], table1.Columns[0]);
1000                         set.Relations.Add (dr);
1001
1002                         //Testing properties of clone
1003                         DataTable cloneTable = table.Clone ();
1004                         Assert.IsTrue (cloneTable.CaseSensitive, "#A01");
1005                         Assert.AreEqual (0 , cloneTable.ChildRelations.Count, "#A02");
1006                         Assert.AreEqual (0 , cloneTable.ParentRelations.Count, "#A03");
1007                         Assert.AreEqual (2,  cloneTable.Columns.Count, "#A04");
1008                         Assert.AreEqual (1, cloneTable.Constraints.Count, "#A05");
1009                         Assert.AreEqual ("Id / Name + (Id * Id)", cloneTable.DisplayExpression, "#A06");
1010                         Assert.AreEqual (1, cloneTable.ExtendedProperties.Count, "#A07");
1011                         Assert.IsFalse (cloneTable.HasErrors, "#A08");
1012                         Assert.AreEqual (100, cloneTable.MinimumCapacity, "#A10");
1013                         Assert.AreEqual ("Namespace#1", cloneTable.Namespace, "#A11");
1014                         Assert.AreEqual ("PrefixNo:1", cloneTable.Prefix, "#A12");
1015                         Assert.AreEqual ("Id",  cloneTable.PrimaryKey[0].ColumnName, "#A13");
1016                         Assert.AreEqual (0, cloneTable.Rows.Count , "#A14");
1017                         Assert.AreEqual ("Table#1", cloneTable.TableName, "#A15");
1018
1019                         //Testing properties of copy
1020                         DataTable copyTable = table.Copy ();
1021                         Assert.IsTrue (copyTable.CaseSensitive, "#A16");
1022                         Assert.AreEqual (0 , copyTable.ChildRelations.Count, "#A17");
1023                         Assert.AreEqual (0 , copyTable.ParentRelations.Count, "#A18");
1024                         Assert.AreEqual (2,  copyTable.Columns.Count, "#A19");
1025                         Assert.AreEqual (1, copyTable.Constraints.Count, "#A20");
1026                         Assert.AreEqual ("Id / Name + (Id * Id)", copyTable.DisplayExpression, "#A21");
1027                         Assert.AreEqual (1, copyTable.ExtendedProperties.Count, "#A22");
1028                         Assert.IsTrue (copyTable.HasErrors, "#A23");
1029                         Assert.AreEqual (100, copyTable.MinimumCapacity, "#A25");
1030                         Assert.AreEqual ("Namespace#1", copyTable.Namespace, "#A26");
1031                         Assert.AreEqual ("PrefixNo:1", copyTable.Prefix, "#A27");
1032                         Assert.AreEqual ("Id",  copyTable.PrimaryKey[0].ColumnName, "#A28");
1033                         Assert.AreEqual (2, copyTable.Rows.Count, "#A29");
1034                         Assert.AreEqual ("Table#1", copyTable.TableName, "#A30");
1035                 }
1036
1037                 [Test]
1038                 public void CloneExtendedProperties ()
1039                 {
1040                         // bug 668
1041                         DataTable t1 = new DataTable ("t1");
1042                         DataColumn c1 = t1.Columns.Add ("c1");
1043                         c1.ExtendedProperties.Add ("Company", "Xamarin");
1044                         
1045                         DataTable t2 = t1.Clone ();
1046                         Assert.AreEqual ("Xamarin", t1.Columns["c1"].ExtendedProperties["Company"], "CEP1");
1047                         Assert.AreEqual ("Xamarin", t2.Columns["c1"].ExtendedProperties["Company"], "CEP2");
1048                 }
1049         
1050                 [Test]
1051                 [ExpectedException (typeof (EvaluateException))]
1052                 public void CloneExtendedProperties1 ()
1053                 {
1054                         // Xamarin bug 666
1055                         DataTable table1 = new DataTable("Table1") ;
1056
1057                         DataColumn c1 = table1.Columns.Add("c1", typeof(string), "'hello ' + c2") ; /* Should cause an exception */
1058                 }
1059
1060                 [Test]
1061                 public void CloneExtendedProperties2 ()
1062                 {
1063                         // Xamarin bug 666
1064                         DataTable table1 = new  DataTable("Table1") ;
1065
1066                         DataColumn c1 = table1.Columns.Add("c1") ;
1067                         DataColumn c2 = table1.Columns.Add("c2") ;
1068
1069                         c1.Expression = "'hello ' + c2";
1070
1071                         DataTable t2 = table1.Clone(); // this should not cause an exception
1072                 }
1073
1074                 [Test]
1075                 public void LoadDataException ()
1076                 {
1077                         DataTable table = new DataTable ();
1078                         DataColumn col = new DataColumn ();
1079                         col.ColumnName = "Id";
1080                         col.DataType = typeof (int);
1081                         col.DefaultValue = 47;
1082                         table.Columns.Add (col);
1083                         UniqueConstraint uc = new UniqueConstraint ("UK1", table.Columns[0] );
1084                         table.Constraints.Add (uc);
1085
1086                         col = new DataColumn ();
1087                         col.ColumnName = "Name";
1088                         col.DataType = typeof (string);
1089                         col.DefaultValue = "Hello";
1090                         table.Columns.Add (col);
1091
1092                         table.BeginLoadData();
1093                         object[] row = {147, "Abc"};
1094                         DataRow newRow = table.LoadDataRow (row, true);
1095
1096                         object[] row1 = {147, "Efg"};
1097                         DataRow newRow1 = table.LoadDataRow (row1, true);
1098
1099                         object[] row2 = {143, "Hij"};
1100                         DataRow newRow2 = table.LoadDataRow (row2, true);
1101
1102                         try {
1103                                 table.EndLoadData ();
1104                                 Assert.Fail ("#A01");
1105                         } catch (ConstraintException) {
1106                         }
1107                 }
1108
1109                 [Test]
1110                 public void Changes () //To test GetChanges and RejectChanges
1111                 {
1112                         DataTable table = new DataTable ();
1113
1114                         DataColumn col = new DataColumn ();
1115                         col.ColumnName = "Id";
1116                         col.DataType = typeof (int);
1117                         table.Columns.Add (col);
1118                         UniqueConstraint uc = new UniqueConstraint ("UK1", table.Columns[0] );
1119                         table.Constraints.Add (uc);
1120
1121                         col = new DataColumn ();
1122                         col.ColumnName = "Name";
1123                         col.DataType = typeof (string);
1124                         table.Columns.Add (col);
1125
1126                         DataRow row = table.NewRow ();
1127                         row ["Id"] = 147;
1128                         row ["name"] = "Abc";
1129                         table.Rows.Add (row);
1130                         table.AcceptChanges ();
1131
1132                         row = table.NewRow ();
1133                         row ["Id"] = 47;
1134                         row ["name"] = "Efg";
1135                         table.Rows.Add (row);
1136
1137                         //Testing GetChanges
1138                         DataTable changesTable = table.GetChanges ();
1139                         Assert.AreEqual (1, changesTable.Rows.Count, "#A01");
1140                         Assert.AreEqual ("Efg", changesTable.Rows[0]["Name"], "#A02");
1141                         table.AcceptChanges ();
1142                         changesTable = table.GetChanges ();
1143
1144                         try {
1145                                 int cnt = changesTable.Rows.Count;
1146                                 Assert.Fail ();
1147                         } catch (NullReferenceException) {
1148                         }
1149                         
1150                         //Testing RejectChanges
1151                         row = table.NewRow ();
1152                         row ["Id"] = 247;
1153                         row ["name"] = "Hij";
1154                         table.Rows.Add (row);
1155
1156                         (table.Rows [0])["Name"] = "AaBbCc";
1157                         table.RejectChanges ();
1158                         Assert.AreEqual ("Abc" , (table.Rows [0]) ["Name"], "#A03");
1159                         Assert.AreEqual (2, table.Rows.Count, "#A04");
1160                 }
1161
1162                 [Test]
1163                 public void ImportRowTest ()
1164                 {
1165                         // build source table
1166                         DataTable src = new DataTable ();
1167                         src.Columns.Add ("id", typeof (int));
1168                         src.Columns.Add ("name", typeof (string));
1169
1170                         src.PrimaryKey = new DataColumn [] {src.Columns [0]} ;
1171
1172                         src.Rows.Add (new object [] { 1, "mono 1" });
1173                         src.Rows.Add (new object [] { 2, "mono 2" });
1174                         src.Rows.Add (new object [] { 3, "mono 3" });
1175                         src.AcceptChanges ();
1176
1177                         src.Rows [0] [1] = "mono changed 1";  // modify 1st row
1178                         src.Rows [1].Delete ();              // delete 2nd row
1179                         // 3rd row is unchanged
1180                         src.Rows.Add (new object [] { 4, "mono 4" }); // add 4th row
1181
1182                         // build target table
1183                         DataTable target = new DataTable ();
1184                         target.Columns.Add ("id", typeof (int));
1185                         target.Columns.Add ("name", typeof (string));
1186
1187                         target.PrimaryKey = new DataColumn [] {target.Columns [0]} ;
1188
1189                         // import all rows
1190                         target.ImportRow (src.Rows [0]);     // import 1st row
1191                         target.ImportRow (src.Rows [1]);     // import 2nd row
1192                         target.ImportRow (src.Rows [2]);     // import 3rd row
1193                         target.ImportRow (src.Rows [3]);     // import 4th row
1194
1195                         try {
1196                                 target.ImportRow (src.Rows [2]); // import 3rd row again
1197                                 Assert.Fail ("#C1");
1198                         } catch (ConstraintException ex) {
1199                                 // Column 'id' is constrained to be unique.
1200                                 // Value '3' is already present
1201                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#C2");
1202                                 Assert.IsNull (ex.InnerException, "#C3");
1203                                 Assert.IsNotNull (ex.Message, "#C4");
1204                                 Assert.IsTrue (ex.Message.IndexOf ("'id'") != -1, "#C5");
1205                                 Assert.IsTrue (ex.Message.IndexOf ("'3'") != -1, "#C6");
1206                         }
1207
1208                         // check row states
1209                         Assert.AreEqual (src.Rows [0].RowState, target.Rows [0].RowState, "#A1");
1210                         Assert.AreEqual (src.Rows [1].RowState, target.Rows [1].RowState, "#A2");
1211                         Assert.AreEqual (src.Rows [2].RowState, target.Rows [2].RowState, "#A3");
1212                         Assert.AreEqual (src.Rows [3].RowState, target.Rows [3].RowState, "#A4");
1213
1214                         // check for modified row (1st row)
1215                         Assert.AreEqual ((string) src.Rows [0] [1], (string) target.Rows [0] [1], "#B1");
1216                         Assert.AreEqual ((string) src.Rows [0] [1, DataRowVersion.Default], (string) target.Rows [0] [1, DataRowVersion.Default], "#B2");
1217                         Assert.AreEqual ((string) src.Rows [0] [1, DataRowVersion.Original], (string) target.Rows [0] [1, DataRowVersion.Original], "#B3");
1218                         Assert.AreEqual ((string) src.Rows [0] [1, DataRowVersion.Current], (string) target.Rows [0] [1, DataRowVersion.Current], "#B4");
1219                         Assert.IsFalse (target.Rows [0].HasVersion(DataRowVersion.Proposed), "#B5");
1220
1221                         // check for deleted row (2nd row)
1222                         Assert.AreEqual ((string) src.Rows [1] [1, DataRowVersion.Original], (string) target.Rows [1] [1, DataRowVersion.Original], "#C1");
1223
1224                         // check for unchanged row (3rd row)
1225                         Assert.AreEqual ((string) src.Rows [2] [1], (string) target.Rows [2] [1], "#D1");
1226                         Assert.AreEqual ((string) src.Rows [2] [1, DataRowVersion.Default], (string) target.Rows [2] [1, DataRowVersion.Default], "#D2");
1227                         Assert.AreEqual ((string) src.Rows [2] [1, DataRowVersion.Original], (string) target.Rows [2] [1, DataRowVersion.Original], "#D3");
1228                         Assert.AreEqual ((string) src.Rows [2] [1, DataRowVersion.Current], (string) target.Rows [2] [1, DataRowVersion.Current], "#D4");
1229
1230                         // check for newly added row (4th row)
1231                         Assert.AreEqual ((string) src.Rows [3] [1], (string) target.Rows [3] [1], "#E1");
1232                         Assert.AreEqual ((string) src.Rows [3] [1, DataRowVersion.Default], (string) target.Rows [3] [1, DataRowVersion.Default], "#E2");
1233                         Assert.AreEqual ((string) src.Rows [3] [1, DataRowVersion.Current], (string) target.Rows [3] [1, DataRowVersion.Current], "#E3");
1234                 }
1235
1236                 [Test]
1237                 public void ImportRowDetachedTest ()
1238                 {
1239                         DataTable table = new DataTable ();
1240                         DataColumn col = new DataColumn ();
1241                         col.ColumnName = "Id";
1242                         col.DataType = typeof (int);
1243                         table.Columns.Add (col);
1244
1245                         table.PrimaryKey = new DataColumn [] {col};
1246
1247                         col = new DataColumn ();
1248                         col.ColumnName = "Name";
1249                         col.DataType = typeof (string);
1250                         table.Columns.Add (col);
1251
1252                         DataRow row = table.NewRow ();
1253                         row ["Id"] = 147;
1254                         row ["name"] = "Abc";
1255
1256                         // keep silent as ms.net ;-), though this is not useful.
1257                         table.ImportRow (row);
1258
1259                         //if RowState is detached, then dont import the row.
1260                         Assert.AreEqual (0, table.Rows.Count, "#1");
1261                 }
1262
1263                 [Test]
1264                 public void ImportRowDeletedTest ()
1265                 {
1266                         DataTable table = new DataTable ();
1267                         table.Columns.Add ("col", typeof (int));
1268                         table.Columns.Add ("col1", typeof (int));
1269
1270                         DataRow row = table.Rows.Add (new object[] {1,2});
1271                         table.PrimaryKey = new DataColumn[] {table.Columns[0]};
1272                         table.AcceptChanges ();
1273
1274                         // If row is in Deleted state, then ImportRow loads the
1275                         // row.
1276                         row.Delete ();
1277                         table.ImportRow (row);
1278                         Assert.AreEqual (2, table.Rows.Count, "#A1");
1279
1280                         // Both the deleted rows shud be now gone
1281                         table.AcceptChanges ();
1282                         Assert.AreEqual (0, table.Rows.Count, "#A2");
1283
1284                         //just add another row
1285                         row = table.Rows.Add (new object[] {1,2});
1286                         // no exception shud be thrown
1287                         table.AcceptChanges ();
1288
1289                         // If row is in Deleted state, then ImportRow loads the
1290                         // row and validate only on RejectChanges
1291                         row.Delete ();
1292                         table.ImportRow (row);
1293                         Assert.AreEqual (2, table.Rows.Count, "#A3");
1294                         Assert.AreEqual (DataRowState.Deleted, table.Rows[1].RowState, "#A4");
1295
1296                         try {
1297                                 table.RejectChanges ();
1298                                 Assert.Fail ("#B1");
1299                         } catch (ConstraintException ex) {
1300                                 // Column 'col' is constrained to be unique.
1301                                 // Value '1' is already present
1302                                 Assert.AreEqual (typeof (ConstraintException), ex.GetType (), "#B2");
1303                                 Assert.IsNull (ex.InnerException, "#B3");
1304                                 Assert.IsNotNull (ex.Message, "#B4");
1305                                 Assert.IsTrue (ex.Message.IndexOf ("'col'") != -1, "#B5");
1306                                 Assert.IsTrue (ex.Message.IndexOf ("'1'") != -1, "#B6");
1307                         }
1308                 }
1309                 
1310 #if NET_4_0
1311                 [Test]
1312                 public void ImportRowTypeChangeTest ()
1313                 {
1314                         // this is from http://bugzilla.xamarin.com/show_bug.cgi?id=2926
1315         
1316                         Type [] types = new Type [] { typeof (string), typeof (sbyte), typeof (byte), typeof (short), typeof (ushort), typeof (int), typeof (uint), typeof (long), typeof (ulong), typeof (float), typeof (double), typeof (char), typeof (decimal), typeof (DateTime) };
1317                         object [] values = new object [] { "1", (sbyte) 1, (byte) 2, (short) 3, (ushort) 4, (int) 5, (uint) 6, (long) 7, (ulong) 8, (float) 9, (double) 10, 'z', (decimal) 13, new DateTime (24) };
1318                         int length = types.Length;
1319         
1320                         HashSet<Tuple<Type, Type>> invalid = new HashSet<Tuple<Type, Type>> () {
1321                                 Tuple.Create (typeof (string), typeof (DateTime)), 
1322                                 Tuple.Create (typeof (sbyte), typeof (DateTime)), 
1323                                 Tuple.Create (typeof (byte), typeof (DateTime)), 
1324                                 Tuple.Create (typeof (short), typeof (DateTime)), 
1325                                 Tuple.Create (typeof (ushort), typeof (DateTime)), 
1326                                 Tuple.Create (typeof (int), typeof (DateTime)), 
1327                                 Tuple.Create (typeof (uint), typeof (DateTime)), 
1328                                 Tuple.Create (typeof (long), typeof (DateTime)), 
1329                                 Tuple.Create (typeof (ulong), typeof (DateTime)), 
1330                                 Tuple.Create (typeof (float), typeof (char)), 
1331                                 Tuple.Create (typeof (float), typeof (DateTime)), 
1332                                 Tuple.Create (typeof (double), typeof (char)), 
1333                                 Tuple.Create (typeof (double), typeof (DateTime)), 
1334                                 Tuple.Create (typeof (char), typeof (float)), 
1335                                 Tuple.Create (typeof (char), typeof (double)), 
1336                                 Tuple.Create (typeof (char), typeof (decimal)), 
1337                                 Tuple.Create (typeof (char), typeof (DateTime)), 
1338                                 Tuple.Create (typeof (Decimal), typeof (char)), 
1339                                 Tuple.Create (typeof (Decimal), typeof (DateTime)), 
1340                                 Tuple.Create (typeof (DateTime), typeof (sbyte)), 
1341                                 Tuple.Create (typeof (DateTime), typeof (byte)), 
1342                                 Tuple.Create (typeof (DateTime), typeof (short)), 
1343                                 Tuple.Create (typeof (DateTime), typeof (ushort)), 
1344                                 Tuple.Create (typeof (DateTime), typeof (int)), 
1345                                 Tuple.Create (typeof (DateTime), typeof (uint)), 
1346                                 Tuple.Create (typeof (DateTime), typeof (long)), 
1347                                 Tuple.Create (typeof (DateTime), typeof (ulong)), 
1348                                 Tuple.Create (typeof (DateTime), typeof (float)), 
1349                                 Tuple.Create (typeof (DateTime), typeof (double)), 
1350                                 Tuple.Create (typeof (DateTime), typeof (char)), 
1351                                 Tuple.Create (typeof (DateTime), typeof (decimal)), 
1352                         };
1353         
1354                         for (int a = 0; a < length; a++) {
1355                                 for (int b = 0; b < length; b++) {
1356                                         DataSet ds = new DataSet ();
1357                                         DataTable dt1 = ds.Tables.Add ("T1");
1358                                         DataTable dt2 = ds.Tables.Add ("T2");
1359         
1360                                         string name = "C-" + types [a].Name + "-to-" + types [b].Name;
1361                                         dt1.Columns.Add (name, types [a]);
1362                                         dt2.Columns.Add (name, types [b]);
1363         
1364                                         DataRow r1 = dt1.NewRow ();
1365                                         dt1.Rows.Add (r1);
1366         
1367                                         r1 [0] = values [a];
1368         
1369                                         if (invalid.Contains (Tuple.Create (types [a], types [b]))) {
1370                                                 try {
1371                                                         dt2.ImportRow (r1);
1372                                                         Assert.Fail ("#B: " + name + " expected ArgumentException");
1373                                                 } catch /*(ArgumentException)*/ {
1374                                                         continue;
1375                                                 }
1376                                         } else {
1377                                                 dt2.ImportRow (r1);
1378                                                 DataRow r2 = dt2.Rows [0];
1379                                                 Assert.AreEqual (types [b], r2 [0].GetType (), "#A: " + name);
1380                                         }
1381                                 }
1382                         }
1383                 }
1384 #endif
1385                         
1386                 [Test]
1387                 public void ClearReset () //To test Clear and Reset methods
1388                 {
1389                         DataTable table = new DataTable ("table");
1390                         DataTable table1 = new DataTable ("table1");
1391
1392                         DataSet set = new DataSet ();
1393                         set.Tables.Add (table);
1394                         set.Tables.Add (table1);
1395
1396                         table.Columns.Add ("Id", typeof (int));
1397                         table.Columns.Add ("Name", typeof (string));
1398                         table.Constraints.Add (new UniqueConstraint ("UK1", table.Columns [0]));
1399                         table.CaseSensitive = false;
1400
1401                         table1.Columns.Add ("Id", typeof (int));
1402                         table1.Columns.Add ("Name", typeof (string));
1403
1404                         DataRelation dr = new DataRelation ("DR", table.Columns[0], table1.Columns[0]);
1405                         set.Relations.Add (dr);
1406
1407                         DataRow row = table.NewRow ();
1408                         row ["Id"] = 147;
1409                         row ["name"] = "Roopa";
1410                         table.Rows.Add (row);
1411
1412                         row = table.NewRow ();
1413                         row ["Id"] = 47;
1414                         row ["Name"] = "roopa";
1415                         table.Rows.Add (row);
1416
1417                         Assert.AreEqual (2, table.Rows.Count);
1418                         Assert.AreEqual (1, table.ChildRelations.Count);
1419                         try {
1420                                 table.Reset ();
1421                                 Assert.Fail ("#A01, should have thrown ArgumentException");
1422                         } catch (ArgumentException) {
1423                         }
1424
1425                         Assert.AreEqual (0, table.Rows.Count, "#CT01");
1426                         Assert.AreEqual (0, table.ChildRelations.Count, "#CT02");
1427                         Assert.AreEqual (0, table.ParentRelations.Count, "#CT03");
1428                         Assert.AreEqual (0, table.Constraints.Count, "#CT04");
1429
1430                         table1.Reset ();
1431                         Assert.AreEqual (0, table1.Rows.Count, "#A05");
1432                         Assert.AreEqual (0, table1.Constraints.Count, "#A06");
1433                         Assert.AreEqual (0, table1.ParentRelations.Count, "#A07");
1434                 
1435                         // clear test
1436                         table.Clear ();
1437                         Assert.AreEqual (0, table.Rows.Count, "#A08");
1438                         Assert.AreEqual (0, table.Constraints.Count, "#A09");
1439                         Assert.AreEqual (0, table.ChildRelations.Count, "#A10");
1440                 }
1441
1442                 [Test]
1443                 public void ClearTest ()
1444                 {
1445                         DataTable table = new DataTable ("test");
1446                         table.Columns.Add ("id", typeof (int));
1447                         table.Columns.Add ("name", typeof (string));
1448
1449                         table.PrimaryKey = new DataColumn [] { table.Columns [0] } ;
1450
1451                         table.Rows.Add (new object [] { 1, "mono 1" });
1452                         table.Rows.Add (new object [] { 2, "mono 2" });
1453                         table.Rows.Add (new object [] { 3, "mono 3" });
1454                         table.Rows.Add (new object [] { 4, "mono 4" });
1455
1456                         table.AcceptChanges ();
1457                         _tableClearedEventFired = false;
1458                         table.TableCleared += new DataTableClearEventHandler (OnTableCleared);
1459                         _tableClearingEventFired = false;
1460                         table.TableClearing += new DataTableClearEventHandler (OnTableClearing);
1461
1462                         table.Clear ();
1463                         Assert.IsTrue (_tableClearingEventFired, "#3 should have fired cleared event");
1464                         Assert.IsTrue (_tableClearedEventFired, "#0 should have fired cleared event");
1465
1466                         DataRow r = table.Rows.Find (1);
1467                         Assert.IsTrue (r == null, "#1 should have cleared");
1468
1469                         // try adding new row. indexes should have cleared
1470                         table.Rows.Add (new object [] { 2, "mono 2" });
1471                         Assert.AreEqual (1, table.Rows.Count, "#2 should add row");
1472                 }
1473
1474                 private bool _tableClearedEventFired;
1475                 private void OnTableCleared (object src, DataTableClearEventArgs args)
1476                 {
1477                         _tableClearedEventFired = true;
1478                 }
1479
1480                 private bool _tableClearingEventFired;
1481                 private void OnTableClearing (object src, DataTableClearEventArgs args)
1482                 {
1483                         _tableClearingEventFired = true;
1484                 }
1485
1486                 private bool _tableNewRowAddedEventFired;
1487                 private void OnTableNewRowAdded (object src, DataTableNewRowEventArgs args)
1488                 {
1489                         _tableNewRowAddedEventFired = true;
1490                 }
1491
1492                 [Test]
1493                 public void TestWriteXmlSchema1 ()
1494                 {
1495                         DataTable dt = new DataTable("TestWriteXmlSchema");
1496                         dt.Columns.Add("Col1", typeof(int));
1497                         dt.Columns.Add("Col2", typeof(int));
1498                         DataRow dr = dt.NewRow();
1499                         dr[0] = 10;
1500                         dr[1] = 20;
1501                         dt.Rows.Add (dr);
1502                         DataTable dt1 = new DataTable("HelloWorld");
1503                         dt1.Columns.Add("T1", typeof(int));
1504                         dt1.Columns.Add("T2", typeof(int));
1505                         DataRow dr1 = dt1.NewRow();
1506                         dr1[0] = 10;
1507                         dr1[1] = 20;
1508                         dt1.Rows.Add(dr1);
1509                         TextWriter writer = new StringWriter ();
1510                         dt.WriteXmlSchema (writer);
1511                         string TextString = writer.ToString ();
1512                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
1513                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1514                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
1515
1516                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1517                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1518                         Assert.AreEqual ("<xs:schema id=\"NewDataSet\" xmlns=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">", substring, "test#02");
1519                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1520                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1521                         Assert.AreEqual ("  <xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"TestWriteXmlSchema\" msdata:UseCurrentLocale=\"true\">", substring, "test#03");
1522                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1523                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1524                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
1525
1526                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1527                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1528                         Assert.AreEqual ("      <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">", substring, "test#05");
1529
1530                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1531                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1532                         Assert.AreEqual ("        <xs:element name=\"TestWriteXmlSchema\">", substring, "test#06");
1533
1534                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1535                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1536                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
1537
1538                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1539                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1540                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
1541                         
1542                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1543                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1544                         Assert.AreEqual ("              <xs:element name=\"Col1\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#09");
1545
1546                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1547                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1548                         Assert.AreEqual ("              <xs:element name=\"Col2\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#10");
1549
1550                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1551                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1552                         Assert.AreEqual ("            </xs:sequence>", substring, "test#11");
1553
1554                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1555                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1556                         Assert.AreEqual ("          </xs:complexType>", substring, "test#12");
1557
1558                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1559                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1560                         Assert.AreEqual ("        </xs:element>", substring, "test#13");
1561
1562                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1563                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1564                         Assert.AreEqual ("      </xs:choice>", substring, "test#14");
1565
1566                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1567                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1568                         Assert.AreEqual ("    </xs:complexType>", substring, "test#15");
1569
1570                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1571                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1572                         Assert.AreEqual ("  </xs:element>", substring, "test#16");
1573                         Assert.AreEqual ("</xs:schema>", TextString, "test#17");
1574                 }
1575
1576                 [Test]
1577                 public void TestWriteXmlSchema2()
1578                 {
1579                         DataTable dt = new DataTable("TestWriteXmlSchema");
1580                         dt.Columns.Add("Col1", typeof(int));
1581                         dt.Columns.Add("Col2", typeof(int));
1582                         DataRow dr = dt.NewRow();
1583                         dr[0] = 10;
1584                         dr[1] = 20;
1585                         dt.Rows.Add (dr);
1586                         DataTable dt1 = new DataTable("HelloWorld");
1587                         dt1.Columns.Add("T1", typeof(int));
1588                         dt1.Columns.Add("T2", typeof(int));
1589                         DataRow dr1 = dt1.NewRow();
1590                         dr1[0] = 10;
1591                         dr1[1] = 20;
1592                         dt1.Rows.Add(dr1);
1593                         DataSet ds = new DataSet();
1594                         ds.Tables.Add(dt);
1595                         ds.Tables.Add(dt1);
1596                         DataRelation rel = new DataRelation("Relation1", dt.Columns["Col1"], dt1.Columns["T1"]);
1597                         ds.Relations.Add(rel);
1598                         TextWriter writer = new StringWriter ();
1599                         dt.WriteXmlSchema (writer);
1600                         string TextString = writer.ToString ();
1601                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
1602                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1603                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
1604
1605                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1606                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1607                         Assert.AreEqual ("<xs:schema id=\"NewDataSet\" xmlns=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">", substring, "test#02");
1608                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1609                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1610                         Assert.AreEqual ("  <xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"TestWriteXmlSchema\" msdata:UseCurrentLocale=\"true\">", substring, "test#03");
1611                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1612                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1613                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
1614
1615                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1616                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1617                         Assert.AreEqual ("      <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">", substring, "test#05");
1618
1619                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1620                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1621                         Assert.AreEqual ("        <xs:element name=\"TestWriteXmlSchema\">", substring, "test#06");
1622
1623                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1624                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1625                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
1626
1627                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1628                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1629                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
1630
1631                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1632                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1633                         Assert.AreEqual ("              <xs:element name=\"Col1\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#09");
1634
1635                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1636                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1637                         Assert.AreEqual ("              <xs:element name=\"Col2\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#10");
1638
1639                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1640                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1641                         Assert.AreEqual ("            </xs:sequence>", substring, "test#11");
1642
1643                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1644                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1645                         Assert.AreEqual ("          </xs:complexType>", substring, "test#12");
1646
1647                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1648                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1649                         Assert.AreEqual ("        </xs:element>", substring, "test#13");
1650
1651                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1652                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1653                         Assert.AreEqual ("      </xs:choice>", substring, "test#14");
1654
1655                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1656                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1657                         Assert.AreEqual ("    </xs:complexType>", substring, "test#15");
1658
1659                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1660                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1661                         Assert.AreEqual ("    <xs:unique name=\"Constraint1\">", substring, "test#16");
1662
1663                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1664                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1665                         Assert.AreEqual ("      <xs:selector xpath=\".//TestWriteXmlSchema\" />", substring, "test#17");
1666
1667                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1668                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1669                         Assert.AreEqual ("      <xs:field xpath=\"Col1\" />", substring, "test#18");
1670
1671                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1672                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1673                         Assert.AreEqual ("    </xs:unique>", substring, "test#19");
1674
1675                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1676                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1677                         Assert.AreEqual ("  </xs:element>", substring, "test#20");
1678                         Assert.AreEqual ("</xs:schema>", TextString, "test#21");
1679                 }
1680
1681                 [Test]
1682                 public void TestWriteXmlSchema3()
1683                 {
1684                         DataTable dt = new DataTable("TestWriteXmlSchema");
1685                         dt.Columns.Add("Col1", typeof(int));
1686                         dt.Columns.Add("Col2", typeof(int));
1687                         DataRow dr = dt.NewRow();
1688                         dr[0] = 10;
1689                         dr[1] = 20;
1690                         dt.Rows.Add (dr);
1691                         DataTable dt1 = new DataTable("HelloWorld");
1692                         dt1.Columns.Add("T1", typeof(int));
1693                         dt1.Columns.Add("T2", typeof(int));
1694                         DataRow dr1 = dt1.NewRow();
1695                         dr1[0] = 10;
1696                         dr1[1] = 20;
1697                         dt1.Rows.Add(dr1);
1698                         DataSet ds = new DataSet();
1699                         ds.Tables.Add(dt);
1700                         ds.Tables.Add(dt1);
1701                         DataRelation rel = new DataRelation("Relation1", dt.Columns["Col1"], dt1.Columns["T1"]);
1702                         ds.Relations.Add(rel);
1703                         TextWriter writer = new StringWriter ();
1704                         dt.WriteXmlSchema (writer, true);
1705                         string TextString = writer.ToString ();
1706                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
1707                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1708                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
1709
1710                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1711                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1712                         Assert.AreEqual ("<xs:schema id=\"NewDataSet\" xmlns=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">", substring, "test#02");
1713                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1714                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1715                         Assert.AreEqual ("  <xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"TestWriteXmlSchema\" msdata:UseCurrentLocale=\"true\">", substring, "test#03");
1716                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1717                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1718                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
1719
1720                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1721                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1722                         Assert.AreEqual ("      <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">", substring, "test#05");
1723
1724                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1725                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1726                         Assert.AreEqual ("        <xs:element name=\"TestWriteXmlSchema\">", substring, "test#06");
1727
1728                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1729                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1730                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
1731
1732                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1733                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1734                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
1735
1736                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1737                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1738                         Assert.AreEqual ("              <xs:element name=\"Col1\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#09");
1739
1740                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1741                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1742                         Assert.AreEqual ("              <xs:element name=\"Col2\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#10");
1743
1744                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1745                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1746                         Assert.AreEqual ("            </xs:sequence>", substring, "test#11");
1747
1748                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1749                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1750                         Assert.AreEqual ("          </xs:complexType>", substring, "test#12");
1751
1752                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1753                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1754                         Assert.AreEqual ("        </xs:element>", substring, "test#13");
1755
1756                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1757                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1758                         Assert.AreEqual ("        <xs:element name=\"HelloWorld\">", substring, "test#14");
1759
1760                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1761                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1762                         Assert.AreEqual ("          <xs:complexType>", substring, "test#15");
1763
1764                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1765                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1766                         Assert.AreEqual ("            <xs:sequence>", substring, "test#16");
1767
1768                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1769                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1770                         Assert.AreEqual ("              <xs:element name=\"T1\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#17");
1771
1772                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1773                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1774                         Assert.AreEqual ("              <xs:element name=\"T2\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#18");
1775
1776                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1777                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1778                         Assert.AreEqual ("            </xs:sequence>", substring, "test#19");
1779
1780                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1781                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1782                         Assert.AreEqual ("          </xs:complexType>", substring, "test#20");
1783
1784                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1785                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1786                         Assert.AreEqual ("        </xs:element>", substring, "test#21");
1787
1788                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1789                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1790                         Assert.AreEqual ("      </xs:choice>", substring, "test#22");
1791
1792                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1793                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1794                         Assert.AreEqual ("    </xs:complexType>", substring, "test#23");
1795
1796                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1797                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1798                         Assert.AreEqual ("    <xs:unique name=\"Constraint1\">", substring, "test#24");
1799
1800                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1801                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1802                         Assert.AreEqual ("      <xs:selector xpath=\".//TestWriteXmlSchema\" />", substring, "test#25");
1803
1804                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1805                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1806                         Assert.AreEqual ("      <xs:field xpath=\"Col1\" />", substring, "test#26");
1807
1808                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1809                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1810                         Assert.AreEqual ("    </xs:unique>", substring, "test#27");
1811
1812                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1813                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1814                         Assert.AreEqual ("    <xs:keyref name=\"Relation1\" refer=\"Constraint1\">", substring, "test#28");
1815
1816                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1817                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1818                         Assert.AreEqual ("      <xs:selector xpath=\".//HelloWorld\" />", substring, "test#29");
1819
1820                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1821                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1822                         Assert.AreEqual ("      <xs:field xpath=\"T1\" />", substring, "test#30");
1823
1824                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1825                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1826                         Assert.AreEqual ("    </xs:keyref>", substring, "test#31");
1827
1828                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1829                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1830                         Assert.AreEqual ("  </xs:element>", substring, "test#32");
1831                         Assert.AreEqual ("</xs:schema>", TextString, "test#33");
1832                 }
1833
1834                 [Test]
1835                 public void Serialize ()
1836                 {
1837                         MemoryStream fs = new MemoryStream ();
1838
1839                         // Construct a BinaryFormatter and use it 
1840                         // to serialize the data to the stream.
1841                         BinaryFormatter formatter = new BinaryFormatter();
1842
1843                         // Create an array with multiple elements refering to 
1844                         // the one Singleton object.
1845                         DataTable dt = new DataTable();
1846
1847                         dt.Columns.Add(new DataColumn("Id", typeof(string)));
1848                         dt.Columns.Add(new DataColumn("ContactName", typeof(string)));
1849                         dt.Columns.Add(new DataColumn("ContactTitle", typeof(string)));
1850                         dt.Columns.Add(new DataColumn("ContactAreaCode", typeof(string)));
1851                         dt.Columns.Add(new DataColumn("ContactPhone", typeof(string)));
1852
1853                         DataRow loRowToAdd;
1854                         loRowToAdd = dt.NewRow();
1855                         loRowToAdd[0] = "a";
1856                         loRowToAdd[1] = "b";
1857                         loRowToAdd[2] = "c";
1858                         loRowToAdd[3] = "d";
1859                         loRowToAdd[4] = "e";
1860                         dt.Rows.Add(loRowToAdd);
1861
1862                         DataTable[] dtarr = new DataTable[] {dt}; 
1863
1864                         // Serialize the array elements.
1865                         formatter.Serialize(fs, dtarr);
1866
1867                         // Deserialize the array elements.
1868                         fs.Position = 0;
1869                         DataTable[] a2 = (DataTable[]) formatter.Deserialize(fs);
1870
1871                         DataSet ds = new DataSet();
1872                         ds.Tables.Add(a2[0]);
1873
1874                         StringWriter sw = new StringWriter ();
1875                         ds.WriteXml(sw);
1876                         XmlDocument doc = new XmlDocument ();
1877                         doc.LoadXml (sw.ToString ());
1878                         Assert.AreEqual (5, doc.DocumentElement.FirstChild.ChildNodes.Count);
1879                 }
1880
1881                 [Test]
1882                 public void SetPrimaryKeyAssertsNonNull ()
1883                 {
1884                         DataTable dt = new DataTable ("table");
1885                         dt.Columns.Add ("col1");
1886                         dt.Columns.Add ("col2");
1887                         dt.Constraints.Add (new UniqueConstraint (dt.Columns [0]));
1888                         dt.Rows.Add (new object [] {1, 3});
1889                         dt.Rows.Add (new object [] {DBNull.Value, 3});
1890
1891                         try {
1892                                 dt.PrimaryKey = new DataColumn [] { dt.Columns [0] };
1893                                 Assert.Fail ("#1");
1894                         } catch (DataException) {
1895                         }
1896                 }
1897
1898                 [Test]
1899                 public void PrimaryKeyColumnChecksNonNull ()
1900                 {
1901                         DataTable dt = new DataTable ("table");
1902                         dt.Columns.Add ("col1");
1903                         dt.Columns.Add ("col2");
1904                         dt.Constraints.Add (new UniqueConstraint (dt.Columns [0]));
1905                         dt.PrimaryKey = new DataColumn [] {dt.Columns [0]};
1906                         dt.Rows.Add (new object [] {1, 3});
1907
1908                         try {
1909                                 dt.Rows.Add (new object [] { DBNull.Value, 3 });
1910                                 Assert.Fail ("#1");
1911                         } catch (NoNullAllowedException) {
1912                         }
1913                 }
1914
1915                 [Test]
1916                 public void PrimaryKey_CheckSetsAllowDBNull ()
1917                 {
1918                         DataTable table = new DataTable ();
1919                         DataColumn col1 = table.Columns.Add ("col1", typeof (int));
1920                         DataColumn col2 = table.Columns.Add ("col2", typeof (int));
1921         
1922                         Assert.IsTrue (col1.AllowDBNull, "#1" );
1923                         Assert.IsTrue (col2.AllowDBNull, "#2" );
1924                         Assert.IsFalse (col2.Unique, "#3" );
1925                         Assert.IsFalse (col2.Unique, "#4" );
1926
1927                         table.PrimaryKey = new DataColumn[] {col1,col2};
1928                         Assert.IsFalse (col1.AllowDBNull, "#5" );
1929                         Assert.IsFalse (col2.AllowDBNull, "#6" );
1930                         // LAMESPEC or bug ?? 
1931                         Assert.IsFalse (col1.Unique, "#7" );
1932                         Assert.IsFalse (col2.Unique, "#8" );
1933                 }
1934
1935                 void RowChanging (object o, DataRowChangeEventArgs e)
1936                 {
1937                         Assert.AreEqual (rowChangingExpectedAction, e.Action, "changing.Action");
1938                         rowChangingRowChanging = true;
1939                 }
1940
1941                 void RowChanged (object o, DataRowChangeEventArgs e)
1942                 {
1943                         Assert.AreEqual (rowChangingExpectedAction, e.Action, "changed.Action");
1944                         rowChangingRowChanged = true;
1945                 }
1946
1947                 bool rowChangingRowChanging, rowChangingRowChanged;
1948                 DataRowAction rowChangingExpectedAction;
1949
1950                 [Test]
1951                 public void RowChanging ()
1952                 {
1953                         DataTable dt = new DataTable ("table");
1954                         dt.Columns.Add ("col1");
1955                         dt.Columns.Add ("col2");
1956                         dt.RowChanging += new DataRowChangeEventHandler (RowChanging);
1957                         dt.RowChanged += new DataRowChangeEventHandler (RowChanged);
1958                         rowChangingExpectedAction = DataRowAction.Add;
1959                         dt.Rows.Add (new object [] {1, 2});
1960                         Assert.IsTrue (rowChangingRowChanging, "changing,Added");
1961                         Assert.IsTrue (rowChangingRowChanged, "changed,Added");
1962                         rowChangingExpectedAction = DataRowAction.Change;
1963                         dt.Rows [0] [0] = 2;
1964                         Assert.IsTrue (rowChangingRowChanging, "changing,Changed");
1965                         Assert.IsTrue (rowChangingRowChanged, "changed,Changed");
1966                 }
1967
1968                 [Test]
1969                 public void CloneSubClassTest()
1970                 {
1971                         MyDataTable dt1 = new MyDataTable();
1972                         MyDataTable dt = (MyDataTable)(dt1.Clone());
1973                         Assert.AreEqual (2, MyDataTable.count, "A#01");
1974                 }
1975
1976                 DataRowAction rowActionChanging = DataRowAction.Nothing;
1977                 DataRowAction rowActionChanged  = DataRowAction.Nothing;
1978                 [Test]
1979                 public void AcceptChangesTest ()
1980                 {
1981                         DataTable dt = new DataTable ("test");
1982                         dt.Columns.Add ("id", typeof (int));
1983                         dt.Columns.Add ("name", typeof (string));
1984
1985                         dt.Rows.Add (new object [] { 1, "mono 1" });
1986
1987                         dt.RowChanged  += new DataRowChangeEventHandler (OnRowChanged);
1988                         dt.RowChanging += new DataRowChangeEventHandler (OnRowChanging);
1989
1990                         try {
1991                                 rowActionChanged = rowActionChanging = DataRowAction.Nothing;
1992                                 dt.AcceptChanges ();
1993
1994                                 Assert.AreEqual (DataRowAction.Commit, rowActionChanging,
1995                                                  "#1 should have fired event and set action to commit");
1996                                 Assert.AreEqual (DataRowAction.Commit, rowActionChanged,
1997                                                  "#2 should have fired event and set action to commit");
1998                         } finally {
1999                                 dt.RowChanged  -= new DataRowChangeEventHandler (OnRowChanged);
2000                                 dt.RowChanging -= new DataRowChangeEventHandler (OnRowChanging);
2001                         }
2002                 }
2003
2004                 [Test]
2005                 [ExpectedException (typeof (ArgumentException))]
2006                 public void ColumnObjectTypeTest() {
2007                         DataTable dt = new DataTable();
2008                         dt.Columns.Add("Series Label", typeof(SqlInt32));
2009                         dt.Rows.Add(new object[] {"sss"});
2010                 }
2011
2012                 private bool tableInitialized;
2013                 [Test]
2014                 public void TableInitializedEventTest1 ()
2015                 {
2016                         DataTable dt = new DataTable();
2017                         tableInitialized = false;
2018                         dt.Initialized += new EventHandler (OnTableInitialized);
2019                         dt.Columns.Add("Series Label", typeof(SqlInt32));
2020                         dt.Rows.Add(new object[] {123});
2021                         Assert.IsFalse (tableInitialized, "TableInitialized #01");
2022                         dt.Initialized -= new EventHandler (OnTableInitialized);
2023                 }
2024
2025                 [Test]
2026                 public void TableInitializedEventTest2 ()
2027                 {
2028                         DataTable dt = new DataTable();
2029                         dt.BeginInit ();
2030                         tableInitialized = false;
2031                         dt.Initialized += new EventHandler (OnTableInitialized);
2032                         dt.Columns.Add("Series Label", typeof(SqlInt32));
2033                         dt.Rows.Add(new object[] {123});
2034                         dt.EndInit ();
2035                         dt.Initialized -= new EventHandler (OnTableInitialized);
2036                         Assert.IsTrue (tableInitialized, "TableInitialized #02");
2037                 }
2038
2039                 [Test]
2040                 public void TableInitializedEventTest3 ()
2041                 {
2042                         DataTable dt = new DataTable();
2043                         tableInitialized = true;
2044                         dt.Initialized += new EventHandler (OnTableInitialized);
2045                         dt.Columns.Add("Series Label", typeof(SqlInt32));
2046                         dt.Rows.Add(new object[] {123});
2047                         Assert.AreEqual (tableInitialized, dt.IsInitialized, "TableInitialized #03");
2048                         dt.Initialized -= new EventHandler (OnTableInitialized);
2049                 }
2050
2051                 [Test]
2052                 public void TableInitializedEventTest4 ()
2053                 {
2054                         DataTable dt = new DataTable();
2055                         Assert.IsTrue (dt.IsInitialized, "TableInitialized #04");
2056                         dt.BeginInit ();
2057                         tableInitialized = false;
2058                         dt.Initialized += new EventHandler (OnTableInitialized);
2059                         dt.Columns.Add("Series Label", typeof(SqlInt32));
2060                         dt.Rows.Add(new object[] {123});
2061                         Assert.IsFalse (dt.IsInitialized, "TableInitialized #05");
2062                         dt.EndInit ();
2063                         Assert.IsTrue (dt.IsInitialized, "TableInitialized #06");
2064                         Assert.IsTrue (tableInitialized, "TableInitialized #07");
2065                         dt.Initialized -= new EventHandler (OnTableInitialized);
2066                 }
2067
2068                 private void OnTableInitialized (object src, EventArgs args)
2069                 {
2070                         tableInitialized = true;
2071                 }
2072
2073                 public void OnRowChanging (object src, DataRowChangeEventArgs args)
2074                 {
2075                         rowActionChanging = args.Action;
2076                 }
2077
2078                 public void OnRowChanged (object src, DataRowChangeEventArgs args)
2079                 {
2080                         rowActionChanged = args.Action;
2081                 }
2082
2083                 private DataTable dt;
2084                 private void localSetup () {
2085                         dt = new DataTable ("test");
2086                         dt.Columns.Add ("id", typeof (int));
2087                         dt.Columns.Add ("name", typeof (string));
2088                         dt.PrimaryKey = new DataColumn[] { dt.Columns["id"] };
2089
2090                         dt.Rows.Add (new object[] { 1, "mono 1" });
2091                         dt.Rows.Add (new object[] { 2, "mono 2" });
2092                         dt.Rows.Add (new object[] { 3, "mono 3" });
2093
2094                         dt.AcceptChanges ();
2095                 }
2096
2097                 #region DataTable.CreateDataReader Tests
2098
2099                 [Test]
2100                 public void CreateDataReader1 ()
2101                 {
2102                         localSetup ();
2103                         DataTableReader dtr = dt.CreateDataReader ();
2104                         Assert.IsTrue (dtr.HasRows, "HasRows");
2105                         Assert.AreEqual (dt.Columns.Count, dtr.FieldCount, "CountCols");
2106                         int ri = 0;
2107                         while (dtr.Read ()) {
2108                                 for (int i = 0; i < dtr.FieldCount; i++) {
2109                                         Assert.AreEqual (dt.Rows[ri][i], dtr[i], "RowData-" + ri + "-" + i);
2110                                 }
2111                                 ri++;
2112                         }
2113                 }
2114
2115                 [Test]
2116                 public void CreateDataReader2 ()
2117                 {
2118                         localSetup ();
2119                         DataTableReader dtr = dt.CreateDataReader ();
2120                         Assert.IsTrue (dtr.HasRows, "HasRows");
2121                         Assert.AreEqual (dt.Columns.Count, dtr.FieldCount, "CountCols");
2122                         dtr.Read ();
2123                         Assert.AreEqual (1, dtr[0], "RowData0-0");
2124                         Assert.AreEqual ("mono 1", dtr[1], "RowData0-1");
2125                         dtr.Read ();
2126                         Assert.AreEqual (2, dtr[0], "RowData1-0");
2127                         Assert.AreEqual ("mono 2", dtr[1], "RowData1-1");
2128                         dtr.Read ();
2129                         Assert.AreEqual (3, dtr[0], "RowData2-0");
2130                         Assert.AreEqual ("mono 3", dtr[1], "RowData2-1");
2131                 }
2132
2133                 #endregion // DataTable.CreateDataReader Tests
2134
2135                 #region DataTable.Load Tests
2136
2137                 [Test]
2138                 public void Load_Basic ()
2139                 {
2140                         localSetup ();
2141                         DataTable dtLoad = new DataTable ("LoadBasic");
2142                         dtLoad.Columns.Add ("id", typeof (int));
2143                         dtLoad.Columns.Add ("name", typeof (string));
2144                         dtLoad.Columns["id"].ReadOnly = true;
2145                         dtLoad.Columns["name"].ReadOnly = true;
2146                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2147                         dtLoad.Rows.Add (new object[] { 1, "load 1" });
2148                         dtLoad.Rows.Add (new object[] { 2, "load 2" });
2149                         dtLoad.Rows.Add (new object[] { 3, "load 3" });
2150                         dtLoad.AcceptChanges ();
2151                         DataTableReader dtr = dt.CreateDataReader ();
2152                         dtLoad.Load (dtr);
2153                         Assert.AreEqual (2, dtLoad.Columns.Count, "NColumns");
2154                         Assert.AreEqual (3, dtLoad.Rows.Count, "NRows");
2155                         Assert.AreEqual (1, dtLoad.Rows[0][0], "RowData0-0");
2156                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1], "RowData0-1");
2157                         Assert.AreEqual (2, dtLoad.Rows[1][0], "RowData1-0");
2158                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1], "RowData1-1");
2159                         Assert.AreEqual (3, dtLoad.Rows[2][0], "RowData2-0");
2160                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1], "RowData2-1");
2161                 }
2162
2163                 [Test]
2164                 public void Load_NoSchema ()
2165                 {
2166                         localSetup ();
2167                         DataTable dtLoad = new DataTable ("LoadNoSchema");
2168                         DataTableReader dtr = dt.CreateDataReader ();
2169                         dtLoad.Load (dtr);
2170                         Assert.AreEqual (2, dtLoad.Columns.Count, "NColumns");
2171                         Assert.AreEqual (3, dtLoad.Rows.Count, "NRows");
2172                         Assert.AreEqual (1, dtLoad.Rows[0][0], "RowData0-0");
2173                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1], "RowData0-1");
2174                         Assert.AreEqual (2, dtLoad.Rows[1][0], "RowData1-0");
2175                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1], "RowData1-1");
2176                         Assert.AreEqual (3, dtLoad.Rows[2][0], "RowData2-0");
2177                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1], "RowData2-1");
2178                 }
2179
2180                 internal struct fillErrorStruct
2181                 {
2182                         internal string error;
2183                         internal string tableName;
2184                         internal int rowKey;
2185                         internal bool contFlag;
2186
2187                         internal void init (string tbl, int row, bool cont, string err)
2188                         {
2189                                 tableName = tbl;
2190                                 rowKey = row;
2191                                 contFlag = cont;
2192                                 error = err;
2193                         }
2194                 }
2195                 private fillErrorStruct[] fillErr = new fillErrorStruct[3];
2196                 private int fillErrCounter;
2197                 private void fillErrorHandler (object sender, FillErrorEventArgs e)
2198                 {
2199                         e.Continue = fillErr[fillErrCounter].contFlag;
2200                         Assert.AreEqual (fillErr[fillErrCounter].tableName, e.DataTable.TableName, "fillErr-T");
2201                         //Assert.AreEqual (fillErr[fillErrCounter].rowKey, e.Values[0], "fillErr-R");
2202                         Assert.AreEqual (fillErr[fillErrCounter].contFlag, e.Continue, "fillErr-C");
2203                         //Assert.AreEqual (fillErr[fillErrCounter].error, e.Errors.Message, "fillErr-E");
2204                         fillErrCounter++;
2205                 }
2206
2207                 [Test]
2208                 public void Load_Incompatible ()
2209                 {
2210                         localSetup ();
2211                         DataTable dtLoad = new DataTable ("LoadIncompatible");
2212                         dtLoad.Columns.Add ("name", typeof (double));
2213                         DataTableReader dtr = dt.CreateDataReader ();
2214                         try {
2215                                 dtLoad.Load (dtr);
2216                                 Assert.Fail ("#1");
2217                         } catch (ArgumentException) {
2218                         }
2219                 }
2220                 [Test]
2221                 // Load doesn't have a third overload in System.Data
2222                 // and is commented-out below
2223                 public void Load_IncompatibleEHandlerT ()
2224                 {
2225                         fillErrCounter = 0;
2226                         fillErr[0].init ("LoadIncompatible", 1, true,
2227                                  "Input string was not in a correct format.Couldn't store <mono 1> in name Column.  Expected type is Double.");
2228                         fillErr[1].init ("LoadIncompatible", 2, true,
2229                                 "Input string was not in a correct format.Couldn't store <mono 2> in name Column.  Expected type is Double.");
2230                         fillErr[2].init ("LoadIncompatible", 3, true,
2231                                 "Input string was not in a correct format.Couldn't store <mono 3> in name Column.  Expected type is Double.");
2232                         localSetup ();
2233                         DataTable dtLoad = new DataTable ("LoadIncompatible");
2234                         dtLoad.Columns.Add ("name", typeof (double));
2235                         DataTableReader dtr = dt.CreateDataReader ();
2236                         dtLoad.Load (dtr,LoadOption.PreserveChanges,fillErrorHandler);
2237                 }
2238
2239                 [Test]
2240                 // Load doesn't have a third overload in System.Data
2241                 // and is commented-out below
2242                 public void Load_IncompatibleEHandlerF ()
2243                 {
2244                         fillErrCounter = 0;
2245                         fillErr[0].init ("LoadIncompatible", 1, false,
2246                                 "Input string was not in a correct format.Couldn't store <mono 1> in name Column.  Expected type is Double.");
2247                         localSetup ();
2248                         DataTable dtLoad = new DataTable ("LoadIncompatible");
2249                         dtLoad.Columns.Add ("name", typeof (double));
2250                         DataTableReader dtr = dt.CreateDataReader ();
2251                         try {
2252                                 dtLoad.Load (dtr, LoadOption.PreserveChanges, fillErrorHandler);
2253                                 Assert.Fail ("#1");
2254                         } catch (ArgumentException) {
2255                         }
2256                 }
2257
2258                 [Test]
2259                 public void Load_ExtraColsEqualVal ()
2260                 {
2261                         localSetup ();
2262                         DataTable dtLoad = new DataTable ("LoadExtraCols");
2263                         dtLoad.Columns.Add ("id", typeof (int));
2264                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2265                         dtLoad.Rows.Add (new object[] { 1 });
2266                         dtLoad.Rows.Add (new object[] { 2 });
2267                         dtLoad.Rows.Add (new object[] { 3 });
2268                         dtLoad.AcceptChanges ();
2269                         DataTableReader dtr = dt.CreateDataReader ();
2270                         dtLoad.Load (dtr);
2271                         Assert.AreEqual (2, dtLoad.Columns.Count, "NColumns");
2272                         Assert.AreEqual (3, dtLoad.Rows.Count, "NRows");
2273                         Assert.AreEqual (1, dtLoad.Rows[0][0], "RowData0-0");
2274                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1], "RowData0-1");
2275                         Assert.AreEqual (2, dtLoad.Rows[1][0], "RowData1-0");
2276                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1], "RowData1-1");
2277                         Assert.AreEqual (3, dtLoad.Rows[2][0], "RowData2-0");
2278                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1], "RowData2-1");
2279                 }
2280
2281                 [Test]
2282                 public void Load_ExtraColsNonEqualVal ()
2283                 {
2284                         localSetup ();
2285                         DataTable dtLoad = new DataTable ("LoadExtraCols");
2286                         dtLoad.Columns.Add ("id", typeof (int));
2287                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2288                         dtLoad.Rows.Add (new object[] { 4 });
2289                         dtLoad.Rows.Add (new object[] { 5 });
2290                         dtLoad.Rows.Add (new object[] { 6 });
2291                         dtLoad.AcceptChanges ();
2292                         DataTableReader dtr = dt.CreateDataReader ();
2293                         dtLoad.Load (dtr);
2294                         Assert.AreEqual (2, dtLoad.Columns.Count, "NColumns");
2295                         Assert.AreEqual (6, dtLoad.Rows.Count, "NRows");
2296                         Assert.AreEqual (4, dtLoad.Rows[0][0], "RowData0-0");
2297                         Assert.AreEqual (5, dtLoad.Rows[1][0], "RowData1-0");
2298                         Assert.AreEqual (6, dtLoad.Rows[2][0], "RowData2-0");
2299                         Assert.AreEqual (1, dtLoad.Rows[3][0], "RowData3-0");
2300                         Assert.AreEqual ("mono 1", dtLoad.Rows[3][1], "RowData3-1");
2301                         Assert.AreEqual (2, dtLoad.Rows[4][0], "RowData4-0");
2302                         Assert.AreEqual ("mono 2", dtLoad.Rows[4][1], "RowData4-1");
2303                         Assert.AreEqual (3, dtLoad.Rows[5][0], "RowData5-0");
2304                         Assert.AreEqual ("mono 3", dtLoad.Rows[5][1], "RowData5-1");
2305                 }
2306
2307                 [Test]
2308                 public void Load_MissingColsNonNullable ()
2309                 {
2310                         localSetup ();
2311                         DataTable dtLoad = new DataTable ("LoadMissingCols");
2312                         dtLoad.Columns.Add ("id", typeof (int));
2313                         dtLoad.Columns.Add ("name", typeof (string));
2314                         dtLoad.Columns.Add ("missing", typeof (string));
2315                         dtLoad.Columns["missing"].AllowDBNull = false;
2316                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2317                         dtLoad.Rows.Add (new object[] { 4, "mono 4", "miss4" });
2318                         dtLoad.Rows.Add (new object[] { 5, "mono 5", "miss5" });
2319                         dtLoad.Rows.Add (new object[] { 6, "mono 6", "miss6" });
2320                         dtLoad.AcceptChanges ();
2321                         DataTableReader dtr = dt.CreateDataReader ();
2322                         try {
2323                                 dtLoad.Load (dtr);
2324                                 Assert.Fail ("#1");
2325                         } catch (ConstraintException) {
2326                         }
2327                 }
2328
2329                 [Test]
2330                 public void Load_MissingColsDefault ()
2331                 {
2332                         localSetup ();
2333                         DataTable dtLoad = new DataTable ("LoadMissingCols");
2334                         dtLoad.Columns.Add ("id", typeof (int));
2335                         dtLoad.Columns.Add ("name", typeof (string));
2336                         dtLoad.Columns.Add ("missing", typeof (string));
2337                         dtLoad.Columns["missing"].AllowDBNull = false;
2338                         dtLoad.Columns["missing"].DefaultValue = "DefaultValue";
2339                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2340                         dtLoad.Rows.Add (new object[] { 4, "mono 4", "miss4" });
2341                         dtLoad.Rows.Add (new object[] { 5, "mono 5", "miss5" });
2342                         dtLoad.Rows.Add (new object[] { 6, "mono 6", "miss6" });
2343                         dtLoad.AcceptChanges ();
2344                         DataTableReader dtr = dt.CreateDataReader ();
2345                         dtLoad.Load (dtr);
2346                         Assert.AreEqual (3, dtLoad.Columns.Count, "NColumns");
2347                         Assert.AreEqual (6, dtLoad.Rows.Count, "NRows");
2348                         Assert.AreEqual (4, dtLoad.Rows[0][0], "RowData0-0");
2349                         Assert.AreEqual ("mono 4", dtLoad.Rows[0][1], "RowData0-1");
2350                         Assert.AreEqual ("miss4", dtLoad.Rows[0][2], "RowData0-2");
2351                         Assert.AreEqual (5, dtLoad.Rows[1][0], "RowData1-0");
2352                         Assert.AreEqual ("mono 5", dtLoad.Rows[1][1], "RowData1-1");
2353                         Assert.AreEqual ("miss5", dtLoad.Rows[1][2], "RowData1-2");
2354                         Assert.AreEqual (6, dtLoad.Rows[2][0], "RowData2-0");
2355                         Assert.AreEqual ("mono 6", dtLoad.Rows[2][1], "RowData2-1");
2356                         Assert.AreEqual ("miss6", dtLoad.Rows[2][2], "RowData2-2");
2357                         Assert.AreEqual (1, dtLoad.Rows[3][0], "RowData3-0");
2358                         Assert.AreEqual ("mono 1", dtLoad.Rows[3][1], "RowData3-1");
2359                         Assert.AreEqual ("DefaultValue", dtLoad.Rows[3][2], "RowData3-2");
2360                         Assert.AreEqual (2, dtLoad.Rows[4][0], "RowData4-0");
2361                         Assert.AreEqual ("mono 2", dtLoad.Rows[4][1], "RowData4-1");
2362                         Assert.AreEqual ("DefaultValue", dtLoad.Rows[4][2], "RowData4-2");
2363                         Assert.AreEqual (3, dtLoad.Rows[5][0], "RowData5-0");
2364                         Assert.AreEqual ("mono 3", dtLoad.Rows[5][1], "RowData5-1");
2365                         Assert.AreEqual ("DefaultValue", dtLoad.Rows[5][2], "RowData5-2");
2366                 }
2367
2368                 [Test]
2369                 public void Load_MissingColsNullable ()
2370                 {
2371                         localSetup ();
2372                         DataTable dtLoad = new DataTable ("LoadMissingCols");
2373                         dtLoad.Columns.Add ("id", typeof (int));
2374                         dtLoad.Columns.Add ("name", typeof (string));
2375                         dtLoad.Columns.Add ("missing", typeof (string));
2376                         dtLoad.Columns["missing"].AllowDBNull = true;
2377                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2378                         dtLoad.Rows.Add (new object[] { 4, "mono 4", "miss4" });
2379                         dtLoad.Rows.Add (new object[] { 5, "mono 5", "miss5" });
2380                         dtLoad.Rows.Add (new object[] { 6, "mono 6", "miss6" });
2381                         dtLoad.AcceptChanges ();
2382                         DataTableReader dtr = dt.CreateDataReader ();
2383                         dtLoad.Load (dtr);
2384                         Assert.AreEqual (3, dtLoad.Columns.Count, "NColumns");
2385                         Assert.AreEqual (6, dtLoad.Rows.Count, "NRows");
2386                         Assert.AreEqual (4, dtLoad.Rows[0][0], "RowData0-0");
2387                         Assert.AreEqual ("mono 4", dtLoad.Rows[0][1], "RowData0-1");
2388                         Assert.AreEqual ("miss4", dtLoad.Rows[0][2], "RowData0-2");
2389                         Assert.AreEqual (5, dtLoad.Rows[1][0], "RowData1-0");
2390                         Assert.AreEqual ("mono 5", dtLoad.Rows[1][1], "RowData1-1");
2391                         Assert.AreEqual ("miss5", dtLoad.Rows[1][2], "RowData1-2");
2392                         Assert.AreEqual (6, dtLoad.Rows[2][0], "RowData2-0");
2393                         Assert.AreEqual ("mono 6", dtLoad.Rows[2][1], "RowData2-1");
2394                         Assert.AreEqual ("miss6", dtLoad.Rows[2][2], "RowData2-2");
2395                         Assert.AreEqual (1, dtLoad.Rows[3][0], "RowData3-0");
2396                         Assert.AreEqual ("mono 1", dtLoad.Rows[3][1], "RowData3-1");
2397                         //Assert.IsNull (dtLoad.Rows[3][2], "RowData3-2");
2398                         Assert.AreEqual (2, dtLoad.Rows[4][0], "RowData4-0");
2399                         Assert.AreEqual ("mono 2", dtLoad.Rows[4][1], "RowData4-1");
2400                         //Assert.IsNull (dtLoad.Rows[4][2], "RowData4-2");
2401                         Assert.AreEqual (3, dtLoad.Rows[5][0], "RowData5-0");
2402                         Assert.AreEqual ("mono 3", dtLoad.Rows[5][1], "RowData5-1");
2403                         //Assert.IsNull (dtLoad.Rows[5][2], "RowData5-2");
2404                 }
2405
2406                 private DataTable setupRowState ()
2407                 {
2408                         DataTable tbl = new DataTable ("LoadRowStateChanges");
2409                         tbl.RowChanged += new DataRowChangeEventHandler (dtLoad_RowChanged);
2410                         tbl.RowChanging += new DataRowChangeEventHandler (dtLoad_RowChanging);
2411                         tbl.Columns.Add ("id", typeof (int));
2412                         tbl.Columns.Add ("name", typeof (string));
2413                         tbl.PrimaryKey = new DataColumn[] { tbl.Columns["id"] };
2414                         tbl.Rows.Add (new object[] { 1, "RowState 1" });
2415                         tbl.Rows.Add (new object[] { 2, "RowState 2" });
2416                         tbl.Rows.Add (new object[] { 3, "RowState 3" });
2417                         tbl.AcceptChanges ();
2418                         // Update Table with following changes: Row0 unmodified, 
2419                         // Row1 modified, Row2 deleted, Row3 added, Row4 not-present.
2420                         tbl.Rows[1]["name"] = "Modify 2";
2421                         tbl.Rows[2].Delete ();
2422                         DataRow row = tbl.NewRow ();
2423                         row["id"] = 4;
2424                         row["name"] = "Add 4";
2425                         tbl.Rows.Add (row);
2426                         return (tbl);
2427                 }
2428
2429                 private DataRowAction[] rowChangeAction = new DataRowAction[5];
2430                 private bool checkAction;
2431                 private int rowChagedCounter, rowChangingCounter;
2432                 private void rowActionInit (DataRowAction[] act)
2433                 {
2434                         checkAction = true;
2435                         rowChagedCounter = 0;
2436                         rowChangingCounter = 0;
2437                         for (int i = 0; i < 5; i++)
2438                                 rowChangeAction[i] = act[i];
2439                 }
2440
2441                 private void rowActionEnd ()
2442                 {
2443                         checkAction = false;
2444                 }
2445
2446                 private void dtLoad_RowChanged (object sender, DataRowChangeEventArgs e)
2447                 {
2448                         if (checkAction) {
2449                                 Assert.AreEqual (rowChangeAction[rowChagedCounter], e.Action, "RowChanged" + rowChagedCounter);
2450                                 rowChagedCounter++;
2451                         }
2452                 }
2453
2454                 private void dtLoad_RowChanging (object sender, DataRowChangeEventArgs e)
2455                 {
2456                         if (checkAction) {
2457                                 Assert.AreEqual (rowChangeAction[rowChangingCounter], e.Action, "RowChanging" + rowChangingCounter);
2458                                 rowChangingCounter++;
2459                         }
2460                 }
2461
2462                 [Test]
2463                 public void Load_RowStateChangesDefault ()
2464                 {
2465                         localSetup ();
2466                         dt.Rows.Add (new object[] { 4, "mono 4" });
2467                         dt.Rows.Add (new object[] { 5, "mono 5" });
2468                         dt.AcceptChanges ();
2469                         DataTableReader dtr = dt.CreateDataReader ();
2470                         DataTable dtLoad = setupRowState ();
2471                         DataRowAction[] dra = new DataRowAction[] {
2472                                 DataRowAction.ChangeCurrentAndOriginal,
2473                                 DataRowAction.ChangeOriginal,
2474                                 DataRowAction.ChangeOriginal,
2475                                 DataRowAction.ChangeOriginal,
2476                                 DataRowAction.ChangeCurrentAndOriginal};
2477                         rowActionInit (dra);
2478                         dtLoad.Load (dtr);
2479                         rowActionEnd ();
2480                         // asserting Unchanged Row0
2481                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1,DataRowVersion.Current], "RowData0-C");
2482                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1,DataRowVersion.Original], "RowData0-O");
2483                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[0].RowState, "RowState0");
2484                         // asserting Modified Row1
2485                         Assert.AreEqual ("Modify 2", dtLoad.Rows[1][1, DataRowVersion.Current], "RowData1-C");
2486                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1, DataRowVersion.Original], "RowData1-O");
2487                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[1].RowState, "RowState1");
2488                         // asserting Deleted Row2
2489                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1, DataRowVersion.Original], "RowData1-O");
2490                         Assert.AreEqual (DataRowState.Deleted, dtLoad.Rows[2].RowState, "RowState2");
2491                         // asserting Added Row3
2492                         Assert.AreEqual ("Add 4", dtLoad.Rows[3][1, DataRowVersion.Current], "RowData3-C");
2493                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2494                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[3].RowState, "RowState3");
2495                         // asserting Unpresent Row4
2496                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Current], "RowData4-C");
2497                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Original], "RowData4-O");
2498                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[4].RowState, "RowState4");
2499                 }
2500
2501                 [Test]
2502                 public void Load_RowStateChangesDefaultDelete ()
2503                 {
2504                         localSetup ();
2505                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2506                         dtLoad.Columns.Add ("id", typeof (int));
2507                         dtLoad.Columns.Add ("name", typeof (string));
2508                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2509                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2510                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2511                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2512                         dtLoad.AcceptChanges ();
2513                         dtLoad.Rows[2].Delete ();
2514                         DataTableReader dtr = dt.CreateDataReader ();
2515                         dtLoad.Load (dtr);
2516
2517                         try {
2518                                 Assert.AreEqual (" ", dtLoad.Rows[2][1, DataRowVersion.Current], "RowData2-C");
2519                                 Assert.Fail ("#1");
2520                         } catch (VersionNotFoundException) {
2521                         }
2522                 }
2523
2524                 [Test]
2525                 public void Load_RowStatePreserveChanges ()
2526                 {
2527                         localSetup ();
2528                         dt.Rows.Add (new object[] { 4, "mono 4" });
2529                         dt.Rows.Add (new object[] { 5, "mono 5" });
2530                         dt.AcceptChanges ();
2531                         DataTableReader dtr = dt.CreateDataReader ();
2532                         DataTable dtLoad = setupRowState ();
2533                         DataRowAction[] dra = new DataRowAction[] {
2534                                 DataRowAction.ChangeCurrentAndOriginal,
2535                                 DataRowAction.ChangeOriginal,
2536                                 DataRowAction.ChangeOriginal,
2537                                 DataRowAction.ChangeOriginal,
2538                                 DataRowAction.ChangeCurrentAndOriginal};
2539                         rowActionInit (dra);
2540                         dtLoad.Load (dtr, LoadOption.PreserveChanges);
2541                         rowActionEnd ();
2542                         // asserting Unchanged Row0
2543                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Current], "RowData0-C");
2544                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Original], "RowData0-O");
2545                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[0].RowState, "RowState0");
2546                         // asserting Modified Row1
2547                         Assert.AreEqual ("Modify 2", dtLoad.Rows[1][1, DataRowVersion.Current], "RowData1-C");
2548                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1, DataRowVersion.Original], "RowData1-O");
2549                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[1].RowState, "RowState1");
2550                         // asserting Deleted Row2
2551                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1, DataRowVersion.Original], "RowData1-O");
2552                         Assert.AreEqual (DataRowState.Deleted, dtLoad.Rows[2].RowState, "RowState2");
2553                         // asserting Added Row3
2554                         Assert.AreEqual ("Add 4", dtLoad.Rows[3][1, DataRowVersion.Current], "RowData3-C");
2555                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2556                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[3].RowState, "RowState3");
2557                         // asserting Unpresent Row4
2558                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Current], "RowData4-C");
2559                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Original], "RowData4-O");
2560                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[4].RowState, "RowState4");
2561                 }
2562
2563                 [Test]
2564                 public void Load_RowStatePreserveChangesDelete () {
2565                         localSetup ();
2566                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2567                         dtLoad.Columns.Add ("id", typeof (int));
2568                         dtLoad.Columns.Add ("name", typeof (string));
2569                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2570                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2571                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2572                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2573                         dtLoad.AcceptChanges ();
2574                         dtLoad.Rows[2].Delete ();
2575                         DataTableReader dtr = dt.CreateDataReader ();
2576                         dtLoad.Load (dtr,LoadOption.PreserveChanges);
2577
2578                         try {
2579                                 Assert.AreEqual (" ", dtLoad.Rows[2][1, DataRowVersion.Current], "RowData2-C");
2580                                 Assert.Fail ("#1");
2581                         } catch (VersionNotFoundException) {
2582                         }
2583                 }
2584
2585                 [Test]
2586                 public void Load_RowStateOverwriteChanges ()
2587                 {
2588                         localSetup ();
2589                         dt.Rows.Add (new object[] { 4, "mono 4" });
2590                         dt.Rows.Add (new object[] { 5, "mono 5" });
2591                         dt.AcceptChanges ();
2592                         DataTableReader dtr = dt.CreateDataReader ();
2593                         DataTable dtLoad = setupRowState ();
2594                         DataRowAction[] dra = new DataRowAction[] {
2595                                 DataRowAction.ChangeCurrentAndOriginal,
2596                                 DataRowAction.ChangeCurrentAndOriginal,
2597                                 DataRowAction.ChangeCurrentAndOriginal,
2598                                 DataRowAction.ChangeCurrentAndOriginal,
2599                                 DataRowAction.ChangeCurrentAndOriginal};
2600                         rowActionInit (dra);
2601                         dtLoad.Load (dtr, LoadOption.OverwriteChanges);
2602                         rowActionEnd ();
2603                         // asserting Unchanged Row0
2604                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Current], "RowData0-C");
2605                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Original], "RowData0-O");
2606                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[0].RowState, "RowState0");
2607                         // asserting Modified Row1
2608                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1, DataRowVersion.Current], "RowData1-C");
2609                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1, DataRowVersion.Original], "RowData1-O");
2610                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[1].RowState, "RowState1");
2611                         // asserting Deleted Row2
2612                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1, DataRowVersion.Current], "RowData1-C");
2613                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1, DataRowVersion.Original], "RowData1-O");
2614                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[2].RowState, "RowState2");
2615                         // asserting Added Row3
2616                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Current], "RowData3-C");
2617                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2618                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[3].RowState, "RowState3");
2619                         // asserting Unpresent Row4
2620                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Current], "RowData4-C");
2621                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Original], "RowData4-O");
2622                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[4].RowState, "RowState4");
2623                 }
2624
2625                 [Test]
2626                 public void Load_RowStateUpsert ()
2627                 {
2628                         localSetup ();
2629                         dt.Rows.Add (new object[] { 4, "mono 4" });
2630                         dt.Rows.Add (new object[] { 5, "mono 5" });
2631                         dt.AcceptChanges ();
2632                         DataTableReader dtr = dt.CreateDataReader ();
2633                         DataTable dtLoad = setupRowState ();
2634                         // Notice rowChange-Actions only occur 5 times, as number 
2635                         // of actual rows, ignoring row duplication of the deleted row.
2636                         DataRowAction[] dra = new DataRowAction[] {
2637                                 DataRowAction.Change,
2638                                 DataRowAction.Change,
2639                                 DataRowAction.Add,
2640                                 DataRowAction.Change,
2641                                 DataRowAction.Add};
2642                         rowActionInit (dra);
2643                         dtLoad.Load (dtr, LoadOption.Upsert);
2644                         rowActionEnd ();
2645                         // asserting Unchanged Row0
2646                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Current], "RowData0-C");
2647                         Assert.AreEqual ("RowState 1", dtLoad.Rows[0][1, DataRowVersion.Original], "RowData0-O");
2648                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[0].RowState, "RowState0");
2649                         // asserting Modified Row1
2650                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1, DataRowVersion.Current], "RowData1-C");
2651                         Assert.AreEqual ("RowState 2", dtLoad.Rows[1][1, DataRowVersion.Original], "RowData1-O");
2652                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[1].RowState, "RowState1");
2653                         // asserting Deleted Row2 and "Deleted-Added" Row4
2654                         Assert.AreEqual ("RowState 3", dtLoad.Rows[2][1, DataRowVersion.Original], "RowData2-O");
2655                         Assert.AreEqual (DataRowState.Deleted, dtLoad.Rows[2].RowState, "RowState2");
2656                         Assert.AreEqual ("mono 3", dtLoad.Rows[4][1, DataRowVersion.Current], "RowData4-C");
2657                         Assert.AreEqual (DataRowState.Added, dtLoad.Rows[4].RowState, "RowState4");
2658                         // asserting Added Row3
2659                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Current], "RowData3-C");
2660                         Assert.AreEqual (DataRowState.Added, dtLoad.Rows[3].RowState, "RowState3");
2661                         // asserting Unpresent Row5
2662                         // Notice row4 is used for added row of deleted row2 and so
2663                         // unpresent row4 moves to row5
2664                         Assert.AreEqual ("mono 5", dtLoad.Rows[5][1, DataRowVersion.Current], "RowData5-C");
2665                         Assert.AreEqual (DataRowState.Added, dtLoad.Rows[5].RowState, "RowState5");
2666                 }
2667
2668                 [Test]
2669                 public void Load_RowStateUpsertDuplicateKey1 ()
2670                 {
2671                         localSetup ();
2672                         dt.Rows.Add (new object[] { 4, "mono 4" });
2673                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2674                         dtLoad.Columns.Add ("id", typeof (int));
2675                         dtLoad.Columns.Add ("name", typeof (string));
2676                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2677                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2678                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2679                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2680                         dtLoad.AcceptChanges ();
2681                         dtLoad.Rows[2].Delete ();
2682                         DataTableReader dtr = dt.CreateDataReader ();
2683                         dtLoad.Load (dtr, LoadOption.Upsert);
2684                         dtLoad.Rows[3][1] = "NEWVAL";
2685                         Assert.AreEqual (DataRowState.Deleted, dtLoad.Rows[2].RowState, "A-RowState2");
2686                         Assert.AreEqual (3, dtLoad.Rows[2][0, DataRowVersion.Original], "A-RowData2-id");
2687                         Assert.AreEqual ("RowState 3", dtLoad.Rows[2][1, DataRowVersion.Original], "A-RowData2-name");
2688                         Assert.AreEqual (DataRowState.Added, dtLoad.Rows[3].RowState, "A-RowState3");
2689                         Assert.AreEqual (3, dtLoad.Rows[3][0, DataRowVersion.Current], "A-RowData3-id");
2690                         Assert.AreEqual ("NEWVAL", dtLoad.Rows[3][1, DataRowVersion.Current], "A-RowData3-name");
2691                         Assert.AreEqual (DataRowState.Added, dtLoad.Rows[4].RowState, "A-RowState4");
2692                         Assert.AreEqual (4, dtLoad.Rows[4][0, DataRowVersion.Current], "A-RowData4-id");
2693                         Assert.AreEqual ("mono 4", dtLoad.Rows[4][1, DataRowVersion.Current], "A-RowData4-name");
2694
2695                         dtLoad.AcceptChanges ();
2696
2697                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[2].RowState, "B-RowState2");
2698                         Assert.AreEqual (3, dtLoad.Rows[2][0, DataRowVersion.Current], "B-RowData2-id");
2699                         Assert.AreEqual ("NEWVAL", dtLoad.Rows[2][1, DataRowVersion.Current], "B-RowData2-name");
2700                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[3].RowState, "B-RowState3");
2701                         Assert.AreEqual (4, dtLoad.Rows[3][0, DataRowVersion.Current], "B-RowData3-id");
2702                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Current], "B-RowData3-name");
2703                 }
2704
2705                 [Test]
2706                 public void Load_RowStateUpsertDuplicateKey2 ()
2707                 {
2708                         localSetup ();
2709                         dt.Rows.Add (new object[] { 4, "mono 4" });
2710                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2711                         dtLoad.Columns.Add ("id", typeof (int));
2712                         dtLoad.Columns.Add ("name", typeof (string));
2713                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2714                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2715                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2716                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2717                         dtLoad.AcceptChanges ();
2718                         dtLoad.Rows[2].Delete ();
2719                         DataTableReader dtr = dt.CreateDataReader ();
2720                         dtLoad.Load (dtr, LoadOption.Upsert);
2721                         dtLoad.AcceptChanges ();
2722
2723                         try {
2724                                 Assert.AreEqual (" ", dtLoad.Rows[4][1], "RowData4");
2725                                 Assert.Fail ("#1");
2726                         } catch (IndexOutOfRangeException) {
2727                         }
2728                 }
2729
2730                 [Test]
2731                 public void Load_RowStateUpsertDelete1 ()
2732                 {
2733                         localSetup ();
2734                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2735                         dtLoad.Columns.Add ("id", typeof (int));
2736                         dtLoad.Columns.Add ("name", typeof (string));
2737                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2738                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2739                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2740                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2741                         dtLoad.AcceptChanges ();
2742                         dtLoad.Rows[2].Delete ();
2743                         DataTableReader dtr = dt.CreateDataReader ();
2744                         dtLoad.Load (dtr, LoadOption.Upsert);
2745
2746                         try {
2747                                 Assert.AreEqual (" ", dtLoad.Rows[2][1, DataRowVersion.Current], "RowData2-C");
2748                                 Assert.Fail ("#1");
2749                         } catch (VersionNotFoundException) {
2750                         }
2751                 }
2752
2753                 [Test]
2754                 public void Load_RowStateUpsertDelete2 ()
2755                 {
2756                         localSetup ();
2757                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2758                         dtLoad.Columns.Add ("id", typeof (int));
2759                         dtLoad.Columns.Add ("name", typeof (string));
2760                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2761                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2762                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2763                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2764                         dtLoad.AcceptChanges ();
2765                         dtLoad.Rows[2].Delete ();
2766                         DataTableReader dtr = dt.CreateDataReader ();
2767                         dtLoad.Load (dtr, LoadOption.Upsert);
2768
2769                         try {
2770                                 Assert.AreEqual (" ", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2771                                 Assert.Fail ("#1");
2772                         } catch (VersionNotFoundException) {
2773                         }
2774                 }
2775
2776                 [Test]
2777                 public void Load_RowStateUpsertAdd ()
2778                 {
2779                         localSetup ();
2780                         dt.Rows.Add (new object[] { 4, "mono 4" });
2781                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2782                         dtLoad.Columns.Add ("id", typeof (int));
2783                         dtLoad.Columns.Add ("name", typeof (string));
2784                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2785                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2786                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2787                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2788                         dtLoad.AcceptChanges ();
2789                         DataRow row = dtLoad.NewRow ();
2790                         row["id"] = 4;
2791                         row["name"] = "Add 4";
2792                         dtLoad.Rows.Add (row);
2793                         DataTableReader dtr = dt.CreateDataReader ();
2794                         dtLoad.Load (dtr, LoadOption.Upsert);
2795
2796                         try {
2797                                 Assert.AreEqual (" ", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2798                                 Assert.Fail ("#1");
2799                         } catch (VersionNotFoundException) {
2800                         }
2801                 }
2802
2803                 [Test]
2804                 public void Load_RowStateUpsertUnpresent () {
2805                         localSetup ();
2806                         dt.Rows.Add (new object[] { 4, "mono 4" });
2807                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2808                         dtLoad.Columns.Add ("id", typeof (int));
2809                         dtLoad.Columns.Add ("name", typeof (string));
2810                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2811                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2812                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2813                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2814                         dtLoad.AcceptChanges ();
2815                         DataTableReader dtr = dt.CreateDataReader ();
2816                         dtLoad.Load (dtr, LoadOption.Upsert);
2817
2818                         try {
2819                                 Assert.AreEqual (" ", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2820                                 Assert.Fail ("#1");
2821                         } catch (VersionNotFoundException) {
2822                         }
2823                 }
2824
2825                 [Test]
2826                 public void Load_RowStateUpsertUnchangedEqualVal ()
2827                 {
2828                         localSetup ();
2829                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2830                         dtLoad.Columns.Add ("id", typeof (int));
2831                         dtLoad.Columns.Add ("name", typeof (string));
2832                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2833                         dtLoad.Rows.Add (new object[] { 1, "mono 1" });
2834                         dtLoad.AcceptChanges ();
2835                         DataTableReader dtr = dt.CreateDataReader ();
2836                         DataRowAction[] dra = new DataRowAction[] {
2837                                 DataRowAction.Nothing,// REAL action
2838                                 DataRowAction.Nothing,// dummy  
2839                                 DataRowAction.Nothing,// dummy  
2840                                 DataRowAction.Nothing,// dummy  
2841                                 DataRowAction.Nothing};// dummy  
2842                         rowActionInit (dra);
2843                         dtLoad.Load (dtr, LoadOption.Upsert);
2844                         rowActionEnd ();
2845                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Current], "RowData0-C");
2846                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Original], "RowData0-O");
2847                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[0].RowState, "RowState0");
2848                 }
2849
2850                 [Test]
2851                 public void LoadDataRow_LoadOptions ()
2852                 {
2853                         // LoadDataRow is covered in detail (without LoadOptions) in DataTableTest2
2854                         // LoadOption tests are covered in detail in DataTable.Load().
2855                         // Therefore only minimal tests of LoadDataRow with LoadOptions are covered here.
2856                         DataTable dt;
2857                         DataRow dr;
2858                         dt = CreateDataTableExample ();
2859                         dt.PrimaryKey = new DataColumn[] { dt.Columns[0] };     //add ParentId as Primary Key
2860                         dt.Columns["String1"].DefaultValue = "Default";
2861
2862                         dr = dt.Select ("ParentId=1")[0];
2863
2864                         //Update existing row with LoadOptions = OverwriteChanges
2865                         dt.BeginLoadData ();
2866                         dt.LoadDataRow (new object[] { 1, null, "Changed" },
2867                                 LoadOption.OverwriteChanges);
2868                         dt.EndLoadData ();
2869
2870                         // LoadDataRow(update1) - check column String2
2871                         Assert.AreEqual ("Changed", dr["String2", DataRowVersion.Current], "DT72-C");
2872                         Assert.AreEqual ("Changed", dr["String2", DataRowVersion.Original], "DT72-O");
2873
2874                         // LoadDataRow(update1) - check row state
2875                         Assert.AreEqual (DataRowState.Unchanged, dr.RowState, "DT73-LO");
2876
2877                         //Add New row with LoadOptions = Upsert
2878                         dt.BeginLoadData ();
2879                         dt.LoadDataRow (new object[] { 99, null, "Changed" },
2880                                 LoadOption.Upsert);
2881                         dt.EndLoadData ();
2882
2883                         // LoadDataRow(insert1) - check column String2
2884                         dr = dt.Select ("ParentId=99")[0];
2885                         Assert.AreEqual ("Changed", dr["String2", DataRowVersion.Current], "DT75-C");
2886
2887                         // LoadDataRow(insert1) - check row state
2888                         Assert.AreEqual (DataRowState.Added, dr.RowState, "DT76-LO");
2889                 }
2890
2891                 public static DataTable CreateDataTableExample ()
2892                 {
2893                         DataTable dtParent = new DataTable ("Parent");
2894
2895                         dtParent.Columns.Add ("ParentId", typeof (int));
2896                         dtParent.Columns.Add ("String1", typeof (string));
2897                         dtParent.Columns.Add ("String2", typeof (string));
2898
2899                         dtParent.Columns.Add ("ParentDateTime", typeof (DateTime));
2900                         dtParent.Columns.Add ("ParentDouble", typeof (double));
2901                         dtParent.Columns.Add ("ParentBool", typeof (bool));
2902
2903                         dtParent.Rows.Add (new object[] { 1, "1-String1", "1-String2", new DateTime (2005, 1, 1, 0, 0, 0, 0), 1.534, true });
2904                         dtParent.Rows.Add (new object[] { 2, "2-String1", "2-String2", new DateTime (2004, 1, 1, 0, 0, 0, 1), -1.534, true });
2905                         dtParent.Rows.Add (new object[] { 3, "3-String1", "3-String2", new DateTime (2003, 1, 1, 0, 0, 1, 0), double.MinValue * 10000, false });
2906                         dtParent.Rows.Add (new object[] { 4, "4-String1", "4-String2", new DateTime (2002, 1, 1, 0, 1, 0, 0), double.MaxValue / 10000, true });
2907                         dtParent.Rows.Add (new object[] { 5, "5-String1", "5-String2", new DateTime (2001, 1, 1, 1, 0, 0, 0), 0.755, true });
2908                         dtParent.Rows.Add (new object[] { 6, "6-String1", "6-String2", new DateTime (2000, 1, 1, 0, 0, 0, 0), 0.001, false });
2909                         dtParent.AcceptChanges ();
2910                         return dtParent;
2911                 }
2912
2913                 #endregion // DataTable.Load Tests
2914
2915                 #region Read/Write XML Tests
2916
2917                 [Test]
2918                 public void ReadXmlSchema ()
2919                 {
2920                         DataTable Table = new DataTable ();
2921                         Table.ReadXmlSchema ("Test/System.Data/own_schema1.xsd");
2922
2923                         Assert.AreEqual ("test_table", Table.TableName, "test#02");
2924                         Assert.AreEqual ("", Table.Namespace, "test#03");
2925                         Assert.AreEqual (2, Table.Columns.Count, "test#04");
2926                         Assert.AreEqual (0, Table.Rows.Count, "test#05");
2927                         Assert.IsFalse (Table.CaseSensitive, "test#06");
2928                         Assert.AreEqual (1, Table.Constraints.Count, "test#07");
2929                         Assert.AreEqual ("", Table.Prefix, "test#08");
2930
2931                         Constraint cons = Table.Constraints[0];
2932                         Assert.AreEqual ("Constraint1", cons.ConstraintName.ToString (), "test#09");
2933                         Assert.AreEqual ("Constraint1", cons.ToString (), "test#10");
2934
2935                         DataColumn column = Table.Columns[0];
2936                         Assert.IsTrue (column.AllowDBNull, "test#11");
2937                         Assert.IsFalse (column.AutoIncrement, "test#12");
2938                         Assert.AreEqual (0L, column.AutoIncrementSeed, "test#13");
2939                         Assert.AreEqual (1L, column.AutoIncrementStep, "test#14");
2940                         Assert.AreEqual ("test", column.Caption, "test#15");
2941                         Assert.AreEqual ("Element", column.ColumnMapping.ToString (), "test#16");
2942                         Assert.AreEqual ("first", column.ColumnName, "test#17");
2943                         Assert.AreEqual (typeof (string), column.DataType, "test#18");
2944                         Assert.AreEqual ("test_default_value", column.DefaultValue.ToString (), "test#19");
2945                         Assert.IsFalse (column.DesignMode, "test#20");
2946                         Assert.AreEqual ("", column.Expression, "test#21");
2947                         Assert.AreEqual (100, column.MaxLength, "test#22");
2948                         Assert.AreEqual ("", column.Namespace, "test#23");
2949                         Assert.AreEqual (0, column.Ordinal, "test#24");
2950                         Assert.AreEqual ("", column.Prefix, "test#25");
2951                         Assert.IsFalse (column.ReadOnly, "test#26");
2952                         Assert.IsTrue (column.Unique, "test#27");
2953
2954                         DataColumn column2 = Table.Columns[1];
2955                         Assert.IsTrue (column2.AllowDBNull, "test#28");
2956                         Assert.IsFalse (column2.AutoIncrement, "test#29");
2957                         Assert.AreEqual (0L, column2.AutoIncrementSeed, "test#30");
2958                         Assert.AreEqual (1L, column2.AutoIncrementStep, "test#31");
2959                         Assert.AreEqual ("second", column2.Caption, "test#32");
2960                         Assert.AreEqual ("Element", column2.ColumnMapping.ToString (), "test#33");
2961                         Assert.AreEqual ("second", column2.ColumnName, "test#34");
2962                         Assert.AreEqual (typeof (SqlGuid), column2.DataType, "test#35");
2963                         Assert.AreEqual (SqlGuid.Null, column2.DefaultValue, "test#36");
2964                         Assert.AreEqual (typeof (SqlGuid), column2.DefaultValue.GetType (), "test#36-2");
2965                         Assert.IsFalse (column2.DesignMode, "test#37");
2966                         Assert.AreEqual ("", column2.Expression, "test#38");
2967                         Assert.AreEqual (-1, column2.MaxLength, "test#39");
2968                         Assert.AreEqual ("", column2.Namespace, "test#40");
2969                         Assert.AreEqual (1, column2.Ordinal, "test#41");
2970                         Assert.AreEqual ("", column2.Prefix, "test#42");
2971                         Assert.IsFalse (column2.ReadOnly, "test#43");
2972                         Assert.IsFalse (column2.Unique, "test#44");
2973
2974                         DataTable Table2 = new DataTable ();
2975                         Table2.ReadXmlSchema ("Test/System.Data/own_schema2.xsd");
2976
2977                         Assert.AreEqual ("second_test_table", Table2.TableName, "test#45");
2978                         Assert.AreEqual ("", Table2.Namespace, "test#46");
2979                         Assert.AreEqual (1, Table2.Columns.Count, "test#47");
2980                         Assert.AreEqual (0, Table2.Rows.Count, "test#48");
2981                         Assert.IsFalse (Table2.CaseSensitive, "test#49");
2982                         Assert.AreEqual (1, Table2.Constraints.Count, "test#50");
2983                         Assert.AreEqual ("", Table2.Prefix, "test#51");
2984
2985                         DataColumn column3 = Table2.Columns[0];
2986                         Assert.IsTrue (column3.AllowDBNull, "test#52");
2987                         Assert.IsFalse (column3.AutoIncrement, "test#53");
2988                         Assert.AreEqual (0L, column3.AutoIncrementSeed, "test#54");
2989                         Assert.AreEqual (1L, column3.AutoIncrementStep, "test#55");
2990                         Assert.AreEqual ("second_first", column3.Caption, "test#56");
2991                         Assert.AreEqual ("Element", column3.ColumnMapping.ToString (), "test#57");
2992                         Assert.AreEqual ("second_first", column3.ColumnName, "test#58");
2993                         Assert.AreEqual (typeof (string), column3.DataType, "test#59");
2994                         Assert.AreEqual ("default_value", column3.DefaultValue.ToString (), "test#60");
2995                         Assert.IsFalse (column3.DesignMode, "test#61");
2996                         Assert.AreEqual ("", column3.Expression, "test#62");
2997                         Assert.AreEqual (100, column3.MaxLength, "test#63");
2998                         Assert.AreEqual ("", column3.Namespace, "test#64");
2999                         Assert.AreEqual (0, column3.Ordinal, "test#65");
3000                         Assert.AreEqual ("", column3.Prefix, "test#66");
3001                         Assert.IsFalse (column3.ReadOnly, "test#67");
3002                         Assert.IsTrue (column3.Unique, "test#68");
3003                 }
3004
3005                 [Test]
3006                 public void ReadXmlSchema_2 ()
3007                 {
3008                         DataTable dt = new DataTable ();
3009                         string xmlData = string.Empty;
3010                         xmlData += "<?xml version=\"1.0\"?>";
3011                         xmlData += "<xs:schema id=\"SiteConfiguration\" targetNamespace=\"http://tempuri.org/PortalCfg.xsd\" xmlns:mstns=\"http://tempuri.org/PortalCfg.xsd\" xmlns=\"http://tempuri.org/PortalCfg.xsd\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\" attributeFormDefault=\"qualified\" elementFormDefault=\"qualified\">";
3012                         xmlData += "<xs:element name=\"SiteConfiguration\" msdata:IsDataSet=\"true\" msdata:EnforceConstraints=\"False\">";
3013                         xmlData += "<xs:complexType>";
3014                         xmlData += "<xs:choice  minOccurs=\"0\" maxOccurs=\"unbounded\">";
3015                         xmlData += "<xs:element name=\"Tab\">";
3016                         xmlData += "<xs:complexType>";
3017                         xmlData += "<xs:sequence>";
3018                         xmlData += "<xs:element name=\"Module\" minOccurs=\"0\" maxOccurs=\"unbounded\">";
3019                         xmlData += "<xs:complexType>";
3020                         xmlData += "<xs:attribute name=\"ModuleId\" form=\"unqualified\" type=\"xs:int\" />";
3021                         xmlData += "</xs:complexType>";
3022                         xmlData += "</xs:element>";
3023                         xmlData += "</xs:sequence>";
3024                         xmlData += "<xs:attribute name=\"TabId\" form=\"unqualified\" type=\"xs:int\" />";
3025                         xmlData += "</xs:complexType>";
3026                         xmlData += "</xs:element>";
3027                         xmlData += "</xs:choice>";
3028                         xmlData += "</xs:complexType>";
3029                         xmlData += "<xs:key name=\"TabKey\" msdata:PrimaryKey=\"true\">";
3030                         xmlData += "<xs:selector xpath=\".//mstns:Tab\" />";
3031                         xmlData += "<xs:field xpath=\"@TabId\" />";
3032                         xmlData += "</xs:key>";
3033                         xmlData += "<xs:key name=\"ModuleKey\" msdata:PrimaryKey=\"true\">";
3034                         xmlData += "<xs:selector xpath=\".//mstns:Module\" />";
3035                         xmlData += "<xs:field xpath=\"@ModuleID\" />";
3036                         xmlData += "</xs:key>";
3037                         xmlData += "</xs:element>";
3038                         xmlData += "</xs:schema>";
3039                         dt.ReadXmlSchema (new StringReader (xmlData));
3040                 }
3041
3042                 [Test]
3043                 public void ReadXmlSchema_ByStream ()
3044                 {
3045                         DataSet ds1 = new DataSet ();
3046                         ds1.Tables.Add (DataProvider.CreateParentDataTable ());
3047                         ds1.Tables.Add (DataProvider.CreateChildDataTable ());
3048
3049                         MemoryStream ms1 = new MemoryStream ();
3050                         MemoryStream ms2 = new MemoryStream ();
3051                         //write xml  schema only
3052                         //ds1.WriteXmlSchema (ms);
3053                         ds1.Tables[0].WriteXmlSchema (ms1);
3054                         ds1.Tables[1].WriteXmlSchema (ms2);
3055
3056                         MemoryStream ms11 = new MemoryStream (ms1.GetBuffer ());
3057                         MemoryStream ms22 = new MemoryStream (ms2.GetBuffer ());
3058                         //copy schema
3059                         //DataSet ds2 = new DataSet ();
3060                         DataTable dt1 = new DataTable ();
3061                         DataTable dt2 = new DataTable ();
3062
3063                         //ds2.ReadXmlSchema (ms1);
3064                         dt1.ReadXmlSchema (ms11);
3065                         dt2.ReadXmlSchema (ms22);
3066
3067                         //check xml schema
3068                         // ReadXmlSchema - Tables count
3069                         //Assert.AreEqual (ds2.Tables.Count, ds1.Tables.Count, "DS269");
3070
3071                         // ReadXmlSchema - Tables 0 Col count
3072                         Assert.AreEqual (ds1.Tables[0].Columns.Count, dt1.Columns.Count, "DS270");
3073
3074                         // ReadXmlSchema - Tables 1 Col count
3075                         Assert.AreEqual (ds1.Tables[1].Columns.Count, dt2.Columns.Count, "DS271");
3076
3077                         //check some colummns types
3078                         // ReadXmlSchema - Tables 0 Col type
3079                         Assert.AreEqual (ds1.Tables[0].Columns[0].GetType (), dt1.Columns[0].GetType (), "DS272");
3080
3081                         // ReadXmlSchema - Tables 1 Col type
3082                         Assert.AreEqual (ds1.Tables[1].Columns[3].GetType (), dt2.Columns[3].GetType (), "DS273");
3083
3084                         //check that no data exists
3085                         // ReadXmlSchema - Table 1 row count
3086                         Assert.AreEqual (0, dt1.Rows.Count, "DS274");
3087
3088                         // ReadXmlSchema - Table 2 row count
3089                         Assert.AreEqual (0, dt2.Rows.Count, "DS275");
3090                 }
3091
3092                 [Test]
3093                 public void ReadWriteXmlSchema_ByFileName ()
3094                 {
3095                         string sTempFileName1 = Path.Combine (Path.GetTempPath (), "tmpDataSet_ReadWriteXml_43899-1.xml");
3096                         string sTempFileName2 = Path.Combine (Path.GetTempPath (), "tmpDataSet_ReadWriteXml_43899-2.xml");
3097
3098                         DataSet ds1 = new DataSet ();
3099                         ds1.Tables.Add (DataProvider.CreateParentDataTable ());
3100                         ds1.Tables.Add (DataProvider.CreateChildDataTable ());
3101
3102                         ds1.Tables[0].WriteXmlSchema (sTempFileName1);
3103                         ds1.Tables[1].WriteXmlSchema (sTempFileName2);
3104
3105                         DataTable dt1 = new DataTable ();
3106                         DataTable dt2 = new DataTable ();
3107
3108                         dt1.ReadXmlSchema (sTempFileName1);
3109                         dt2.ReadXmlSchema (sTempFileName2);
3110
3111                         Assert.AreEqual (ds1.Tables[0].Columns.Count, dt1.Columns.Count, "DS277");
3112                         Assert.AreEqual (ds1.Tables[1].Columns.Count, dt2.Columns.Count, "DS278");
3113                         Assert.AreEqual (ds1.Tables[0].Columns[0].GetType (), dt1.Columns[0].GetType (), "DS279");
3114                         Assert.AreEqual (ds1.Tables[1].Columns[3].GetType (), dt2.Columns[3].GetType (), "DS280");
3115                         Assert.AreEqual (0, dt1.Rows.Count, "DS281");
3116                         Assert.AreEqual (0, dt2.Rows.Count, "DS282");
3117
3118                         File.Delete (sTempFileName1);
3119                         File.Delete (sTempFileName2);
3120                 }
3121
3122                 [Test]
3123                 public void ReadXmlSchema_ByTextReader ()
3124                 {
3125                         DataSet ds1 = new DataSet ();
3126                         ds1.Tables.Add (DataProvider.CreateParentDataTable ());
3127                         ds1.Tables.Add (DataProvider.CreateChildDataTable ());
3128
3129                         StringWriter sw1 = new StringWriter ();
3130                         StringWriter sw2 = new StringWriter ();
3131                         //write xml file, schema only
3132                         //ds1.WriteXmlSchema (sw);
3133                         ds1.Tables[0].WriteXmlSchema (sw1);
3134                         ds1.Tables[1].WriteXmlSchema (sw2);
3135
3136                         StringReader sr1 = new StringReader (sw1.GetStringBuilder ().ToString ());
3137                         StringReader sr2 = new StringReader (sw2.GetStringBuilder ().ToString ());
3138                         //copy both data and schema
3139                         //DataSet ds2 = new DataSet ();
3140                         DataTable dt1 = new DataTable ();
3141                         DataTable dt2 = new DataTable ();
3142
3143                         //ds2.ReadXmlSchema (sr);
3144                         dt1.ReadXmlSchema (sr1);
3145                         dt2.ReadXmlSchema (sr2);
3146
3147                         //check xml schema
3148                         // ReadXmlSchema - Tables count
3149                         //Assert.AreEqual (ds2.Tables.Count, ds1.Tables.Count, "DS283");
3150
3151                         // ReadXmlSchema - Tables 0 Col count
3152                         Assert.AreEqual (ds1.Tables[0].Columns.Count, dt1.Columns.Count, "DS284");
3153
3154                         // ReadXmlSchema - Tables 1 Col count
3155                         Assert.AreEqual (ds1.Tables[1].Columns.Count, dt2.Columns.Count, "DS285");
3156
3157                         //check some colummns types
3158                         // ReadXmlSchema - Tables 0 Col type
3159                         Assert.AreEqual (ds1.Tables[0].Columns[0].GetType (), dt1.Columns[0].GetType (), "DS286");
3160
3161                         // ReadXmlSchema - Tables 1 Col type
3162                         Assert.AreEqual (ds1.Tables[1].Columns[3].GetType (), dt2.Columns[3].GetType (), "DS287");
3163
3164                         //check that no data exists
3165                         // ReadXmlSchema - Table 1 row count
3166                         Assert.AreEqual (0, dt1.Rows.Count, "DS288");
3167
3168                         // ReadXmlSchema - Table 2 row count
3169                         Assert.AreEqual (0, dt2.Rows.Count, "DS289");
3170                 }
3171
3172                 [Test]
3173                 public void ReadXmlSchema_ByXmlReader ()
3174                 {
3175                         DataSet ds1 = new DataSet ();
3176                         ds1.Tables.Add (DataProvider.CreateParentDataTable ());
3177                         ds1.Tables.Add (DataProvider.CreateChildDataTable ());
3178
3179                         StringWriter sw1 = new StringWriter ();
3180                         XmlTextWriter xmlTW1 = new XmlTextWriter (sw1);
3181                         StringWriter sw2 = new StringWriter ();
3182                         XmlTextWriter xmlTW2 = new XmlTextWriter (sw2);
3183
3184                         //write xml file, schema only
3185                         ds1.Tables[0].WriteXmlSchema (xmlTW1);
3186                         xmlTW1.Flush ();
3187                         ds1.Tables[1].WriteXmlSchema (xmlTW2);
3188                         xmlTW2.Flush ();
3189
3190                         StringReader sr1 = new StringReader (sw1.ToString ());
3191                         XmlTextReader xmlTR1 = new XmlTextReader (sr1);
3192                         StringReader sr2 = new StringReader (sw2.ToString ());
3193                         XmlTextReader xmlTR2 = new XmlTextReader (sr2);
3194
3195                         //copy both data and schema
3196                         //DataSet ds2 = new DataSet ();
3197                         DataTable dt1 = new DataTable ();
3198                         DataTable dt2 = new DataTable ();
3199
3200                         //ds2.ReadXmlSchema (xmlTR);
3201                         dt1.ReadXmlSchema (xmlTR1);
3202                         dt2.ReadXmlSchema (xmlTR2);
3203
3204                         //check xml schema
3205                         // ReadXmlSchema - Tables count
3206                         //Assert.AreEqual (ds2.Tables.Count, ds1.Tables.Count, "DS290");
3207
3208                         // ReadXmlSchema - Tables 0 Col count
3209                         Assert.AreEqual (ds1.Tables[0].Columns.Count, dt1.Columns.Count, "DS291");
3210
3211                         // ReadXmlSchema - Tables 1 Col count
3212                         Assert.AreEqual (ds1.Tables[1].Columns.Count, dt2.Columns.Count, "DS292");
3213
3214                         //check some colummns types
3215                         // ReadXmlSchema - Tables 0 Col type
3216                         Assert.AreEqual (ds1.Tables[0].Columns[0].GetType (), dt1.Columns[0].GetType (), "DS293");
3217
3218                         // ReadXmlSchema - Tables 1 Col type
3219                         Assert.AreEqual (ds1.Tables[1].Columns[3].GetType (), dt2.Columns[3].GetType (), "DS294");
3220
3221                         //check that no data exists
3222                         // ReadXmlSchema - Table 1 row count
3223                         Assert.AreEqual (0, dt1.Rows.Count, "DS295");
3224
3225                         // ReadXmlSchema - Table 2 row count
3226                         Assert.AreEqual (0, dt2.Rows.Count, "DS296");
3227                 }
3228
3229                 [Test]
3230                 [SetCulture ("en-GB")]
3231                 public void WriteXmlSchema ()
3232                 {
3233                         DataSet ds = new DataSet ();
3234                         ds.ReadXml ("Test/System.Data/region.xml");
3235                         TextWriter writer = new StringWriter ();
3236                         ds.Tables[0].WriteXmlSchema (writer);
3237
3238                         string TextString = GetNormalizedSchema (writer.ToString ());
3239                         //string TextString = writer.ToString ();
3240
3241                         EOL = "\n";
3242                         string substring = TextString.Substring (0, TextString.IndexOf (EOL));
3243                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3244                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
3245
3246                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3247                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3248                         Assert.AreEqual ("<xs:schema id=\"Root\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">", substring, "test#02");
3249
3250                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3251                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3252                         // Looks like whoever added this test depended on English culture, which is wrong.
3253                         Assert.AreEqual ("  <xs:element msdata:IsDataSet=\"true\" msdata:Locale=\"en-US\" msdata:MainDataTable=\"Region\" name=\"Root\">", substring, "test#03");
3254
3255                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3256                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3257                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
3258
3259                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3260                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3261                         Assert.AreEqual ("      <xs:choice maxOccurs=\"unbounded\" minOccurs=\"0\">", substring, "test#05");
3262
3263                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3264                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3265                         Assert.AreEqual ("        <xs:element name=\"Region\">", substring, "test#06");
3266
3267                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3268                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3269                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
3270
3271                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3272                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3273                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
3274
3275                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3276                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3277                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" name=\"RegionID\" type=\"xs:string\" />", substring, "test#09");
3278
3279                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3280                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3281                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" name=\"RegionDescription\" type=\"xs:string\" />", substring, "test#10");
3282
3283                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3284                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3285                         Assert.AreEqual ("            </xs:sequence>", substring, "test#11");
3286
3287                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3288                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3289                         Assert.AreEqual ("          </xs:complexType>", substring, "test#12");
3290
3291                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3292                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3293                         Assert.AreEqual ("        </xs:element>", substring, "test#13");
3294
3295                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3296                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3297                         Assert.AreEqual ("      </xs:choice>", substring, "test#14");
3298
3299                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3300                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3301                         Assert.AreEqual ("    </xs:complexType>", substring, "test#15");
3302
3303                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3304                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3305                         Assert.AreEqual ("  </xs:element>", substring, "test#16");
3306
3307                         Assert.AreEqual ("</xs:schema>", TextString, "test#17");
3308                 }
3309
3310                 [Test]
3311                 public void WriteXmlSchema2 ()
3312                 {
3313                         string xml = @"<myDataSet xmlns='NetFrameWork'><myTable><id>0</id><item>item 0</item></myTable><myTable><id>1</id><item>item 1</item></myTable><myTable><id>2</id><item>item 2</item></myTable><myTable><id>3</id><item>item 3</item></myTable><myTable><id>4</id><item>item 4</item></myTable><myTable><id>5</id><item>item 5</item></myTable><myTable><id>6</id><item>item 6</item></myTable><myTable><id>7</id><item>item 7</item></myTable><myTable><id>8</id><item>item 8</item></myTable><myTable><id>9</id><item>item 9</item></myTable></myDataSet>";
3314                         string schema = @"<?xml version='1.0' encoding='utf-16'?>
3315 <xs:schema id='myDataSet' targetNamespace='NetFrameWork' xmlns:mstns='NetFrameWork' xmlns='NetFrameWork' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata' attributeFormDefault='qualified' elementFormDefault='qualified'>
3316   <xs:element name='myDataSet' msdata:IsDataSet='true' msdata:MainDataTable='NetFrameWork_x003A_myTable' msdata:UseCurrentLocale='true'>
3317     <xs:complexType>
3318       <xs:choice minOccurs='0' maxOccurs='unbounded'>
3319         <xs:element name='myTable'>
3320           <xs:complexType>
3321             <xs:sequence>
3322               <xs:element name='id' msdata:AutoIncrement='true' type='xs:int' minOccurs='0' />
3323               <xs:element name='item' type='xs:string' minOccurs='0' />
3324             </xs:sequence>
3325           </xs:complexType>
3326         </xs:element>
3327       </xs:choice>
3328     </xs:complexType>
3329   </xs:element>
3330 </xs:schema>";
3331                         DataSet OriginalDataSet = new DataSet ("myDataSet");
3332                         OriginalDataSet.Namespace = "NetFrameWork";
3333                         DataTable myTable = new DataTable ("myTable");
3334                         DataColumn c1 = new DataColumn ("id", typeof (int));
3335                         c1.AutoIncrement = true;
3336                         DataColumn c2 = new DataColumn ("item");
3337                         myTable.Columns.Add (c1);
3338                         myTable.Columns.Add (c2);
3339                         OriginalDataSet.Tables.Add (myTable);
3340                         // Add ten rows.
3341                         DataRow newRow;
3342                         for (int i = 0; i < 10; i++) {
3343                                 newRow = myTable.NewRow ();
3344                                 newRow["item"] = "item " + i;
3345                                 myTable.Rows.Add (newRow);
3346                         }
3347                         OriginalDataSet.AcceptChanges ();
3348
3349                         StringWriter sw = new StringWriter ();
3350                         XmlTextWriter xtw = new XmlTextWriter (sw);
3351                         xtw.QuoteChar = '\'';
3352                         OriginalDataSet.WriteXml (xtw);
3353                         string result = sw.ToString ();
3354
3355                         Assert.AreEqual (xml, result);
3356
3357                         sw = new StringWriter ();
3358                         xtw = new XmlTextWriter (sw);
3359                         xtw.Formatting = Formatting.Indented;
3360                         OriginalDataSet.Tables[0].WriteXmlSchema (xtw);
3361                         result = sw.ToString ();
3362
3363                         result = result.Replace ("\r\n", "\n").Replace ('"', '\'');
3364                         Assert.AreEqual (schema.Replace ("\r\n", "\n"), result);
3365                 }
3366
3367                 [Test]
3368                 public void WriteXmlSchema3 ()
3369                 {
3370                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
3371 <xs:schema id=""ExampleDataSet"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3372   <xs:element name=""ExampleDataSet"" msdata:IsDataSet=""true"" msdata:MainDataTable=""ExampleDataTable"" msdata:UseCurrentLocale=""true"">
3373     <xs:complexType>
3374       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3375         <xs:element name=""ExampleDataTable"">
3376           <xs:complexType>
3377             <xs:attribute name=""PrimaryKeyColumn"" type=""xs:int"" use=""required"" />
3378           </xs:complexType>
3379         </xs:element>
3380       </xs:choice>
3381     </xs:complexType>
3382     <xs:unique name=""PK_ExampleDataTable"" msdata:PrimaryKey=""true"">
3383       <xs:selector xpath="".//ExampleDataTable"" />
3384       <xs:field xpath=""@PrimaryKeyColumn"" />
3385     </xs:unique>
3386   </xs:element>
3387 </xs:schema>";
3388                         DataSet ds = new DataSet ("ExampleDataSet");
3389
3390                         ds.Tables.Add (new DataTable ("ExampleDataTable"));
3391                         ds.Tables["ExampleDataTable"].Columns.Add (
3392                                 new DataColumn ("PrimaryKeyColumn", typeof (int), "", MappingType.Attribute));
3393                         ds.Tables["ExampleDataTable"].Columns["PrimaryKeyColumn"].AllowDBNull = false;
3394
3395                         ds.Tables["ExampleDataTable"].Constraints.Add (
3396                                 "PK_ExampleDataTable",
3397                                 ds.Tables["ExampleDataTable"].Columns["PrimaryKeyColumn"],
3398                                 true);
3399
3400                         ds.AcceptChanges ();
3401                         StringWriter sw = new StringWriter ();
3402                         ds.Tables[0].WriteXmlSchema (sw);
3403
3404                         string result = sw.ToString ();
3405
3406                         Assert.AreEqual (xmlschema.Replace ("\r\n", "\n"), result.Replace ("\r\n", "\n"));
3407                         //Assert.AreEqual (xmlschema, result.Replace ("\r\n", "\n"));
3408                 }
3409
3410                 [Test]
3411                 public void WriteXmlSchema4 ()
3412                 {
3413                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
3414 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3415   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""MyType"" msdata:UseCurrentLocale=""true"">
3416     <xs:complexType>
3417       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3418         <xs:element name=""MyType"">
3419           <xs:complexType>
3420             <xs:attribute name=""ID"" type=""xs:int"" use=""required"" />
3421             <xs:attribute name=""Desc"" type=""xs:string"" />
3422           </xs:complexType>
3423         </xs:element>
3424       </xs:choice>
3425     </xs:complexType>
3426   </xs:element>
3427 </xs:schema>";
3428                         DataSet ds = new DataSet ("Example");
3429
3430                         // Add MyType DataTable
3431                         DataTable dt = new DataTable ("MyType");
3432                         ds.Tables.Add (dt);
3433
3434                         dt.Columns.Add (new DataColumn ("ID", typeof (int), "",
3435                                 MappingType.Attribute));
3436                         dt.Columns["ID"].AllowDBNull = false;
3437
3438                         dt.Columns.Add (new DataColumn ("Desc", typeof
3439                                 (string), "", MappingType.Attribute));
3440
3441                         ds.AcceptChanges ();
3442
3443                         StringWriter sw = new StringWriter ();
3444                         ds.Tables[0].WriteXmlSchema (sw);
3445
3446                         string result = sw.ToString ();
3447
3448                         Assert.AreEqual (xmlschema.Replace ("\r\n", "\n"), result.Replace ("\r\n", "\n"));
3449                 }
3450
3451                 [Test]
3452                 public void WriteXmlSchema5 ()
3453                 {
3454                         string xmlschema1 = @"<?xml version=""1.0"" encoding=""utf-16""?>
3455 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3456   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""StandAlone"" msdata:UseCurrentLocale=""true"">
3457     <xs:complexType>
3458       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3459         <xs:element name=""StandAlone"">
3460           <xs:complexType>
3461             <xs:attribute name=""ID"" type=""xs:int"" use=""required"" />
3462             <xs:attribute name=""Desc"" type=""xs:string"" use=""required"" />
3463           </xs:complexType>
3464         </xs:element>
3465       </xs:choice>
3466     </xs:complexType>
3467   </xs:element>
3468 </xs:schema>";
3469                         string xmlschema2 = @"<?xml version=""1.0"" encoding=""utf-16""?>
3470 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3471   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""Dimension"" msdata:UseCurrentLocale=""true"">
3472     <xs:complexType>
3473       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3474         <xs:element name=""Dimension"">
3475           <xs:complexType>
3476             <xs:attribute name=""Number"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
3477             <xs:attribute name=""Title"" type=""xs:string"" use=""required"" />
3478           </xs:complexType>
3479         </xs:element>
3480       </xs:choice>
3481     </xs:complexType>
3482     <xs:unique name=""PK_Dimension"" msdata:PrimaryKey=""true"">
3483       <xs:selector xpath="".//Dimension"" />
3484       <xs:field xpath=""@Number"" />
3485     </xs:unique>
3486   </xs:element>
3487 </xs:schema>";
3488                         string xmlschema3 = @"<?xml version=""1.0"" encoding=""utf-16""?>
3489 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3490   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""Element"" msdata:UseCurrentLocale=""true"">
3491     <xs:complexType>
3492       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3493         <xs:element name=""Element"">
3494           <xs:complexType>
3495             <xs:attribute name=""Dimension"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
3496             <xs:attribute name=""Number"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
3497             <xs:attribute name=""Title"" type=""xs:string"" use=""required"" />
3498           </xs:complexType>
3499         </xs:element>
3500       </xs:choice>
3501     </xs:complexType>
3502     <xs:unique name=""PK_Element"" msdata:PrimaryKey=""true"">
3503       <xs:selector xpath="".//Element"" />
3504       <xs:field xpath=""@Dimension"" />
3505       <xs:field xpath=""@Number"" />
3506     </xs:unique>
3507   </xs:element>
3508 </xs:schema>";
3509                         DataSet ds = new DataSet ("Example");
3510
3511                         // Add a DataTable with no ReadOnly columns
3512                         DataTable dt1 = new DataTable ("StandAlone");
3513                         ds.Tables.Add (dt1);
3514
3515                         // Add a ReadOnly column
3516                         dt1.Columns.Add (new DataColumn ("ID", typeof (int), "",
3517                                 MappingType.Attribute));
3518                         dt1.Columns["ID"].AllowDBNull = false;
3519
3520                         dt1.Columns.Add (new DataColumn ("Desc", typeof
3521                                 (string), "", MappingType.Attribute));
3522                         dt1.Columns["Desc"].AllowDBNull = false;
3523
3524                         // Add related DataTables with ReadOnly columns
3525                         DataTable dt2 = new DataTable ("Dimension");
3526                         ds.Tables.Add (dt2);
3527                         dt2.Columns.Add (new DataColumn ("Number", typeof
3528                                 (int), "", MappingType.Attribute));
3529                         dt2.Columns["Number"].AllowDBNull = false;
3530                         dt2.Columns["Number"].ReadOnly = true;
3531
3532                         dt2.Columns.Add (new DataColumn ("Title", typeof
3533                                 (string), "", MappingType.Attribute));
3534                         dt2.Columns["Title"].AllowDBNull = false;
3535
3536                         dt2.Constraints.Add ("PK_Dimension", dt2.Columns["Number"], true);
3537
3538                         DataTable dt3 = new DataTable ("Element");
3539                         ds.Tables.Add (dt3);
3540
3541                         dt3.Columns.Add (new DataColumn ("Dimension", typeof
3542                                 (int), "", MappingType.Attribute));
3543                         dt3.Columns["Dimension"].AllowDBNull = false;
3544                         dt3.Columns["Dimension"].ReadOnly = true;
3545
3546                         dt3.Columns.Add (new DataColumn ("Number", typeof
3547                                 (int), "", MappingType.Attribute));
3548                         dt3.Columns["Number"].AllowDBNull = false;
3549                         dt3.Columns["Number"].ReadOnly = true;
3550
3551                         dt3.Columns.Add (new DataColumn ("Title", typeof
3552                                 (string), "", MappingType.Attribute));
3553                         dt3.Columns["Title"].AllowDBNull = false;
3554
3555                         dt3.Constraints.Add ("PK_Element", new DataColumn[] { 
3556                                 dt3.Columns ["Dimension"],
3557                                 dt3.Columns ["Number"] }, true);
3558
3559                         ds.AcceptChanges ();
3560
3561                         StringWriter sw1 = new StringWriter ();
3562                         ds.Tables[0].WriteXmlSchema (sw1);
3563                         string result1 = sw1.ToString ();
3564                         Assert.AreEqual (xmlschema1.Replace ("\r\n", "\n"), result1.Replace ("\r\n", "\n"));
3565
3566                         StringWriter sw2 = new StringWriter ();
3567                         ds.Tables[1].WriteXmlSchema (sw2);
3568                         string result2 = sw2.ToString ();
3569                         Assert.AreEqual (xmlschema2.Replace ("\r\n", "\n"), result2.Replace ("\r\n", "\n"));
3570
3571                         StringWriter sw3 = new StringWriter ();
3572                         ds.Tables[2].WriteXmlSchema (sw3);
3573                         string result3 = sw3.ToString ();
3574                         Assert.AreEqual (xmlschema3.Replace ("\r\n", "\n"), result3.Replace ("\r\n", "\n"));
3575                 }
3576
3577                 [Test]
3578                 public void WriteXmlSchema6 ()
3579                 {
3580                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
3581 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3582   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""MyType"" msdata:UseCurrentLocale=""true"">
3583     <xs:complexType>
3584       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3585         <xs:element name=""MyType"">
3586           <xs:complexType>
3587             <xs:attribute name=""Desc"">
3588               <xs:simpleType>
3589                 <xs:restriction base=""xs:string"">
3590                   <xs:maxLength value=""32"" />
3591                 </xs:restriction>
3592               </xs:simpleType>
3593             </xs:attribute>
3594           </xs:complexType>
3595         </xs:element>
3596       </xs:choice>
3597     </xs:complexType>
3598   </xs:element>
3599 </xs:schema>";
3600                         DataSet ds = new DataSet ("Example");
3601
3602                         // Add MyType DataTable
3603                         ds.Tables.Add ("MyType");
3604
3605                         ds.Tables["MyType"].Columns.Add (new DataColumn (
3606                                 "Desc", typeof (string), "", MappingType.Attribute));
3607                         ds.Tables["MyType"].Columns["Desc"].MaxLength = 32;
3608
3609                         ds.AcceptChanges ();
3610
3611                         StringWriter sw = new StringWriter ();
3612                         ds.Tables[0].WriteXmlSchema (sw);
3613
3614                         string result = sw.ToString ();
3615
3616                         Assert.AreEqual (xmlschema.Replace ("\r\n", "\n"), result.Replace ("\r\n", "\n"));
3617                 }
3618
3619                 [Test]
3620                 public void WriteXmlSchema7 ()
3621                 {
3622                         DataSet ds = new DataSet ();
3623                         DataTable dt = new DataTable ("table");
3624                         dt.Columns.Add ("col1");
3625                         dt.Columns.Add ("col2");
3626                         ds.Tables.Add (dt);
3627                         dt.Rows.Add (new object[] { "foo", "bar" });
3628                         StringWriter sw = new StringWriter ();
3629                         ds.Tables[0].WriteXmlSchema (sw);
3630                         Assert.IsTrue (sw.ToString ().IndexOf ("xmlns=\"\"") > 0);
3631                 }
3632
3633                 [Test]
3634                 public void WriteXmlSchema_ConstraintNameWithSpaces ()
3635                 {
3636                         DataSet ds = new DataSet ();
3637                         DataTable table1 = ds.Tables.Add ("table1");
3638                         DataTable table2 = ds.Tables.Add ("table2");
3639
3640                         table1.Columns.Add ("col1", typeof (int));
3641                         table2.Columns.Add ("col1", typeof (int));
3642
3643                         table1.Constraints.Add ("uc 1", table1.Columns[0], false);
3644                         table2.Constraints.Add ("fc 1", table1.Columns[0], table2.Columns[0]);
3645
3646                         StringWriter sw1 = new StringWriter ();
3647                         StringWriter sw2 = new StringWriter ();
3648
3649                         //should not throw an exception
3650                         ds.Tables[0].WriteXmlSchema (sw1);
3651                         ds.Tables[1].WriteXmlSchema (sw2);
3652                 }
3653
3654                 [Test]
3655                 public void WriteXmlSchema_ForignKeyConstraint ()
3656                 {
3657                         DataSet ds1 = new DataSet ();
3658
3659                         DataTable table1 = ds1.Tables.Add ();
3660                         DataTable table2 = ds1.Tables.Add ();
3661
3662                         DataColumn col1_1 = table1.Columns.Add ("col1", typeof (int));
3663                         DataColumn col2_1 = table2.Columns.Add ("col1", typeof (int));
3664
3665                         table2.Constraints.Add ("fk", col1_1, col2_1);
3666
3667                         StringWriter sw1 = new StringWriter ();
3668                         ds1.Tables[0].WriteXmlSchema (sw1);
3669                         String xml1 = sw1.ToString ();
3670                         Assert.IsTrue (xml1.IndexOf (@"<xs:unique name=""Constraint1"">") != -1, "#1");
3671
3672                         StringWriter sw2 = new StringWriter ();
3673                         ds1.Tables[1].WriteXmlSchema (sw2);
3674                         String xml2 = sw2.ToString ();
3675                         Assert.IsTrue (xml2.IndexOf (@"<xs:unique name=""Constraint1"">") == -1, "#2");
3676                 }
3677
3678                 [Test]
3679                 public void WriteXmlSchema_Relations_ForeignKeys ()
3680                 {
3681                         MemoryStream ms1 = null;
3682                         MemoryStream ms2 = null;
3683                         MemoryStream msA = null;
3684                         MemoryStream msB = null;
3685
3686                         DataSet ds1 = new DataSet ();
3687
3688                         DataTable table1 = ds1.Tables.Add ("Table 1");
3689                         DataTable table2 = ds1.Tables.Add ("Table 2");
3690
3691                         DataColumn col1_1 = table1.Columns.Add ("col 1", typeof (int));
3692                         DataColumn col1_2 = table1.Columns.Add ("col 2", typeof (int));
3693                         DataColumn col1_3 = table1.Columns.Add ("col 3", typeof (int));
3694                         DataColumn col1_4 = table1.Columns.Add ("col 4", typeof (int));
3695                         DataColumn col1_5 = table1.Columns.Add ("col 5", typeof (int));
3696                         DataColumn col1_6 = table1.Columns.Add ("col 6", typeof (int));
3697                         DataColumn col1_7 = table1.Columns.Add ("col 7", typeof (int));
3698
3699                         DataColumn col2_1 = table2.Columns.Add ("col 1", typeof (int));
3700                         DataColumn col2_2 = table2.Columns.Add ("col 2", typeof (int));
3701                         DataColumn col2_3 = table2.Columns.Add ("col 3", typeof (int));
3702                         DataColumn col2_4 = table2.Columns.Add ("col 4", typeof (int));
3703                         DataColumn col2_5 = table2.Columns.Add ("col 5", typeof (int));
3704                         DataColumn col2_6 = table2.Columns.Add ("col 6", typeof (int));
3705                         DataColumn col2_7 = table2.Columns.Add ("col 7", typeof (int));
3706
3707                         ds1.Relations.Add ("rel 1",
3708                                 new DataColumn[] { col1_1, col1_2 },
3709                                 new DataColumn[] { col2_1, col2_2 },
3710                                 false);
3711                         ds1.Relations.Add ("rel 2",
3712                                 new DataColumn[] { col1_3, col1_4 },
3713                                 new DataColumn[] { col2_3, col2_4 },
3714                                 true);
3715                         table2.Constraints.Add ("fk 1",
3716                                 new DataColumn[] { col1_5, col1_6 },
3717                                 new DataColumn[] { col2_5, col2_6 });
3718                         table1.Constraints.Add ("fk 2",
3719                                 new DataColumn[] { col2_5, col2_6 },
3720                                 new DataColumn[] { col1_5, col1_6 });
3721
3722                         table1.Constraints.Add ("pk 1", col1_7, true);
3723                         table2.Constraints.Add ("pk 2", col2_7, true);
3724
3725                         ms1 = new MemoryStream ();
3726                         ds1.Tables[0].WriteXmlSchema (ms1);
3727                         ms2 = new MemoryStream ();
3728                         ds1.Tables[1].WriteXmlSchema (ms2);
3729
3730                         msA = new MemoryStream (ms1.GetBuffer ());
3731                         DataTable dtA = new DataTable ();
3732                         dtA.ReadXmlSchema (msA);
3733
3734                         msB = new MemoryStream (ms2.GetBuffer ());
3735                         DataTable dtB = new DataTable ();
3736                         dtB.ReadXmlSchema (msB);
3737
3738                         Assert.AreEqual (3, dtA.Constraints.Count, "#2");
3739                         Assert.AreEqual (2, dtB.Constraints.Count, "#3");
3740
3741                         Assert.IsTrue (dtA.Constraints.Contains ("pk 1"), "#5");
3742                         Assert.IsTrue (dtA.Constraints.Contains ("Constraint1"), "#6");
3743                         Assert.IsTrue (dtA.Constraints.Contains ("Constraint2"), "#7");
3744                         Assert.IsTrue (dtB.Constraints.Contains ("pk 2"), "#9");
3745                         Assert.IsTrue (dtB.Constraints.Contains ("Constraint1"), "#10");
3746                 }
3747
3748                 [Test]
3749                 [Category ("NotWorking")]
3750                 public void WriteXmlSchema_DifferentNamespace ()
3751                 {
3752                         string schema = @"<xs:schema id='NewDataSet' targetNamespace='urn:bar' xmlns:mstns='urn:bar' xmlns='urn:bar' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata' attributeFormDefault='qualified' elementFormDefault='qualified' xmlns:app1='urn:baz' xmlns:app2='urn:foo' msdata:schemafragmentcount='3'>
3753   <xs:import namespace='urn:foo' />
3754   <xs:import namespace='urn:baz' />
3755   <xs:element name='NewDataSet' msdata:IsDataSet='true' msdata:MainDataTable='urn_x003A_foo_x003A_NS1Table' msdata:UseCurrentLocale='true'>
3756     <xs:complexType>
3757       <xs:choice minOccurs='0' maxOccurs='unbounded'>
3758         <xs:element ref='app2:NS1Table' />
3759       </xs:choice>
3760     </xs:complexType>
3761   </xs:element>
3762 </xs:schema>
3763 <xs:schema targetNamespace='urn:baz' xmlns:mstns='urn:bar' xmlns='urn:baz' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata' attributeFormDefault='qualified' elementFormDefault='qualified' xmlns:app1='urn:baz' xmlns:app2='urn:foo'>
3764   <xs:import namespace='urn:foo' />
3765   <xs:import namespace='urn:bar' />
3766   <xs:element name='column2' type='xs:string' />
3767 </xs:schema>
3768 <xs:schema targetNamespace='urn:foo' xmlns:mstns='urn:bar' xmlns='urn:foo' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata' attributeFormDefault='qualified' elementFormDefault='qualified' xmlns:app2='urn:foo' xmlns:app1='urn:baz'>
3769   <xs:import namespace='urn:bar' />
3770   <xs:import namespace='urn:baz' />
3771   <xs:element name='NS1Table'>
3772     <xs:complexType>
3773       <xs:sequence>
3774         <xs:element name='column1' type='xs:string' minOccurs='0' />
3775         <xs:element ref='app1:column2' minOccurs='0' />
3776       </xs:sequence>
3777     </xs:complexType>
3778   </xs:element>
3779 </xs:schema>";
3780                         DataSet ds = new DataSet ();
3781                         DataTable dt = new DataTable ();
3782                         dt.TableName = "NS1Table";
3783                         dt.Namespace = "urn:foo";
3784                         dt.Columns.Add ("column1");
3785                         dt.Columns.Add ("column2");
3786                         dt.Columns[1].Namespace = "urn:baz";
3787                         ds.Tables.Add (dt);
3788                         DataTable dt2 = new DataTable ();
3789                         dt2.TableName = "NS2Table";
3790                         dt2.Namespace = "urn:bar";
3791                         ds.Tables.Add (dt2);
3792                         ds.Namespace = "urn:bar";
3793
3794                         StringWriter sw1 = new StringWriter ();
3795                         XmlTextWriter xw1 = new XmlTextWriter (sw1);
3796                         xw1.Formatting = Formatting.Indented;
3797                         xw1.QuoteChar = '\'';
3798                         ds.Tables[0].WriteXmlSchema (xw1);
3799                         string result1 = sw1.ToString ();
3800                         Assert.AreEqual (schema, result1.Replace ("\r\n", "\n"), "#1");
3801
3802                         StringWriter sw2 = new StringWriter ();
3803                         XmlTextWriter xw2 = new XmlTextWriter (sw2);
3804                         xw2.Formatting = Formatting.Indented;
3805                         xw2.QuoteChar = '\'';
3806                         ds.Tables[0].WriteXmlSchema (xw2);
3807                         string result2 = sw2.ToString ();
3808                         Assert.AreEqual (schema, result2.Replace ("\r\n", "\n"), "#2");
3809                 }
3810
3811                 [Test]
3812                 public void WriteXmlSchema_Hierarchy ()
3813                 {
3814                         DataSet ds = new DataSet ();
3815                         DataTable table1 = new DataTable ();
3816                         DataColumn idColumn = table1.Columns.Add ("ID", typeof (Int32));
3817                         table1.Columns.Add ("Name", typeof (String));
3818                         table1.PrimaryKey = new DataColumn[] { idColumn };
3819                         DataTable table2 = new DataTable ();
3820                         table2.Columns.Add (new DataColumn ("OrderID", typeof (Int32)));
3821                         table2.Columns.Add (new DataColumn ("CustomerID", typeof (Int32)));
3822                         table2.Columns.Add (new DataColumn ("OrderDate", typeof (DateTime)));
3823                         table2.PrimaryKey = new DataColumn[] { table2.Columns[0] };
3824                         ds.Tables.Add (table1);
3825                         ds.Tables.Add (table2);
3826                         ds.Relations.Add ("CustomerOrder",
3827                                 new DataColumn[] { table1.Columns[0] },
3828                                 new DataColumn[] { table2.Columns[1] }, true);
3829
3830                         StringWriter writer1 = new StringWriter ();
3831                         table1.WriteXmlSchema (writer1, false);
3832                         string expected1 = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<xs:schema id=\"NewDataSet\" xmlns=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n  <xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"Table1\" msdata:UseCurrentLocale=\"true\">\n    <xs:complexType>\n      <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xs:element name=\"Table1\">\n          <xs:complexType>\n            <xs:sequence>\n              <xs:element name=\"ID\" type=\"xs:int\" />\n              <xs:element name=\"Name\" type=\"xs:string\" minOccurs=\"0\" />\n            </xs:sequence>\n          </xs:complexType>\n        </xs:element>\n      </xs:choice>\n    </xs:complexType>\n    <xs:unique name=\"Constraint1\" msdata:PrimaryKey=\"true\">\n      <xs:selector xpath=\".//Table1\" />\n      <xs:field xpath=\"ID\" />\n    </xs:unique>\n  </xs:element>\n</xs:schema>";
3833                         Assert.AreEqual (expected1, writer1.ToString().Replace("\r\n", "\n"), "#1");
3834
3835                         StringWriter writer2 = new StringWriter ();
3836                         table1.WriteXmlSchema (writer2, true);
3837                         string expected2 = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<xs:schema id=\"NewDataSet\" xmlns=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n  <xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"Table1\" msdata:UseCurrentLocale=\"true\">\n    <xs:complexType>\n      <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n        <xs:element name=\"Table1\">\n          <xs:complexType>\n            <xs:sequence>\n              <xs:element name=\"ID\" type=\"xs:int\" />\n              <xs:element name=\"Name\" type=\"xs:string\" minOccurs=\"0\" />\n            </xs:sequence>\n          </xs:complexType>\n        </xs:element>\n        <xs:element name=\"Table2\">\n          <xs:complexType>\n            <xs:sequence>\n              <xs:element name=\"OrderID\" type=\"xs:int\" />\n              <xs:element name=\"CustomerID\" type=\"xs:int\" minOccurs=\"0\" />\n              <xs:element name=\"OrderDate\" type=\"xs:dateTime\" minOccurs=\"0\" />\n            </xs:sequence>\n          </xs:complexType>\n        </xs:element>\n      </xs:choice>\n    </xs:complexType>\n    <xs:unique name=\"Constraint1\" msdata:PrimaryKey=\"true\">\n      <xs:selector xpath=\".//Table1\" />\n      <xs:field xpath=\"ID\" />\n    </xs:unique>\n    <xs:unique name=\"Table2_Constraint1\" msdata:ConstraintName=\"Constraint1\" msdata:PrimaryKey=\"true\">\n      <xs:selector xpath=\".//Table2\" />\n      <xs:field xpath=\"OrderID\" />\n    </xs:unique>\n    <xs:keyref name=\"CustomerOrder\" refer=\"Constraint1\">\n      <xs:selector xpath=\".//Table2\" />\n      <xs:field xpath=\"CustomerID\" />\n    </xs:keyref>\n  </xs:element>\n</xs:schema>";
3838                         Assert.AreEqual (expected2, writer2.ToString ().Replace("\r\n", "\n"), "#2");
3839                 }
3840
3841                 [Test]
3842                 [Ignore ("MS behavior is far from consistent to be regarded as a reference implementation.")]
3843                 // See the same-named tests in DataSetTest.cs
3844                 // WriteXmlSchema doesn't have overload wityh 2 parameters in System.Data
3845                 // and is commented-out TWICE below
3846                 public void ReadWriteXmlSchema()
3847                 {
3848                         DataSet ds = new DataSet();
3849                         ds.ReadXmlSchema("Test/System.Data/store.xsd");
3850                         // check dataset properties before testing write
3851                         AssertDataSet("ds", ds, "NewDataSet", 3, 2);
3852                         AssertDataTable("tab1", ds.Tables[0], "bookstore", 1, 0, 0, 1, 1, 1);
3853                         AssertDataTable("tab2", ds.Tables[1], "book", 5, 0, 1, 1, 2, 1);
3854                         AssertDataTable("tab3", ds.Tables[2], "author", 3, 0, 1, 0, 1, 0);
3855                         // FIXME: currently order is not compatible. Use name as index
3856                         AssertDataRelation("rel1", ds.Relations["book_author"], "book_author", true, new string[] { "book_Id" }, new string[] { "book_Id" }, true, true);
3857                         AssertDataRelation("rel2", ds.Relations["bookstore_book"], "bookstore_book", true, new string[] { "bookstore_Id" }, new string[] { "bookstore_Id" }, true, true);
3858
3859                         ds.ReadXml("Test/System.Data/region.xml", XmlReadMode.InferSchema);
3860                         ds.Relations.Clear(); // because can not call WriteXmlSchema with nested relations.
3861
3862                         TextWriter writer1 = new StringWriter();
3863                         ds.Tables[0].WriteXmlSchema(writer1);
3864                         //string TextString1 = GetNormalizedSchema(writer1.ToString());
3865                         string TextString1 = writer1.ToString();
3866                         string expected1 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3867 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3868   @"<xs:complexType name=""bookstoreType"">" +
3869   @"</xs:complexType>" +
3870   @"<xs:element name=""bookstore"" type=""bookstoreType"" />" +
3871   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""bookstore"" msdata:Locale=""en-US"">" +
3872     @"<xs:complexType>" +
3873       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3874     @"<xs:element ref=""bookstore"" />" +
3875       @"</xs:choice>" +
3876     @"</xs:complexType>" +
3877   @"</xs:element>" +
3878 @"</xs:schema>";
3879                         Assert.AreEqual(expected1.Replace("\n", ""), TextString1.Replace("\r\n", "").Replace("  ", "").Replace("\n", ""), "#1");
3880
3881                         TextWriter writer2 = new StringWriter();
3882                         ds.Tables[1].WriteXmlSchema(writer2, false);
3883                         //string TextString2 = GetNormalizedSchema(writer2.ToString());
3884                         string TextString2 = writer2.ToString();
3885                         string expected2 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3886 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3887   @"<xs:complexType name=""bookType"">" +
3888     @"<xs:sequence>" +
3889       @"<xs:element name=""title"" type=""xs:string"" msdata:Ordinal=""1"" />" +
3890       @"<xs:element name=""price"" type=""xs:decimal"" msdata:Ordinal=""2"" />" +
3891     @"</xs:sequence>" +
3892     @"<xs:attribute name=""genre"" type=""xs:string"" />" +
3893     @"<xs:attribute name=""bookstore_Id"" type=""xs:int"" use=""prohibited"" />" +
3894   @"</xs:complexType>" +
3895   @"<xs:element name=""book"" type=""bookType"" />" +
3896   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""book"" msdata:Locale=""en-US"">" +
3897     @"<xs:complexType>" +
3898       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3899     @"<xs:element ref=""book"" />" +
3900       @"</xs:choice>" +
3901     @"</xs:complexType>" +
3902   @"</xs:element>" +
3903 @"</xs:schema>";
3904                         Assert.AreEqual(expected2, TextString2.Replace("\r\n", "").Replace("  ", ""), "#2");
3905
3906                         TextWriter writer3 = new StringWriter();
3907                         ds.Tables[2].WriteXmlSchema(writer3);
3908                         //string TextString3 = GetNormalizedSchema(writer3.ToString());
3909                         string TextString3 = writer3.ToString();
3910                         string expected3 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3911 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3912   @"<xs:complexType name=""authorName"">" +
3913     @"<xs:sequence>" +
3914       @"<xs:element name=""first-name"" type=""xs:string"" msdata:Ordinal=""0"" />" +
3915       @"<xs:element name=""last-name"" type=""xs:string"" msdata:Ordinal=""1"" />" +
3916     @"</xs:sequence>" +
3917     @"<xs:attribute name=""book_Id"" type=""xs:int"" use=""prohibited"" />" +
3918   @"</xs:complexType>" +
3919   @"<xs:element name=""author"" type=""authorName"" />" +
3920   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""author"" msdata:Locale=""en-US"">" +
3921     @"<xs:complexType>" +
3922       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3923         @"<xs:element ref=""author"" />" +
3924       @"</xs:choice>" +
3925     @"</xs:complexType>" +
3926   @"</xs:element>" +
3927 @"</xs:schema>";
3928                         Assert.AreEqual(expected3, TextString3.Replace("\r\n", "").Replace("  ", ""), "#3");
3929
3930                         TextWriter writer4 = new StringWriter();
3931                         ds.Tables[3].WriteXmlSchema(writer4);
3932                         //string TextString4 = GetNormalizedSchema(writer4.ToString());
3933                         string TextString4 = writer4.ToString();
3934                         string expected4 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3935 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3936   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""Region"" msdata:Locale=""en-US"">" +
3937     @"<xs:complexType>" +
3938       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3939         @"<xs:element name=""Region"">" +
3940           @"<xs:complexType>" +
3941             @"<xs:sequence>" +
3942               @"<xs:element name=""RegionID"" type=""xs:string"" minOccurs=""0"" />" +
3943               @"<xs:element name=""RegionDescription"" type=""xs:string"" minOccurs=""0"" />" +
3944             @"</xs:sequence>" +
3945           @"</xs:complexType>" +
3946         @"</xs:element>" +
3947       @"</xs:choice>" +
3948     @"</xs:complexType>" +
3949   @"</xs:element>" +
3950 @"</xs:schema>";
3951                         Assert.AreEqual(expected4, TextString4.Replace("\r\n", "").Replace("  ", ""), "#4");
3952                 }
3953
3954                 [Test]
3955                 [Ignore ("MS behavior is far from consistent to be regarded as a reference implementation.")]
3956                 // See the same-named tests in DataSetTest.cs
3957                 public void ReadWriteXmlSchema_IgnoreSchema ()
3958                 {
3959                         DataSet ds = new DataSet ();
3960                         ds.ReadXmlSchema ("Test/System.Data/store.xsd");
3961                         // check dataset properties before testing write
3962                         AssertDataSet ("ds", ds, "NewDataSet", 3, 2);
3963                         AssertDataTable ("tab1", ds.Tables[0], "bookstore", 1, 0, 0, 1, 1, 1);
3964                         AssertDataTable ("tab2", ds.Tables[1], "book", 5, 0, 1, 1, 2, 1);
3965                         AssertDataTable ("tab3", ds.Tables[2], "author", 3, 0, 1, 0, 1, 0);
3966                         // FIXME: currently order is not compatible. Use name as index
3967                         AssertDataRelation ("rel1", ds.Relations["book_author"], "book_author", true, new string[] { "book_Id" }, new string[] { "book_Id" }, true, true);
3968                         AssertDataRelation ("rel2", ds.Relations["bookstore_book"], "bookstore_book", true, new string[] { "bookstore_Id" }, new string[] { "bookstore_Id" }, true, true);
3969
3970                         ds.ReadXml ("Test/System.Data/region.xml", XmlReadMode.IgnoreSchema);
3971                         ds.Relations.Clear (); // because can not call WriteXmlSchema with nested relations.
3972
3973                         TextWriter writer1 = new StringWriter ();
3974                         ds.Tables[0].WriteXmlSchema (writer1);
3975                         //string TextString1 = GetNormalizedSchema (writer1.ToString ());
3976                         string TextString1 = writer1.ToString ();
3977                         string expected1 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3978 @"<xs:schema id=""NewDataSet"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3979   @"<xs:complexType name=""bookstoreType"">" +
3980   @"</xs:complexType>" +
3981   @"<xs:element name=""bookstore"" type=""bookstoreType"" />" +
3982   @"<xs:element name=""NewDataSet"" msdata:IsDataSet=""true"" msdata:MainDataTable=""bookstore"" msdata:UseCurrentLocale=""true"">" +
3983     @"<xs:complexType>" +
3984       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3985         @"<xs:element ref=""bookstore"" />" +
3986       @"</xs:choice>" +
3987     @"</xs:complexType>" +
3988   @"</xs:element>" +
3989 @"</xs:schema>";
3990                         Console.WriteLine ("{0} - {1}", TextString1, expected1);
3991                         Assert.AreEqual (expected1, TextString1.Replace ("\r\n", "").Replace ("  ", "").Replace ("\n", ""), "#1");
3992
3993                         TextWriter writer2 = new StringWriter ();
3994                         ds.Tables[1].WriteXmlSchema (writer2, false);
3995                         string TextString2 = GetNormalizedSchema (writer2.ToString ());
3996                         string expected2 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3997 @"<xs:schema id=""NewDataSet"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"">" +
3998   @"<xs:complexType name=""bookType"">" +
3999     @"<xs:sequence>" +
4000       @"<xs:element msdata:Ordinal=""1"" name=""title"" type=""xs:string"" />" +
4001       @"<xs:element msdata:Ordinal=""2"" name=""price"" type=""xs:decimal"" />" +
4002     @"</xs:sequence>" +
4003     @"<xs:attribute name=""genre"" type=""xs:string"" />" +
4004     @"<xs:attribute name=""bookstore_Id"" type=""xs:int"" use=""prohibited"" />" +
4005   @"</xs:complexType>" +
4006   @"<xs:element name=""book"" type=""bookType"" />" +
4007   @"<xs:element msdata:IsDataSet=""true"" msdata:MainDataTable=""book"" msdata:UseCurrentLocale=""true"" name=""NewDataSet"">" +
4008     @"<xs:complexType>" +
4009       @"<xs:choice maxOccurs=""unbounded"" minOccurs=""0"">" +
4010         @"<xs:element ref=""book"" />" +
4011       @"</xs:choice>" +
4012     @"</xs:complexType>" +
4013   @"</xs:element>" +
4014 @"</xs:schema>";
4015                         Assert.AreEqual (expected2, TextString2.Replace ("\r\n", "").Replace ("  ", ""), "#2");
4016
4017                         TextWriter writer3 = new StringWriter ();
4018                         ds.Tables[2].WriteXmlSchema (writer3);
4019                         string TextString3 = GetNormalizedSchema (writer3.ToString ());
4020                         string expected3 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
4021 @"<xs:schema id=""NewDataSet"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"">" +
4022   @"<xs:complexType name=""authorName"">" +
4023     @"<xs:sequence>" +
4024       @"<xs:element msdata:Ordinal=""0"" name=""first-name"" type=""xs:string"" />" +
4025       @"<xs:element msdata:Ordinal=""1"" name=""last-name"" type=""xs:string"" />" +
4026     @"</xs:sequence>" +
4027     @"<xs:attribute name=""book_Id"" type=""xs:int"" use=""prohibited"" />" +
4028   @"</xs:complexType>" +
4029   @"<xs:element name=""author"" type=""authorName"" />" +
4030   @"<xs:element msdata:IsDataSet=""true"" msdata:MainDataTable=""author"" msdata:UseCurrentLocale=""true"" name=""NewDataSet"">" +
4031     @"<xs:complexType>" +
4032       @"<xs:choice maxOccurs=""unbounded"" minOccurs=""0"">" +
4033         @"<xs:element ref=""author"" />" +
4034       @"</xs:choice>" +
4035     @"</xs:complexType>" +
4036   @"</xs:element>" +
4037 @"</xs:schema>";
4038                         Assert.AreEqual (expected3, TextString3.Replace ("\r\n", "").Replace ("  ", ""), "#3");
4039
4040                         TextWriter writer4 = new StringWriter ();
4041
4042                         try {
4043                                 ds.Tables [3].WriteXmlSchema (writer4);
4044                                 Assert.Fail ("expected exception");
4045                         } catch (InvalidOperationException ex) {
4046                                 throw ex;
4047                         }
4048                 }
4049
4050                 [Test]
4051                 public void ReadWriteXmlSchema_2 ()
4052                 {
4053                         DataSet ds = new DataSet ("dataset");
4054                         ds.Tables.Add ("table1");
4055                         ds.Tables.Add ("table2");
4056                         ds.Tables[0].Columns.Add ("col");
4057                         ds.Tables[1].Columns.Add ("col");
4058                         ds.Relations.Add ("rel", ds.Tables[0].Columns[0], ds.Tables[1].Columns[0], true);
4059
4060                         MemoryStream ms1 = new MemoryStream ();
4061                         ds.Tables[0].WriteXmlSchema (ms1);
4062                         MemoryStream ms2 = new MemoryStream ();
4063                         ds.Tables[1].WriteXmlSchema (ms2);
4064
4065                         DataSet ds1 = new DataSet ();
4066                         ds1.Tables.Add ();
4067                         ds1.Tables.Add ();
4068                         ds1.Tables[0].ReadXmlSchema (new MemoryStream (ms1.GetBuffer ()));
4069                         ds1.Tables[1].ReadXmlSchema (new MemoryStream (ms2.GetBuffer ()));
4070
4071                         Assert.AreEqual (0, ds1.Relations.Count, "#1");
4072                         Assert.AreEqual (1, ds1.Tables[0].Columns.Count, "#2");
4073                         Assert.AreEqual (1, ds1.Tables[1].Columns.Count, "#3");
4074                 }
4075
4076                 [Test]
4077                 public void ReadWriteXmlSchemaExp_NoRootElmnt ()
4078                 {
4079                         MemoryStream ms = new MemoryStream ();
4080                         DataTable dtr = new DataTable ();
4081                         try {
4082                                 dtr.ReadXmlSchema (ms);
4083                                 Assert.Fail ("#1");
4084                         } catch (XmlException) {
4085                         }
4086                 }
4087
4088                 [Test]
4089                 public void ReadWriteXmlSchemaExp_NoTableName ()
4090                 {
4091                         DataTable dtw = new DataTable ();
4092                         MemoryStream ms = new MemoryStream ();
4093                         try {
4094                                 dtw.WriteXmlSchema (ms);
4095                                 Assert.Fail ("#1");
4096                         } catch (InvalidOperationException) {
4097                         }
4098                 }
4099
4100                 [Test]
4101                 public void ReadWriteXmlSchemaExp_NoFileName ()
4102                 {
4103                         DataTable dtw = new DataTable ();
4104                         try {
4105                                 dtw.WriteXmlSchema (string.Empty);
4106                                 Assert.Fail ("#1");
4107                         } catch (ArgumentException) {
4108                         }
4109                 }
4110
4111                 [Test]
4112                 public void ReadWriteXmlSchemaExp_TableNameConflict ()
4113                 {
4114                         DataTable dtw = new DataTable ("Table1");
4115                         StringWriter writer1 = new StringWriter ();
4116                         dtw.WriteXmlSchema (writer1);
4117                         DataTable dtr = new DataTable ("Table2");
4118                         StringReader reader1 = new StringReader (writer1.ToString());
4119                         try {
4120                                 dtr.ReadXmlSchema (reader1);
4121                                 Assert.Fail ("#1");
4122                         } catch (ArgumentException) {
4123                         }
4124                 }
4125
4126                 [Test]
4127                 public void ReadXmlSchemeWithoutScheme ()
4128                 {
4129                         const string xml = @"<CustomElement />";
4130                         using (var s = new StringReader (xml)) {
4131                                 DataTable dt = new DataTable ();
4132                                 dt.ReadXmlSchema (s);
4133                                 Assert.AreEqual ("", dt.TableName);
4134                         }
4135                 }
4136
4137                 [Test]
4138                 public void ReadXmlSchemeWithScheme ()
4139                 {
4140                         const string xml = @"<CustomElement>
4141                                   <xs:schema id='NewDataSet' xmlns='' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'>
4142                                         <xs:element name='NewDataSet' msdata:IsDataSet='true' msdata:MainDataTable='row' msdata:Locale=''>
4143                                           <xs:complexType>
4144                                                 <xs:choice minOccurs='0' maxOccurs='unbounded'>
4145                                                   <xs:element name='row' msdata:Locale=''>
4146                                                         <xs:complexType>
4147                                                           <xs:sequence>
4148                                                                 <xs:element name='Text' type='xs:string' minOccurs='0' />
4149                                                           </xs:sequence>
4150                                                         </xs:complexType>
4151                                                   </xs:element>
4152                                                 </xs:choice>
4153                                           </xs:complexType>
4154                                         </xs:element>
4155                                   </xs:schema>
4156                                 </CustomElement>";
4157                         using (var s = new StringReader (xml)) {
4158                                 DataTable dt = new DataTable ();
4159                                 dt.ReadXmlSchema (s);
4160                                 Assert.AreEqual ("row", dt.TableName);
4161                         }
4162                 }
4163
4164                 [Test]
4165                 [ExpectedException (typeof (ArgumentException))]
4166                 public void ReadXmlSchemeWithBadScheme ()
4167                 {
4168                         const string xml = @"<CustomElement>
4169                                   <xs:schema id='NewDataSet' xmlns='' xmlns:xs='http://www.w3.org/2001/BAD' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'>
4170                                   </xs:schema>
4171                                 </CustomElement>";
4172                         using (var s = new StringReader (xml)) {
4173                                 DataTable dt = new DataTable ();
4174                                 dt.ReadXmlSchema (s);
4175                         }
4176                 }
4177
4178                 #endregion // Read/Write XML Tests
4179
4180         }
4181
4182         public  class MyDataTable : DataTable
4183         {
4184                 public static int count;
4185
4186                 public MyDataTable()
4187                 {
4188                         count++;
4189                 }
4190         }
4191
4192         [Serializable]
4193         [TestFixture]
4194         public class AppDomainsAndFormatInfo
4195         {
4196                 public void Remote ()
4197                 {
4198                         int n = (int) Convert.ChangeType ("5", typeof (int));
4199                         Assert.AreEqual (5, n, "n");
4200                 }
4201
4202 #if !MONOTOUCH
4203                 [Test]
4204                 public void NFIFromBug55978 ()
4205                 {
4206                         AppDomain domain = AppDomain.CreateDomain ("testdomain", null,
4207                                 AppDomain.CurrentDomain.SetupInformation);
4208                         AppDomainsAndFormatInfo test = new AppDomainsAndFormatInfo ();
4209                         test.Remote ();
4210                         domain.DoCallBack (new CrossAppDomainDelegate (test.Remote));
4211                         AppDomain.Unload (domain);
4212                 }
4213 #endif
4214
4215                 [Test]
4216                 [SetCulture ("en-US")]
4217                 public void Bug55978 ()
4218                 {
4219                         DataTable dt = new DataTable ();
4220                         dt.Columns.Add ("StartDate", typeof (DateTime));
4221          
4222                         DataRow dr;
4223                         DateTime date = DateTime.Now;
4224          
4225                         for (int i = 0; i < 10; i++) {
4226                                 dr = dt.NewRow ();
4227                                 dr ["StartDate"] = date.AddDays (i);
4228                                 dt.Rows.Add (dr);
4229                         }
4230          
4231                         DataView dv = dt.DefaultView;
4232                         dv.RowFilter = String.Format (CultureInfo.InvariantCulture,
4233                                                       "StartDate >= '{0}' and StartDate <= '{1}'",
4234                                                       DateTime.Now.AddDays (2),
4235                                                       DateTime.Now.AddDays (4));
4236                         Assert.AreEqual (10, dt.Rows.Count, "Table");
4237                         Assert.AreEqual (2, dv.Count, "View");
4238                 }
4239
4240                 [Test]
4241                 public void Bug82109 ()
4242                 {
4243                         DataTable tbl = new DataTable ();
4244                         tbl.Columns.Add ("data", typeof (DateTime));
4245                         DataRow row = tbl.NewRow ();
4246                         row ["Data"] = new DateTime (2007, 7, 1);
4247                         tbl.Rows.Add (row);
4248
4249                         CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
4250                         Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
4251                         Select (tbl);
4252
4253                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("it-IT");
4254                         Select (tbl);
4255
4256                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("fr-FR");
4257                         Select (tbl);
4258                         Thread.CurrentThread.CurrentCulture = currentCulture;
4259                 }
4260
4261                 private static void Select (DataTable tbl)
4262                 {
4263                         tbl.Locale = CultureInfo.InvariantCulture;
4264                         string filter = string.Format ("Data = '{0}'", new DateTime (2007, 7, 1).ToString (CultureInfo.InvariantCulture));
4265                         DataRow [] rows = tbl.Select (filter);
4266                         Assert.AreEqual (1, rows.Length, "Incorrect number of rows found");
4267                 }
4268         }
4269 }