Merge pull request #3213 from henricm/fix-for-win-securestring-to-bstr
[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                 [Test]
1311                 public void ImportRowTypeChangeTest ()
1312                 {
1313                         // this is from http://bugzilla.xamarin.com/show_bug.cgi?id=2926
1314         
1315                         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) };
1316                         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) };
1317                         int length = types.Length;
1318         
1319                         HashSet<Tuple<Type, Type>> invalid = new HashSet<Tuple<Type, Type>> () {
1320                                 Tuple.Create (typeof (string), typeof (DateTime)), 
1321                                 Tuple.Create (typeof (sbyte), typeof (DateTime)), 
1322                                 Tuple.Create (typeof (byte), typeof (DateTime)), 
1323                                 Tuple.Create (typeof (short), typeof (DateTime)), 
1324                                 Tuple.Create (typeof (ushort), typeof (DateTime)), 
1325                                 Tuple.Create (typeof (int), typeof (DateTime)), 
1326                                 Tuple.Create (typeof (uint), typeof (DateTime)), 
1327                                 Tuple.Create (typeof (long), typeof (DateTime)), 
1328                                 Tuple.Create (typeof (ulong), typeof (DateTime)), 
1329                                 Tuple.Create (typeof (float), typeof (char)), 
1330                                 Tuple.Create (typeof (float), typeof (DateTime)), 
1331                                 Tuple.Create (typeof (double), typeof (char)), 
1332                                 Tuple.Create (typeof (double), typeof (DateTime)), 
1333                                 Tuple.Create (typeof (char), typeof (float)), 
1334                                 Tuple.Create (typeof (char), typeof (double)), 
1335                                 Tuple.Create (typeof (char), typeof (decimal)), 
1336                                 Tuple.Create (typeof (char), typeof (DateTime)), 
1337                                 Tuple.Create (typeof (Decimal), typeof (char)), 
1338                                 Tuple.Create (typeof (Decimal), typeof (DateTime)), 
1339                                 Tuple.Create (typeof (DateTime), typeof (sbyte)), 
1340                                 Tuple.Create (typeof (DateTime), typeof (byte)), 
1341                                 Tuple.Create (typeof (DateTime), typeof (short)), 
1342                                 Tuple.Create (typeof (DateTime), typeof (ushort)), 
1343                                 Tuple.Create (typeof (DateTime), typeof (int)), 
1344                                 Tuple.Create (typeof (DateTime), typeof (uint)), 
1345                                 Tuple.Create (typeof (DateTime), typeof (long)), 
1346                                 Tuple.Create (typeof (DateTime), typeof (ulong)), 
1347                                 Tuple.Create (typeof (DateTime), typeof (float)), 
1348                                 Tuple.Create (typeof (DateTime), typeof (double)), 
1349                                 Tuple.Create (typeof (DateTime), typeof (char)), 
1350                                 Tuple.Create (typeof (DateTime), typeof (decimal)), 
1351                         };
1352         
1353                         for (int a = 0; a < length; a++) {
1354                                 for (int b = 0; b < length; b++) {
1355                                         DataSet ds = new DataSet ();
1356                                         DataTable dt1 = ds.Tables.Add ("T1");
1357                                         DataTable dt2 = ds.Tables.Add ("T2");
1358         
1359                                         string name = "C-" + types [a].Name + "-to-" + types [b].Name;
1360                                         dt1.Columns.Add (name, types [a]);
1361                                         dt2.Columns.Add (name, types [b]);
1362         
1363                                         DataRow r1 = dt1.NewRow ();
1364                                         dt1.Rows.Add (r1);
1365         
1366                                         r1 [0] = values [a];
1367         
1368                                         if (invalid.Contains (Tuple.Create (types [a], types [b]))) {
1369                                                 try {
1370                                                         dt2.ImportRow (r1);
1371                                                         Assert.Fail ("#B: " + name + " expected ArgumentException");
1372                                                 } catch /*(ArgumentException)*/ {
1373                                                         continue;
1374                                                 }
1375                                         } else {
1376                                                 dt2.ImportRow (r1);
1377                                                 DataRow r2 = dt2.Rows [0];
1378                                                 Assert.AreEqual (types [b], r2 [0].GetType (), "#A: " + name);
1379                                         }
1380                                 }
1381                         }
1382                 }
1383                         
1384                 [Test]
1385                 public void ClearReset () //To test Clear and Reset methods
1386                 {
1387                         DataTable table = new DataTable ("table");
1388                         DataTable table1 = new DataTable ("table1");
1389
1390                         DataSet set = new DataSet ();
1391                         set.Tables.Add (table);
1392                         set.Tables.Add (table1);
1393
1394                         table.Columns.Add ("Id", typeof (int));
1395                         table.Columns.Add ("Name", typeof (string));
1396                         table.Constraints.Add (new UniqueConstraint ("UK1", table.Columns [0]));
1397                         table.CaseSensitive = false;
1398
1399                         table1.Columns.Add ("Id", typeof (int));
1400                         table1.Columns.Add ("Name", typeof (string));
1401
1402                         DataRelation dr = new DataRelation ("DR", table.Columns[0], table1.Columns[0]);
1403                         set.Relations.Add (dr);
1404
1405                         DataRow row = table.NewRow ();
1406                         row ["Id"] = 147;
1407                         row ["name"] = "Roopa";
1408                         table.Rows.Add (row);
1409
1410                         row = table.NewRow ();
1411                         row ["Id"] = 47;
1412                         row ["Name"] = "roopa";
1413                         table.Rows.Add (row);
1414
1415                         Assert.AreEqual (2, table.Rows.Count);
1416                         Assert.AreEqual (1, table.ChildRelations.Count);
1417                         try {
1418                                 table.Reset ();
1419                                 Assert.Fail ("#A01, should have thrown ArgumentException");
1420                         } catch (ArgumentException) {
1421                         }
1422
1423                         Assert.AreEqual (0, table.Rows.Count, "#CT01");
1424                         Assert.AreEqual (0, table.ChildRelations.Count, "#CT02");
1425                         Assert.AreEqual (0, table.ParentRelations.Count, "#CT03");
1426                         Assert.AreEqual (0, table.Constraints.Count, "#CT04");
1427
1428                         table1.Reset ();
1429                         Assert.AreEqual (0, table1.Rows.Count, "#A05");
1430                         Assert.AreEqual (0, table1.Constraints.Count, "#A06");
1431                         Assert.AreEqual (0, table1.ParentRelations.Count, "#A07");
1432                 
1433                         // clear test
1434                         table.Clear ();
1435                         Assert.AreEqual (0, table.Rows.Count, "#A08");
1436                         Assert.AreEqual (0, table.Constraints.Count, "#A09");
1437                         Assert.AreEqual (0, table.ChildRelations.Count, "#A10");
1438                 }
1439
1440                 [Test]
1441                 public void ClearTest ()
1442                 {
1443                         DataTable table = new DataTable ("test");
1444                         table.Columns.Add ("id", typeof (int));
1445                         table.Columns.Add ("name", typeof (string));
1446
1447                         table.PrimaryKey = new DataColumn [] { table.Columns [0] } ;
1448
1449                         table.Rows.Add (new object [] { 1, "mono 1" });
1450                         table.Rows.Add (new object [] { 2, "mono 2" });
1451                         table.Rows.Add (new object [] { 3, "mono 3" });
1452                         table.Rows.Add (new object [] { 4, "mono 4" });
1453
1454                         table.AcceptChanges ();
1455                         _tableClearedEventFired = false;
1456                         table.TableCleared += new DataTableClearEventHandler (OnTableCleared);
1457                         _tableClearingEventFired = false;
1458                         table.TableClearing += new DataTableClearEventHandler (OnTableClearing);
1459
1460                         table.Clear ();
1461                         Assert.IsTrue (_tableClearingEventFired, "#3 should have fired cleared event");
1462                         Assert.IsTrue (_tableClearedEventFired, "#0 should have fired cleared event");
1463
1464                         DataRow r = table.Rows.Find (1);
1465                         Assert.IsTrue (r == null, "#1 should have cleared");
1466
1467                         // try adding new row. indexes should have cleared
1468                         table.Rows.Add (new object [] { 2, "mono 2" });
1469                         Assert.AreEqual (1, table.Rows.Count, "#2 should add row");
1470                 }
1471
1472                 private bool _tableClearedEventFired;
1473                 private void OnTableCleared (object src, DataTableClearEventArgs args)
1474                 {
1475                         _tableClearedEventFired = true;
1476                 }
1477
1478                 private bool _tableClearingEventFired;
1479                 private void OnTableClearing (object src, DataTableClearEventArgs args)
1480                 {
1481                         _tableClearingEventFired = true;
1482                 }
1483
1484                 private bool _tableNewRowAddedEventFired;
1485                 private void OnTableNewRowAdded (object src, DataTableNewRowEventArgs args)
1486                 {
1487                         _tableNewRowAddedEventFired = true;
1488                 }
1489
1490                 [Test]
1491                 public void TestWriteXmlSchema1 ()
1492                 {
1493                         DataTable dt = new DataTable("TestWriteXmlSchema");
1494                         dt.Columns.Add("Col1", typeof(int));
1495                         dt.Columns.Add("Col2", typeof(int));
1496                         DataRow dr = dt.NewRow();
1497                         dr[0] = 10;
1498                         dr[1] = 20;
1499                         dt.Rows.Add (dr);
1500                         DataTable dt1 = new DataTable("HelloWorld");
1501                         dt1.Columns.Add("T1", typeof(int));
1502                         dt1.Columns.Add("T2", typeof(int));
1503                         DataRow dr1 = dt1.NewRow();
1504                         dr1[0] = 10;
1505                         dr1[1] = 20;
1506                         dt1.Rows.Add(dr1);
1507                         TextWriter writer = new StringWriter ();
1508                         dt.WriteXmlSchema (writer);
1509                         string TextString = writer.ToString ();
1510                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
1511                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1512                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
1513
1514                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1515                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1516                         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");
1517                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1518                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1519                         Assert.AreEqual ("  <xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"TestWriteXmlSchema\" msdata:UseCurrentLocale=\"true\">", substring, "test#03");
1520                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1521                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1522                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
1523
1524                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1525                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1526                         Assert.AreEqual ("      <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">", substring, "test#05");
1527
1528                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1529                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1530                         Assert.AreEqual ("        <xs:element name=\"TestWriteXmlSchema\">", substring, "test#06");
1531
1532                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1533                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1534                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
1535
1536                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1537                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1538                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
1539                         
1540                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1541                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1542                         Assert.AreEqual ("              <xs:element name=\"Col1\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#09");
1543
1544                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1545                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1546                         Assert.AreEqual ("              <xs:element name=\"Col2\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#10");
1547
1548                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1549                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1550                         Assert.AreEqual ("            </xs:sequence>", substring, "test#11");
1551
1552                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1553                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1554                         Assert.AreEqual ("          </xs:complexType>", substring, "test#12");
1555
1556                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1557                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1558                         Assert.AreEqual ("        </xs:element>", substring, "test#13");
1559
1560                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1561                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1562                         Assert.AreEqual ("      </xs:choice>", substring, "test#14");
1563
1564                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1565                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1566                         Assert.AreEqual ("    </xs:complexType>", substring, "test#15");
1567
1568                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1569                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1570                         Assert.AreEqual ("  </xs:element>", substring, "test#16");
1571                         Assert.AreEqual ("</xs:schema>", TextString, "test#17");
1572                 }
1573
1574                 [Test]
1575                 public void TestWriteXmlSchema2()
1576                 {
1577                         DataTable dt = new DataTable("TestWriteXmlSchema");
1578                         dt.Columns.Add("Col1", typeof(int));
1579                         dt.Columns.Add("Col2", typeof(int));
1580                         DataRow dr = dt.NewRow();
1581                         dr[0] = 10;
1582                         dr[1] = 20;
1583                         dt.Rows.Add (dr);
1584                         DataTable dt1 = new DataTable("HelloWorld");
1585                         dt1.Columns.Add("T1", typeof(int));
1586                         dt1.Columns.Add("T2", typeof(int));
1587                         DataRow dr1 = dt1.NewRow();
1588                         dr1[0] = 10;
1589                         dr1[1] = 20;
1590                         dt1.Rows.Add(dr1);
1591                         DataSet ds = new DataSet();
1592                         ds.Tables.Add(dt);
1593                         ds.Tables.Add(dt1);
1594                         DataRelation rel = new DataRelation("Relation1", dt.Columns["Col1"], dt1.Columns["T1"]);
1595                         ds.Relations.Add(rel);
1596                         TextWriter writer = new StringWriter ();
1597                         dt.WriteXmlSchema (writer);
1598                         string TextString = writer.ToString ();
1599                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
1600                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1601                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
1602
1603                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1604                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1605                         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");
1606                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1607                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1608                         Assert.AreEqual ("  <xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"TestWriteXmlSchema\" msdata:UseCurrentLocale=\"true\">", substring, "test#03");
1609                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1610                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1611                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
1612
1613                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1614                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1615                         Assert.AreEqual ("      <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">", substring, "test#05");
1616
1617                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1618                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1619                         Assert.AreEqual ("        <xs:element name=\"TestWriteXmlSchema\">", substring, "test#06");
1620
1621                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1622                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1623                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
1624
1625                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1626                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1627                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
1628
1629                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1630                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1631                         Assert.AreEqual ("              <xs:element name=\"Col1\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#09");
1632
1633                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1634                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1635                         Assert.AreEqual ("              <xs:element name=\"Col2\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#10");
1636
1637                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1638                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1639                         Assert.AreEqual ("            </xs:sequence>", substring, "test#11");
1640
1641                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1642                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1643                         Assert.AreEqual ("          </xs:complexType>", substring, "test#12");
1644
1645                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1646                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1647                         Assert.AreEqual ("        </xs:element>", substring, "test#13");
1648
1649                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1650                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1651                         Assert.AreEqual ("      </xs:choice>", substring, "test#14");
1652
1653                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1654                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1655                         Assert.AreEqual ("    </xs:complexType>", substring, "test#15");
1656
1657                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1658                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1659                         Assert.AreEqual ("    <xs:unique name=\"Constraint1\">", substring, "test#16");
1660
1661                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1662                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1663                         Assert.AreEqual ("      <xs:selector xpath=\".//TestWriteXmlSchema\" />", substring, "test#17");
1664
1665                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1666                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1667                         Assert.AreEqual ("      <xs:field xpath=\"Col1\" />", substring, "test#18");
1668
1669                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1670                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1671                         Assert.AreEqual ("    </xs:unique>", substring, "test#19");
1672
1673                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1674                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1675                         Assert.AreEqual ("  </xs:element>", substring, "test#20");
1676                         Assert.AreEqual ("</xs:schema>", TextString, "test#21");
1677                 }
1678
1679                 [Test]
1680                 public void TestWriteXmlSchema3()
1681                 {
1682                         DataTable dt = new DataTable("TestWriteXmlSchema");
1683                         dt.Columns.Add("Col1", typeof(int));
1684                         dt.Columns.Add("Col2", typeof(int));
1685                         DataRow dr = dt.NewRow();
1686                         dr[0] = 10;
1687                         dr[1] = 20;
1688                         dt.Rows.Add (dr);
1689                         DataTable dt1 = new DataTable("HelloWorld");
1690                         dt1.Columns.Add("T1", typeof(int));
1691                         dt1.Columns.Add("T2", typeof(int));
1692                         DataRow dr1 = dt1.NewRow();
1693                         dr1[0] = 10;
1694                         dr1[1] = 20;
1695                         dt1.Rows.Add(dr1);
1696                         DataSet ds = new DataSet();
1697                         ds.Tables.Add(dt);
1698                         ds.Tables.Add(dt1);
1699                         DataRelation rel = new DataRelation("Relation1", dt.Columns["Col1"], dt1.Columns["T1"]);
1700                         ds.Relations.Add(rel);
1701                         TextWriter writer = new StringWriter ();
1702                         dt.WriteXmlSchema (writer, true);
1703                         string TextString = writer.ToString ();
1704                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
1705                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1706                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
1707
1708                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1709                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1710                         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");
1711                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1712                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1713                         Assert.AreEqual ("  <xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"TestWriteXmlSchema\" msdata:UseCurrentLocale=\"true\">", substring, "test#03");
1714                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1715                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1716                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
1717
1718                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1719                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1720                         Assert.AreEqual ("      <xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">", substring, "test#05");
1721
1722                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1723                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1724                         Assert.AreEqual ("        <xs:element name=\"TestWriteXmlSchema\">", substring, "test#06");
1725
1726                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1727                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1728                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
1729
1730                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1731                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1732                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
1733
1734                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1735                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1736                         Assert.AreEqual ("              <xs:element name=\"Col1\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#09");
1737
1738                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1739                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1740                         Assert.AreEqual ("              <xs:element name=\"Col2\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#10");
1741
1742                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1743                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1744                         Assert.AreEqual ("            </xs:sequence>", substring, "test#11");
1745
1746                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1747                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1748                         Assert.AreEqual ("          </xs:complexType>", substring, "test#12");
1749
1750                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1751                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1752                         Assert.AreEqual ("        </xs:element>", substring, "test#13");
1753
1754                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1755                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1756                         Assert.AreEqual ("        <xs:element name=\"HelloWorld\">", substring, "test#14");
1757
1758                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1759                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1760                         Assert.AreEqual ("          <xs:complexType>", substring, "test#15");
1761
1762                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1763                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1764                         Assert.AreEqual ("            <xs:sequence>", substring, "test#16");
1765
1766                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1767                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1768                         Assert.AreEqual ("              <xs:element name=\"T1\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#17");
1769
1770                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1771                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1772                         Assert.AreEqual ("              <xs:element name=\"T2\" type=\"xs:int\" minOccurs=\"0\" />", substring, "test#18");
1773
1774                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1775                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1776                         Assert.AreEqual ("            </xs:sequence>", substring, "test#19");
1777
1778                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1779                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1780                         Assert.AreEqual ("          </xs:complexType>", substring, "test#20");
1781
1782                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1783                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1784                         Assert.AreEqual ("        </xs:element>", substring, "test#21");
1785
1786                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1787                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1788                         Assert.AreEqual ("      </xs:choice>", substring, "test#22");
1789
1790                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1791                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1792                         Assert.AreEqual ("    </xs:complexType>", substring, "test#23");
1793
1794                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1795                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1796                         Assert.AreEqual ("    <xs:unique name=\"Constraint1\">", substring, "test#24");
1797
1798                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1799                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1800                         Assert.AreEqual ("      <xs:selector xpath=\".//TestWriteXmlSchema\" />", substring, "test#25");
1801
1802                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1803                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1804                         Assert.AreEqual ("      <xs:field xpath=\"Col1\" />", substring, "test#26");
1805
1806                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1807                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1808                         Assert.AreEqual ("    </xs:unique>", substring, "test#27");
1809
1810                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1811                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1812                         Assert.AreEqual ("    <xs:keyref name=\"Relation1\" refer=\"Constraint1\">", substring, "test#28");
1813
1814                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1815                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1816                         Assert.AreEqual ("      <xs:selector xpath=\".//HelloWorld\" />", substring, "test#29");
1817
1818                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1819                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1820                         Assert.AreEqual ("      <xs:field xpath=\"T1\" />", substring, "test#30");
1821
1822                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1823                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1824                         Assert.AreEqual ("    </xs:keyref>", substring, "test#31");
1825
1826                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
1827                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
1828                         Assert.AreEqual ("  </xs:element>", substring, "test#32");
1829                         Assert.AreEqual ("</xs:schema>", TextString, "test#33");
1830                 }
1831
1832                 [Test]
1833                 public void Serialize ()
1834                 {
1835                         MemoryStream fs = new MemoryStream ();
1836
1837                         // Construct a BinaryFormatter and use it 
1838                         // to serialize the data to the stream.
1839                         BinaryFormatter formatter = new BinaryFormatter();
1840
1841                         // Create an array with multiple elements refering to 
1842                         // the one Singleton object.
1843                         DataTable dt = new DataTable();
1844
1845                         dt.Columns.Add(new DataColumn("Id", typeof(string)));
1846                         dt.Columns.Add(new DataColumn("ContactName", typeof(string)));
1847                         dt.Columns.Add(new DataColumn("ContactTitle", typeof(string)));
1848                         dt.Columns.Add(new DataColumn("ContactAreaCode", typeof(string)));
1849                         dt.Columns.Add(new DataColumn("ContactPhone", typeof(string)));
1850
1851                         DataRow loRowToAdd;
1852                         loRowToAdd = dt.NewRow();
1853                         loRowToAdd[0] = "a";
1854                         loRowToAdd[1] = "b";
1855                         loRowToAdd[2] = "c";
1856                         loRowToAdd[3] = "d";
1857                         loRowToAdd[4] = "e";
1858                         dt.Rows.Add(loRowToAdd);
1859
1860                         DataTable[] dtarr = new DataTable[] {dt}; 
1861
1862                         // Serialize the array elements.
1863                         formatter.Serialize(fs, dtarr);
1864
1865                         // Deserialize the array elements.
1866                         fs.Position = 0;
1867                         DataTable[] a2 = (DataTable[]) formatter.Deserialize(fs);
1868
1869                         DataSet ds = new DataSet();
1870                         ds.Tables.Add(a2[0]);
1871
1872                         StringWriter sw = new StringWriter ();
1873                         ds.WriteXml(sw);
1874                         XmlDocument doc = new XmlDocument ();
1875                         doc.LoadXml (sw.ToString ());
1876                         Assert.AreEqual (5, doc.DocumentElement.FirstChild.ChildNodes.Count);
1877                 }
1878
1879                 [Test]
1880                 public void SetPrimaryKeyAssertsNonNull ()
1881                 {
1882                         DataTable dt = new DataTable ("table");
1883                         dt.Columns.Add ("col1");
1884                         dt.Columns.Add ("col2");
1885                         dt.Constraints.Add (new UniqueConstraint (dt.Columns [0]));
1886                         dt.Rows.Add (new object [] {1, 3});
1887                         dt.Rows.Add (new object [] {DBNull.Value, 3});
1888
1889                         try {
1890                                 dt.PrimaryKey = new DataColumn [] { dt.Columns [0] };
1891                                 Assert.Fail ("#1");
1892                         } catch (DataException) {
1893                         }
1894                 }
1895
1896                 [Test]
1897                 public void PrimaryKeyColumnChecksNonNull ()
1898                 {
1899                         DataTable dt = new DataTable ("table");
1900                         dt.Columns.Add ("col1");
1901                         dt.Columns.Add ("col2");
1902                         dt.Constraints.Add (new UniqueConstraint (dt.Columns [0]));
1903                         dt.PrimaryKey = new DataColumn [] {dt.Columns [0]};
1904                         dt.Rows.Add (new object [] {1, 3});
1905
1906                         try {
1907                                 dt.Rows.Add (new object [] { DBNull.Value, 3 });
1908                                 Assert.Fail ("#1");
1909                         } catch (NoNullAllowedException) {
1910                         }
1911                 }
1912
1913                 [Test]
1914                 public void PrimaryKey_CheckSetsAllowDBNull ()
1915                 {
1916                         DataTable table = new DataTable ();
1917                         DataColumn col1 = table.Columns.Add ("col1", typeof (int));
1918                         DataColumn col2 = table.Columns.Add ("col2", typeof (int));
1919         
1920                         Assert.IsTrue (col1.AllowDBNull, "#1" );
1921                         Assert.IsTrue (col2.AllowDBNull, "#2" );
1922                         Assert.IsFalse (col2.Unique, "#3" );
1923                         Assert.IsFalse (col2.Unique, "#4" );
1924
1925                         table.PrimaryKey = new DataColumn[] {col1,col2};
1926                         Assert.IsFalse (col1.AllowDBNull, "#5" );
1927                         Assert.IsFalse (col2.AllowDBNull, "#6" );
1928                         // LAMESPEC or bug ?? 
1929                         Assert.IsFalse (col1.Unique, "#7" );
1930                         Assert.IsFalse (col2.Unique, "#8" );
1931                 }
1932
1933                 void RowChanging (object o, DataRowChangeEventArgs e)
1934                 {
1935                         Assert.AreEqual (rowChangingExpectedAction, e.Action, "changing.Action");
1936                         rowChangingRowChanging = true;
1937                 }
1938
1939                 void RowChanged (object o, DataRowChangeEventArgs e)
1940                 {
1941                         Assert.AreEqual (rowChangingExpectedAction, e.Action, "changed.Action");
1942                         rowChangingRowChanged = true;
1943                 }
1944
1945                 bool rowChangingRowChanging, rowChangingRowChanged;
1946                 DataRowAction rowChangingExpectedAction;
1947
1948                 [Test]
1949                 public void RowChanging ()
1950                 {
1951                         DataTable dt = new DataTable ("table");
1952                         dt.Columns.Add ("col1");
1953                         dt.Columns.Add ("col2");
1954                         dt.RowChanging += new DataRowChangeEventHandler (RowChanging);
1955                         dt.RowChanged += new DataRowChangeEventHandler (RowChanged);
1956                         rowChangingExpectedAction = DataRowAction.Add;
1957                         dt.Rows.Add (new object [] {1, 2});
1958                         Assert.IsTrue (rowChangingRowChanging, "changing,Added");
1959                         Assert.IsTrue (rowChangingRowChanged, "changed,Added");
1960                         rowChangingExpectedAction = DataRowAction.Change;
1961                         dt.Rows [0] [0] = 2;
1962                         Assert.IsTrue (rowChangingRowChanging, "changing,Changed");
1963                         Assert.IsTrue (rowChangingRowChanged, "changed,Changed");
1964                 }
1965
1966                 [Test]
1967                 public void CloneSubClassTest()
1968                 {
1969                         MyDataTable dt1 = new MyDataTable();
1970                         MyDataTable dt = (MyDataTable)(dt1.Clone());
1971                         Assert.AreEqual (2, MyDataTable.count, "A#01");
1972                 }
1973
1974                 DataRowAction rowActionChanging = DataRowAction.Nothing;
1975                 DataRowAction rowActionChanged  = DataRowAction.Nothing;
1976                 [Test]
1977                 public void AcceptChangesTest ()
1978                 {
1979                         DataTable dt = new DataTable ("test");
1980                         dt.Columns.Add ("id", typeof (int));
1981                         dt.Columns.Add ("name", typeof (string));
1982
1983                         dt.Rows.Add (new object [] { 1, "mono 1" });
1984
1985                         dt.RowChanged  += new DataRowChangeEventHandler (OnRowChanged);
1986                         dt.RowChanging += new DataRowChangeEventHandler (OnRowChanging);
1987
1988                         try {
1989                                 rowActionChanged = rowActionChanging = DataRowAction.Nothing;
1990                                 dt.AcceptChanges ();
1991
1992                                 Assert.AreEqual (DataRowAction.Commit, rowActionChanging,
1993                                                  "#1 should have fired event and set action to commit");
1994                                 Assert.AreEqual (DataRowAction.Commit, rowActionChanged,
1995                                                  "#2 should have fired event and set action to commit");
1996                         } finally {
1997                                 dt.RowChanged  -= new DataRowChangeEventHandler (OnRowChanged);
1998                                 dt.RowChanging -= new DataRowChangeEventHandler (OnRowChanging);
1999                         }
2000                 }
2001
2002                 [Test]
2003                 [ExpectedException (typeof (ArgumentException))]
2004                 public void ColumnObjectTypeTest() {
2005                         DataTable dt = new DataTable();
2006                         dt.Columns.Add("Series Label", typeof(SqlInt32));
2007                         dt.Rows.Add(new object[] {"sss"});
2008                 }
2009
2010                 private bool tableInitialized;
2011                 [Test]
2012                 public void TableInitializedEventTest1 ()
2013                 {
2014                         DataTable dt = new DataTable();
2015                         tableInitialized = false;
2016                         dt.Initialized += new EventHandler (OnTableInitialized);
2017                         dt.Columns.Add("Series Label", typeof(SqlInt32));
2018                         dt.Rows.Add(new object[] {123});
2019                         Assert.IsFalse (tableInitialized, "TableInitialized #01");
2020                         dt.Initialized -= new EventHandler (OnTableInitialized);
2021                 }
2022
2023                 [Test]
2024                 public void TableInitializedEventTest2 ()
2025                 {
2026                         DataTable dt = new DataTable();
2027                         dt.BeginInit ();
2028                         tableInitialized = false;
2029                         dt.Initialized += new EventHandler (OnTableInitialized);
2030                         dt.Columns.Add("Series Label", typeof(SqlInt32));
2031                         dt.Rows.Add(new object[] {123});
2032                         dt.EndInit ();
2033                         dt.Initialized -= new EventHandler (OnTableInitialized);
2034                         Assert.IsTrue (tableInitialized, "TableInitialized #02");
2035                 }
2036
2037                 [Test]
2038                 public void TableInitializedEventTest3 ()
2039                 {
2040                         DataTable dt = new DataTable();
2041                         tableInitialized = true;
2042                         dt.Initialized += new EventHandler (OnTableInitialized);
2043                         dt.Columns.Add("Series Label", typeof(SqlInt32));
2044                         dt.Rows.Add(new object[] {123});
2045                         Assert.AreEqual (tableInitialized, dt.IsInitialized, "TableInitialized #03");
2046                         dt.Initialized -= new EventHandler (OnTableInitialized);
2047                 }
2048
2049                 [Test]
2050                 public void TableInitializedEventTest4 ()
2051                 {
2052                         DataTable dt = new DataTable();
2053                         Assert.IsTrue (dt.IsInitialized, "TableInitialized #04");
2054                         dt.BeginInit ();
2055                         tableInitialized = false;
2056                         dt.Initialized += new EventHandler (OnTableInitialized);
2057                         dt.Columns.Add("Series Label", typeof(SqlInt32));
2058                         dt.Rows.Add(new object[] {123});
2059                         Assert.IsFalse (dt.IsInitialized, "TableInitialized #05");
2060                         dt.EndInit ();
2061                         Assert.IsTrue (dt.IsInitialized, "TableInitialized #06");
2062                         Assert.IsTrue (tableInitialized, "TableInitialized #07");
2063                         dt.Initialized -= new EventHandler (OnTableInitialized);
2064                 }
2065
2066                 private void OnTableInitialized (object src, EventArgs args)
2067                 {
2068                         tableInitialized = true;
2069                 }
2070
2071                 public void OnRowChanging (object src, DataRowChangeEventArgs args)
2072                 {
2073                         rowActionChanging = args.Action;
2074                 }
2075
2076                 public void OnRowChanged (object src, DataRowChangeEventArgs args)
2077                 {
2078                         rowActionChanged = args.Action;
2079                 }
2080
2081                 private DataTable dt;
2082                 private void localSetup () {
2083                         dt = new DataTable ("test");
2084                         dt.Columns.Add ("id", typeof (int));
2085                         dt.Columns.Add ("name", typeof (string));
2086                         dt.PrimaryKey = new DataColumn[] { dt.Columns["id"] };
2087
2088                         dt.Rows.Add (new object[] { 1, "mono 1" });
2089                         dt.Rows.Add (new object[] { 2, "mono 2" });
2090                         dt.Rows.Add (new object[] { 3, "mono 3" });
2091
2092                         dt.AcceptChanges ();
2093                 }
2094
2095                 #region DataTable.CreateDataReader Tests
2096
2097                 [Test]
2098                 public void CreateDataReader1 ()
2099                 {
2100                         localSetup ();
2101                         DataTableReader dtr = dt.CreateDataReader ();
2102                         Assert.IsTrue (dtr.HasRows, "HasRows");
2103                         Assert.AreEqual (dt.Columns.Count, dtr.FieldCount, "CountCols");
2104                         int ri = 0;
2105                         while (dtr.Read ()) {
2106                                 for (int i = 0; i < dtr.FieldCount; i++) {
2107                                         Assert.AreEqual (dt.Rows[ri][i], dtr[i], "RowData-" + ri + "-" + i);
2108                                 }
2109                                 ri++;
2110                         }
2111                 }
2112
2113                 [Test]
2114                 public void CreateDataReader2 ()
2115                 {
2116                         localSetup ();
2117                         DataTableReader dtr = dt.CreateDataReader ();
2118                         Assert.IsTrue (dtr.HasRows, "HasRows");
2119                         Assert.AreEqual (dt.Columns.Count, dtr.FieldCount, "CountCols");
2120                         dtr.Read ();
2121                         Assert.AreEqual (1, dtr[0], "RowData0-0");
2122                         Assert.AreEqual ("mono 1", dtr[1], "RowData0-1");
2123                         dtr.Read ();
2124                         Assert.AreEqual (2, dtr[0], "RowData1-0");
2125                         Assert.AreEqual ("mono 2", dtr[1], "RowData1-1");
2126                         dtr.Read ();
2127                         Assert.AreEqual (3, dtr[0], "RowData2-0");
2128                         Assert.AreEqual ("mono 3", dtr[1], "RowData2-1");
2129                 }
2130
2131                 #endregion // DataTable.CreateDataReader Tests
2132
2133                 #region DataTable.Load Tests
2134
2135                 [Test]
2136                 public void Load_Basic ()
2137                 {
2138                         localSetup ();
2139                         DataTable dtLoad = new DataTable ("LoadBasic");
2140                         dtLoad.Columns.Add ("id", typeof (int));
2141                         dtLoad.Columns.Add ("name", typeof (string));
2142                         dtLoad.Columns["id"].ReadOnly = true;
2143                         dtLoad.Columns["name"].ReadOnly = true;
2144                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2145                         dtLoad.Rows.Add (new object[] { 1, "load 1" });
2146                         dtLoad.Rows.Add (new object[] { 2, "load 2" });
2147                         dtLoad.Rows.Add (new object[] { 3, "load 3" });
2148                         dtLoad.AcceptChanges ();
2149                         DataTableReader dtr = dt.CreateDataReader ();
2150                         dtLoad.Load (dtr);
2151                         Assert.AreEqual (2, dtLoad.Columns.Count, "NColumns");
2152                         Assert.AreEqual (3, dtLoad.Rows.Count, "NRows");
2153                         Assert.AreEqual (1, dtLoad.Rows[0][0], "RowData0-0");
2154                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1], "RowData0-1");
2155                         Assert.AreEqual (2, dtLoad.Rows[1][0], "RowData1-0");
2156                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1], "RowData1-1");
2157                         Assert.AreEqual (3, dtLoad.Rows[2][0], "RowData2-0");
2158                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1], "RowData2-1");
2159                 }
2160
2161                 [Test]
2162                 public void Load_NoSchema ()
2163                 {
2164                         localSetup ();
2165                         DataTable dtLoad = new DataTable ("LoadNoSchema");
2166                         DataTableReader dtr = dt.CreateDataReader ();
2167                         dtLoad.Load (dtr);
2168                         Assert.AreEqual (2, dtLoad.Columns.Count, "NColumns");
2169                         Assert.AreEqual (3, dtLoad.Rows.Count, "NRows");
2170                         Assert.AreEqual (1, dtLoad.Rows[0][0], "RowData0-0");
2171                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1], "RowData0-1");
2172                         Assert.AreEqual (2, dtLoad.Rows[1][0], "RowData1-0");
2173                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1], "RowData1-1");
2174                         Assert.AreEqual (3, dtLoad.Rows[2][0], "RowData2-0");
2175                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1], "RowData2-1");
2176                 }
2177
2178                 internal struct fillErrorStruct
2179                 {
2180                         internal string error;
2181                         internal string tableName;
2182                         internal int rowKey;
2183                         internal bool contFlag;
2184
2185                         internal void init (string tbl, int row, bool cont, string err)
2186                         {
2187                                 tableName = tbl;
2188                                 rowKey = row;
2189                                 contFlag = cont;
2190                                 error = err;
2191                         }
2192                 }
2193                 private fillErrorStruct[] fillErr = new fillErrorStruct[3];
2194                 private int fillErrCounter;
2195                 private void fillErrorHandler (object sender, FillErrorEventArgs e)
2196                 {
2197                         e.Continue = fillErr[fillErrCounter].contFlag;
2198                         Assert.AreEqual (fillErr[fillErrCounter].tableName, e.DataTable.TableName, "fillErr-T");
2199                         //Assert.AreEqual (fillErr[fillErrCounter].rowKey, e.Values[0], "fillErr-R");
2200                         Assert.AreEqual (fillErr[fillErrCounter].contFlag, e.Continue, "fillErr-C");
2201                         //Assert.AreEqual (fillErr[fillErrCounter].error, e.Errors.Message, "fillErr-E");
2202                         fillErrCounter++;
2203                 }
2204
2205                 [Test]
2206                 public void Load_Incompatible ()
2207                 {
2208                         localSetup ();
2209                         DataTable dtLoad = new DataTable ("LoadIncompatible");
2210                         dtLoad.Columns.Add ("name", typeof (double));
2211                         DataTableReader dtr = dt.CreateDataReader ();
2212                         try {
2213                                 dtLoad.Load (dtr);
2214                                 Assert.Fail ("#1");
2215                         } catch (ArgumentException) {
2216                         }
2217                 }
2218                 [Test]
2219                 // Load doesn't have a third overload in System.Data
2220                 // and is commented-out below
2221                 public void Load_IncompatibleEHandlerT ()
2222                 {
2223                         fillErrCounter = 0;
2224                         fillErr[0].init ("LoadIncompatible", 1, true,
2225                                  "Input string was not in a correct format.Couldn't store <mono 1> in name Column.  Expected type is Double.");
2226                         fillErr[1].init ("LoadIncompatible", 2, true,
2227                                 "Input string was not in a correct format.Couldn't store <mono 2> in name Column.  Expected type is Double.");
2228                         fillErr[2].init ("LoadIncompatible", 3, true,
2229                                 "Input string was not in a correct format.Couldn't store <mono 3> in name Column.  Expected type is Double.");
2230                         localSetup ();
2231                         DataTable dtLoad = new DataTable ("LoadIncompatible");
2232                         dtLoad.Columns.Add ("name", typeof (double));
2233                         DataTableReader dtr = dt.CreateDataReader ();
2234                         dtLoad.Load (dtr,LoadOption.PreserveChanges,fillErrorHandler);
2235                 }
2236
2237                 [Test]
2238                 // Load doesn't have a third overload in System.Data
2239                 // and is commented-out below
2240                 public void Load_IncompatibleEHandlerF ()
2241                 {
2242                         fillErrCounter = 0;
2243                         fillErr[0].init ("LoadIncompatible", 1, false,
2244                                 "Input string was not in a correct format.Couldn't store <mono 1> in name Column.  Expected type is Double.");
2245                         localSetup ();
2246                         DataTable dtLoad = new DataTable ("LoadIncompatible");
2247                         dtLoad.Columns.Add ("name", typeof (double));
2248                         DataTableReader dtr = dt.CreateDataReader ();
2249                         try {
2250                                 dtLoad.Load (dtr, LoadOption.PreserveChanges, fillErrorHandler);
2251                                 Assert.Fail ("#1");
2252                         } catch (ArgumentException) {
2253                         }
2254                 }
2255
2256                 [Test]
2257                 public void Load_ExtraColsEqualVal ()
2258                 {
2259                         localSetup ();
2260                         DataTable dtLoad = new DataTable ("LoadExtraCols");
2261                         dtLoad.Columns.Add ("id", typeof (int));
2262                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2263                         dtLoad.Rows.Add (new object[] { 1 });
2264                         dtLoad.Rows.Add (new object[] { 2 });
2265                         dtLoad.Rows.Add (new object[] { 3 });
2266                         dtLoad.AcceptChanges ();
2267                         DataTableReader dtr = dt.CreateDataReader ();
2268                         dtLoad.Load (dtr);
2269                         Assert.AreEqual (2, dtLoad.Columns.Count, "NColumns");
2270                         Assert.AreEqual (3, dtLoad.Rows.Count, "NRows");
2271                         Assert.AreEqual (1, dtLoad.Rows[0][0], "RowData0-0");
2272                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1], "RowData0-1");
2273                         Assert.AreEqual (2, dtLoad.Rows[1][0], "RowData1-0");
2274                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1], "RowData1-1");
2275                         Assert.AreEqual (3, dtLoad.Rows[2][0], "RowData2-0");
2276                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1], "RowData2-1");
2277                 }
2278
2279                 [Test]
2280                 public void Load_ExtraColsNonEqualVal ()
2281                 {
2282                         localSetup ();
2283                         DataTable dtLoad = new DataTable ("LoadExtraCols");
2284                         dtLoad.Columns.Add ("id", typeof (int));
2285                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2286                         dtLoad.Rows.Add (new object[] { 4 });
2287                         dtLoad.Rows.Add (new object[] { 5 });
2288                         dtLoad.Rows.Add (new object[] { 6 });
2289                         dtLoad.AcceptChanges ();
2290                         DataTableReader dtr = dt.CreateDataReader ();
2291                         dtLoad.Load (dtr);
2292                         Assert.AreEqual (2, dtLoad.Columns.Count, "NColumns");
2293                         Assert.AreEqual (6, dtLoad.Rows.Count, "NRows");
2294                         Assert.AreEqual (4, dtLoad.Rows[0][0], "RowData0-0");
2295                         Assert.AreEqual (5, dtLoad.Rows[1][0], "RowData1-0");
2296                         Assert.AreEqual (6, dtLoad.Rows[2][0], "RowData2-0");
2297                         Assert.AreEqual (1, dtLoad.Rows[3][0], "RowData3-0");
2298                         Assert.AreEqual ("mono 1", dtLoad.Rows[3][1], "RowData3-1");
2299                         Assert.AreEqual (2, dtLoad.Rows[4][0], "RowData4-0");
2300                         Assert.AreEqual ("mono 2", dtLoad.Rows[4][1], "RowData4-1");
2301                         Assert.AreEqual (3, dtLoad.Rows[5][0], "RowData5-0");
2302                         Assert.AreEqual ("mono 3", dtLoad.Rows[5][1], "RowData5-1");
2303                 }
2304
2305                 [Test]
2306                 public void Load_MissingColsNonNullable ()
2307                 {
2308                         localSetup ();
2309                         DataTable dtLoad = new DataTable ("LoadMissingCols");
2310                         dtLoad.Columns.Add ("id", typeof (int));
2311                         dtLoad.Columns.Add ("name", typeof (string));
2312                         dtLoad.Columns.Add ("missing", typeof (string));
2313                         dtLoad.Columns["missing"].AllowDBNull = false;
2314                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2315                         dtLoad.Rows.Add (new object[] { 4, "mono 4", "miss4" });
2316                         dtLoad.Rows.Add (new object[] { 5, "mono 5", "miss5" });
2317                         dtLoad.Rows.Add (new object[] { 6, "mono 6", "miss6" });
2318                         dtLoad.AcceptChanges ();
2319                         DataTableReader dtr = dt.CreateDataReader ();
2320                         try {
2321                                 dtLoad.Load (dtr);
2322                                 Assert.Fail ("#1");
2323                         } catch (ConstraintException) {
2324                         }
2325                 }
2326
2327                 [Test]
2328                 public void Load_MissingColsDefault ()
2329                 {
2330                         localSetup ();
2331                         DataTable dtLoad = new DataTable ("LoadMissingCols");
2332                         dtLoad.Columns.Add ("id", typeof (int));
2333                         dtLoad.Columns.Add ("name", typeof (string));
2334                         dtLoad.Columns.Add ("missing", typeof (string));
2335                         dtLoad.Columns["missing"].AllowDBNull = false;
2336                         dtLoad.Columns["missing"].DefaultValue = "DefaultValue";
2337                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2338                         dtLoad.Rows.Add (new object[] { 4, "mono 4", "miss4" });
2339                         dtLoad.Rows.Add (new object[] { 5, "mono 5", "miss5" });
2340                         dtLoad.Rows.Add (new object[] { 6, "mono 6", "miss6" });
2341                         dtLoad.AcceptChanges ();
2342                         DataTableReader dtr = dt.CreateDataReader ();
2343                         dtLoad.Load (dtr);
2344                         Assert.AreEqual (3, dtLoad.Columns.Count, "NColumns");
2345                         Assert.AreEqual (6, dtLoad.Rows.Count, "NRows");
2346                         Assert.AreEqual (4, dtLoad.Rows[0][0], "RowData0-0");
2347                         Assert.AreEqual ("mono 4", dtLoad.Rows[0][1], "RowData0-1");
2348                         Assert.AreEqual ("miss4", dtLoad.Rows[0][2], "RowData0-2");
2349                         Assert.AreEqual (5, dtLoad.Rows[1][0], "RowData1-0");
2350                         Assert.AreEqual ("mono 5", dtLoad.Rows[1][1], "RowData1-1");
2351                         Assert.AreEqual ("miss5", dtLoad.Rows[1][2], "RowData1-2");
2352                         Assert.AreEqual (6, dtLoad.Rows[2][0], "RowData2-0");
2353                         Assert.AreEqual ("mono 6", dtLoad.Rows[2][1], "RowData2-1");
2354                         Assert.AreEqual ("miss6", dtLoad.Rows[2][2], "RowData2-2");
2355                         Assert.AreEqual (1, dtLoad.Rows[3][0], "RowData3-0");
2356                         Assert.AreEqual ("mono 1", dtLoad.Rows[3][1], "RowData3-1");
2357                         Assert.AreEqual ("DefaultValue", dtLoad.Rows[3][2], "RowData3-2");
2358                         Assert.AreEqual (2, dtLoad.Rows[4][0], "RowData4-0");
2359                         Assert.AreEqual ("mono 2", dtLoad.Rows[4][1], "RowData4-1");
2360                         Assert.AreEqual ("DefaultValue", dtLoad.Rows[4][2], "RowData4-2");
2361                         Assert.AreEqual (3, dtLoad.Rows[5][0], "RowData5-0");
2362                         Assert.AreEqual ("mono 3", dtLoad.Rows[5][1], "RowData5-1");
2363                         Assert.AreEqual ("DefaultValue", dtLoad.Rows[5][2], "RowData5-2");
2364                 }
2365
2366                 [Test]
2367                 public void Load_MissingColsNullable ()
2368                 {
2369                         localSetup ();
2370                         DataTable dtLoad = new DataTable ("LoadMissingCols");
2371                         dtLoad.Columns.Add ("id", typeof (int));
2372                         dtLoad.Columns.Add ("name", typeof (string));
2373                         dtLoad.Columns.Add ("missing", typeof (string));
2374                         dtLoad.Columns["missing"].AllowDBNull = true;
2375                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2376                         dtLoad.Rows.Add (new object[] { 4, "mono 4", "miss4" });
2377                         dtLoad.Rows.Add (new object[] { 5, "mono 5", "miss5" });
2378                         dtLoad.Rows.Add (new object[] { 6, "mono 6", "miss6" });
2379                         dtLoad.AcceptChanges ();
2380                         DataTableReader dtr = dt.CreateDataReader ();
2381                         dtLoad.Load (dtr);
2382                         Assert.AreEqual (3, dtLoad.Columns.Count, "NColumns");
2383                         Assert.AreEqual (6, dtLoad.Rows.Count, "NRows");
2384                         Assert.AreEqual (4, dtLoad.Rows[0][0], "RowData0-0");
2385                         Assert.AreEqual ("mono 4", dtLoad.Rows[0][1], "RowData0-1");
2386                         Assert.AreEqual ("miss4", dtLoad.Rows[0][2], "RowData0-2");
2387                         Assert.AreEqual (5, dtLoad.Rows[1][0], "RowData1-0");
2388                         Assert.AreEqual ("mono 5", dtLoad.Rows[1][1], "RowData1-1");
2389                         Assert.AreEqual ("miss5", dtLoad.Rows[1][2], "RowData1-2");
2390                         Assert.AreEqual (6, dtLoad.Rows[2][0], "RowData2-0");
2391                         Assert.AreEqual ("mono 6", dtLoad.Rows[2][1], "RowData2-1");
2392                         Assert.AreEqual ("miss6", dtLoad.Rows[2][2], "RowData2-2");
2393                         Assert.AreEqual (1, dtLoad.Rows[3][0], "RowData3-0");
2394                         Assert.AreEqual ("mono 1", dtLoad.Rows[3][1], "RowData3-1");
2395                         //Assert.IsNull (dtLoad.Rows[3][2], "RowData3-2");
2396                         Assert.AreEqual (2, dtLoad.Rows[4][0], "RowData4-0");
2397                         Assert.AreEqual ("mono 2", dtLoad.Rows[4][1], "RowData4-1");
2398                         //Assert.IsNull (dtLoad.Rows[4][2], "RowData4-2");
2399                         Assert.AreEqual (3, dtLoad.Rows[5][0], "RowData5-0");
2400                         Assert.AreEqual ("mono 3", dtLoad.Rows[5][1], "RowData5-1");
2401                         //Assert.IsNull (dtLoad.Rows[5][2], "RowData5-2");
2402                 }
2403
2404                 private DataTable setupRowState ()
2405                 {
2406                         DataTable tbl = new DataTable ("LoadRowStateChanges");
2407                         tbl.RowChanged += new DataRowChangeEventHandler (dtLoad_RowChanged);
2408                         tbl.RowChanging += new DataRowChangeEventHandler (dtLoad_RowChanging);
2409                         tbl.Columns.Add ("id", typeof (int));
2410                         tbl.Columns.Add ("name", typeof (string));
2411                         tbl.PrimaryKey = new DataColumn[] { tbl.Columns["id"] };
2412                         tbl.Rows.Add (new object[] { 1, "RowState 1" });
2413                         tbl.Rows.Add (new object[] { 2, "RowState 2" });
2414                         tbl.Rows.Add (new object[] { 3, "RowState 3" });
2415                         tbl.AcceptChanges ();
2416                         // Update Table with following changes: Row0 unmodified, 
2417                         // Row1 modified, Row2 deleted, Row3 added, Row4 not-present.
2418                         tbl.Rows[1]["name"] = "Modify 2";
2419                         tbl.Rows[2].Delete ();
2420                         DataRow row = tbl.NewRow ();
2421                         row["id"] = 4;
2422                         row["name"] = "Add 4";
2423                         tbl.Rows.Add (row);
2424                         return (tbl);
2425                 }
2426
2427                 private DataRowAction[] rowChangeAction = new DataRowAction[5];
2428                 private bool checkAction;
2429                 private int rowChagedCounter, rowChangingCounter;
2430                 private void rowActionInit (DataRowAction[] act)
2431                 {
2432                         checkAction = true;
2433                         rowChagedCounter = 0;
2434                         rowChangingCounter = 0;
2435                         for (int i = 0; i < 5; i++)
2436                                 rowChangeAction[i] = act[i];
2437                 }
2438
2439                 private void rowActionEnd ()
2440                 {
2441                         checkAction = false;
2442                 }
2443
2444                 private void dtLoad_RowChanged (object sender, DataRowChangeEventArgs e)
2445                 {
2446                         if (checkAction) {
2447                                 Assert.AreEqual (rowChangeAction[rowChagedCounter], e.Action, "RowChanged" + rowChagedCounter);
2448                                 rowChagedCounter++;
2449                         }
2450                 }
2451
2452                 private void dtLoad_RowChanging (object sender, DataRowChangeEventArgs e)
2453                 {
2454                         if (checkAction) {
2455                                 Assert.AreEqual (rowChangeAction[rowChangingCounter], e.Action, "RowChanging" + rowChangingCounter);
2456                                 rowChangingCounter++;
2457                         }
2458                 }
2459
2460                 [Test]
2461                 public void Load_RowStateChangesDefault ()
2462                 {
2463                         localSetup ();
2464                         dt.Rows.Add (new object[] { 4, "mono 4" });
2465                         dt.Rows.Add (new object[] { 5, "mono 5" });
2466                         dt.AcceptChanges ();
2467                         DataTableReader dtr = dt.CreateDataReader ();
2468                         DataTable dtLoad = setupRowState ();
2469                         DataRowAction[] dra = new DataRowAction[] {
2470                                 DataRowAction.ChangeCurrentAndOriginal,
2471                                 DataRowAction.ChangeOriginal,
2472                                 DataRowAction.ChangeOriginal,
2473                                 DataRowAction.ChangeOriginal,
2474                                 DataRowAction.ChangeCurrentAndOriginal};
2475                         rowActionInit (dra);
2476                         dtLoad.Load (dtr);
2477                         rowActionEnd ();
2478                         // asserting Unchanged Row0
2479                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1,DataRowVersion.Current], "RowData0-C");
2480                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1,DataRowVersion.Original], "RowData0-O");
2481                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[0].RowState, "RowState0");
2482                         // asserting Modified Row1
2483                         Assert.AreEqual ("Modify 2", dtLoad.Rows[1][1, DataRowVersion.Current], "RowData1-C");
2484                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1, DataRowVersion.Original], "RowData1-O");
2485                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[1].RowState, "RowState1");
2486                         // asserting Deleted Row2
2487                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1, DataRowVersion.Original], "RowData1-O");
2488                         Assert.AreEqual (DataRowState.Deleted, dtLoad.Rows[2].RowState, "RowState2");
2489                         // asserting Added Row3
2490                         Assert.AreEqual ("Add 4", dtLoad.Rows[3][1, DataRowVersion.Current], "RowData3-C");
2491                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2492                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[3].RowState, "RowState3");
2493                         // asserting Unpresent Row4
2494                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Current], "RowData4-C");
2495                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Original], "RowData4-O");
2496                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[4].RowState, "RowState4");
2497                 }
2498
2499                 [Test]
2500                 public void Load_RowStateChangesDefaultDelete ()
2501                 {
2502                         localSetup ();
2503                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2504                         dtLoad.Columns.Add ("id", typeof (int));
2505                         dtLoad.Columns.Add ("name", typeof (string));
2506                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2507                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2508                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2509                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2510                         dtLoad.AcceptChanges ();
2511                         dtLoad.Rows[2].Delete ();
2512                         DataTableReader dtr = dt.CreateDataReader ();
2513                         dtLoad.Load (dtr);
2514
2515                         try {
2516                                 Assert.AreEqual (" ", dtLoad.Rows[2][1, DataRowVersion.Current], "RowData2-C");
2517                                 Assert.Fail ("#1");
2518                         } catch (VersionNotFoundException) {
2519                         }
2520                 }
2521
2522                 [Test]
2523                 public void Load_RowStatePreserveChanges ()
2524                 {
2525                         localSetup ();
2526                         dt.Rows.Add (new object[] { 4, "mono 4" });
2527                         dt.Rows.Add (new object[] { 5, "mono 5" });
2528                         dt.AcceptChanges ();
2529                         DataTableReader dtr = dt.CreateDataReader ();
2530                         DataTable dtLoad = setupRowState ();
2531                         DataRowAction[] dra = new DataRowAction[] {
2532                                 DataRowAction.ChangeCurrentAndOriginal,
2533                                 DataRowAction.ChangeOriginal,
2534                                 DataRowAction.ChangeOriginal,
2535                                 DataRowAction.ChangeOriginal,
2536                                 DataRowAction.ChangeCurrentAndOriginal};
2537                         rowActionInit (dra);
2538                         dtLoad.Load (dtr, LoadOption.PreserveChanges);
2539                         rowActionEnd ();
2540                         // asserting Unchanged Row0
2541                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Current], "RowData0-C");
2542                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Original], "RowData0-O");
2543                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[0].RowState, "RowState0");
2544                         // asserting Modified Row1
2545                         Assert.AreEqual ("Modify 2", dtLoad.Rows[1][1, DataRowVersion.Current], "RowData1-C");
2546                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1, DataRowVersion.Original], "RowData1-O");
2547                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[1].RowState, "RowState1");
2548                         // asserting Deleted Row2
2549                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1, DataRowVersion.Original], "RowData1-O");
2550                         Assert.AreEqual (DataRowState.Deleted, dtLoad.Rows[2].RowState, "RowState2");
2551                         // asserting Added Row3
2552                         Assert.AreEqual ("Add 4", dtLoad.Rows[3][1, DataRowVersion.Current], "RowData3-C");
2553                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2554                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[3].RowState, "RowState3");
2555                         // asserting Unpresent Row4
2556                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Current], "RowData4-C");
2557                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Original], "RowData4-O");
2558                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[4].RowState, "RowState4");
2559                 }
2560
2561                 [Test]
2562                 public void Load_RowStatePreserveChangesDelete () {
2563                         localSetup ();
2564                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2565                         dtLoad.Columns.Add ("id", typeof (int));
2566                         dtLoad.Columns.Add ("name", typeof (string));
2567                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2568                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2569                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2570                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2571                         dtLoad.AcceptChanges ();
2572                         dtLoad.Rows[2].Delete ();
2573                         DataTableReader dtr = dt.CreateDataReader ();
2574                         dtLoad.Load (dtr,LoadOption.PreserveChanges);
2575
2576                         try {
2577                                 Assert.AreEqual (" ", dtLoad.Rows[2][1, DataRowVersion.Current], "RowData2-C");
2578                                 Assert.Fail ("#1");
2579                         } catch (VersionNotFoundException) {
2580                         }
2581                 }
2582
2583                 [Test]
2584                 public void Load_RowStateOverwriteChanges ()
2585                 {
2586                         localSetup ();
2587                         dt.Rows.Add (new object[] { 4, "mono 4" });
2588                         dt.Rows.Add (new object[] { 5, "mono 5" });
2589                         dt.AcceptChanges ();
2590                         DataTableReader dtr = dt.CreateDataReader ();
2591                         DataTable dtLoad = setupRowState ();
2592                         DataRowAction[] dra = new DataRowAction[] {
2593                                 DataRowAction.ChangeCurrentAndOriginal,
2594                                 DataRowAction.ChangeCurrentAndOriginal,
2595                                 DataRowAction.ChangeCurrentAndOriginal,
2596                                 DataRowAction.ChangeCurrentAndOriginal,
2597                                 DataRowAction.ChangeCurrentAndOriginal};
2598                         rowActionInit (dra);
2599                         dtLoad.Load (dtr, LoadOption.OverwriteChanges);
2600                         rowActionEnd ();
2601                         // asserting Unchanged Row0
2602                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Current], "RowData0-C");
2603                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Original], "RowData0-O");
2604                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[0].RowState, "RowState0");
2605                         // asserting Modified Row1
2606                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1, DataRowVersion.Current], "RowData1-C");
2607                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1, DataRowVersion.Original], "RowData1-O");
2608                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[1].RowState, "RowState1");
2609                         // asserting Deleted Row2
2610                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1, DataRowVersion.Current], "RowData1-C");
2611                         Assert.AreEqual ("mono 3", dtLoad.Rows[2][1, DataRowVersion.Original], "RowData1-O");
2612                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[2].RowState, "RowState2");
2613                         // asserting Added Row3
2614                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Current], "RowData3-C");
2615                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2616                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[3].RowState, "RowState3");
2617                         // asserting Unpresent Row4
2618                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Current], "RowData4-C");
2619                         Assert.AreEqual ("mono 5", dtLoad.Rows[4][1, DataRowVersion.Original], "RowData4-O");
2620                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[4].RowState, "RowState4");
2621                 }
2622
2623                 [Test]
2624                 public void Load_RowStateUpsert ()
2625                 {
2626                         localSetup ();
2627                         dt.Rows.Add (new object[] { 4, "mono 4" });
2628                         dt.Rows.Add (new object[] { 5, "mono 5" });
2629                         dt.AcceptChanges ();
2630                         DataTableReader dtr = dt.CreateDataReader ();
2631                         DataTable dtLoad = setupRowState ();
2632                         // Notice rowChange-Actions only occur 5 times, as number 
2633                         // of actual rows, ignoring row duplication of the deleted row.
2634                         DataRowAction[] dra = new DataRowAction[] {
2635                                 DataRowAction.Change,
2636                                 DataRowAction.Change,
2637                                 DataRowAction.Add,
2638                                 DataRowAction.Change,
2639                                 DataRowAction.Add};
2640                         rowActionInit (dra);
2641                         dtLoad.Load (dtr, LoadOption.Upsert);
2642                         rowActionEnd ();
2643                         // asserting Unchanged Row0
2644                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Current], "RowData0-C");
2645                         Assert.AreEqual ("RowState 1", dtLoad.Rows[0][1, DataRowVersion.Original], "RowData0-O");
2646                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[0].RowState, "RowState0");
2647                         // asserting Modified Row1
2648                         Assert.AreEqual ("mono 2", dtLoad.Rows[1][1, DataRowVersion.Current], "RowData1-C");
2649                         Assert.AreEqual ("RowState 2", dtLoad.Rows[1][1, DataRowVersion.Original], "RowData1-O");
2650                         Assert.AreEqual (DataRowState.Modified, dtLoad.Rows[1].RowState, "RowState1");
2651                         // asserting Deleted Row2 and "Deleted-Added" Row4
2652                         Assert.AreEqual ("RowState 3", dtLoad.Rows[2][1, DataRowVersion.Original], "RowData2-O");
2653                         Assert.AreEqual (DataRowState.Deleted, dtLoad.Rows[2].RowState, "RowState2");
2654                         Assert.AreEqual ("mono 3", dtLoad.Rows[4][1, DataRowVersion.Current], "RowData4-C");
2655                         Assert.AreEqual (DataRowState.Added, dtLoad.Rows[4].RowState, "RowState4");
2656                         // asserting Added Row3
2657                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Current], "RowData3-C");
2658                         Assert.AreEqual (DataRowState.Added, dtLoad.Rows[3].RowState, "RowState3");
2659                         // asserting Unpresent Row5
2660                         // Notice row4 is used for added row of deleted row2 and so
2661                         // unpresent row4 moves to row5
2662                         Assert.AreEqual ("mono 5", dtLoad.Rows[5][1, DataRowVersion.Current], "RowData5-C");
2663                         Assert.AreEqual (DataRowState.Added, dtLoad.Rows[5].RowState, "RowState5");
2664                 }
2665
2666                 [Test]
2667                 public void Load_RowStateUpsertDuplicateKey1 ()
2668                 {
2669                         localSetup ();
2670                         dt.Rows.Add (new object[] { 4, "mono 4" });
2671                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2672                         dtLoad.Columns.Add ("id", typeof (int));
2673                         dtLoad.Columns.Add ("name", typeof (string));
2674                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2675                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2676                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2677                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2678                         dtLoad.AcceptChanges ();
2679                         dtLoad.Rows[2].Delete ();
2680                         DataTableReader dtr = dt.CreateDataReader ();
2681                         dtLoad.Load (dtr, LoadOption.Upsert);
2682                         dtLoad.Rows[3][1] = "NEWVAL";
2683                         Assert.AreEqual (DataRowState.Deleted, dtLoad.Rows[2].RowState, "A-RowState2");
2684                         Assert.AreEqual (3, dtLoad.Rows[2][0, DataRowVersion.Original], "A-RowData2-id");
2685                         Assert.AreEqual ("RowState 3", dtLoad.Rows[2][1, DataRowVersion.Original], "A-RowData2-name");
2686                         Assert.AreEqual (DataRowState.Added, dtLoad.Rows[3].RowState, "A-RowState3");
2687                         Assert.AreEqual (3, dtLoad.Rows[3][0, DataRowVersion.Current], "A-RowData3-id");
2688                         Assert.AreEqual ("NEWVAL", dtLoad.Rows[3][1, DataRowVersion.Current], "A-RowData3-name");
2689                         Assert.AreEqual (DataRowState.Added, dtLoad.Rows[4].RowState, "A-RowState4");
2690                         Assert.AreEqual (4, dtLoad.Rows[4][0, DataRowVersion.Current], "A-RowData4-id");
2691                         Assert.AreEqual ("mono 4", dtLoad.Rows[4][1, DataRowVersion.Current], "A-RowData4-name");
2692
2693                         dtLoad.AcceptChanges ();
2694
2695                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[2].RowState, "B-RowState2");
2696                         Assert.AreEqual (3, dtLoad.Rows[2][0, DataRowVersion.Current], "B-RowData2-id");
2697                         Assert.AreEqual ("NEWVAL", dtLoad.Rows[2][1, DataRowVersion.Current], "B-RowData2-name");
2698                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[3].RowState, "B-RowState3");
2699                         Assert.AreEqual (4, dtLoad.Rows[3][0, DataRowVersion.Current], "B-RowData3-id");
2700                         Assert.AreEqual ("mono 4", dtLoad.Rows[3][1, DataRowVersion.Current], "B-RowData3-name");
2701                 }
2702
2703                 [Test]
2704                 public void Load_RowStateUpsertDuplicateKey2 ()
2705                 {
2706                         localSetup ();
2707                         dt.Rows.Add (new object[] { 4, "mono 4" });
2708                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2709                         dtLoad.Columns.Add ("id", typeof (int));
2710                         dtLoad.Columns.Add ("name", typeof (string));
2711                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2712                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2713                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2714                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2715                         dtLoad.AcceptChanges ();
2716                         dtLoad.Rows[2].Delete ();
2717                         DataTableReader dtr = dt.CreateDataReader ();
2718                         dtLoad.Load (dtr, LoadOption.Upsert);
2719                         dtLoad.AcceptChanges ();
2720
2721                         try {
2722                                 Assert.AreEqual (" ", dtLoad.Rows[4][1], "RowData4");
2723                                 Assert.Fail ("#1");
2724                         } catch (IndexOutOfRangeException) {
2725                         }
2726                 }
2727
2728                 [Test]
2729                 public void Load_RowStateUpsertDelete1 ()
2730                 {
2731                         localSetup ();
2732                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2733                         dtLoad.Columns.Add ("id", typeof (int));
2734                         dtLoad.Columns.Add ("name", typeof (string));
2735                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2736                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2737                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2738                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2739                         dtLoad.AcceptChanges ();
2740                         dtLoad.Rows[2].Delete ();
2741                         DataTableReader dtr = dt.CreateDataReader ();
2742                         dtLoad.Load (dtr, LoadOption.Upsert);
2743
2744                         try {
2745                                 Assert.AreEqual (" ", dtLoad.Rows[2][1, DataRowVersion.Current], "RowData2-C");
2746                                 Assert.Fail ("#1");
2747                         } catch (VersionNotFoundException) {
2748                         }
2749                 }
2750
2751                 [Test]
2752                 public void Load_RowStateUpsertDelete2 ()
2753                 {
2754                         localSetup ();
2755                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2756                         dtLoad.Columns.Add ("id", typeof (int));
2757                         dtLoad.Columns.Add ("name", typeof (string));
2758                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2759                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2760                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2761                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2762                         dtLoad.AcceptChanges ();
2763                         dtLoad.Rows[2].Delete ();
2764                         DataTableReader dtr = dt.CreateDataReader ();
2765                         dtLoad.Load (dtr, LoadOption.Upsert);
2766
2767                         try {
2768                                 Assert.AreEqual (" ", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2769                                 Assert.Fail ("#1");
2770                         } catch (VersionNotFoundException) {
2771                         }
2772                 }
2773
2774                 [Test]
2775                 public void Load_RowStateUpsertAdd ()
2776                 {
2777                         localSetup ();
2778                         dt.Rows.Add (new object[] { 4, "mono 4" });
2779                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2780                         dtLoad.Columns.Add ("id", typeof (int));
2781                         dtLoad.Columns.Add ("name", typeof (string));
2782                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2783                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2784                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2785                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2786                         dtLoad.AcceptChanges ();
2787                         DataRow row = dtLoad.NewRow ();
2788                         row["id"] = 4;
2789                         row["name"] = "Add 4";
2790                         dtLoad.Rows.Add (row);
2791                         DataTableReader dtr = dt.CreateDataReader ();
2792                         dtLoad.Load (dtr, LoadOption.Upsert);
2793
2794                         try {
2795                                 Assert.AreEqual (" ", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2796                                 Assert.Fail ("#1");
2797                         } catch (VersionNotFoundException) {
2798                         }
2799                 }
2800
2801                 [Test]
2802                 public void Load_RowStateUpsertUnpresent () {
2803                         localSetup ();
2804                         dt.Rows.Add (new object[] { 4, "mono 4" });
2805                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2806                         dtLoad.Columns.Add ("id", typeof (int));
2807                         dtLoad.Columns.Add ("name", typeof (string));
2808                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2809                         dtLoad.Rows.Add (new object[] { 1, "RowState 1" });
2810                         dtLoad.Rows.Add (new object[] { 2, "RowState 2" });
2811                         dtLoad.Rows.Add (new object[] { 3, "RowState 3" });
2812                         dtLoad.AcceptChanges ();
2813                         DataTableReader dtr = dt.CreateDataReader ();
2814                         dtLoad.Load (dtr, LoadOption.Upsert);
2815
2816                         try {
2817                                 Assert.AreEqual (" ", dtLoad.Rows[3][1, DataRowVersion.Original], "RowData3-O");
2818                                 Assert.Fail ("#1");
2819                         } catch (VersionNotFoundException) {
2820                         }
2821                 }
2822
2823                 [Test]
2824                 public void Load_RowStateUpsertUnchangedEqualVal ()
2825                 {
2826                         localSetup ();
2827                         DataTable dtLoad = new DataTable ("LoadRowStateChanges");
2828                         dtLoad.Columns.Add ("id", typeof (int));
2829                         dtLoad.Columns.Add ("name", typeof (string));
2830                         dtLoad.PrimaryKey = new DataColumn[] { dtLoad.Columns["id"] };
2831                         dtLoad.Rows.Add (new object[] { 1, "mono 1" });
2832                         dtLoad.AcceptChanges ();
2833                         DataTableReader dtr = dt.CreateDataReader ();
2834                         DataRowAction[] dra = new DataRowAction[] {
2835                                 DataRowAction.Nothing,// REAL action
2836                                 DataRowAction.Nothing,// dummy  
2837                                 DataRowAction.Nothing,// dummy  
2838                                 DataRowAction.Nothing,// dummy  
2839                                 DataRowAction.Nothing};// dummy  
2840                         rowActionInit (dra);
2841                         dtLoad.Load (dtr, LoadOption.Upsert);
2842                         rowActionEnd ();
2843                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Current], "RowData0-C");
2844                         Assert.AreEqual ("mono 1", dtLoad.Rows[0][1, DataRowVersion.Original], "RowData0-O");
2845                         Assert.AreEqual (DataRowState.Unchanged, dtLoad.Rows[0].RowState, "RowState0");
2846                 }
2847
2848                 [Test]
2849                 public void LoadDataRow_LoadOptions ()
2850                 {
2851                         // LoadDataRow is covered in detail (without LoadOptions) in DataTableTest2
2852                         // LoadOption tests are covered in detail in DataTable.Load().
2853                         // Therefore only minimal tests of LoadDataRow with LoadOptions are covered here.
2854                         DataTable dt;
2855                         DataRow dr;
2856                         dt = CreateDataTableExample ();
2857                         dt.PrimaryKey = new DataColumn[] { dt.Columns[0] };     //add ParentId as Primary Key
2858                         dt.Columns["String1"].DefaultValue = "Default";
2859
2860                         dr = dt.Select ("ParentId=1")[0];
2861
2862                         //Update existing row with LoadOptions = OverwriteChanges
2863                         dt.BeginLoadData ();
2864                         dt.LoadDataRow (new object[] { 1, null, "Changed" },
2865                                 LoadOption.OverwriteChanges);
2866                         dt.EndLoadData ();
2867
2868                         // LoadDataRow(update1) - check column String2
2869                         Assert.AreEqual ("Changed", dr["String2", DataRowVersion.Current], "DT72-C");
2870                         Assert.AreEqual ("Changed", dr["String2", DataRowVersion.Original], "DT72-O");
2871
2872                         // LoadDataRow(update1) - check row state
2873                         Assert.AreEqual (DataRowState.Unchanged, dr.RowState, "DT73-LO");
2874
2875                         //Add New row with LoadOptions = Upsert
2876                         dt.BeginLoadData ();
2877                         dt.LoadDataRow (new object[] { 99, null, "Changed" },
2878                                 LoadOption.Upsert);
2879                         dt.EndLoadData ();
2880
2881                         // LoadDataRow(insert1) - check column String2
2882                         dr = dt.Select ("ParentId=99")[0];
2883                         Assert.AreEqual ("Changed", dr["String2", DataRowVersion.Current], "DT75-C");
2884
2885                         // LoadDataRow(insert1) - check row state
2886                         Assert.AreEqual (DataRowState.Added, dr.RowState, "DT76-LO");
2887                 }
2888
2889                 public static DataTable CreateDataTableExample ()
2890                 {
2891                         DataTable dtParent = new DataTable ("Parent");
2892
2893                         dtParent.Columns.Add ("ParentId", typeof (int));
2894                         dtParent.Columns.Add ("String1", typeof (string));
2895                         dtParent.Columns.Add ("String2", typeof (string));
2896
2897                         dtParent.Columns.Add ("ParentDateTime", typeof (DateTime));
2898                         dtParent.Columns.Add ("ParentDouble", typeof (double));
2899                         dtParent.Columns.Add ("ParentBool", typeof (bool));
2900
2901                         dtParent.Rows.Add (new object[] { 1, "1-String1", "1-String2", new DateTime (2005, 1, 1, 0, 0, 0, 0), 1.534, true });
2902                         dtParent.Rows.Add (new object[] { 2, "2-String1", "2-String2", new DateTime (2004, 1, 1, 0, 0, 0, 1), -1.534, true });
2903                         dtParent.Rows.Add (new object[] { 3, "3-String1", "3-String2", new DateTime (2003, 1, 1, 0, 0, 1, 0), double.MinValue * 10000, false });
2904                         dtParent.Rows.Add (new object[] { 4, "4-String1", "4-String2", new DateTime (2002, 1, 1, 0, 1, 0, 0), double.MaxValue / 10000, true });
2905                         dtParent.Rows.Add (new object[] { 5, "5-String1", "5-String2", new DateTime (2001, 1, 1, 1, 0, 0, 0), 0.755, true });
2906                         dtParent.Rows.Add (new object[] { 6, "6-String1", "6-String2", new DateTime (2000, 1, 1, 0, 0, 0, 0), 0.001, false });
2907                         dtParent.AcceptChanges ();
2908                         return dtParent;
2909                 }
2910
2911                 #endregion // DataTable.Load Tests
2912
2913                 #region Read/Write XML Tests
2914
2915                 [Test]
2916                 public void ReadXmlSchema ()
2917                 {
2918                         DataTable Table = new DataTable ();
2919                         Table.ReadXmlSchema ("Test/System.Data/own_schema1.xsd");
2920
2921                         Assert.AreEqual ("test_table", Table.TableName, "test#02");
2922                         Assert.AreEqual ("", Table.Namespace, "test#03");
2923                         Assert.AreEqual (2, Table.Columns.Count, "test#04");
2924                         Assert.AreEqual (0, Table.Rows.Count, "test#05");
2925                         Assert.IsFalse (Table.CaseSensitive, "test#06");
2926                         Assert.AreEqual (1, Table.Constraints.Count, "test#07");
2927                         Assert.AreEqual ("", Table.Prefix, "test#08");
2928
2929                         Constraint cons = Table.Constraints[0];
2930                         Assert.AreEqual ("Constraint1", cons.ConstraintName.ToString (), "test#09");
2931                         Assert.AreEqual ("Constraint1", cons.ToString (), "test#10");
2932
2933                         DataColumn column = Table.Columns[0];
2934                         Assert.IsTrue (column.AllowDBNull, "test#11");
2935                         Assert.IsFalse (column.AutoIncrement, "test#12");
2936                         Assert.AreEqual (0L, column.AutoIncrementSeed, "test#13");
2937                         Assert.AreEqual (1L, column.AutoIncrementStep, "test#14");
2938                         Assert.AreEqual ("test", column.Caption, "test#15");
2939                         Assert.AreEqual ("Element", column.ColumnMapping.ToString (), "test#16");
2940                         Assert.AreEqual ("first", column.ColumnName, "test#17");
2941                         Assert.AreEqual (typeof (string), column.DataType, "test#18");
2942                         Assert.AreEqual ("test_default_value", column.DefaultValue.ToString (), "test#19");
2943                         Assert.IsFalse (column.DesignMode, "test#20");
2944                         Assert.AreEqual ("", column.Expression, "test#21");
2945                         Assert.AreEqual (100, column.MaxLength, "test#22");
2946                         Assert.AreEqual ("", column.Namespace, "test#23");
2947                         Assert.AreEqual (0, column.Ordinal, "test#24");
2948                         Assert.AreEqual ("", column.Prefix, "test#25");
2949                         Assert.IsFalse (column.ReadOnly, "test#26");
2950                         Assert.IsTrue (column.Unique, "test#27");
2951
2952                         DataColumn column2 = Table.Columns[1];
2953                         Assert.IsTrue (column2.AllowDBNull, "test#28");
2954                         Assert.IsFalse (column2.AutoIncrement, "test#29");
2955                         Assert.AreEqual (0L, column2.AutoIncrementSeed, "test#30");
2956                         Assert.AreEqual (1L, column2.AutoIncrementStep, "test#31");
2957                         Assert.AreEqual ("second", column2.Caption, "test#32");
2958                         Assert.AreEqual ("Element", column2.ColumnMapping.ToString (), "test#33");
2959                         Assert.AreEqual ("second", column2.ColumnName, "test#34");
2960                         Assert.AreEqual (typeof (SqlGuid), column2.DataType, "test#35");
2961                         Assert.AreEqual (SqlGuid.Null, column2.DefaultValue, "test#36");
2962                         Assert.AreEqual (typeof (SqlGuid), column2.DefaultValue.GetType (), "test#36-2");
2963                         Assert.IsFalse (column2.DesignMode, "test#37");
2964                         Assert.AreEqual ("", column2.Expression, "test#38");
2965                         Assert.AreEqual (-1, column2.MaxLength, "test#39");
2966                         Assert.AreEqual ("", column2.Namespace, "test#40");
2967                         Assert.AreEqual (1, column2.Ordinal, "test#41");
2968                         Assert.AreEqual ("", column2.Prefix, "test#42");
2969                         Assert.IsFalse (column2.ReadOnly, "test#43");
2970                         Assert.IsFalse (column2.Unique, "test#44");
2971
2972                         DataTable Table2 = new DataTable ();
2973                         Table2.ReadXmlSchema ("Test/System.Data/own_schema2.xsd");
2974
2975                         Assert.AreEqual ("second_test_table", Table2.TableName, "test#45");
2976                         Assert.AreEqual ("", Table2.Namespace, "test#46");
2977                         Assert.AreEqual (1, Table2.Columns.Count, "test#47");
2978                         Assert.AreEqual (0, Table2.Rows.Count, "test#48");
2979                         Assert.IsFalse (Table2.CaseSensitive, "test#49");
2980                         Assert.AreEqual (1, Table2.Constraints.Count, "test#50");
2981                         Assert.AreEqual ("", Table2.Prefix, "test#51");
2982
2983                         DataColumn column3 = Table2.Columns[0];
2984                         Assert.IsTrue (column3.AllowDBNull, "test#52");
2985                         Assert.IsFalse (column3.AutoIncrement, "test#53");
2986                         Assert.AreEqual (0L, column3.AutoIncrementSeed, "test#54");
2987                         Assert.AreEqual (1L, column3.AutoIncrementStep, "test#55");
2988                         Assert.AreEqual ("second_first", column3.Caption, "test#56");
2989                         Assert.AreEqual ("Element", column3.ColumnMapping.ToString (), "test#57");
2990                         Assert.AreEqual ("second_first", column3.ColumnName, "test#58");
2991                         Assert.AreEqual (typeof (string), column3.DataType, "test#59");
2992                         Assert.AreEqual ("default_value", column3.DefaultValue.ToString (), "test#60");
2993                         Assert.IsFalse (column3.DesignMode, "test#61");
2994                         Assert.AreEqual ("", column3.Expression, "test#62");
2995                         Assert.AreEqual (100, column3.MaxLength, "test#63");
2996                         Assert.AreEqual ("", column3.Namespace, "test#64");
2997                         Assert.AreEqual (0, column3.Ordinal, "test#65");
2998                         Assert.AreEqual ("", column3.Prefix, "test#66");
2999                         Assert.IsFalse (column3.ReadOnly, "test#67");
3000                         Assert.IsTrue (column3.Unique, "test#68");
3001                 }
3002
3003                 [Test]
3004                 public void ReadXmlSchema_2 ()
3005                 {
3006                         DataTable dt = new DataTable ();
3007                         string xmlData = string.Empty;
3008                         xmlData += "<?xml version=\"1.0\"?>";
3009                         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\">";
3010                         xmlData += "<xs:element name=\"SiteConfiguration\" msdata:IsDataSet=\"true\" msdata:EnforceConstraints=\"False\">";
3011                         xmlData += "<xs:complexType>";
3012                         xmlData += "<xs:choice  minOccurs=\"0\" maxOccurs=\"unbounded\">";
3013                         xmlData += "<xs:element name=\"Tab\">";
3014                         xmlData += "<xs:complexType>";
3015                         xmlData += "<xs:sequence>";
3016                         xmlData += "<xs:element name=\"Module\" minOccurs=\"0\" maxOccurs=\"unbounded\">";
3017                         xmlData += "<xs:complexType>";
3018                         xmlData += "<xs:attribute name=\"ModuleId\" form=\"unqualified\" type=\"xs:int\" />";
3019                         xmlData += "</xs:complexType>";
3020                         xmlData += "</xs:element>";
3021                         xmlData += "</xs:sequence>";
3022                         xmlData += "<xs:attribute name=\"TabId\" form=\"unqualified\" type=\"xs:int\" />";
3023                         xmlData += "</xs:complexType>";
3024                         xmlData += "</xs:element>";
3025                         xmlData += "</xs:choice>";
3026                         xmlData += "</xs:complexType>";
3027                         xmlData += "<xs:key name=\"TabKey\" msdata:PrimaryKey=\"true\">";
3028                         xmlData += "<xs:selector xpath=\".//mstns:Tab\" />";
3029                         xmlData += "<xs:field xpath=\"@TabId\" />";
3030                         xmlData += "</xs:key>";
3031                         xmlData += "<xs:key name=\"ModuleKey\" msdata:PrimaryKey=\"true\">";
3032                         xmlData += "<xs:selector xpath=\".//mstns:Module\" />";
3033                         xmlData += "<xs:field xpath=\"@ModuleID\" />";
3034                         xmlData += "</xs:key>";
3035                         xmlData += "</xs:element>";
3036                         xmlData += "</xs:schema>";
3037                         dt.ReadXmlSchema (new StringReader (xmlData));
3038                 }
3039
3040                 [Test]
3041                 public void ReadXmlSchema_ByStream ()
3042                 {
3043                         DataSet ds1 = new DataSet ();
3044                         ds1.Tables.Add (DataProvider.CreateParentDataTable ());
3045                         ds1.Tables.Add (DataProvider.CreateChildDataTable ());
3046
3047                         MemoryStream ms1 = new MemoryStream ();
3048                         MemoryStream ms2 = new MemoryStream ();
3049                         //write xml  schema only
3050                         //ds1.WriteXmlSchema (ms);
3051                         ds1.Tables[0].WriteXmlSchema (ms1);
3052                         ds1.Tables[1].WriteXmlSchema (ms2);
3053
3054                         MemoryStream ms11 = new MemoryStream (ms1.GetBuffer ());
3055                         MemoryStream ms22 = new MemoryStream (ms2.GetBuffer ());
3056                         //copy schema
3057                         //DataSet ds2 = new DataSet ();
3058                         DataTable dt1 = new DataTable ();
3059                         DataTable dt2 = new DataTable ();
3060
3061                         //ds2.ReadXmlSchema (ms1);
3062                         dt1.ReadXmlSchema (ms11);
3063                         dt2.ReadXmlSchema (ms22);
3064
3065                         //check xml schema
3066                         // ReadXmlSchema - Tables count
3067                         //Assert.AreEqual (ds2.Tables.Count, ds1.Tables.Count, "DS269");
3068
3069                         // ReadXmlSchema - Tables 0 Col count
3070                         Assert.AreEqual (ds1.Tables[0].Columns.Count, dt1.Columns.Count, "DS270");
3071
3072                         // ReadXmlSchema - Tables 1 Col count
3073                         Assert.AreEqual (ds1.Tables[1].Columns.Count, dt2.Columns.Count, "DS271");
3074
3075                         //check some colummns types
3076                         // ReadXmlSchema - Tables 0 Col type
3077                         Assert.AreEqual (ds1.Tables[0].Columns[0].GetType (), dt1.Columns[0].GetType (), "DS272");
3078
3079                         // ReadXmlSchema - Tables 1 Col type
3080                         Assert.AreEqual (ds1.Tables[1].Columns[3].GetType (), dt2.Columns[3].GetType (), "DS273");
3081
3082                         //check that no data exists
3083                         // ReadXmlSchema - Table 1 row count
3084                         Assert.AreEqual (0, dt1.Rows.Count, "DS274");
3085
3086                         // ReadXmlSchema - Table 2 row count
3087                         Assert.AreEqual (0, dt2.Rows.Count, "DS275");
3088                 }
3089
3090                 [Test]
3091                 public void ReadWriteXmlSchema_ByFileName ()
3092                 {
3093                         string sTempFileName1 = Path.Combine (Path.GetTempPath (), "tmpDataSet_ReadWriteXml_43899-1.xml");
3094                         string sTempFileName2 = Path.Combine (Path.GetTempPath (), "tmpDataSet_ReadWriteXml_43899-2.xml");
3095
3096                         DataSet ds1 = new DataSet ();
3097                         ds1.Tables.Add (DataProvider.CreateParentDataTable ());
3098                         ds1.Tables.Add (DataProvider.CreateChildDataTable ());
3099
3100                         ds1.Tables[0].WriteXmlSchema (sTempFileName1);
3101                         ds1.Tables[1].WriteXmlSchema (sTempFileName2);
3102
3103                         DataTable dt1 = new DataTable ();
3104                         DataTable dt2 = new DataTable ();
3105
3106                         dt1.ReadXmlSchema (sTempFileName1);
3107                         dt2.ReadXmlSchema (sTempFileName2);
3108
3109                         Assert.AreEqual (ds1.Tables[0].Columns.Count, dt1.Columns.Count, "DS277");
3110                         Assert.AreEqual (ds1.Tables[1].Columns.Count, dt2.Columns.Count, "DS278");
3111                         Assert.AreEqual (ds1.Tables[0].Columns[0].GetType (), dt1.Columns[0].GetType (), "DS279");
3112                         Assert.AreEqual (ds1.Tables[1].Columns[3].GetType (), dt2.Columns[3].GetType (), "DS280");
3113                         Assert.AreEqual (0, dt1.Rows.Count, "DS281");
3114                         Assert.AreEqual (0, dt2.Rows.Count, "DS282");
3115
3116                         File.Delete (sTempFileName1);
3117                         File.Delete (sTempFileName2);
3118                 }
3119
3120                 [Test]
3121                 public void ReadXmlSchema_ByTextReader ()
3122                 {
3123                         DataSet ds1 = new DataSet ();
3124                         ds1.Tables.Add (DataProvider.CreateParentDataTable ());
3125                         ds1.Tables.Add (DataProvider.CreateChildDataTable ());
3126
3127                         StringWriter sw1 = new StringWriter ();
3128                         StringWriter sw2 = new StringWriter ();
3129                         //write xml file, schema only
3130                         //ds1.WriteXmlSchema (sw);
3131                         ds1.Tables[0].WriteXmlSchema (sw1);
3132                         ds1.Tables[1].WriteXmlSchema (sw2);
3133
3134                         StringReader sr1 = new StringReader (sw1.GetStringBuilder ().ToString ());
3135                         StringReader sr2 = new StringReader (sw2.GetStringBuilder ().ToString ());
3136                         //copy both data and schema
3137                         //DataSet ds2 = new DataSet ();
3138                         DataTable dt1 = new DataTable ();
3139                         DataTable dt2 = new DataTable ();
3140
3141                         //ds2.ReadXmlSchema (sr);
3142                         dt1.ReadXmlSchema (sr1);
3143                         dt2.ReadXmlSchema (sr2);
3144
3145                         //check xml schema
3146                         // ReadXmlSchema - Tables count
3147                         //Assert.AreEqual (ds2.Tables.Count, ds1.Tables.Count, "DS283");
3148
3149                         // ReadXmlSchema - Tables 0 Col count
3150                         Assert.AreEqual (ds1.Tables[0].Columns.Count, dt1.Columns.Count, "DS284");
3151
3152                         // ReadXmlSchema - Tables 1 Col count
3153                         Assert.AreEqual (ds1.Tables[1].Columns.Count, dt2.Columns.Count, "DS285");
3154
3155                         //check some colummns types
3156                         // ReadXmlSchema - Tables 0 Col type
3157                         Assert.AreEqual (ds1.Tables[0].Columns[0].GetType (), dt1.Columns[0].GetType (), "DS286");
3158
3159                         // ReadXmlSchema - Tables 1 Col type
3160                         Assert.AreEqual (ds1.Tables[1].Columns[3].GetType (), dt2.Columns[3].GetType (), "DS287");
3161
3162                         //check that no data exists
3163                         // ReadXmlSchema - Table 1 row count
3164                         Assert.AreEqual (0, dt1.Rows.Count, "DS288");
3165
3166                         // ReadXmlSchema - Table 2 row count
3167                         Assert.AreEqual (0, dt2.Rows.Count, "DS289");
3168                 }
3169
3170                 [Test]
3171                 public void ReadXmlSchema_ByXmlReader ()
3172                 {
3173                         DataSet ds1 = new DataSet ();
3174                         ds1.Tables.Add (DataProvider.CreateParentDataTable ());
3175                         ds1.Tables.Add (DataProvider.CreateChildDataTable ());
3176
3177                         StringWriter sw1 = new StringWriter ();
3178                         XmlTextWriter xmlTW1 = new XmlTextWriter (sw1);
3179                         StringWriter sw2 = new StringWriter ();
3180                         XmlTextWriter xmlTW2 = new XmlTextWriter (sw2);
3181
3182                         //write xml file, schema only
3183                         ds1.Tables[0].WriteXmlSchema (xmlTW1);
3184                         xmlTW1.Flush ();
3185                         ds1.Tables[1].WriteXmlSchema (xmlTW2);
3186                         xmlTW2.Flush ();
3187
3188                         StringReader sr1 = new StringReader (sw1.ToString ());
3189                         XmlTextReader xmlTR1 = new XmlTextReader (sr1);
3190                         StringReader sr2 = new StringReader (sw2.ToString ());
3191                         XmlTextReader xmlTR2 = new XmlTextReader (sr2);
3192
3193                         //copy both data and schema
3194                         //DataSet ds2 = new DataSet ();
3195                         DataTable dt1 = new DataTable ();
3196                         DataTable dt2 = new DataTable ();
3197
3198                         //ds2.ReadXmlSchema (xmlTR);
3199                         dt1.ReadXmlSchema (xmlTR1);
3200                         dt2.ReadXmlSchema (xmlTR2);
3201
3202                         //check xml schema
3203                         // ReadXmlSchema - Tables count
3204                         //Assert.AreEqual (ds2.Tables.Count, ds1.Tables.Count, "DS290");
3205
3206                         // ReadXmlSchema - Tables 0 Col count
3207                         Assert.AreEqual (ds1.Tables[0].Columns.Count, dt1.Columns.Count, "DS291");
3208
3209                         // ReadXmlSchema - Tables 1 Col count
3210                         Assert.AreEqual (ds1.Tables[1].Columns.Count, dt2.Columns.Count, "DS292");
3211
3212                         //check some colummns types
3213                         // ReadXmlSchema - Tables 0 Col type
3214                         Assert.AreEqual (ds1.Tables[0].Columns[0].GetType (), dt1.Columns[0].GetType (), "DS293");
3215
3216                         // ReadXmlSchema - Tables 1 Col type
3217                         Assert.AreEqual (ds1.Tables[1].Columns[3].GetType (), dt2.Columns[3].GetType (), "DS294");
3218
3219                         //check that no data exists
3220                         // ReadXmlSchema - Table 1 row count
3221                         Assert.AreEqual (0, dt1.Rows.Count, "DS295");
3222
3223                         // ReadXmlSchema - Table 2 row count
3224                         Assert.AreEqual (0, dt2.Rows.Count, "DS296");
3225                 }
3226
3227                 [Test]
3228                 [SetCulture ("en-GB")]
3229                 public void WriteXmlSchema ()
3230                 {
3231                         DataSet ds = new DataSet ();
3232                         ds.ReadXml ("Test/System.Data/region.xml");
3233                         TextWriter writer = new StringWriter ();
3234                         ds.Tables[0].WriteXmlSchema (writer);
3235
3236                         string TextString = GetNormalizedSchema (writer.ToString ());
3237                         //string TextString = writer.ToString ();
3238
3239                         EOL = "\n";
3240                         string substring = TextString.Substring (0, TextString.IndexOf (EOL));
3241                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3242                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
3243
3244                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3245                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3246                         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");
3247
3248                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3249                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3250                         // Looks like whoever added this test depended on English culture, which is wrong.
3251                         Assert.AreEqual ("  <xs:element msdata:IsDataSet=\"true\" msdata:Locale=\"en-US\" msdata:MainDataTable=\"Region\" name=\"Root\">", substring, "test#03");
3252
3253                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3254                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3255                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
3256
3257                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3258                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3259                         Assert.AreEqual ("      <xs:choice maxOccurs=\"unbounded\" minOccurs=\"0\">", substring, "test#05");
3260
3261                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3262                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3263                         Assert.AreEqual ("        <xs:element name=\"Region\">", substring, "test#06");
3264
3265                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3266                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3267                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
3268
3269                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3270                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3271                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
3272
3273                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3274                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3275                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" name=\"RegionID\" type=\"xs:string\" />", substring, "test#09");
3276
3277                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3278                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3279                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" name=\"RegionDescription\" type=\"xs:string\" />", substring, "test#10");
3280
3281                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3282                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3283                         Assert.AreEqual ("            </xs:sequence>", substring, "test#11");
3284
3285                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3286                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3287                         Assert.AreEqual ("          </xs:complexType>", substring, "test#12");
3288
3289                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3290                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3291                         Assert.AreEqual ("        </xs:element>", substring, "test#13");
3292
3293                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3294                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3295                         Assert.AreEqual ("      </xs:choice>", substring, "test#14");
3296
3297                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3298                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3299                         Assert.AreEqual ("    </xs:complexType>", substring, "test#15");
3300
3301                         substring = TextString.Substring (0, TextString.IndexOf (EOL));
3302                         TextString = TextString.Substring (TextString.IndexOf (EOL) + EOL.Length);
3303                         Assert.AreEqual ("  </xs:element>", substring, "test#16");
3304
3305                         Assert.AreEqual ("</xs:schema>", TextString, "test#17");
3306                 }
3307
3308                 [Test]
3309                 public void WriteXmlSchema2 ()
3310                 {
3311                         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>";
3312                         string schema = @"<?xml version='1.0' encoding='utf-16'?>
3313 <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'>
3314   <xs:element name='myDataSet' msdata:IsDataSet='true' msdata:MainDataTable='NetFrameWork_x003A_myTable' msdata:UseCurrentLocale='true'>
3315     <xs:complexType>
3316       <xs:choice minOccurs='0' maxOccurs='unbounded'>
3317         <xs:element name='myTable'>
3318           <xs:complexType>
3319             <xs:sequence>
3320               <xs:element name='id' msdata:AutoIncrement='true' type='xs:int' minOccurs='0' />
3321               <xs:element name='item' type='xs:string' minOccurs='0' />
3322             </xs:sequence>
3323           </xs:complexType>
3324         </xs:element>
3325       </xs:choice>
3326     </xs:complexType>
3327   </xs:element>
3328 </xs:schema>";
3329                         DataSet OriginalDataSet = new DataSet ("myDataSet");
3330                         OriginalDataSet.Namespace = "NetFrameWork";
3331                         DataTable myTable = new DataTable ("myTable");
3332                         DataColumn c1 = new DataColumn ("id", typeof (int));
3333                         c1.AutoIncrement = true;
3334                         DataColumn c2 = new DataColumn ("item");
3335                         myTable.Columns.Add (c1);
3336                         myTable.Columns.Add (c2);
3337                         OriginalDataSet.Tables.Add (myTable);
3338                         // Add ten rows.
3339                         DataRow newRow;
3340                         for (int i = 0; i < 10; i++) {
3341                                 newRow = myTable.NewRow ();
3342                                 newRow["item"] = "item " + i;
3343                                 myTable.Rows.Add (newRow);
3344                         }
3345                         OriginalDataSet.AcceptChanges ();
3346
3347                         StringWriter sw = new StringWriter ();
3348                         XmlTextWriter xtw = new XmlTextWriter (sw);
3349                         xtw.QuoteChar = '\'';
3350                         OriginalDataSet.WriteXml (xtw);
3351                         string result = sw.ToString ();
3352
3353                         Assert.AreEqual (xml, result);
3354
3355                         sw = new StringWriter ();
3356                         xtw = new XmlTextWriter (sw);
3357                         xtw.Formatting = Formatting.Indented;
3358                         OriginalDataSet.Tables[0].WriteXmlSchema (xtw);
3359                         result = sw.ToString ();
3360
3361                         result = result.Replace ("\r\n", "\n").Replace ('"', '\'');
3362                         Assert.AreEqual (schema.Replace ("\r\n", "\n"), result);
3363                 }
3364
3365                 [Test]
3366                 public void WriteXmlSchema3 ()
3367                 {
3368                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
3369 <xs:schema id=""ExampleDataSet"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3370   <xs:element name=""ExampleDataSet"" msdata:IsDataSet=""true"" msdata:MainDataTable=""ExampleDataTable"" msdata:UseCurrentLocale=""true"">
3371     <xs:complexType>
3372       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3373         <xs:element name=""ExampleDataTable"">
3374           <xs:complexType>
3375             <xs:attribute name=""PrimaryKeyColumn"" type=""xs:int"" use=""required"" />
3376           </xs:complexType>
3377         </xs:element>
3378       </xs:choice>
3379     </xs:complexType>
3380     <xs:unique name=""PK_ExampleDataTable"" msdata:PrimaryKey=""true"">
3381       <xs:selector xpath="".//ExampleDataTable"" />
3382       <xs:field xpath=""@PrimaryKeyColumn"" />
3383     </xs:unique>
3384   </xs:element>
3385 </xs:schema>";
3386                         DataSet ds = new DataSet ("ExampleDataSet");
3387
3388                         ds.Tables.Add (new DataTable ("ExampleDataTable"));
3389                         ds.Tables["ExampleDataTable"].Columns.Add (
3390                                 new DataColumn ("PrimaryKeyColumn", typeof (int), "", MappingType.Attribute));
3391                         ds.Tables["ExampleDataTable"].Columns["PrimaryKeyColumn"].AllowDBNull = false;
3392
3393                         ds.Tables["ExampleDataTable"].Constraints.Add (
3394                                 "PK_ExampleDataTable",
3395                                 ds.Tables["ExampleDataTable"].Columns["PrimaryKeyColumn"],
3396                                 true);
3397
3398                         ds.AcceptChanges ();
3399                         StringWriter sw = new StringWriter ();
3400                         ds.Tables[0].WriteXmlSchema (sw);
3401
3402                         string result = sw.ToString ();
3403
3404                         Assert.AreEqual (xmlschema.Replace ("\r\n", "\n"), result.Replace ("\r\n", "\n"));
3405                         //Assert.AreEqual (xmlschema, result.Replace ("\r\n", "\n"));
3406                 }
3407
3408                 [Test]
3409                 public void WriteXmlSchema4 ()
3410                 {
3411                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
3412 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3413   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""MyType"" msdata:UseCurrentLocale=""true"">
3414     <xs:complexType>
3415       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3416         <xs:element name=""MyType"">
3417           <xs:complexType>
3418             <xs:attribute name=""ID"" type=""xs:int"" use=""required"" />
3419             <xs:attribute name=""Desc"" type=""xs:string"" />
3420           </xs:complexType>
3421         </xs:element>
3422       </xs:choice>
3423     </xs:complexType>
3424   </xs:element>
3425 </xs:schema>";
3426                         DataSet ds = new DataSet ("Example");
3427
3428                         // Add MyType DataTable
3429                         DataTable dt = new DataTable ("MyType");
3430                         ds.Tables.Add (dt);
3431
3432                         dt.Columns.Add (new DataColumn ("ID", typeof (int), "",
3433                                 MappingType.Attribute));
3434                         dt.Columns["ID"].AllowDBNull = false;
3435
3436                         dt.Columns.Add (new DataColumn ("Desc", typeof
3437                                 (string), "", MappingType.Attribute));
3438
3439                         ds.AcceptChanges ();
3440
3441                         StringWriter sw = new StringWriter ();
3442                         ds.Tables[0].WriteXmlSchema (sw);
3443
3444                         string result = sw.ToString ();
3445
3446                         Assert.AreEqual (xmlschema.Replace ("\r\n", "\n"), result.Replace ("\r\n", "\n"));
3447                 }
3448
3449                 [Test]
3450                 public void WriteXmlSchema5 ()
3451                 {
3452                         string xmlschema1 = @"<?xml version=""1.0"" encoding=""utf-16""?>
3453 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3454   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""StandAlone"" msdata:UseCurrentLocale=""true"">
3455     <xs:complexType>
3456       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3457         <xs:element name=""StandAlone"">
3458           <xs:complexType>
3459             <xs:attribute name=""ID"" type=""xs:int"" use=""required"" />
3460             <xs:attribute name=""Desc"" type=""xs:string"" use=""required"" />
3461           </xs:complexType>
3462         </xs:element>
3463       </xs:choice>
3464     </xs:complexType>
3465   </xs:element>
3466 </xs:schema>";
3467                         string xmlschema2 = @"<?xml version=""1.0"" encoding=""utf-16""?>
3468 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3469   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""Dimension"" msdata:UseCurrentLocale=""true"">
3470     <xs:complexType>
3471       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3472         <xs:element name=""Dimension"">
3473           <xs:complexType>
3474             <xs:attribute name=""Number"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
3475             <xs:attribute name=""Title"" type=""xs:string"" use=""required"" />
3476           </xs:complexType>
3477         </xs:element>
3478       </xs:choice>
3479     </xs:complexType>
3480     <xs:unique name=""PK_Dimension"" msdata:PrimaryKey=""true"">
3481       <xs:selector xpath="".//Dimension"" />
3482       <xs:field xpath=""@Number"" />
3483     </xs:unique>
3484   </xs:element>
3485 </xs:schema>";
3486                         string xmlschema3 = @"<?xml version=""1.0"" encoding=""utf-16""?>
3487 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3488   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""Element"" msdata:UseCurrentLocale=""true"">
3489     <xs:complexType>
3490       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3491         <xs:element name=""Element"">
3492           <xs:complexType>
3493             <xs:attribute name=""Dimension"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
3494             <xs:attribute name=""Number"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
3495             <xs:attribute name=""Title"" type=""xs:string"" use=""required"" />
3496           </xs:complexType>
3497         </xs:element>
3498       </xs:choice>
3499     </xs:complexType>
3500     <xs:unique name=""PK_Element"" msdata:PrimaryKey=""true"">
3501       <xs:selector xpath="".//Element"" />
3502       <xs:field xpath=""@Dimension"" />
3503       <xs:field xpath=""@Number"" />
3504     </xs:unique>
3505   </xs:element>
3506 </xs:schema>";
3507                         DataSet ds = new DataSet ("Example");
3508
3509                         // Add a DataTable with no ReadOnly columns
3510                         DataTable dt1 = new DataTable ("StandAlone");
3511                         ds.Tables.Add (dt1);
3512
3513                         // Add a ReadOnly column
3514                         dt1.Columns.Add (new DataColumn ("ID", typeof (int), "",
3515                                 MappingType.Attribute));
3516                         dt1.Columns["ID"].AllowDBNull = false;
3517
3518                         dt1.Columns.Add (new DataColumn ("Desc", typeof
3519                                 (string), "", MappingType.Attribute));
3520                         dt1.Columns["Desc"].AllowDBNull = false;
3521
3522                         // Add related DataTables with ReadOnly columns
3523                         DataTable dt2 = new DataTable ("Dimension");
3524                         ds.Tables.Add (dt2);
3525                         dt2.Columns.Add (new DataColumn ("Number", typeof
3526                                 (int), "", MappingType.Attribute));
3527                         dt2.Columns["Number"].AllowDBNull = false;
3528                         dt2.Columns["Number"].ReadOnly = true;
3529
3530                         dt2.Columns.Add (new DataColumn ("Title", typeof
3531                                 (string), "", MappingType.Attribute));
3532                         dt2.Columns["Title"].AllowDBNull = false;
3533
3534                         dt2.Constraints.Add ("PK_Dimension", dt2.Columns["Number"], true);
3535
3536                         DataTable dt3 = new DataTable ("Element");
3537                         ds.Tables.Add (dt3);
3538
3539                         dt3.Columns.Add (new DataColumn ("Dimension", typeof
3540                                 (int), "", MappingType.Attribute));
3541                         dt3.Columns["Dimension"].AllowDBNull = false;
3542                         dt3.Columns["Dimension"].ReadOnly = true;
3543
3544                         dt3.Columns.Add (new DataColumn ("Number", typeof
3545                                 (int), "", MappingType.Attribute));
3546                         dt3.Columns["Number"].AllowDBNull = false;
3547                         dt3.Columns["Number"].ReadOnly = true;
3548
3549                         dt3.Columns.Add (new DataColumn ("Title", typeof
3550                                 (string), "", MappingType.Attribute));
3551                         dt3.Columns["Title"].AllowDBNull = false;
3552
3553                         dt3.Constraints.Add ("PK_Element", new DataColumn[] { 
3554                                 dt3.Columns ["Dimension"],
3555                                 dt3.Columns ["Number"] }, true);
3556
3557                         ds.AcceptChanges ();
3558
3559                         StringWriter sw1 = new StringWriter ();
3560                         ds.Tables[0].WriteXmlSchema (sw1);
3561                         string result1 = sw1.ToString ();
3562                         Assert.AreEqual (xmlschema1.Replace ("\r\n", "\n"), result1.Replace ("\r\n", "\n"));
3563
3564                         StringWriter sw2 = new StringWriter ();
3565                         ds.Tables[1].WriteXmlSchema (sw2);
3566                         string result2 = sw2.ToString ();
3567                         Assert.AreEqual (xmlschema2.Replace ("\r\n", "\n"), result2.Replace ("\r\n", "\n"));
3568
3569                         StringWriter sw3 = new StringWriter ();
3570                         ds.Tables[2].WriteXmlSchema (sw3);
3571                         string result3 = sw3.ToString ();
3572                         Assert.AreEqual (xmlschema3.Replace ("\r\n", "\n"), result3.Replace ("\r\n", "\n"));
3573                 }
3574
3575                 [Test]
3576                 public void WriteXmlSchema6 ()
3577                 {
3578                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
3579 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
3580   <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:MainDataTable=""MyType"" msdata:UseCurrentLocale=""true"">
3581     <xs:complexType>
3582       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
3583         <xs:element name=""MyType"">
3584           <xs:complexType>
3585             <xs:attribute name=""Desc"">
3586               <xs:simpleType>
3587                 <xs:restriction base=""xs:string"">
3588                   <xs:maxLength value=""32"" />
3589                 </xs:restriction>
3590               </xs:simpleType>
3591             </xs:attribute>
3592           </xs:complexType>
3593         </xs:element>
3594       </xs:choice>
3595     </xs:complexType>
3596   </xs:element>
3597 </xs:schema>";
3598                         DataSet ds = new DataSet ("Example");
3599
3600                         // Add MyType DataTable
3601                         ds.Tables.Add ("MyType");
3602
3603                         ds.Tables["MyType"].Columns.Add (new DataColumn (
3604                                 "Desc", typeof (string), "", MappingType.Attribute));
3605                         ds.Tables["MyType"].Columns["Desc"].MaxLength = 32;
3606
3607                         ds.AcceptChanges ();
3608
3609                         StringWriter sw = new StringWriter ();
3610                         ds.Tables[0].WriteXmlSchema (sw);
3611
3612                         string result = sw.ToString ();
3613
3614                         Assert.AreEqual (xmlschema.Replace ("\r\n", "\n"), result.Replace ("\r\n", "\n"));
3615                 }
3616
3617                 [Test]
3618                 public void WriteXmlSchema7 ()
3619                 {
3620                         DataSet ds = new DataSet ();
3621                         DataTable dt = new DataTable ("table");
3622                         dt.Columns.Add ("col1");
3623                         dt.Columns.Add ("col2");
3624                         ds.Tables.Add (dt);
3625                         dt.Rows.Add (new object[] { "foo", "bar" });
3626                         StringWriter sw = new StringWriter ();
3627                         ds.Tables[0].WriteXmlSchema (sw);
3628                         Assert.IsTrue (sw.ToString ().IndexOf ("xmlns=\"\"") > 0);
3629                 }
3630
3631                 [Test]
3632                 public void WriteXmlSchema_ConstraintNameWithSpaces ()
3633                 {
3634                         DataSet ds = new DataSet ();
3635                         DataTable table1 = ds.Tables.Add ("table1");
3636                         DataTable table2 = ds.Tables.Add ("table2");
3637
3638                         table1.Columns.Add ("col1", typeof (int));
3639                         table2.Columns.Add ("col1", typeof (int));
3640
3641                         table1.Constraints.Add ("uc 1", table1.Columns[0], false);
3642                         table2.Constraints.Add ("fc 1", table1.Columns[0], table2.Columns[0]);
3643
3644                         StringWriter sw1 = new StringWriter ();
3645                         StringWriter sw2 = new StringWriter ();
3646
3647                         //should not throw an exception
3648                         ds.Tables[0].WriteXmlSchema (sw1);
3649                         ds.Tables[1].WriteXmlSchema (sw2);
3650                 }
3651
3652                 [Test]
3653                 public void WriteXmlSchema_ForignKeyConstraint ()
3654                 {
3655                         DataSet ds1 = new DataSet ();
3656
3657                         DataTable table1 = ds1.Tables.Add ();
3658                         DataTable table2 = ds1.Tables.Add ();
3659
3660                         DataColumn col1_1 = table1.Columns.Add ("col1", typeof (int));
3661                         DataColumn col2_1 = table2.Columns.Add ("col1", typeof (int));
3662
3663                         table2.Constraints.Add ("fk", col1_1, col2_1);
3664
3665                         StringWriter sw1 = new StringWriter ();
3666                         ds1.Tables[0].WriteXmlSchema (sw1);
3667                         String xml1 = sw1.ToString ();
3668                         Assert.IsTrue (xml1.IndexOf (@"<xs:unique name=""Constraint1"">") != -1, "#1");
3669
3670                         StringWriter sw2 = new StringWriter ();
3671                         ds1.Tables[1].WriteXmlSchema (sw2);
3672                         String xml2 = sw2.ToString ();
3673                         Assert.IsTrue (xml2.IndexOf (@"<xs:unique name=""Constraint1"">") == -1, "#2");
3674                 }
3675
3676                 [Test]
3677                 public void WriteXmlSchema_Relations_ForeignKeys ()
3678                 {
3679                         MemoryStream ms1 = null;
3680                         MemoryStream ms2 = null;
3681                         MemoryStream msA = null;
3682                         MemoryStream msB = null;
3683
3684                         DataSet ds1 = new DataSet ();
3685
3686                         DataTable table1 = ds1.Tables.Add ("Table 1");
3687                         DataTable table2 = ds1.Tables.Add ("Table 2");
3688
3689                         DataColumn col1_1 = table1.Columns.Add ("col 1", typeof (int));
3690                         DataColumn col1_2 = table1.Columns.Add ("col 2", typeof (int));
3691                         DataColumn col1_3 = table1.Columns.Add ("col 3", typeof (int));
3692                         DataColumn col1_4 = table1.Columns.Add ("col 4", typeof (int));
3693                         DataColumn col1_5 = table1.Columns.Add ("col 5", typeof (int));
3694                         DataColumn col1_6 = table1.Columns.Add ("col 6", typeof (int));
3695                         DataColumn col1_7 = table1.Columns.Add ("col 7", typeof (int));
3696
3697                         DataColumn col2_1 = table2.Columns.Add ("col 1", typeof (int));
3698                         DataColumn col2_2 = table2.Columns.Add ("col 2", typeof (int));
3699                         DataColumn col2_3 = table2.Columns.Add ("col 3", typeof (int));
3700                         DataColumn col2_4 = table2.Columns.Add ("col 4", typeof (int));
3701                         DataColumn col2_5 = table2.Columns.Add ("col 5", typeof (int));
3702                         DataColumn col2_6 = table2.Columns.Add ("col 6", typeof (int));
3703                         DataColumn col2_7 = table2.Columns.Add ("col 7", typeof (int));
3704
3705                         ds1.Relations.Add ("rel 1",
3706                                 new DataColumn[] { col1_1, col1_2 },
3707                                 new DataColumn[] { col2_1, col2_2 },
3708                                 false);
3709                         ds1.Relations.Add ("rel 2",
3710                                 new DataColumn[] { col1_3, col1_4 },
3711                                 new DataColumn[] { col2_3, col2_4 },
3712                                 true);
3713                         table2.Constraints.Add ("fk 1",
3714                                 new DataColumn[] { col1_5, col1_6 },
3715                                 new DataColumn[] { col2_5, col2_6 });
3716                         table1.Constraints.Add ("fk 2",
3717                                 new DataColumn[] { col2_5, col2_6 },
3718                                 new DataColumn[] { col1_5, col1_6 });
3719
3720                         table1.Constraints.Add ("pk 1", col1_7, true);
3721                         table2.Constraints.Add ("pk 2", col2_7, true);
3722
3723                         ms1 = new MemoryStream ();
3724                         ds1.Tables[0].WriteXmlSchema (ms1);
3725                         ms2 = new MemoryStream ();
3726                         ds1.Tables[1].WriteXmlSchema (ms2);
3727
3728                         msA = new MemoryStream (ms1.GetBuffer ());
3729                         DataTable dtA = new DataTable ();
3730                         dtA.ReadXmlSchema (msA);
3731
3732                         msB = new MemoryStream (ms2.GetBuffer ());
3733                         DataTable dtB = new DataTable ();
3734                         dtB.ReadXmlSchema (msB);
3735
3736                         Assert.AreEqual (3, dtA.Constraints.Count, "#2");
3737                         Assert.AreEqual (2, dtB.Constraints.Count, "#3");
3738
3739                         Assert.IsTrue (dtA.Constraints.Contains ("pk 1"), "#5");
3740                         Assert.IsTrue (dtA.Constraints.Contains ("Constraint1"), "#6");
3741                         Assert.IsTrue (dtA.Constraints.Contains ("Constraint2"), "#7");
3742                         Assert.IsTrue (dtB.Constraints.Contains ("pk 2"), "#9");
3743                         Assert.IsTrue (dtB.Constraints.Contains ("Constraint1"), "#10");
3744                 }
3745
3746                 [Test]
3747                 [Category ("NotWorking")]
3748                 public void WriteXmlSchema_DifferentNamespace ()
3749                 {
3750                         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'>
3751   <xs:import namespace='urn:foo' />
3752   <xs:import namespace='urn:baz' />
3753   <xs:element name='NewDataSet' msdata:IsDataSet='true' msdata:MainDataTable='urn_x003A_foo_x003A_NS1Table' msdata:UseCurrentLocale='true'>
3754     <xs:complexType>
3755       <xs:choice minOccurs='0' maxOccurs='unbounded'>
3756         <xs:element ref='app2:NS1Table' />
3757       </xs:choice>
3758     </xs:complexType>
3759   </xs:element>
3760 </xs:schema>
3761 <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'>
3762   <xs:import namespace='urn:foo' />
3763   <xs:import namespace='urn:bar' />
3764   <xs:element name='column2' type='xs:string' />
3765 </xs:schema>
3766 <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'>
3767   <xs:import namespace='urn:bar' />
3768   <xs:import namespace='urn:baz' />
3769   <xs:element name='NS1Table'>
3770     <xs:complexType>
3771       <xs:sequence>
3772         <xs:element name='column1' type='xs:string' minOccurs='0' />
3773         <xs:element ref='app1:column2' minOccurs='0' />
3774       </xs:sequence>
3775     </xs:complexType>
3776   </xs:element>
3777 </xs:schema>";
3778                         DataSet ds = new DataSet ();
3779                         DataTable dt = new DataTable ();
3780                         dt.TableName = "NS1Table";
3781                         dt.Namespace = "urn:foo";
3782                         dt.Columns.Add ("column1");
3783                         dt.Columns.Add ("column2");
3784                         dt.Columns[1].Namespace = "urn:baz";
3785                         ds.Tables.Add (dt);
3786                         DataTable dt2 = new DataTable ();
3787                         dt2.TableName = "NS2Table";
3788                         dt2.Namespace = "urn:bar";
3789                         ds.Tables.Add (dt2);
3790                         ds.Namespace = "urn:bar";
3791
3792                         StringWriter sw1 = new StringWriter ();
3793                         XmlTextWriter xw1 = new XmlTextWriter (sw1);
3794                         xw1.Formatting = Formatting.Indented;
3795                         xw1.QuoteChar = '\'';
3796                         ds.Tables[0].WriteXmlSchema (xw1);
3797                         string result1 = sw1.ToString ();
3798                         Assert.AreEqual (schema, result1.Replace ("\r\n", "\n"), "#1");
3799
3800                         StringWriter sw2 = new StringWriter ();
3801                         XmlTextWriter xw2 = new XmlTextWriter (sw2);
3802                         xw2.Formatting = Formatting.Indented;
3803                         xw2.QuoteChar = '\'';
3804                         ds.Tables[0].WriteXmlSchema (xw2);
3805                         string result2 = sw2.ToString ();
3806                         Assert.AreEqual (schema, result2.Replace ("\r\n", "\n"), "#2");
3807                 }
3808
3809                 [Test]
3810                 public void WriteXmlSchema_Hierarchy ()
3811                 {
3812                         DataSet ds = new DataSet ();
3813                         DataTable table1 = new DataTable ();
3814                         DataColumn idColumn = table1.Columns.Add ("ID", typeof (Int32));
3815                         table1.Columns.Add ("Name", typeof (String));
3816                         table1.PrimaryKey = new DataColumn[] { idColumn };
3817                         DataTable table2 = new DataTable ();
3818                         table2.Columns.Add (new DataColumn ("OrderID", typeof (Int32)));
3819                         table2.Columns.Add (new DataColumn ("CustomerID", typeof (Int32)));
3820                         table2.Columns.Add (new DataColumn ("OrderDate", typeof (DateTime)));
3821                         table2.PrimaryKey = new DataColumn[] { table2.Columns[0] };
3822                         ds.Tables.Add (table1);
3823                         ds.Tables.Add (table2);
3824                         ds.Relations.Add ("CustomerOrder",
3825                                 new DataColumn[] { table1.Columns[0] },
3826                                 new DataColumn[] { table2.Columns[1] }, true);
3827
3828                         StringWriter writer1 = new StringWriter ();
3829                         table1.WriteXmlSchema (writer1, false);
3830                         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>";
3831                         Assert.AreEqual (expected1, writer1.ToString().Replace("\r\n", "\n"), "#1");
3832
3833                         StringWriter writer2 = new StringWriter ();
3834                         table1.WriteXmlSchema (writer2, true);
3835                         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>";
3836                         Assert.AreEqual (expected2, writer2.ToString ().Replace("\r\n", "\n"), "#2");
3837                 }
3838
3839                 [Test]
3840                 [Ignore ("MS behavior is far from consistent to be regarded as a reference implementation.")]
3841                 // See the same-named tests in DataSetTest.cs
3842                 // WriteXmlSchema doesn't have overload wityh 2 parameters in System.Data
3843                 // and is commented-out TWICE below
3844                 public void ReadWriteXmlSchema()
3845                 {
3846                         DataSet ds = new DataSet();
3847                         ds.ReadXmlSchema("Test/System.Data/store.xsd");
3848                         // check dataset properties before testing write
3849                         AssertDataSet("ds", ds, "NewDataSet", 3, 2);
3850                         AssertDataTable("tab1", ds.Tables[0], "bookstore", 1, 0, 0, 1, 1, 1);
3851                         AssertDataTable("tab2", ds.Tables[1], "book", 5, 0, 1, 1, 2, 1);
3852                         AssertDataTable("tab3", ds.Tables[2], "author", 3, 0, 1, 0, 1, 0);
3853                         // FIXME: currently order is not compatible. Use name as index
3854                         AssertDataRelation("rel1", ds.Relations["book_author"], "book_author", true, new string[] { "book_Id" }, new string[] { "book_Id" }, true, true);
3855                         AssertDataRelation("rel2", ds.Relations["bookstore_book"], "bookstore_book", true, new string[] { "bookstore_Id" }, new string[] { "bookstore_Id" }, true, true);
3856
3857                         ds.ReadXml("Test/System.Data/region.xml", XmlReadMode.InferSchema);
3858                         ds.Relations.Clear(); // because can not call WriteXmlSchema with nested relations.
3859
3860                         TextWriter writer1 = new StringWriter();
3861                         ds.Tables[0].WriteXmlSchema(writer1);
3862                         //string TextString1 = GetNormalizedSchema(writer1.ToString());
3863                         string TextString1 = writer1.ToString();
3864                         string expected1 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3865 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3866   @"<xs:complexType name=""bookstoreType"">" +
3867   @"</xs:complexType>" +
3868   @"<xs:element name=""bookstore"" type=""bookstoreType"" />" +
3869   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""bookstore"" msdata:Locale=""en-US"">" +
3870     @"<xs:complexType>" +
3871       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3872     @"<xs:element ref=""bookstore"" />" +
3873       @"</xs:choice>" +
3874     @"</xs:complexType>" +
3875   @"</xs:element>" +
3876 @"</xs:schema>";
3877                         Assert.AreEqual(expected1.Replace("\n", ""), TextString1.Replace("\r\n", "").Replace("  ", "").Replace("\n", ""), "#1");
3878
3879                         TextWriter writer2 = new StringWriter();
3880                         ds.Tables[1].WriteXmlSchema(writer2, false);
3881                         //string TextString2 = GetNormalizedSchema(writer2.ToString());
3882                         string TextString2 = writer2.ToString();
3883                         string expected2 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3884 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3885   @"<xs:complexType name=""bookType"">" +
3886     @"<xs:sequence>" +
3887       @"<xs:element name=""title"" type=""xs:string"" msdata:Ordinal=""1"" />" +
3888       @"<xs:element name=""price"" type=""xs:decimal"" msdata:Ordinal=""2"" />" +
3889     @"</xs:sequence>" +
3890     @"<xs:attribute name=""genre"" type=""xs:string"" />" +
3891     @"<xs:attribute name=""bookstore_Id"" type=""xs:int"" use=""prohibited"" />" +
3892   @"</xs:complexType>" +
3893   @"<xs:element name=""book"" type=""bookType"" />" +
3894   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""book"" msdata:Locale=""en-US"">" +
3895     @"<xs:complexType>" +
3896       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3897     @"<xs:element ref=""book"" />" +
3898       @"</xs:choice>" +
3899     @"</xs:complexType>" +
3900   @"</xs:element>" +
3901 @"</xs:schema>";
3902                         Assert.AreEqual(expected2, TextString2.Replace("\r\n", "").Replace("  ", ""), "#2");
3903
3904                         TextWriter writer3 = new StringWriter();
3905                         ds.Tables[2].WriteXmlSchema(writer3);
3906                         //string TextString3 = GetNormalizedSchema(writer3.ToString());
3907                         string TextString3 = writer3.ToString();
3908                         string expected3 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3909 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3910   @"<xs:complexType name=""authorName"">" +
3911     @"<xs:sequence>" +
3912       @"<xs:element name=""first-name"" type=""xs:string"" msdata:Ordinal=""0"" />" +
3913       @"<xs:element name=""last-name"" type=""xs:string"" msdata:Ordinal=""1"" />" +
3914     @"</xs:sequence>" +
3915     @"<xs:attribute name=""book_Id"" type=""xs:int"" use=""prohibited"" />" +
3916   @"</xs:complexType>" +
3917   @"<xs:element name=""author"" type=""authorName"" />" +
3918   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""author"" msdata:Locale=""en-US"">" +
3919     @"<xs:complexType>" +
3920       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3921         @"<xs:element ref=""author"" />" +
3922       @"</xs:choice>" +
3923     @"</xs:complexType>" +
3924   @"</xs:element>" +
3925 @"</xs:schema>";
3926                         Assert.AreEqual(expected3, TextString3.Replace("\r\n", "").Replace("  ", ""), "#3");
3927
3928                         TextWriter writer4 = new StringWriter();
3929                         ds.Tables[3].WriteXmlSchema(writer4);
3930                         //string TextString4 = GetNormalizedSchema(writer4.ToString());
3931                         string TextString4 = writer4.ToString();
3932                         string expected4 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3933 @"<xs:schema id=""Root"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3934   @"<xs:element name=""Root"" msdata:IsDataSet=""true"" msdata:MainDataTable=""Region"" msdata:Locale=""en-US"">" +
3935     @"<xs:complexType>" +
3936       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3937         @"<xs:element name=""Region"">" +
3938           @"<xs:complexType>" +
3939             @"<xs:sequence>" +
3940               @"<xs:element name=""RegionID"" type=""xs:string"" minOccurs=""0"" />" +
3941               @"<xs:element name=""RegionDescription"" type=""xs:string"" minOccurs=""0"" />" +
3942             @"</xs:sequence>" +
3943           @"</xs:complexType>" +
3944         @"</xs:element>" +
3945       @"</xs:choice>" +
3946     @"</xs:complexType>" +
3947   @"</xs:element>" +
3948 @"</xs:schema>";
3949                         Assert.AreEqual(expected4, TextString4.Replace("\r\n", "").Replace("  ", ""), "#4");
3950                 }
3951
3952                 [Test]
3953                 [Ignore ("MS behavior is far from consistent to be regarded as a reference implementation.")]
3954                 // See the same-named tests in DataSetTest.cs
3955                 public void ReadWriteXmlSchema_IgnoreSchema ()
3956                 {
3957                         DataSet ds = new DataSet ();
3958                         ds.ReadXmlSchema ("Test/System.Data/store.xsd");
3959                         // check dataset properties before testing write
3960                         AssertDataSet ("ds", ds, "NewDataSet", 3, 2);
3961                         AssertDataTable ("tab1", ds.Tables[0], "bookstore", 1, 0, 0, 1, 1, 1);
3962                         AssertDataTable ("tab2", ds.Tables[1], "book", 5, 0, 1, 1, 2, 1);
3963                         AssertDataTable ("tab3", ds.Tables[2], "author", 3, 0, 1, 0, 1, 0);
3964                         // FIXME: currently order is not compatible. Use name as index
3965                         AssertDataRelation ("rel1", ds.Relations["book_author"], "book_author", true, new string[] { "book_Id" }, new string[] { "book_Id" }, true, true);
3966                         AssertDataRelation ("rel2", ds.Relations["bookstore_book"], "bookstore_book", true, new string[] { "bookstore_Id" }, new string[] { "bookstore_Id" }, true, true);
3967
3968                         ds.ReadXml ("Test/System.Data/region.xml", XmlReadMode.IgnoreSchema);
3969                         ds.Relations.Clear (); // because can not call WriteXmlSchema with nested relations.
3970
3971                         TextWriter writer1 = new StringWriter ();
3972                         ds.Tables[0].WriteXmlSchema (writer1);
3973                         //string TextString1 = GetNormalizedSchema (writer1.ToString ());
3974                         string TextString1 = writer1.ToString ();
3975                         string expected1 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3976 @"<xs:schema id=""NewDataSet"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">" +
3977   @"<xs:complexType name=""bookstoreType"">" +
3978   @"</xs:complexType>" +
3979   @"<xs:element name=""bookstore"" type=""bookstoreType"" />" +
3980   @"<xs:element name=""NewDataSet"" msdata:IsDataSet=""true"" msdata:MainDataTable=""bookstore"" msdata:UseCurrentLocale=""true"">" +
3981     @"<xs:complexType>" +
3982       @"<xs:choice minOccurs=""0"" maxOccurs=""unbounded"">" +
3983         @"<xs:element ref=""bookstore"" />" +
3984       @"</xs:choice>" +
3985     @"</xs:complexType>" +
3986   @"</xs:element>" +
3987 @"</xs:schema>";
3988                         Console.WriteLine ("{0} - {1}", TextString1, expected1);
3989                         Assert.AreEqual (expected1, TextString1.Replace ("\r\n", "").Replace ("  ", "").Replace ("\n", ""), "#1");
3990
3991                         TextWriter writer2 = new StringWriter ();
3992                         ds.Tables[1].WriteXmlSchema (writer2, false);
3993                         string TextString2 = GetNormalizedSchema (writer2.ToString ());
3994                         string expected2 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
3995 @"<xs:schema id=""NewDataSet"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"">" +
3996   @"<xs:complexType name=""bookType"">" +
3997     @"<xs:sequence>" +
3998       @"<xs:element msdata:Ordinal=""1"" name=""title"" type=""xs:string"" />" +
3999       @"<xs:element msdata:Ordinal=""2"" name=""price"" type=""xs:decimal"" />" +
4000     @"</xs:sequence>" +
4001     @"<xs:attribute name=""genre"" type=""xs:string"" />" +
4002     @"<xs:attribute name=""bookstore_Id"" type=""xs:int"" use=""prohibited"" />" +
4003   @"</xs:complexType>" +
4004   @"<xs:element name=""book"" type=""bookType"" />" +
4005   @"<xs:element msdata:IsDataSet=""true"" msdata:MainDataTable=""book"" msdata:UseCurrentLocale=""true"" name=""NewDataSet"">" +
4006     @"<xs:complexType>" +
4007       @"<xs:choice maxOccurs=""unbounded"" minOccurs=""0"">" +
4008         @"<xs:element ref=""book"" />" +
4009       @"</xs:choice>" +
4010     @"</xs:complexType>" +
4011   @"</xs:element>" +
4012 @"</xs:schema>";
4013                         Assert.AreEqual (expected2, TextString2.Replace ("\r\n", "").Replace ("  ", ""), "#2");
4014
4015                         TextWriter writer3 = new StringWriter ();
4016                         ds.Tables[2].WriteXmlSchema (writer3);
4017                         string TextString3 = GetNormalizedSchema (writer3.ToString ());
4018                         string expected3 = @"<?xml version=""1.0"" encoding=""utf-16""?>" +
4019 @"<xs:schema id=""NewDataSet"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"">" +
4020   @"<xs:complexType name=""authorName"">" +
4021     @"<xs:sequence>" +
4022       @"<xs:element msdata:Ordinal=""0"" name=""first-name"" type=""xs:string"" />" +
4023       @"<xs:element msdata:Ordinal=""1"" name=""last-name"" type=""xs:string"" />" +
4024     @"</xs:sequence>" +
4025     @"<xs:attribute name=""book_Id"" type=""xs:int"" use=""prohibited"" />" +
4026   @"</xs:complexType>" +
4027   @"<xs:element name=""author"" type=""authorName"" />" +
4028   @"<xs:element msdata:IsDataSet=""true"" msdata:MainDataTable=""author"" msdata:UseCurrentLocale=""true"" name=""NewDataSet"">" +
4029     @"<xs:complexType>" +
4030       @"<xs:choice maxOccurs=""unbounded"" minOccurs=""0"">" +
4031         @"<xs:element ref=""author"" />" +
4032       @"</xs:choice>" +
4033     @"</xs:complexType>" +
4034   @"</xs:element>" +
4035 @"</xs:schema>";
4036                         Assert.AreEqual (expected3, TextString3.Replace ("\r\n", "").Replace ("  ", ""), "#3");
4037
4038                         TextWriter writer4 = new StringWriter ();
4039
4040                         try {
4041                                 ds.Tables [3].WriteXmlSchema (writer4);
4042                                 Assert.Fail ("expected exception");
4043                         } catch (InvalidOperationException ex) {
4044                                 throw ex;
4045                         }
4046                 }
4047
4048                 [Test]
4049                 public void ReadWriteXmlSchema_2 ()
4050                 {
4051                         DataSet ds = new DataSet ("dataset");
4052                         ds.Tables.Add ("table1");
4053                         ds.Tables.Add ("table2");
4054                         ds.Tables[0].Columns.Add ("col");
4055                         ds.Tables[1].Columns.Add ("col");
4056                         ds.Relations.Add ("rel", ds.Tables[0].Columns[0], ds.Tables[1].Columns[0], true);
4057
4058                         MemoryStream ms1 = new MemoryStream ();
4059                         ds.Tables[0].WriteXmlSchema (ms1);
4060                         MemoryStream ms2 = new MemoryStream ();
4061                         ds.Tables[1].WriteXmlSchema (ms2);
4062
4063                         DataSet ds1 = new DataSet ();
4064                         ds1.Tables.Add ();
4065                         ds1.Tables.Add ();
4066                         ds1.Tables[0].ReadXmlSchema (new MemoryStream (ms1.GetBuffer ()));
4067                         ds1.Tables[1].ReadXmlSchema (new MemoryStream (ms2.GetBuffer ()));
4068
4069                         Assert.AreEqual (0, ds1.Relations.Count, "#1");
4070                         Assert.AreEqual (1, ds1.Tables[0].Columns.Count, "#2");
4071                         Assert.AreEqual (1, ds1.Tables[1].Columns.Count, "#3");
4072                 }
4073
4074                 [Test]
4075                 public void ReadWriteXmlSchemaExp_NoRootElmnt ()
4076                 {
4077                         MemoryStream ms = new MemoryStream ();
4078                         DataTable dtr = new DataTable ();
4079                         try {
4080                                 dtr.ReadXmlSchema (ms);
4081                                 Assert.Fail ("#1");
4082                         } catch (XmlException) {
4083                         }
4084                 }
4085
4086                 [Test]
4087                 public void ReadWriteXmlSchemaExp_NoTableName ()
4088                 {
4089                         DataTable dtw = new DataTable ();
4090                         MemoryStream ms = new MemoryStream ();
4091                         try {
4092                                 dtw.WriteXmlSchema (ms);
4093                                 Assert.Fail ("#1");
4094                         } catch (InvalidOperationException) {
4095                         }
4096                 }
4097
4098                 [Test]
4099                 public void ReadWriteXmlSchemaExp_NoFileName ()
4100                 {
4101                         DataTable dtw = new DataTable ();
4102                         try {
4103                                 dtw.WriteXmlSchema (string.Empty);
4104                                 Assert.Fail ("#1");
4105                         } catch (ArgumentException) {
4106                         }
4107                 }
4108
4109                 [Test]
4110                 public void ReadWriteXmlSchemaExp_TableNameConflict ()
4111                 {
4112                         DataTable dtw = new DataTable ("Table1");
4113                         StringWriter writer1 = new StringWriter ();
4114                         dtw.WriteXmlSchema (writer1);
4115                         DataTable dtr = new DataTable ("Table2");
4116                         StringReader reader1 = new StringReader (writer1.ToString());
4117                         try {
4118                                 dtr.ReadXmlSchema (reader1);
4119                                 Assert.Fail ("#1");
4120                         } catch (ArgumentException) {
4121                         }
4122                 }
4123
4124                 [Test]
4125                 public void ReadXmlSchemeWithoutScheme ()
4126                 {
4127                         const string xml = @"<CustomElement />";
4128                         using (var s = new StringReader (xml)) {
4129                                 DataTable dt = new DataTable ();
4130                                 dt.ReadXmlSchema (s);
4131                                 Assert.AreEqual ("", dt.TableName);
4132                         }
4133                 }
4134
4135                 [Test]
4136                 public void ReadXmlSchemeWithScheme ()
4137                 {
4138                         const string xml = @"<CustomElement>
4139                                   <xs:schema id='NewDataSet' xmlns='' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'>
4140                                         <xs:element name='NewDataSet' msdata:IsDataSet='true' msdata:MainDataTable='row' msdata:Locale=''>
4141                                           <xs:complexType>
4142                                                 <xs:choice minOccurs='0' maxOccurs='unbounded'>
4143                                                   <xs:element name='row' msdata:Locale=''>
4144                                                         <xs:complexType>
4145                                                           <xs:sequence>
4146                                                                 <xs:element name='Text' type='xs:string' minOccurs='0' />
4147                                                           </xs:sequence>
4148                                                         </xs:complexType>
4149                                                   </xs:element>
4150                                                 </xs:choice>
4151                                           </xs:complexType>
4152                                         </xs:element>
4153                                   </xs:schema>
4154                                 </CustomElement>";
4155                         using (var s = new StringReader (xml)) {
4156                                 DataTable dt = new DataTable ();
4157                                 dt.ReadXmlSchema (s);
4158                                 Assert.AreEqual ("row", dt.TableName);
4159                         }
4160                 }
4161
4162                 [Test]
4163                 [ExpectedException (typeof (ArgumentException))]
4164                 public void ReadXmlSchemeWithBadScheme ()
4165                 {
4166                         const string xml = @"<CustomElement>
4167                                   <xs:schema id='NewDataSet' xmlns='' xmlns:xs='http://www.w3.org/2001/BAD' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'>
4168                                   </xs:schema>
4169                                 </CustomElement>";
4170                         using (var s = new StringReader (xml)) {
4171                                 DataTable dt = new DataTable ();
4172                                 dt.ReadXmlSchema (s);
4173                         }
4174                 }
4175
4176                 #endregion // Read/Write XML Tests
4177
4178         }
4179
4180         public  class MyDataTable : DataTable
4181         {
4182                 public static int count;
4183
4184                 public MyDataTable()
4185                 {
4186                         count++;
4187                 }
4188         }
4189
4190         [Serializable]
4191         [TestFixture]
4192         public class AppDomainsAndFormatInfo
4193         {
4194                 public void Remote ()
4195                 {
4196                         int n = (int) Convert.ChangeType ("5", typeof (int));
4197                         Assert.AreEqual (5, n, "n");
4198                 }
4199
4200 #if !MONOTOUCH && !MOBILE_STATIC
4201                 [Test]
4202                 public void NFIFromBug55978 ()
4203                 {
4204                         AppDomain domain = AppDomain.CreateDomain ("testdomain", null,
4205                                 AppDomain.CurrentDomain.SetupInformation);
4206                         AppDomainsAndFormatInfo test = new AppDomainsAndFormatInfo ();
4207                         test.Remote ();
4208                         domain.DoCallBack (new CrossAppDomainDelegate (test.Remote));
4209                         AppDomain.Unload (domain);
4210                 }
4211 #endif
4212
4213                 [Test]
4214                 [SetCulture ("en-US")]
4215                 public void Bug55978 ()
4216                 {
4217                         DataTable dt = new DataTable ();
4218                         dt.Columns.Add ("StartDate", typeof (DateTime));
4219          
4220                         DataRow dr;
4221                         DateTime date = DateTime.Now;
4222          
4223                         for (int i = 0; i < 10; i++) {
4224                                 dr = dt.NewRow ();
4225                                 dr ["StartDate"] = date.AddDays (i);
4226                                 dt.Rows.Add (dr);
4227                         }
4228          
4229                         DataView dv = dt.DefaultView;
4230                         dv.RowFilter = String.Format (CultureInfo.InvariantCulture,
4231                                                       "StartDate >= '{0}' and StartDate <= '{1}'",
4232                                                       DateTime.Now.AddDays (2),
4233                                                       DateTime.Now.AddDays (4));
4234                         Assert.AreEqual (10, dt.Rows.Count, "Table");
4235                         Assert.AreEqual (2, dv.Count, "View");
4236                 }
4237
4238                 [Test]
4239                 public void Bug82109 ()
4240                 {
4241                         DataTable tbl = new DataTable ();
4242                         tbl.Columns.Add ("data", typeof (DateTime));
4243                         DataRow row = tbl.NewRow ();
4244                         row ["Data"] = new DateTime (2007, 7, 1);
4245                         tbl.Rows.Add (row);
4246
4247                         CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
4248                         Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
4249                         Select (tbl);
4250
4251                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("it-IT");
4252                         Select (tbl);
4253
4254                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("fr-FR");
4255                         Select (tbl);
4256                         Thread.CurrentThread.CurrentCulture = currentCulture;
4257                 }
4258
4259                 private static void Select (DataTable tbl)
4260                 {
4261                         tbl.Locale = CultureInfo.InvariantCulture;
4262                         string filter = string.Format ("Data = '{0}'", new DateTime (2007, 7, 1).ToString (CultureInfo.InvariantCulture));
4263                         DataRow [] rows = tbl.Select (filter);
4264                         Assert.AreEqual (1, rows.Length, "Incorrect number of rows found");
4265                 }
4266         }
4267 }