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