[system.data] SqlConnectionStringBuilder from reference sources. Fixes #29823
[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                 public void WriteXmlSchema ()
3231                 {
3232                         DataSet ds = new DataSet ();
3233                         ds.ReadXml ("Test/System.Data/region.xml");
3234                         TextWriter writer = new StringWriter ();
3235                         ds.Tables[0].WriteXmlSchema (writer);
3236
3237                         string TextString = GetNormalizedSchema (writer.ToString ());
3238                         //string TextString = writer.ToString ();
3239
3240                         EOL = "\n";
3241                         string substring = TextString.Substring (0, TextString.IndexOf (EOL));
3242                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3243                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
3244
3245                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3246                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3247                         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");
3248
3249                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3250                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3251                         // Looks like whoever added this test depended on English culture, which is wrong.
3252                         Assert.AreEqual ("  <xs:element msdata:IsDataSet=\"true\" msdata:Locale=\"en-US\" msdata:MainDataTable=\"Region\" name=\"Root\">", substring, "test#03");
3253
3254                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3255                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3256                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
3257
3258                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3259                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3260                         Assert.AreEqual ("      <xs:choice maxOccurs=\"unbounded\" minOccurs=\"0\">", substring, "test#05");
3261
3262                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3263                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3264                         Assert.AreEqual ("        <xs:element name=\"Region\">", substring, "test#06");
3265
3266                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3267                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3268                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
3269
3270                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3271                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3272                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
3273
3274                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3275                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3276                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" name=\"RegionID\" type=\"xs:string\" />", substring, "test#09");
3277
3278                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3279                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3280                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" name=\"RegionDescription\" type=\"xs:string\" />", substring, "test#10");
3281
3282                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3283                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3284                         Assert.AreEqual ("            </xs:sequence>", substring, "test#11");
3285
3286                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3287                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3288                         Assert.AreEqual ("          </xs:complexType>", substring, "test#12");
3289
3290                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3291                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3292                         Assert.AreEqual ("        </xs:element>", substring, "test#13");
3293
3294                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3295                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3296                         Assert.AreEqual ("      </xs:choice>", substring, "test#14");
3297
3298                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3299                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3300                         Assert.AreEqual ("    </xs:complexType>", substring, "test#15");
3301
3302                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3303                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3304                         Assert.AreEqual ("  </xs:element>", substring, "test#16");
3305
3306                         Assert.AreEqual ("</xs:schema>", TextString, "test#17");
3307                 }
3308
3309                 [Test]
3310                 public void WriteXmlSchema2 ()
3311                 {
3312                         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>";
3313                         string schema = @"<?xml version='1.0' encoding='utf-16'?>
3314 <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'>
3315   <xs:element name='myDataSet' msdata:IsDataSet='true' msdata:MainDataTable='NetFrameWork_x003A_myTable' msdata:UseCurrentLocale='true'>
3316     <xs:complexType>
3317       <xs:choice minOccurs='0' maxOccurs='unbounded'>
3318         <xs:element name='myTable'>
3319           <xs:complexType>
3320             <xs:sequence>
3321               <xs:element name='id' msdata:AutoIncrement='true' type='xs:int' minOccurs='0' />
3322               <xs:element name='item' type='xs:string' minOccurs='0' />
3323             </xs:sequence>
3324           </xs:complexType>
3325         </xs:element>
3326       </xs:choice>
3327     </xs:complexType>
3328   </xs:element>
3329 </xs:schema>";
3330                         DataSet OriginalDataSet = new DataSet ("myDataSet");
3331                         OriginalDataSet.Namespace = "NetFrameWork";
3332                         DataTable myTable = new DataTable ("myTable");
3333                         DataColumn c1 = new DataColumn ("id", typeof (int));
3334                         c1.AutoIncrement = true;
3335                         DataColumn c2 = new DataColumn ("item");
3336                         myTable.Columns.Add (c1);
3337                         myTable.Columns.Add (c2);
3338                         OriginalDataSet.Tables.Add (myTable);
3339                         // Add ten rows.
3340                         DataRow newRow;
3341                         for (int i = 0; i < 10; i++) {
3342                                 newRow = myTable.NewRow ();
3343                                 newRow["item"] = "item " + i;
3344                                 myTable.Rows.Add (newRow);
3345                         }
3346                         OriginalDataSet.AcceptChanges ();
3347
3348                         StringWriter sw = new StringWriter ();
3349                         XmlTextWriter xtw = new XmlTextWriter (sw);
3350                         xtw.QuoteChar = '\'';
3351                         OriginalDataSet.WriteXml (xtw);
3352                         string result = sw.ToString ();
3353
3354                         Assert.AreEqual (xml, result);
3355
3356                         sw = new StringWriter ();
3357                         xtw = new XmlTextWriter (sw);
3358                         xtw.Formatting = Formatting.Indented;
3359                         OriginalDataSet.Tables[0].WriteXmlSchema (xtw);
3360                         result = sw.ToString ();
3361
3362                         result = result.Replace ("\r\n", "\n").Replace ('"', '\'');
3363                         Assert.AreEqual (schema.Replace ("\r\n", "\n"), result);
3364                 }
3365
3366                 [Test]
3367                 public void WriteXmlSchema3 ()
3368                 {
3369                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
3370 <xs:schema id=""ExampleDataSet"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3371   <xs:element name=""ExampleDataSet"" msdata:IsDataSet=""true"" msdata:MainDataTable=""ExampleDataTable"" msdata:UseCurrentLocale=""true"">
3372     <xs:complexType>
3373       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3374         <xs:element name=""ExampleDataTable"">
3375           <xs:complexType>
3376             <xs:attribute name=""PrimaryKeyColumn"" type=""xs:int"" use=""required"" />
3377           </xs:complexType>
3378         </xs:element>
3379       </xs:choice>
3380     </xs:complexType>
3381     <xs:unique name=""PK_ExampleDataTable"" msdata:PrimaryKey=""true"">
3382       <xs:selector xpath="".//ExampleDataTable"" />
3383       <xs:field xpath=""@PrimaryKeyColumn"" />
3384     </xs:unique>
3385   </xs:element>
3386 </xs:schema>";
3387                         DataSet ds = new DataSet ("ExampleDataSet");
3388
3389                         ds.Tables.Add (new DataTable ("ExampleDataTable"));
3390                         ds.Tables["ExampleDataTable"].Columns.Add (
3391                                 new DataColumn ("PrimaryKeyColumn", typeof (int), "", MappingType.Attribute));
3392                         ds.Tables["ExampleDataTable"].Columns["PrimaryKeyColumn"].AllowDBNull = false;
3393
3394                         ds.Tables["ExampleDataTable"].Constraints.Add (
3395                                 "PK_ExampleDataTable",
3396                                 ds.Tables["ExampleDataTable"].Columns["PrimaryKeyColumn"],
3397                                 true);
3398
3399                         ds.AcceptChanges ();
3400                         StringWriter sw = new StringWriter ();
3401                         ds.Tables[0].WriteXmlSchema (sw);
3402
3403                         string result = sw.ToString ();
3404
3405                         Assert.AreEqual (xmlschema.Replace ("\r\n", "\n"), result.Replace ("\r\n", "\n"));
3406                         //Assert.AreEqual (xmlschema, result.Replace ("\r\n", "\n"));
3407                 }
3408
3409                 [Test]
3410                 public void WriteXmlSchema4 ()
3411                 {
3412                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
3413 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3414   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""MyType"" msdata:UseCurrentLocale=""true"">
3415     <xs:complexType>
3416       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3417         <xs:element name=""MyType"">
3418           <xs:complexType>
3419             <xs:attribute name=""ID"" type=""xs:int"" use=""required"" />
3420             <xs:attribute name=""Desc"" type=""xs:string"" />
3421           </xs:complexType>
3422         </xs:element>
3423       </xs:choice>
3424     </xs:complexType>
3425   </xs:element>
3426 </xs:schema>";
3427                         DataSet ds = new DataSet ("Example");
3428
3429                         // Add MyType DataTable
3430                         DataTable dt = new DataTable ("MyType");
3431                         ds.Tables.Add (dt);
3432
3433                         dt.Columns.Add (new DataColumn ("ID", typeof (int), "",
3434                                 MappingType.Attribute));
3435                         dt.Columns["ID"].AllowDBNull = false;
3436
3437                         dt.Columns.Add (new DataColumn ("Desc", typeof
3438                                 (string), "", MappingType.Attribute));
3439
3440                         ds.AcceptChanges ();
3441
3442                         StringWriter sw = new StringWriter ();
3443                         ds.Tables[0].WriteXmlSchema (sw);
3444
3445                         string result = sw.ToString ();
3446
3447                         Assert.AreEqual (xmlschema.Replace ("\r\n", "\n"), result.Replace ("\r\n", "\n"));
3448                 }
3449
3450                 [Test]
3451                 public void WriteXmlSchema5 ()
3452                 {
3453                         string xmlschema1 = @"<?xml version=""1.0"" encoding=""utf-16""?>
3454 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3455   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""StandAlone"" msdata:UseCurrentLocale=""true"">
3456     <xs:complexType>
3457       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3458         <xs:element name=""StandAlone"">
3459           <xs:complexType>
3460             <xs:attribute name=""ID"" type=""xs:int"" use=""required"" />
3461             <xs:attribute name=""Desc"" type=""xs:string"" use=""required"" />
3462           </xs:complexType>
3463         </xs:element>
3464       </xs:choice>
3465     </xs:complexType>
3466   </xs:element>
3467 </xs:schema>";
3468                         string xmlschema2 = @"<?xml version=""1.0"" encoding=""utf-16""?>
3469 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3470   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""Dimension"" msdata:UseCurrentLocale=""true"">
3471     <xs:complexType>
3472       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3473         <xs:element name=""Dimension"">
3474           <xs:complexType>
3475             <xs:attribute name=""Number"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
3476             <xs:attribute name=""Title"" type=""xs:string"" use=""required"" />
3477           </xs:complexType>
3478         </xs:element>
3479       </xs:choice>
3480     </xs:complexType>
3481     <xs:unique name=""PK_Dimension"" msdata:PrimaryKey=""true"">
3482       <xs:selector xpath="".//Dimension"" />
3483       <xs:field xpath=""@Number"" />
3484     </xs:unique>
3485   </xs:element>
3486 </xs:schema>";
3487                         string xmlschema3 = @"<?xml version=""1.0"" encoding=""utf-16""?>
3488 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3489   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""Element"" msdata:UseCurrentLocale=""true"">
3490     <xs:complexType>
3491       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3492         <xs:element name=""Element"">
3493           <xs:complexType>
3494             <xs:attribute name=""Dimension"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
3495             <xs:attribute name=""Number"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
3496             <xs:attribute name=""Title"" type=""xs:string"" use=""required"" />
3497           </xs:complexType>
3498         </xs:element>
3499       </xs:choice>
3500     </xs:complexType>
3501     <xs:unique name=""PK_Element"" msdata:PrimaryKey=""true"">
3502       <xs:selector xpath="".//Element"" />
3503       <xs:field xpath=""@Dimension"" />
3504       <xs:field xpath=""@Number"" />
3505     </xs:unique>
3506   </xs:element>
3507 </xs:schema>";
3508                         DataSet ds = new DataSet ("Example");
3509
3510                         // Add a DataTable with no ReadOnly columns
3511                         DataTable dt1 = new DataTable ("StandAlone");
3512                         ds.Tables.Add (dt1);
3513
3514                         // Add a ReadOnly column
3515                         dt1.Columns.Add (new DataColumn ("ID", typeof (int), "",
3516                                 MappingType.Attribute));
3517                         dt1.Columns["ID"].AllowDBNull = false;
3518
3519                         dt1.Columns.Add (new DataColumn ("Desc", typeof
3520                                 (string), "", MappingType.Attribute));
3521                         dt1.Columns["Desc"].AllowDBNull = false;
3522
3523                         // Add related DataTables with ReadOnly columns
3524                         DataTable dt2 = new DataTable ("Dimension");
3525                         ds.Tables.Add (dt2);
3526                         dt2.Columns.Add (new DataColumn ("Number", typeof
3527                                 (int), "", MappingType.Attribute));
3528                         dt2.Columns["Number"].AllowDBNull = false;
3529                         dt2.Columns["Number"].ReadOnly = true;
3530
3531                         dt2.Columns.Add (new DataColumn ("Title", typeof
3532                                 (string), "", MappingType.Attribute));
3533                         dt2.Columns["Title"].AllowDBNull = false;
3534
3535                         dt2.Constraints.Add ("PK_Dimension", dt2.Columns["Number"], true);
3536
3537                         DataTable dt3 = new DataTable ("Element");
3538                         ds.Tables.Add (dt3);
3539
3540                         dt3.Columns.Add (new DataColumn ("Dimension", typeof
3541                                 (int), "", MappingType.Attribute));
3542                         dt3.Columns["Dimension"].AllowDBNull = false;
3543                         dt3.Columns["Dimension"].ReadOnly = true;
3544
3545                         dt3.Columns.Add (new DataColumn ("Number", typeof
3546                                 (int), "", MappingType.Attribute));
3547                         dt3.Columns["Number"].AllowDBNull = false;
3548                         dt3.Columns["Number"].ReadOnly = true;
3549
3550                         dt3.Columns.Add (new DataColumn ("Title", typeof
3551                                 (string), "", MappingType.Attribute));
3552                         dt3.Columns["Title"].AllowDBNull = false;
3553
3554                         dt3.Constraints.Add ("PK_Element", new DataColumn[] { 
3555                                 dt3.Columns ["Dimension"],
3556                                 dt3.Columns ["Number"] }, true);
3557
3558                         ds.AcceptChanges ();
3559
3560                         StringWriter sw1 = new StringWriter ();
3561                         ds.Tables[0].WriteXmlSchema (sw1);
3562                         string result1 = sw1.ToString ();
3563                         Assert.AreEqual (xmlschema1.Replace ("\r\n", "\n"), result1.Replace ("\r\n", "\n"));
3564
3565                         StringWriter sw2 = new StringWriter ();
3566                         ds.Tables[1].WriteXmlSchema (sw2);
3567                         string result2 = sw2.ToString ();
3568                         Assert.AreEqual (xmlschema2.Replace ("\r\n", "\n"), result2.Replace ("\r\n", "\n"));
3569
3570                         StringWriter sw3 = new StringWriter ();
3571                         ds.Tables[2].WriteXmlSchema (sw3);
3572                         string result3 = sw3.ToString ();
3573                         Assert.AreEqual (xmlschema3.Replace ("\r\n", "\n"), result3.Replace ("\r\n", "\n"));
3574                 }
3575
3576                 [Test]
3577                 public void WriteXmlSchema6 ()
3578                 {
3579                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
3580 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3581   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""MyType"" msdata:UseCurrentLocale=""true"">
3582     <xs:complexType>
3583       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3584         <xs:element name=""MyType"">
3585           <xs:complexType>
3586             <xs:attribute name=""Desc"">
3587               <xs:simpleType>
3588                 <xs:restriction base=""xs:string"">
3589                   <xs:maxLength value=""32"" />
3590                 </xs:restriction>
3591               </xs:simpleType>
3592             </xs:attribute>
3593           </xs:complexType>
3594         </xs:element>
3595       </xs:choice>
3596     </xs:complexType>
3597   </xs:element>
3598 </xs:schema>";
3599                         DataSet ds = new DataSet ("Example");
3600
3601                         // Add MyType DataTable
3602                         ds.Tables.Add ("MyType");
3603
3604                         ds.Tables["MyType"].Columns.Add (new DataColumn (
3605                                 "Desc", typeof (string), "", MappingType.Attribute));
3606                         ds.Tables["MyType"].Columns["Desc"].MaxLength = 32;
3607
3608                         ds.AcceptChanges ();
3609
3610                         StringWriter sw = new StringWriter ();
3611                         ds.Tables[0].WriteXmlSchema (sw);
3612
3613                         string result = sw.ToString ();
3614
3615                         Assert.AreEqual (xmlschema.Replace ("\r\n", "\n"), result.Replace ("\r\n", "\n"));
3616                 }
3617
3618                 [Test]
3619                 public void WriteXmlSchema7 ()
3620                 {
3621                         DataSet ds = new DataSet ();
3622                         DataTable dt = new DataTable ("table");
3623                         dt.Columns.Add ("col1");
3624                         dt.Columns.Add ("col2");
3625                         ds.Tables.Add (dt);
3626                         dt.Rows.Add (new object[] { "foo", "bar" });
3627                         StringWriter sw = new StringWriter ();
3628                         ds.Tables[0].WriteXmlSchema (sw);
3629                         Assert.IsTrue (sw.ToString ().IndexOf ("xmlns=\"\"") > 0);
3630                 }
3631
3632                 [Test]
3633                 public void WriteXmlSchema_ConstraintNameWithSpaces ()
3634                 {
3635                         DataSet ds = new DataSet ();
3636                         DataTable table1 = ds.Tables.Add ("table1");
3637                         DataTable table2 = ds.Tables.Add ("table2");
3638
3639                         table1.Columns.Add ("col1", typeof (int));
3640                         table2.Columns.Add ("col1", typeof (int));
3641
3642                         table1.Constraints.Add ("uc 1", table1.Columns[0], false);
3643                         table2.Constraints.Add ("fc 1", table1.Columns[0], table2.Columns[0]);
3644
3645                         StringWriter sw1 = new StringWriter ();
3646                         StringWriter sw2 = new StringWriter ();
3647
3648                         //should not throw an exception
3649                         ds.Tables[0].WriteXmlSchema (sw1);
3650                         ds.Tables[1].WriteXmlSchema (sw2);
3651                 }
3652
3653                 [Test]
3654                 public void WriteXmlSchema_ForignKeyConstraint ()
3655                 {
3656                         DataSet ds1 = new DataSet ();
3657
3658                         DataTable table1 = ds1.Tables.Add ();
3659                         DataTable table2 = ds1.Tables.Add ();
3660
3661                         DataColumn col1_1 = table1.Columns.Add ("col1", typeof (int));
3662                         DataColumn col2_1 = table2.Columns.Add ("col1", typeof (int));
3663
3664                         table2.Constraints.Add ("fk", col1_1, col2_1);
3665
3666                         StringWriter sw1 = new StringWriter ();
3667                         ds1.Tables[0].WriteXmlSchema (sw1);
3668                         String xml1 = sw1.ToString ();
3669                         Assert.IsTrue (xml1.IndexOf (@"<xs:unique name=""Constraint1"">") != -1, "#1");
3670
3671                         StringWriter sw2 = new StringWriter ();
3672                         ds1.Tables[1].WriteXmlSchema (sw2);
3673                         String xml2 = sw2.ToString ();
3674                         Assert.IsTrue (xml2.IndexOf (@"<xs:unique name=""Constraint1"">") == -1, "#2");
3675                 }
3676
3677                 [Test]
3678                 public void WriteXmlSchema_Relations_ForeignKeys ()
3679                 {
3680                         MemoryStream ms1 = null;
3681                         MemoryStream ms2 = null;
3682                         MemoryStream msA = null;
3683                         MemoryStream msB = null;
3684
3685                         DataSet ds1 = new DataSet ();
3686
3687                         DataTable table1 = ds1.Tables.Add ("Table 1");
3688                         DataTable table2 = ds1.Tables.Add ("Table 2");
3689
3690                         DataColumn col1_1 = table1.Columns.Add ("col 1", typeof (int));
3691                         DataColumn col1_2 = table1.Columns.Add ("col 2", typeof (int));
3692                         DataColumn col1_3 = table1.Columns.Add ("col 3", typeof (int));
3693                         DataColumn col1_4 = table1.Columns.Add ("col 4", typeof (int));
3694                         DataColumn col1_5 = table1.Columns.Add ("col 5", typeof (int));
3695                         DataColumn col1_6 = table1.Columns.Add ("col 6", typeof (int));
3696                         DataColumn col1_7 = table1.Columns.Add ("col 7", typeof (int));
3697
3698                         DataColumn col2_1 = table2.Columns.Add ("col 1", typeof (int));
3699                         DataColumn col2_2 = table2.Columns.Add ("col 2", typeof (int));
3700                         DataColumn col2_3 = table2.Columns.Add ("col 3", typeof (int));
3701                         DataColumn col2_4 = table2.Columns.Add ("col 4", typeof (int));
3702                         DataColumn col2_5 = table2.Columns.Add ("col 5", typeof (int));
3703                         DataColumn col2_6 = table2.Columns.Add ("col 6", typeof (int));
3704                         DataColumn col2_7 = table2.Columns.Add ("col 7", typeof (int));
3705
3706                         ds1.Relations.Add ("rel 1",
3707                                 new DataColumn[] { col1_1, col1_2 },
3708                                 new DataColumn[] { col2_1, col2_2 },
3709                                 false);
3710                         ds1.Relations.Add ("rel 2",
3711                                 new DataColumn[] { col1_3, col1_4 },
3712                                 new DataColumn[] { col2_3, col2_4 },
3713                                 true);
3714                         table2.Constraints.Add ("fk 1",
3715                                 new DataColumn[] { col1_5, col1_6 },
3716                                 new DataColumn[] { col2_5, col2_6 });
3717                         table1.Constraints.Add ("fk 2",
3718                                 new DataColumn[] { col2_5, col2_6 },
3719                                 new DataColumn[] { col1_5, col1_6 });
3720
3721                         table1.Constraints.Add ("pk 1", col1_7, true);
3722                         table2.Constraints.Add ("pk 2", col2_7, true);
3723
3724                         ms1 = new MemoryStream ();
3725                         ds1.Tables[0].WriteXmlSchema (ms1);
3726                         ms2 = new MemoryStream ();
3727                         ds1.Tables[1].WriteXmlSchema (ms2);
3728
3729                         msA = new MemoryStream (ms1.GetBuffer ());
3730                         DataTable dtA = new DataTable ();
3731                         dtA.ReadXmlSchema (msA);
3732
3733                         msB = new MemoryStream (ms2.GetBuffer ());
3734                         DataTable dtB = new DataTable ();
3735                         dtB.ReadXmlSchema (msB);
3736
3737                         Assert.AreEqual (3, dtA.Constraints.Count, "#2");
3738                         Assert.AreEqual (2, dtB.Constraints.Count, "#3");
3739
3740                         Assert.IsTrue (dtA.Constraints.Contains ("pk 1"), "#5");
3741                         Assert.IsTrue (dtA.Constraints.Contains ("Constraint1"), "#6");
3742                         Assert.IsTrue (dtA.Constraints.Contains ("Constraint2"), "#7");
3743                         Assert.IsTrue (dtB.Constraints.Contains ("pk 2"), "#9");
3744                         Assert.IsTrue (dtB.Constraints.Contains ("Constraint1"), "#10");
3745                 }
3746
3747                 [Test]
3748                 [Category ("NotWorking")]
3749                 public void WriteXmlSchema_DifferentNamespace ()
3750                 {
3751                         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'>
3752   <xs:import namespace='urn:foo' />
3753   <xs:import namespace='urn:baz' />
3754   <xs:element name='NewDataSet' msdata:IsDataSet='true' msdata:MainDataTable='urn_x003A_foo_x003A_NS1Table' msdata:UseCurrentLocale='true'>
3755     <xs:complexType>
3756       <xs:choice minOccurs='0' maxOccurs='unbounded'>
3757         <xs:element ref='app2:NS1Table' />
3758       </xs:choice>
3759     </xs:complexType>
3760   </xs:element>
3761 </xs:schema>
3762 <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'>
3763   <xs:import namespace='urn:foo' />
3764   <xs:import namespace='urn:bar' />
3765   <xs:element name='column2' type='xs:string' />
3766 </xs:schema>
3767 <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'>
3768   <xs:import namespace='urn:bar' />
3769   <xs:import namespace='urn:baz' />
3770   <xs:element name='NS1Table'>
3771     <xs:complexType>
3772       <xs:sequence>
3773         <xs:element name='column1' type='xs:string' minOccurs='0' />
3774         <xs:element ref='app1:column2' minOccurs='0' />
3775       </xs:sequence>
3776     </xs:complexType>
3777   </xs:element>
3778 </xs:schema>";
3779                         DataSet ds = new DataSet ();
3780                         DataTable dt = new DataTable ();
3781                         dt.TableName = "NS1Table";
3782                         dt.Namespace = "urn:foo";
3783                         dt.Columns.Add ("column1");
3784                         dt.Columns.Add ("column2");
3785                         dt.Columns[1].Namespace = "urn:baz";
3786                         ds.Tables.Add (dt);
3787                         DataTable dt2 = new DataTable ();
3788                         dt2.TableName = "NS2Table";
3789                         dt2.Namespace = "urn:bar";
3790                         ds.Tables.Add (dt2);
3791                         ds.Namespace = "urn:bar";
3792
3793                         StringWriter sw1 = new StringWriter ();
3794                         XmlTextWriter xw1 = new XmlTextWriter (sw1);
3795                         xw1.Formatting = Formatting.Indented;
3796                         xw1.QuoteChar = '\'';
3797                         ds.Tables[0].WriteXmlSchema (xw1);
3798                         string result1 = sw1.ToString ();
3799                         Assert.AreEqual (schema, result1.Replace ("\r\n", "\n"), "#1");
3800
3801                         StringWriter sw2 = new StringWriter ();
3802                         XmlTextWriter xw2 = new XmlTextWriter (sw2);
3803                         xw2.Formatting = Formatting.Indented;
3804                         xw2.QuoteChar = '\'';
3805                         ds.Tables[0].WriteXmlSchema (xw2);
3806                         string result2 = sw2.ToString ();
3807                         Assert.AreEqual (schema, result2.Replace ("\r\n", "\n"), "#2");
3808                 }
3809
3810                 [Test]
3811                 public void WriteXmlSchema_Hierarchy ()
3812                 {
3813                         DataSet ds = new DataSet ();
3814                         DataTable table1 = new DataTable ();
3815                         DataColumn idColumn = table1.Columns.Add ("ID", typeof (Int32));
3816                         table1.Columns.Add ("Name", typeof (String));
3817                         table1.PrimaryKey = new DataColumn[] { idColumn };
3818                         DataTable table2 = new DataTable ();
3819                         table2.Columns.Add (new DataColumn ("OrderID", typeof (Int32)));
3820                         table2.Columns.Add (new DataColumn ("CustomerID", typeof (Int32)));
3821                         table2.Columns.Add (new DataColumn ("OrderDate", typeof (DateTime)));
3822                         table2.PrimaryKey = new DataColumn[] { table2.Columns[0] };
3823                         ds.Tables.Add (table1);
3824                         ds.Tables.Add (table2);
3825                         ds.Relations.Add ("CustomerOrder",
3826                                 new DataColumn[] { table1.Columns[0] },
3827                                 new DataColumn[] { table2.Columns[1] }, true);
3828
3829                         StringWriter writer1 = new StringWriter ();
3830                         table1.WriteXmlSchema (writer1, false);
3831                         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>";
3832                         Assert.AreEqual (expected1, writer1.ToString().Replace("\r\n", "\n"), "#1");
3833
3834                         StringWriter writer2 = new StringWriter ();
3835                         table1.WriteXmlSchema (writer2, true);
3836                         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>";
3837                         Assert.AreEqual (expected2, writer2.ToString ().Replace("\r\n", "\n"), "#2");
3838                 }
3839
3840                 [Test]
3841                 [Ignore ("MS behavior is far from consistent to be regarded as a reference implementation.")]
3842                 // See the same-named tests in DataSetTest.cs
3843                 // WriteXmlSchema doesn't have overload wityh 2 parameters in System.Data
3844                 // and is commented-out TWICE below
3845                 public void ReadWriteXmlSchema()
3846                 {
3847                         DataSet ds = new DataSet();
3848                         ds.ReadXmlSchema("Test/System.Data/store.xsd");
3849                         // check dataset properties before testing write
3850                         AssertDataSet("ds", ds, "NewDataSet", 3, 2);
3851                         AssertDataTable("tab1", ds.Tables[0], "bookstore", 1, 0, 0, 1, 1, 1);
3852                         AssertDataTable("tab2", ds.Tables[1], "book", 5, 0, 1, 1, 2, 1);
3853                         AssertDataTable("tab3", ds.Tables[2], "author", 3, 0, 1, 0, 1, 0);
3854                         // FIXME: currently order is not compatible. Use name as index
3855                         AssertDataRelation("rel1", ds.Relations["book_author"], "book_author", true, new string[] { "book_Id" }, new string[] { "book_Id" }, true, true);
3856                         AssertDataRelation("rel2", ds.Relations["bookstore_book"], "bookstore_book", true, new string[] { "bookstore_Id" }, new string[] { "bookstore_Id" }, true, true);
3857
3858                         ds.ReadXml("Test/System.Data/region.xml", XmlReadMode.InferSchema);
3859                         ds.Relations.Clear(); // because can not call WriteXmlSchema with nested relations.
3860
3861                         TextWriter writer1 = new StringWriter();
3862                         ds.Tables[0].WriteXmlSchema(writer1);
3863                         //string TextString1 = GetNormalizedSchema(writer1.ToString());
3864                         string TextString1 = writer1.ToString();
3865                         string expected1 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3866 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3867   @"<xs:complexType name=""bookstoreType"">" +
3868   @"</xs:complexType>" +
3869   @"<xs:element name=""bookstore"" type=""bookstoreType"" />" +
3870   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""bookstore"" msdata:Locale=""en-US"">" +
3871     @"<xs:complexType>" +
3872       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3873     @"<xs:element ref=""bookstore"" />" +
3874       @"</xs:choice>" +
3875     @"</xs:complexType>" +
3876   @"</xs:element>" +
3877 @"</xs:schema>";
3878                         Assert.AreEqual(expected1.Replace("\n", ""), TextString1.Replace("\r\n", "").Replace("  ", "").Replace("\n", ""), "#1");
3879
3880                         TextWriter writer2 = new StringWriter();
3881                         ds.Tables[1].WriteXmlSchema(writer2, false);
3882                         //string TextString2 = GetNormalizedSchema(writer2.ToString());
3883                         string TextString2 = writer2.ToString();
3884                         string expected2 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3885 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3886   @"<xs:complexType name=""bookType"">" +
3887     @"<xs:sequence>" +
3888       @"<xs:element name=""title"" type=""xs:string"" msdata:Ordinal=""1"" />" +
3889       @"<xs:element name=""price"" type=""xs:decimal"" msdata:Ordinal=""2"" />" +
3890     @"</xs:sequence>" +
3891     @"<xs:attribute name=""genre"" type=""xs:string"" />" +
3892     @"<xs:attribute name=""bookstore_Id"" type=""xs:int"" use=""prohibited"" />" +
3893   @"</xs:complexType>" +
3894   @"<xs:element name=""book"" type=""bookType"" />" +
3895   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""book"" msdata:Locale=""en-US"">" +
3896     @"<xs:complexType>" +
3897       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3898     @"<xs:element ref=""book"" />" +
3899       @"</xs:choice>" +
3900     @"</xs:complexType>" +
3901   @"</xs:element>" +
3902 @"</xs:schema>";
3903                         Assert.AreEqual(expected2, TextString2.Replace("\r\n", "").Replace("  ", ""), "#2");
3904
3905                         TextWriter writer3 = new StringWriter();
3906                         ds.Tables[2].WriteXmlSchema(writer3);
3907                         //string TextString3 = GetNormalizedSchema(writer3.ToString());
3908                         string TextString3 = writer3.ToString();
3909                         string expected3 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3910 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3911   @"<xs:complexType name=""authorName"">" +
3912     @"<xs:sequence>" +
3913       @"<xs:element name=""first-name"" type=""xs:string"" msdata:Ordinal=""0"" />" +
3914       @"<xs:element name=""last-name"" type=""xs:string"" msdata:Ordinal=""1"" />" +
3915     @"</xs:sequence>" +
3916     @"<xs:attribute name=""book_Id"" type=""xs:int"" use=""prohibited"" />" +
3917   @"</xs:complexType>" +
3918   @"<xs:element name=""author"" type=""authorName"" />" +
3919   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""author"" msdata:Locale=""en-US"">" +
3920     @"<xs:complexType>" +
3921       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3922         @"<xs:element ref=""author"" />" +
3923       @"</xs:choice>" +
3924     @"</xs:complexType>" +
3925   @"</xs:element>" +
3926 @"</xs:schema>";
3927                         Assert.AreEqual(expected3, TextString3.Replace("\r\n", "").Replace("  ", ""), "#3");
3928
3929                         TextWriter writer4 = new StringWriter();
3930                         ds.Tables[3].WriteXmlSchema(writer4);
3931                         //string TextString4 = GetNormalizedSchema(writer4.ToString());
3932                         string TextString4 = writer4.ToString();
3933                         string expected4 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3934 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3935   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""Region"" msdata:Locale=""en-US"">" +
3936     @"<xs:complexType>" +
3937       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3938         @"<xs:element name=""Region"">" +
3939           @"<xs:complexType>" +
3940             @"<xs:sequence>" +
3941               @"<xs:element name=""RegionID"" type=""xs:string"" minOccurs=""0"" />" +
3942               @"<xs:element name=""RegionDescription"" type=""xs:string"" minOccurs=""0"" />" +
3943             @"</xs:sequence>" +
3944           @"</xs:complexType>" +
3945         @"</xs:element>" +
3946       @"</xs:choice>" +
3947     @"</xs:complexType>" +
3948   @"</xs:element>" +
3949 @"</xs:schema>";
3950                         Assert.AreEqual(expected4, TextString4.Replace("\r\n", "").Replace("  ", ""), "#4");
3951                 }
3952
3953                 [Test]
3954                 [Ignore ("MS behavior is far from consistent to be regarded as a reference implementation.")]
3955                 // See the same-named tests in DataSetTest.cs
3956                 public void ReadWriteXmlSchema_IgnoreSchema ()
3957                 {
3958                         DataSet ds = new DataSet ();
3959                         ds.ReadXmlSchema ("Test/System.Data/store.xsd");
3960                         // check dataset properties before testing write
3961                         AssertDataSet ("ds", ds, "NewDataSet", 3, 2);
3962                         AssertDataTable ("tab1", ds.Tables[0], "bookstore", 1, 0, 0, 1, 1, 1);
3963                         AssertDataTable ("tab2", ds.Tables[1], "book", 5, 0, 1, 1, 2, 1);
3964                         AssertDataTable ("tab3", ds.Tables[2], "author", 3, 0, 1, 0, 1, 0);
3965                         // FIXME: currently order is not compatible. Use name as index
3966                         AssertDataRelation ("rel1", ds.Relations["book_author"], "book_author", true, new string[] { "book_Id" }, new string[] { "book_Id" }, true, true);
3967                         AssertDataRelation ("rel2", ds.Relations["bookstore_book"], "bookstore_book", true, new string[] { "bookstore_Id" }, new string[] { "bookstore_Id" }, true, true);
3968
3969                         ds.ReadXml ("Test/System.Data/region.xml", XmlReadMode.IgnoreSchema);
3970                         ds.Relations.Clear (); // because can not call WriteXmlSchema with nested relations.
3971
3972                         TextWriter writer1 = new StringWriter ();
3973                         ds.Tables[0].WriteXmlSchema (writer1);
3974                         //string TextString1 = GetNormalizedSchema (writer1.ToString ());
3975                         string TextString1 = writer1.ToString ();
3976                         string expected1 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3977 @"<xs:schema id=""NewDataSet"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3978   @"<xs:complexType name=""bookstoreType"">" +
3979   @"</xs:complexType>" +
3980   @"<xs:element name=""bookstore"" type=""bookstoreType"" />" +
3981   @"<xs:element name=""NewDataSet"" msdata:IsDataSet=""true"" msdata:MainDataTable=""bookstore"" msdata:UseCurrentLocale=""true"">" +
3982     @"<xs:complexType>" +
3983       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3984         @"<xs:element ref=""bookstore"" />" +
3985       @"</xs:choice>" +
3986     @"</xs:complexType>" +
3987   @"</xs:element>" +
3988 @"</xs:schema>";
3989                         Console.WriteLine ("{0} - {1}", TextString1, expected1);
3990                         Assert.AreEqual (expected1, TextString1.Replace ("\r\n", "").Replace ("  ", "").Replace ("\n", ""), "#1");
3991
3992                         TextWriter writer2 = new StringWriter ();
3993                         ds.Tables[1].WriteXmlSchema (writer2, false);
3994                         string TextString2 = GetNormalizedSchema (writer2.ToString ());
3995                         string expected2 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3996 @"<xs:schema id=""NewDataSet"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"">" +
3997   @"<xs:complexType name=""bookType"">" +
3998     @"<xs:sequence>" +
3999       @"<xs:element msdata:Ordinal=""1"" name=""title"" type=""xs:string"" />" +
4000       @"<xs:element msdata:Ordinal=""2"" name=""price"" type=""xs:decimal"" />" +
4001     @"</xs:sequence>" +
4002     @"<xs:attribute name=""genre"" type=""xs:string"" />" +
4003     @"<xs:attribute name=""bookstore_Id"" type=""xs:int"" use=""prohibited"" />" +
4004   @"</xs:complexType>" +
4005   @"<xs:element name=""book"" type=""bookType"" />" +
4006   @"<xs:element msdata:IsDataSet=""true"" msdata:MainDataTable=""book"" msdata:UseCurrentLocale=""true"" name=""NewDataSet"">" +
4007     @"<xs:complexType>" +
4008       @"<xs:choice maxOccurs=""unbounded"" minOccurs=""0"">" +
4009         @"<xs:element ref=""book"" />" +
4010       @"</xs:choice>" +
4011     @"</xs:complexType>" +
4012   @"</xs:element>" +
4013 @"</xs:schema>";
4014                         Assert.AreEqual (expected2, TextString2.Replace ("\r\n", "").Replace ("  ", ""), "#2");
4015
4016                         TextWriter writer3 = new StringWriter ();
4017                         ds.Tables[2].WriteXmlSchema (writer3);
4018                         string TextString3 = GetNormalizedSchema (writer3.ToString ());
4019                         string expected3 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
4020 @"<xs:schema id=""NewDataSet"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"">" +
4021   @"<xs:complexType name=""authorName"">" +
4022     @"<xs:sequence>" +
4023       @"<xs:element msdata:Ordinal=""0"" name=""first-name"" type=""xs:string"" />" +
4024       @"<xs:element msdata:Ordinal=""1"" name=""last-name"" type=""xs:string"" />" +
4025     @"</xs:sequence>" +
4026     @"<xs:attribute name=""book_Id"" type=""xs:int"" use=""prohibited"" />" +
4027   @"</xs:complexType>" +
4028   @"<xs:element name=""author"" type=""authorName"" />" +
4029   @"<xs:element msdata:IsDataSet=""true"" msdata:MainDataTable=""author"" msdata:UseCurrentLocale=""true"" name=""NewDataSet"">" +
4030     @"<xs:complexType>" +
4031       @"<xs:choice maxOccurs=""unbounded"" minOccurs=""0"">" +
4032         @"<xs:element ref=""author"" />" +
4033       @"</xs:choice>" +
4034     @"</xs:complexType>" +
4035   @"</xs:element>" +
4036 @"</xs:schema>";
4037                         Assert.AreEqual (expected3, TextString3.Replace ("\r\n", "").Replace ("  ", ""), "#3");
4038
4039                         TextWriter writer4 = new StringWriter ();
4040
4041                         try {
4042                                 ds.Tables [3].WriteXmlSchema (writer4);
4043                                 Assert.Fail ("expected exception");
4044                         } catch (InvalidOperationException ex) {
4045                                 throw ex;
4046                         }
4047                 }
4048
4049                 [Test]
4050                 public void ReadWriteXmlSchema_2 ()
4051                 {
4052                         DataSet ds = new DataSet ("dataset");
4053                         ds.Tables.Add ("table1");
4054                         ds.Tables.Add ("table2");
4055                         ds.Tables[0].Columns.Add ("col");
4056                         ds.Tables[1].Columns.Add ("col");
4057                         ds.Relations.Add ("rel", ds.Tables[0].Columns[0], ds.Tables[1].Columns[0], true);
4058
4059                         MemoryStream ms1 = new MemoryStream ();
4060                         ds.Tables[0].WriteXmlSchema (ms1);
4061                         MemoryStream ms2 = new MemoryStream ();
4062                         ds.Tables[1].WriteXmlSchema (ms2);
4063
4064                         DataSet ds1 = new DataSet ();
4065                         ds1.Tables.Add ();
4066                         ds1.Tables.Add ();
4067                         ds1.Tables[0].ReadXmlSchema (new MemoryStream (ms1.GetBuffer ()));
4068                         ds1.Tables[1].ReadXmlSchema (new MemoryStream (ms2.GetBuffer ()));
4069
4070                         Assert.AreEqual (0, ds1.Relations.Count, "#1");
4071                         Assert.AreEqual (1, ds1.Tables[0].Columns.Count, "#2");
4072                         Assert.AreEqual (1, ds1.Tables[1].Columns.Count, "#3");
4073                 }
4074
4075                 [Test]
4076                 public void ReadWriteXmlSchemaExp_NoRootElmnt ()
4077                 {
4078                         MemoryStream ms = new MemoryStream ();
4079                         DataTable dtr = new DataTable ();
4080                         try {
4081                                 dtr.ReadXmlSchema (ms);
4082                                 Assert.Fail ("#1");
4083                         } catch (XmlException) {
4084                         }
4085                 }
4086
4087                 [Test]
4088                 public void ReadWriteXmlSchemaExp_NoTableName ()
4089                 {
4090                         DataTable dtw = new DataTable ();
4091                         MemoryStream ms = new MemoryStream ();
4092                         try {
4093                                 dtw.WriteXmlSchema (ms);
4094                                 Assert.Fail ("#1");
4095                         } catch (InvalidOperationException) {
4096                         }
4097                 }
4098
4099                 [Test]
4100                 public void ReadWriteXmlSchemaExp_NoFileName ()
4101                 {
4102                         DataTable dtw = new DataTable ();
4103                         try {
4104                                 dtw.WriteXmlSchema (string.Empty);
4105                                 Assert.Fail ("#1");
4106                         } catch (ArgumentException) {
4107                         }
4108                 }
4109
4110                 [Test]
4111                 public void ReadWriteXmlSchemaExp_TableNameConflict ()
4112                 {
4113                         DataTable dtw = new DataTable ("Table1");
4114                         StringWriter writer1 = new StringWriter ();
4115                         dtw.WriteXmlSchema (writer1);
4116                         DataTable dtr = new DataTable ("Table2");
4117                         StringReader reader1 = new StringReader (writer1.ToString());
4118                         try {
4119                                 dtr.ReadXmlSchema (reader1);
4120                                 Assert.Fail ("#1");
4121                         } catch (ArgumentException) {
4122                         }
4123                 }
4124
4125                 [Test]
4126                 public void ReadXmlSchemeWithoutScheme ()
4127                 {
4128                         const string xml = @"<CustomElement />";
4129                         using (var s = new StringReader (xml)) {
4130                                 DataTable dt = new DataTable ();
4131                                 dt.ReadXmlSchema (s);
4132                                 Assert.AreEqual ("", dt.TableName);
4133                         }
4134                 }
4135
4136                 [Test]
4137                 public void ReadXmlSchemeWithScheme ()
4138                 {
4139                         const string xml = @"<CustomElement>
4140                                   <xs:schema id='NewDataSet' xmlns='' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'>
4141                                         <xs:element name='NewDataSet' msdata:IsDataSet='true' msdata:MainDataTable='row' msdata:Locale=''>
4142                                           <xs:complexType>
4143                                                 <xs:choice minOccurs='0' maxOccurs='unbounded'>
4144                                                   <xs:element name='row' msdata:Locale=''>
4145                                                         <xs:complexType>
4146                                                           <xs:sequence>
4147                                                                 <xs:element name='Text' type='xs:string' minOccurs='0' />
4148                                                           </xs:sequence>
4149                                                         </xs:complexType>
4150                                                   </xs:element>
4151                                                 </xs:choice>
4152                                           </xs:complexType>
4153                                         </xs:element>
4154                                   </xs:schema>
4155                                 </CustomElement>";
4156                         using (var s = new StringReader (xml)) {
4157                                 DataTable dt = new DataTable ();
4158                                 dt.ReadXmlSchema (s);
4159                                 Assert.AreEqual ("row", dt.TableName);
4160                         }
4161                 }
4162
4163                 [Test]
4164                 [ExpectedException (typeof (ArgumentException))]
4165                 public void ReadXmlSchemeWithBadScheme ()
4166                 {
4167                         const string xml = @"<CustomElement>
4168                                   <xs:schema id='NewDataSet' xmlns='' xmlns:xs='http://www.w3.org/2001/BAD' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'>
4169                                   </xs:schema>
4170                                 </CustomElement>";
4171                         using (var s = new StringReader (xml)) {
4172                                 DataTable dt = new DataTable ();
4173                                 dt.ReadXmlSchema (s);
4174                         }
4175                 }
4176
4177                 #endregion // Read/Write XML Tests
4178
4179         }
4180
4181         public  class MyDataTable : DataTable
4182         {
4183                 public static int count;
4184
4185                 public MyDataTable()
4186                 {
4187                         count++;
4188                 }
4189         }
4190
4191         [Serializable]
4192         [TestFixture]
4193         public class AppDomainsAndFormatInfo
4194         {
4195                 public void Remote ()
4196                 {
4197                         int n = (int) Convert.ChangeType ("5", typeof (int));
4198                         Assert.AreEqual (5, n, "n");
4199                 }
4200
4201 #if !MONOTOUCH
4202                 [Test]
4203                 public void NFIFromBug55978 ()
4204                 {
4205                         AppDomain domain = AppDomain.CreateDomain ("testdomain", null,
4206                                 AppDomain.CurrentDomain.SetupInformation);
4207                         AppDomainsAndFormatInfo test = new AppDomainsAndFormatInfo ();
4208                         test.Remote ();
4209                         domain.DoCallBack (new CrossAppDomainDelegate (test.Remote));
4210                         AppDomain.Unload (domain);
4211                 }
4212 #endif
4213
4214                 [Test]
4215                 [SetCulture ("en-US")]
4216                 public void Bug55978 ()
4217                 {
4218                         DataTable dt = new DataTable ();
4219                         dt.Columns.Add ("StartDate", typeof (DateTime));
4220          
4221                         DataRow dr;
4222                         DateTime date = DateTime.Now;
4223          
4224                         for (int i = 0; i < 10; i++) {
4225                                 dr = dt.NewRow ();
4226                                 dr ["StartDate"] = date.AddDays (i);
4227                                 dt.Rows.Add (dr);
4228                         }
4229          
4230                         DataView dv = dt.DefaultView;
4231                         dv.RowFilter = String.Format (CultureInfo.InvariantCulture,
4232                                                       "StartDate >= '{0}' and StartDate <= '{1}'",
4233                                                       DateTime.Now.AddDays (2),
4234                                                       DateTime.Now.AddDays (4));
4235                         Assert.AreEqual (10, dt.Rows.Count, "Table");
4236                         Assert.AreEqual (2, dv.Count, "View");
4237                 }
4238
4239                 [Test]
4240                 public void Bug82109 ()
4241                 {
4242                         DataTable tbl = new DataTable ();
4243                         tbl.Columns.Add ("data", typeof (DateTime));
4244                         DataRow row = tbl.NewRow ();
4245                         row ["Data"] = new DateTime (2007, 7, 1);
4246                         tbl.Rows.Add (row);
4247
4248                         CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
4249                         Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
4250                         Select (tbl);
4251
4252                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("it-IT");
4253                         Select (tbl);
4254
4255                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("fr-FR");
4256                         Select (tbl);
4257                         Thread.CurrentThread.CurrentCulture = currentCulture;
4258                 }
4259
4260                 private static void Select (DataTable tbl)
4261                 {
4262                         tbl.Locale = CultureInfo.InvariantCulture;
4263                         string filter = string.Format ("Data = '{0}'", new DateTime (2007, 7, 1).ToString (CultureInfo.InvariantCulture));
4264                         DataRow [] rows = tbl.Select (filter);
4265                         Assert.AreEqual (1, rows.Length, "Incorrect number of rows found");
4266                 }
4267         }
4268 }