Merge pull request #1624 from esdrubal/getprocesstimes
[mono.git] / mcs / class / System.Data / Test / System.Data / DataSetTest.cs
1 // MonoTests.System.Data.DataSetTest.cs
2 //
3 // Authors:
4 //   Ville Palo <vi64pa@koti.soon.fi>
5 //   Martin Willemoes Hansen <mwh@sysrq.dk>
6 //   Atsushi Enomoto <atsushi@ximian.com>
7 //   Hagit Yidov <hagity@mainsoft.com>
8 //
9 // (C) Copyright 2002 Ville Palo
10 // (C) Copyright 2003 Martin Willemoes Hansen
11 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
12 // Copyright 2011 Xamarin Inc.
13 //
14 // Copyright (C) 2004 Novell, Inc (http://www.novell.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
37 using NUnit.Framework;
38 using System;
39 using System.Xml;
40 using System.Xml.Schema;
41 using System.Xml.Serialization;
42 using System.IO;
43 using System.Data;
44 using System.Data.SqlTypes;
45 using System.Globalization;
46 using System.Threading;
47 using System.Text;
48
49 namespace MonoTests.System.Data
50 {
51         [TestFixture]
52         public class DataSetTest : DataSetAssertion
53         {
54                 string EOL = Environment.NewLine;
55                 CultureInfo currentCultureBackup;
56
57                 [SetUp]
58                 public void Setup () {
59                         currentCultureBackup = Thread.CurrentThread.CurrentCulture;
60                         Thread.CurrentThread.CurrentCulture = new CultureInfo ("fi-FI");
61                 }
62
63                 //[SetUp]
64                 //public void GetReady()
65                 //{
66                 //        currentCultureBackup = Thread.CurrentThread.CurrentCulture;
67                 //        Thread.CurrentThread.CurrentCulture = new CultureInfo ("fi-FI");
68                 //}
69
70                 [TearDown]
71                 public void Teardown ()
72                 {
73                         Thread.CurrentThread.CurrentCulture = currentCultureBackup;
74                 }
75
76                 [Test]
77                 public void Properties ()
78                 {
79                         DataSet ds = new DataSet ();
80                         Assert.AreEqual (String.Empty, ds.Namespace, "default namespace");
81                         ds.Namespace = null; // setting null == setting ""
82                         Assert.AreEqual (String.Empty, ds.Namespace, "after setting null to namespace");
83
84                         Assert.AreEqual (String.Empty, ds.Prefix, "default prefix");
85                         ds.Prefix = null; // setting null == setting ""
86                         Assert.AreEqual (String.Empty, ds.Prefix, "after setting null to prefix");
87                 }
88
89                 [Test]
90                 public void ReadXmlSchema ()
91                 {
92                         DataSet ds = new DataSet ();
93                         ds.ReadXmlSchema ("Test/System.Data/own_schema.xsd");
94                         
95                         Assert.AreEqual (2, ds.Tables.Count, "test#01");
96                         DataTable Table = ds.Tables [0];
97                         Assert.AreEqual ("test_table", Table.TableName, "test#02");
98                         Assert.AreEqual ("", Table.Namespace, "test#03");
99                         Assert.AreEqual (2, Table.Columns.Count, "test#04");
100                         Assert.AreEqual (0, Table.Rows.Count, "test#05");
101                         Assert.IsFalse (Table.CaseSensitive, "test#06");
102                         Assert.AreEqual (1, Table.Constraints.Count, "test#07");
103                         Assert.AreEqual ("", Table.Prefix, "test#08");
104                         
105                         Constraint cons = Table.Constraints [0];
106                         Assert.AreEqual ("Constraint1", cons.ConstraintName.ToString (), "test#09");
107                         Assert.AreEqual ("Constraint1", cons.ToString (), "test#10");
108                         
109                         DataColumn column = Table.Columns [0];
110                         Assert.IsTrue (column.AllowDBNull, "test#11");
111                         Assert.IsFalse (column.AutoIncrement, "test#12");
112                         Assert.AreEqual (0L, column.AutoIncrementSeed, "test#13");
113                         Assert.AreEqual (1L, column.AutoIncrementStep, "test#14");
114                         Assert.AreEqual ("test", column.Caption, "test#15");
115                         Assert.AreEqual ("Element", column.ColumnMapping.ToString (), "test#16");
116                         Assert.AreEqual ("first", column.ColumnName, "test#17");
117                         Assert.AreEqual ("System.String", column.DataType.ToString (), "test#18");
118                         Assert.AreEqual ("test_default_value", column.DefaultValue.ToString (), "test#19");
119                         Assert.IsFalse (column.DesignMode, "test#20");
120                         Assert.AreEqual ("", column.Expression, "test#21");
121                         Assert.AreEqual (100, column.MaxLength, "test#22");
122                         Assert.AreEqual ("", column.Namespace, "test#23");
123                         Assert.AreEqual (0, column.Ordinal, "test#24");
124                         Assert.AreEqual ("", column.Prefix, "test#25");
125                         Assert.IsFalse (column.ReadOnly, "test#26");
126                         Assert.IsTrue (column.Unique, "test#27");
127                                                 
128                         DataColumn column2 = Table.Columns [1];
129                         Assert.IsTrue (column2.AllowDBNull, "test#28");
130                         Assert.IsFalse (column2.AutoIncrement, "test#29");
131                         Assert.AreEqual (0L, column2.AutoIncrementSeed, "test#30");
132                         Assert.AreEqual (1L, column2.AutoIncrementStep, "test#31");
133                         Assert.AreEqual ("second", column2.Caption, "test#32");
134                         Assert.AreEqual ("Element", column2.ColumnMapping.ToString (), "test#33");
135                         Assert.AreEqual ("second", column2.ColumnName, "test#34");
136                         Assert.AreEqual ("System.Data.SqlTypes.SqlGuid", column2.DataType.ToString (), "test#35");
137                         Assert.AreEqual (SqlGuid.Null, column2.DefaultValue, "test#36");
138                         Assert.IsFalse (column2.DesignMode, "test#37");
139                         Assert.AreEqual ("", column2.Expression, "test#38");
140                         Assert.AreEqual (-1, column2.MaxLength, "test#39");
141                         Assert.AreEqual ("", column2.Namespace, "test#40");
142                         Assert.AreEqual (1, column2.Ordinal, "test#41");
143                         Assert.AreEqual ("", column2.Prefix, "test#42");
144                         Assert.IsFalse (column2.ReadOnly, "test#43");
145                         Assert.IsFalse (column2.Unique, "test#44");
146                         
147                         DataTable Table2 = ds.Tables [1];
148                         Assert.AreEqual ("second_test_table", Table2.TableName, "test#45");
149                         Assert.AreEqual ("", Table2.Namespace, "test#46");
150                         Assert.AreEqual (1, Table2.Columns.Count, "test#47");
151                         Assert.AreEqual (0, Table2.Rows.Count, "test#48");
152                         Assert.IsFalse (Table2.CaseSensitive, "test#49");
153                         Assert.AreEqual (1, Table2.Constraints.Count, "test#50");
154                         Assert.AreEqual ("", Table2.Prefix, "test#51");
155                         
156                         DataColumn column3 = Table2.Columns [0];
157                         Assert.IsTrue (column3.AllowDBNull, "test#52");
158                         Assert.IsFalse (column3.AutoIncrement, "test#53");
159                         Assert.AreEqual (0L, column3.AutoIncrementSeed, "test#54");
160                         Assert.AreEqual (1L, column3.AutoIncrementStep, "test#55");
161                         Assert.AreEqual ("second_first", column3.Caption, "test#56");
162                         Assert.AreEqual ("Element", column3.ColumnMapping.ToString (), "test#57");
163                         Assert.AreEqual ("second_first", column3.ColumnName, "test#58");
164                         Assert.AreEqual ("System.String", column3.DataType.ToString (), "test#59");
165                         Assert.AreEqual ("default_value", column3.DefaultValue.ToString (), "test#60");
166                         Assert.IsFalse (column3.DesignMode, "test#61");
167                         Assert.AreEqual ("", column3.Expression, "test#62");
168                         Assert.AreEqual (100, column3.MaxLength, "test#63");
169                         Assert.AreEqual ("", column3.Namespace, "test#64");
170                         Assert.AreEqual (0, column3.Ordinal, "test#65");
171                         Assert.AreEqual ("", column3.Prefix, "test#66");
172                         Assert.IsFalse (column3.ReadOnly, "test#67");
173                         Assert.IsTrue (column3.Unique, "test#68");
174                 }
175
176                 [Test]
177                 public void OwnWriteXmlSchema ()
178                 {
179                         DataSet ds = new DataSet ("test_dataset");
180                         DataTable table = new DataTable ("test_table");
181                         DataColumn column = new DataColumn ("first", typeof (string));
182                         column.AllowDBNull = true;
183                         column.DefaultValue = "test_default_value";                     
184                         column.MaxLength = 100;
185                         column.Caption = "test";
186                         column.Unique = true;
187                         table.Columns.Add (column);
188
189                         DataColumn column2 = new DataColumn ("second", typeof (SqlGuid));
190                         column2.ColumnMapping = MappingType.Element;
191                         table.Columns.Add (column2);
192                         ds.Tables.Add (table);
193                         
194                         DataTable table2 = new DataTable ("second_test_table");
195                         DataColumn column3 = new DataColumn ("second_first", typeof (string));
196                         column3.AllowDBNull = true;
197                         column3.DefaultValue = "default_value";
198                         column3.MaxLength = 100;
199                         column3.Unique = true;
200                         table2.Columns.Add (column3);
201                         ds.Tables.Add (table2);
202
203                         TextWriter writer = new StringWriter ();
204                         ds.WriteXmlSchema (writer);
205
206                         string TextString = GetNormalizedSchema (writer.ToString ());
207 //                      string TextString = writer.ToString ();
208
209                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
210                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
211                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
212                         
213                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
214                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
215                         // This is original DataSet.WriteXmlSchema() output
216 //                      Assert.AreEqual ("<xs:schema id=\"test_dataset\" xmlns=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">", substring, "test#02");
217                         Assert.AreEqual ("<xs:schema id=\"test_dataset\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">", substring, "test#02");
218                         
219                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
220                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
221                         // This is original DataSet.WriteXmlSchema() output
222 //                      Assert.AreEqual ("  <xs:element name=\"test_dataset\" msdata:IsDataSet=\"true\" msdata:Locale=\"fi-FI\">", substring, "test#03");
223                         Assert.AreEqual ("  <xs:element msdata:IsDataSet=\"true\" msdata:UseCurrentLocale=\"true\" name=\"test_dataset\">", substring, "test#03");
224
225                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
226                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
227                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
228                         
229                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
230                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
231                         Assert.AreEqual ("      <xs:choice maxOccurs=\"unbounded\" minOccurs=\"0\">", substring, "test#05");
232                         
233                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
234                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
235                         Assert.AreEqual ("        <xs:element name=\"test_table\">", substring, "test#06");
236                         
237                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
238                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
239                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
240                         
241                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
242                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
243                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
244                         
245                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
246                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
247                         // This is original DataSet.WriteXmlSchema() output
248 //                      Assert.AreEqual ("              <xs:element name=\"first\" msdata:Caption=\"test\" default=\"test_default_value\" minOccurs=\"0\">", substring, "test#09");
249                         Assert.AreEqual ("              <xs:element default=\"test_default_value\" minOccurs=\"0\" msdata:Caption=\"test\" name=\"first\">", substring, "test#09");
250                         
251                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
252                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
253                         Assert.AreEqual ("                <xs:simpleType>", substring, "test#10");
254                         
255                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
256                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
257                         Assert.AreEqual ("                  <xs:restriction base=\"xs:string\">", substring, "test#11");
258                         
259                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
260                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
261                         Assert.AreEqual ("                    <xs:maxLength value=\"100\" />", substring, "test#12");
262                         
263                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
264                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
265                         Assert.AreEqual ("                  </xs:restriction>", substring, "test#13");
266                         
267                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
268                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
269                         Assert.AreEqual ("                </xs:simpleType>", substring, "test#14");
270                         
271                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
272                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
273                         Assert.AreEqual ("              </xs:element>", substring, "test#15");
274                         
275                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
276                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
277                         // This is original DataSet.WriteXmlSchema() output
278                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" msdata:DataType=\"System.Data.SqlTypes.SqlGuid\" name=\"second\" type=\"xs:string\" />", substring, "test#16");
279                         
280                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
281                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
282                         Assert.AreEqual ("            </xs:sequence>", substring, "test#17");
283                         
284                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
285                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
286                         Assert.AreEqual ("          </xs:complexType>", substring, "test#18");
287                         
288                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
289                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
290                         Assert.AreEqual ("        </xs:element>", substring, "test#19");
291                         
292                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
293                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
294                         Assert.AreEqual ("        <xs:element name=\"second_test_table\">", substring, "test#20");
295                         
296                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
297                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
298                         Assert.AreEqual ("          <xs:complexType>", substring, "test#21");
299                         
300                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
301                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
302                         Assert.AreEqual ("            <xs:sequence>", substring, "test#22");
303                         
304                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
305                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
306                         // This is original DataSet.WriteXmlSchema() output
307 //                      Assert.AreEqual ("              <xs:element name=\"second_first\" default=\"default_value\" minOccurs=\"0\">", substring, "test#23");
308                         Assert.AreEqual ("              <xs:element default=\"default_value\" minOccurs=\"0\" name=\"second_first\">", substring, "test#23");
309                         
310                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
311                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
312                         Assert.AreEqual ("                <xs:simpleType>", substring, "test#24");
313                         
314                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
315                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
316                         Assert.AreEqual ("                  <xs:restriction base=\"xs:string\">", substring, "test#25");
317                         
318                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
319                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
320                         Assert.AreEqual ("                    <xs:maxLength value=\"100\" />", substring, "test#26");
321                         
322                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
323                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
324                         Assert.AreEqual ("                  </xs:restriction>", substring, "test#27");
325                         
326                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
327                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
328                         Assert.AreEqual ("                </xs:simpleType>", substring, "test#28");
329                         
330                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
331                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
332                         Assert.AreEqual ("              </xs:element>", substring, "test#29");
333                         
334                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
335                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
336                         Assert.AreEqual ("            </xs:sequence>", substring, "test#30");
337                         
338                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
339                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
340                         Assert.AreEqual ("          </xs:complexType>", substring, "test#31");
341                         
342                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
343                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
344                         Assert.AreEqual ("        </xs:element>", substring, "test#32");
345                         
346                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
347                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
348                         Assert.AreEqual ("      </xs:choice>", substring, "test#33");
349
350                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
351                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
352                         Assert.AreEqual ("    </xs:complexType>", substring, "test#34");
353
354                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
355                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
356                         Assert.AreEqual ("    <xs:unique name=\"Constraint1\">", substring, "test#36");
357
358                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
359                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
360                         Assert.AreEqual ("      <xs:selector xpath=\".//test_table\" />", substring, "test#37");
361
362                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
363                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
364                         Assert.AreEqual ("      <xs:field xpath=\"first\" />", substring, "test#38");
365
366                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
367                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
368                         Assert.AreEqual ("    </xs:unique>", substring, "test#39");
369
370                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
371                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
372                         // This is original DataSet.WriteXmlSchema() output
373 //                      Assert.AreEqual ("    <xs:unique name=\"second_test_table_Constraint1\" msdata:ConstraintName=\"Constraint1\">", substring, "test#40");
374                         Assert.AreEqual ("    <xs:unique msdata:ConstraintName=\"Constraint1\" name=\"second_test_table_Constraint1\">", substring, "test#40");
375
376                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
377                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
378                         Assert.AreEqual ("      <xs:selector xpath=\".//second_test_table\" />", substring, "test#41");
379                         
380                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
381                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
382                         Assert.AreEqual ("      <xs:field xpath=\"second_first\" />", substring, "test#42");
383                         
384                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
385                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
386                         Assert.AreEqual ("    </xs:unique>", substring, "test#43");
387                         
388                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
389                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
390                         Assert.AreEqual ("  </xs:element>", substring, "test#44");                      
391                         Assert.AreEqual ("</xs:schema>", TextString, "test#45");
392                 }
393                 
394                 [Test]
395                 public void ReadWriteXml ()
396                 {
397                         DataSet ds = new DataSet ();
398                         ds.ReadXml ("Test/System.Data/region.xml");
399                         TextWriter writer = new StringWriter ();
400                         ds.WriteXml (writer);
401                 
402                         string TextString = writer.ToString ();
403                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
404                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
405                         Assert.AreEqual ("<Root>", substring, "test#01");
406
407                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
408                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
409                         Assert.AreEqual ("  <Region>", substring, "test#02");
410                         
411                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
412                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
413                         Assert.AreEqual ("    <RegionID>1</RegionID>", substring, "test#03");
414                         // Here the end of line is text markup "\n"
415                         substring = TextString.Substring (0, TextString.IndexOf('\n'));
416                         TextString = TextString.Substring (TextString.IndexOf('\n') + 1);
417                         Assert.AreEqual ("    <RegionDescription>Eastern", substring, "test#04");
418
419                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
420                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
421                         Assert.AreEqual ("   </RegionDescription>", substring, "test#05");
422
423                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
424                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
425                         Assert.AreEqual ("  </Region>", substring, "test#06");
426
427                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
428                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
429                         Assert.AreEqual ("  <Region>", substring, "test#07");
430                         
431                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
432                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
433                         Assert.AreEqual ("    <RegionID>2</RegionID>", substring, "test#08");
434
435                         // Here the end of line is text markup "\n"
436                         substring = TextString.Substring (0, TextString.IndexOf('\n'));
437                         TextString = TextString.Substring (TextString.IndexOf('\n') + 1);
438                         Assert.AreEqual ("    <RegionDescription>Western", substring, "test#09");
439
440                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
441                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
442                         Assert.AreEqual ("   </RegionDescription>", substring, "test#10");
443
444                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
445                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
446                         Assert.AreEqual ("  </Region>", substring, "test#11");
447
448                         Assert.AreEqual ("</Root>", TextString, "test#11");
449                 }
450
451                 [Test]
452                 public void ReadWriteXmlDiffGram ()
453                 {
454                         DataSet ds = new DataSet ();
455                         // It is not a diffgram, so no data loading should be done.
456                         ds.ReadXml ("Test/System.Data/region.xml", XmlReadMode.DiffGram);
457                         TextWriter writer = new StringWriter ();
458                         ds.WriteXml (writer);
459                 
460                         string TextString = writer.ToString ();
461                         Assert.AreEqual ("<NewDataSet />", TextString, "test#01");
462
463                         ds.WriteXml (writer, XmlWriteMode.DiffGram);
464                         TextString = writer.ToString ();
465                         
466                         Assert.AreEqual ("<NewDataSet /><diffgr:diffgram xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\" xmlns:diffgr=\"urn:schemas-microsoft-com:xml-diffgram-v1\" />", TextString, "test#02");
467
468                         
469                         ds = new DataSet ();
470                         ds.ReadXml ("Test/System.Data/region.xml");
471                         DataTable table = ds.Tables ["Region"];
472                         table.Rows [0] [0] = "64";
473                         ds.ReadXml ("Test/System.Data/region.xml", XmlReadMode.DiffGram);
474                         ds.WriteXml (writer, XmlWriteMode.DiffGram);
475                         
476                         TextString = writer.ToString ();
477                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
478                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
479                         Assert.AreEqual ("<NewDataSet /><diffgr:diffgram xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\" xmlns:diffgr=\"urn:schemas-microsoft-com:xml-diffgram-v1\" /><diffgr:diffgram xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\" xmlns:diffgr=\"urn:schemas-microsoft-com:xml-diffgram-v1\">", substring, "test#03");
480
481                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
482                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
483                         Assert.AreEqual ("  <Root>", substring, "test#04");
484
485                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
486                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
487                         Assert.AreEqual ("    <Region diffgr:id=\"Region1\" msdata:rowOrder=\"0\" diffgr:hasChanges=\"inserted\">", substring, "test#05");
488
489                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
490                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
491                         Assert.AreEqual ("      <RegionID>64</RegionID>", substring, "test#06");
492
493                         // not EOL but literal '\n'
494                         substring = TextString.Substring (0, TextString.IndexOf('\n'));
495                         TextString = TextString.Substring (TextString.IndexOf('\n') + 1);
496                         Assert.AreEqual ("      <RegionDescription>Eastern", substring, "test#07");
497
498                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
499                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
500                         Assert.AreEqual ("   </RegionDescription>", substring, "test#07");
501
502                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
503                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
504                         Assert.AreEqual ("    </Region>", substring, "test#08");
505
506                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
507                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
508                         Assert.AreEqual ("    <Region diffgr:id=\"Region2\" msdata:rowOrder=\"1\" diffgr:hasChanges=\"inserted\">", substring, "test#09");
509
510                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
511                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
512                         Assert.AreEqual ("      <RegionID>2</RegionID>", substring, "test#10");
513
514                         // not EOL but literal '\n'
515                         substring = TextString.Substring (0, TextString.IndexOf('\n'));
516                         TextString = TextString.Substring (TextString.IndexOf('\n') + 1);
517                         Assert.AreEqual ("      <RegionDescription>Western", substring, "test#11");
518
519                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
520                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
521                         Assert.AreEqual ("   </RegionDescription>", substring, "test#12");
522
523                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
524                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
525                         Assert.AreEqual ("    </Region>", substring, "test#13");
526
527                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
528                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
529                         Assert.AreEqual ("  </Root>", substring, "test#14");
530                         
531                         Assert.AreEqual ("</diffgr:diffgram>", TextString, "test#15");
532                 }
533
534                 [Test]
535                 public void WriteXmlSchema ()
536                 {
537                         DataSet ds = new DataSet ();                    
538                         ds.ReadXml ("Test/System.Data/region.xml");
539                         TextWriter writer = new StringWriter ();
540                         ds.WriteXmlSchema (writer);
541                 
542
543                         string TextString = GetNormalizedSchema (writer.ToString ());
544 //                      string TextString = writer.ToString ();
545                         
546                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
547                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
548                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
549                         
550                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
551                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
552                         // This is original DataSet.WriteXmlSchema() output
553 //                      Assert.AreEqual ("<xs:schema id=\"Root\" xmlns=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">", substring, "test#02");
554                         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");
555
556                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
557                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
558                         Assert.AreEqual ("  <xs:element msdata:IsDataSet=\"true\" msdata:Locale=\"en-US\" name=\"Root\">", substring, "test#03");
559
560                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
561                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
562                         Assert.AreEqual ("    <xs:complexType>", substring, "test#04");
563
564                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
565                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
566                         Assert.AreEqual ("      <xs:choice maxOccurs=\"unbounded\" minOccurs=\"0\">", substring, "test#05");
567
568                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
569                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
570                         Assert.AreEqual ("        <xs:element name=\"Region\">", substring, "test#06");
571
572                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
573                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
574                         Assert.AreEqual ("          <xs:complexType>", substring, "test#07");
575
576                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
577                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
578                         Assert.AreEqual ("            <xs:sequence>", substring, "test#08");
579
580                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
581                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
582                         // This is original DataSet.WriteXmlSchema() output
583 //                      Assert.AreEqual ("              <xs:element name=\"RegionID\" type=\"xs:string\" minOccurs=\"0\" />", substring, "test#09");
584                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" name=\"RegionID\" type=\"xs:string\" />", substring, "test#09");
585
586                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
587                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
588                         // This is original DataSet.WriteXmlSchema() output
589 //                      Assert.AreEqual ("              <xs:element name=\"RegionDescription\" type=\"xs:string\" minOccurs=\"0\" />", substring, "test#10");
590                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" name=\"RegionDescription\" type=\"xs:string\" />", substring, "test#10");
591
592                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
593                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
594                         Assert.AreEqual ("            </xs:sequence>", substring, "test#11");
595
596                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
597                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
598                         Assert.AreEqual ("          </xs:complexType>", substring, "test#12");
599
600                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
601                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
602                         Assert.AreEqual ("        </xs:element>", substring, "test#13");
603
604                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
605                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
606                         Assert.AreEqual ("      </xs:choice>", substring, "test#14");
607
608                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
609                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
610                         Assert.AreEqual ("    </xs:complexType>", substring, "test#15");
611
612                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
613                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
614                         Assert.AreEqual ("  </xs:element>", substring, "test#16");
615
616                         Assert.AreEqual ("</xs:schema>", TextString, "test#17");
617                 }
618                 
619                 [Test]
620                 [Ignore ("MS behavior is far from consistent to be regarded as a reference implementation.")]
621                 // MS ReadXmlSchema() is too inconsistent to regard as a 
622                 // reference implementation. To find the reason why, try to
623                 // read store2.xsd and store4.xsd, write and compare for each
624                 // DataSet property.
625                 public void ReadWriteXmlSchemaIgnoreSchema ()
626                 {
627                         DataSet ds = new DataSet ();
628                         ds.ReadXmlSchema ("Test/System.Data/store.xsd");
629                         AssertDataSet ("read DataSet", ds, "NewDataSet", 3, 2);
630                         AssertDataTable ("read bookstore table", ds.Tables [0], "bookstore", 1, 0, 0, 1, 1, 1);
631                         AssertDataTable ("read book table", ds.Tables [1], "book", 5, 0, 1, 1, 2, 1);
632                         ds.ReadXml ("Test/System.Data/region.xml", XmlReadMode.IgnoreSchema);
633                         TextWriter writer = new StringWriter ();
634                         
635                         ds.WriteXmlSchema (writer);
636                         string TextString = GetNormalizedSchema (writer.ToString ());
637 //                      string TextString = writer.ToString ();
638                         
639
640                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
641                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
642                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
643                         
644                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
645                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
646                         // This is original DataSet.WriteXmlSchema() output
647 //                      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");
648                         Assert.AreEqual ("<xs:schema id=\"NewDataSet\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">", substring, "test#02");
649
650                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
651                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
652                         Assert.AreEqual ("  <xs:complexType name=\"bookstoreType\">", substring, "test#03");
653
654                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
655                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
656                         Assert.AreEqual ("    <xs:sequence>", substring, "test#04");
657
658                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
659                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
660                         // This is original DataSet.WriteXmlSchema() output
661 //                      Assert.AreEqual ("      <xs:element name=\"book\" type=\"bookType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />", substring, "test#05");
662                         Assert.AreEqual ("      <xs:element maxOccurs=\"unbounded\" minOccurs=\"0\" name=\"book\" type=\"bookType\" />", substring, "test#05");
663
664                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
665                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
666                         Assert.AreEqual ("    </xs:sequence>", substring, "test#06");
667
668                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
669                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
670                         Assert.AreEqual ("  </xs:complexType>", substring, "test#07");
671                         
672                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
673                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
674                         Assert.AreEqual ("  <xs:complexType name=\"bookType\">", substring, "test#08");
675
676                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
677                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
678                         Assert.AreEqual ("    <xs:sequence>", substring, "test#09");
679
680                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
681                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
682                         // This is original DataSet.WriteXmlSchema() output
683 //                      Assert.AreEqual ("      <xs:element name=\"title\" type=\"xs:string\" msdata:Ordinal=\"1\" />", substring, "test#10");
684                         
685                         Assert.AreEqual ("      <xs:element msdata:Ordinal=\"1\" name=\"title\" type=\"xs:string\" />", substring, "test#10");
686                         
687                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
688                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
689                         // This is original DataSet.WriteXmlSchema() output
690 //                      Assert.AreEqual ("      <xs:element name=\"price\" type=\"xs:decimal\" msdata:Ordinal=\"2\" />", substring, "test#11");
691                         Assert.AreEqual ("      <xs:element msdata:Ordinal=\"2\" name=\"price\" type=\"xs:decimal\" />", substring, "test#11");
692
693                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
694                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
695                         // This is original DataSet.WriteXmlSchema() output
696 //                      Assert.AreEqual ("      <xs:element name=\"author\" type=\"authorName\" minOccurs=\"0\" maxOccurs=\"unbounded\" />", substring, "test#12");
697                         Assert.AreEqual ("      <xs:element maxOccurs=\"unbounded\" minOccurs=\"0\" name=\"author\" type=\"authorName\" />", substring, "test#12");
698
699                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
700                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
701                         Assert.AreEqual ("    </xs:sequence>", substring, "test#13");
702
703                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
704                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
705                         Assert.AreEqual ("    <xs:attribute name=\"genre\" type=\"xs:string\" />", substring, "test#14");
706
707                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
708                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
709                         Assert.AreEqual ("  </xs:complexType>", substring, "test#15");
710
711                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
712                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
713                         Assert.AreEqual ("  <xs:complexType name=\"authorName\">", substring, "test#16");
714
715                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
716                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
717                         Assert.AreEqual ("    <xs:sequence>", substring, "test#17");
718
719                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
720                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
721                         Assert.AreEqual ("      <xs:element name=\"first-name\" type=\"xs:string\" />", substring, "test#18");
722
723                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
724                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
725                         Assert.AreEqual ("      <xs:element name=\"last-name\" type=\"xs:string\" />", substring, "test#19");
726
727                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
728                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
729                         Assert.AreEqual ("    </xs:sequence>", substring, "test#20");
730
731                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
732                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
733                         Assert.AreEqual ("  </xs:complexType>", substring, "test#21");
734
735                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
736                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
737                         Assert.AreEqual ("  <xs:element name=\"bookstore\" type=\"bookstoreType\" />", substring, "test#22");
738
739                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
740                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
741                         // This is original DataSet.WriteXmlSchema() output
742 //                      Assert.AreEqual ("  <xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:Locale=\"fi-FI\">", substring, "test#23");
743                         Assert.AreEqual ("  <xs:element msdata:IsDataSet=\"true\" msdata:Locale=\"fi-FI\" name=\"NewDataSet\">", substring, "test#23");
744
745                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
746                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
747                         Assert.AreEqual ("    <xs:complexType>", substring, "test#24");
748
749                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
750                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
751                         Assert.AreEqual ("      <xs:choice maxOccurs=\"unbounded\" minOccurs=\"0\">", substring, "test#25");
752
753                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
754                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
755                         Assert.AreEqual ("        <xs:element ref=\"bookstore\" />", substring, "test#26");
756
757                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
758                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
759                         Assert.AreEqual ("      </xs:choice>", substring, "test#27");
760
761                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
762                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
763                         Assert.AreEqual ("    </xs:complexType>", substring, "test#28");
764
765                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
766                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
767                         Assert.AreEqual ("  </xs:element>", substring, "test#29");
768
769                         Assert.AreEqual ("</xs:schema>", TextString, "test#30");
770                 }
771                 
772                 [Test]
773                 [Ignore ("MS behavior is far from consistent to be regarded as a reference implementation.")]
774                 // See comments on ReadWriteXmlSchemaIgnoreSchema().
775                 public void ReadWriteXmlSchema ()
776                 {
777                         DataSet ds = new DataSet ();
778                         ds.ReadXmlSchema ("Test/System.Data/store.xsd");
779                         // check dataset properties before testing write
780                         AssertDataSet ("ds", ds, "NewDataSet", 3, 2);
781                         AssertDataTable ("tab1", ds.Tables [0], "bookstore", 1, 0, 0, 1, 1, 1);
782                         AssertDataTable ("tab2", ds.Tables [1], "book", 5, 0, 1, 1, 2, 1);
783                         AssertDataTable ("tab3", ds.Tables [2], "author", 3, 0, 1, 0, 1, 0);
784                         // FIXME: currently order is not compatible. Use name as index
785                         AssertDataRelation ("rel1", ds.Relations ["book_author"], "book_author", true, new string [] {"book_Id"}, new string [] {"book_Id"}, true, true);
786                         AssertDataRelation ("rel2", ds.Relations ["bookstore_book"], "bookstore_book", true, new string [] {"bookstore_Id"}, new string [] {"bookstore_Id"}, true, true);
787
788                         ds.ReadXml ("Test/System.Data/region.xml", XmlReadMode.InferSchema);
789
790                         TextWriter writer = new StringWriter ();
791                         ds.WriteXmlSchema (writer);
792                 
793                         string TextString = GetNormalizedSchema (writer.ToString ());
794 //                      string TextString = writer.ToString ();
795                         
796                         string substring = TextString.Substring (0, TextString.IndexOf(EOL));
797                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
798                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>", substring, "test#01");
799                         
800                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
801                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
802                         // This is original DataSet.WriteXmlSchema() output
803 //                      Assert.AreEqual ("<xs:schema id=\"Root\" xmlns=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">", substring, "test#02");
804                         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");
805                         
806                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
807                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
808                         Assert.AreEqual ("  <xs:complexType name=\"bookstoreType\">", substring, "test#03");
809                         
810                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
811                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
812                         Assert.AreEqual ("    <xs:sequence>", substring, "test#04");
813                         
814                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
815                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
816                         // This is original DataSet.WriteXmlSchema() output
817 //                      Assert.AreEqual ("      <xs:element name=\"book\" type=\"bookType\" minOccurs=\"0\" maxOccurs=\"unbounded\" />", substring, "test#05");
818                         Assert.AreEqual ("      <xs:element maxOccurs=\"unbounded\" minOccurs=\"0\" name=\"book\" type=\"bookType\" />", substring, "test#05");
819                         
820                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
821                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
822                         Assert.AreEqual ("    </xs:sequence>", substring, "test#06");
823                         
824                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
825                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
826                         Assert.AreEqual ("  </xs:complexType>", substring, "test#07");
827                         
828                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
829                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
830                         Assert.AreEqual ("  <xs:complexType name=\"bookType\">", substring, "test#08");
831                         
832                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
833                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
834                         Assert.AreEqual ("    <xs:sequence>", substring, "test#09");
835                         
836                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
837                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
838                         // This is original DataSet.WriteXmlSchema() output
839 //                      Assert.AreEqual ("      <xs:element name=\"title\" type=\"xs:string\" msdata:Ordinal=\"1\" />", substring, "test#10");
840                         Assert.AreEqual ("      <xs:element msdata:Ordinal=\"1\" name=\"title\" type=\"xs:string\" />", substring, "test#10");
841                         
842                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
843                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
844                         // This is original DataSet.WriteXmlSchema() output
845 //                      Assert.AreEqual ("      <xs:element name=\"price\" type=\"xs:decimal\" msdata:Ordinal=\"2\" />", substring, "test#11");
846                         Assert.AreEqual ("      <xs:element msdata:Ordinal=\"2\" name=\"price\" type=\"xs:decimal\" />", substring, "test#11");
847                         
848                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
849                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
850                         // This is original DataSet.WriteXmlSchema() output
851 //                      Assert.AreEqual ("      <xs:element name=\"author\" type=\"authorName\" minOccurs=\"0\" maxOccurs=\"unbounded\" />", substring, "test#12");
852                         Assert.AreEqual ("      <xs:element maxOccurs=\"unbounded\" minOccurs=\"0\" name=\"author\" type=\"authorName\" />", substring, "test#12");
853         
854                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
855                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
856                         Assert.AreEqual ("    </xs:sequence>", substring, "test#13");
857                         
858                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
859                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
860                         Assert.AreEqual ("    <xs:attribute name=\"genre\" type=\"xs:string\" />", substring, "test#14");
861                         
862                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
863                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
864                         Assert.AreEqual ("  </xs:complexType>", substring, "test#15");
865                         
866                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
867                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
868                         Assert.AreEqual ("  <xs:complexType name=\"authorName\">", substring, "test#16");
869                         
870                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
871                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
872                         Assert.AreEqual ("    <xs:sequence>", substring, "test#17");
873                         
874                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
875                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
876                         Assert.AreEqual ("      <xs:element name=\"first-name\" type=\"xs:string\" />", substring, "test#18");
877                         
878                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
879                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
880                         Assert.AreEqual ("      <xs:element name=\"last-name\" type=\"xs:string\" />", substring, "test#19");
881
882                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
883                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
884                         Assert.AreEqual ("    </xs:sequence>", substring, "test#20");
885                 
886                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
887                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
888                         Assert.AreEqual ("  </xs:complexType>", substring, "test#21");
889
890                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
891                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
892                         Assert.AreEqual ("  <xs:element name=\"bookstore\" type=\"bookstoreType\" />", substring, "test#22");
893
894                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
895                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
896                         // This is original DataSet.WriteXmlSchema() output
897 //                      Assert.AreEqual ("  <xs:element name=\"Root\" msdata:IsDataSet=\"true\" msdata:Locale=\"fi-FI\">", substring, "test#23");
898                         Assert.AreEqual ("  <xs:element msdata:IsDataSet=\"true\" msdata:Locale=\"fi-FI\" name=\"Root\">", substring, "test#23");
899
900                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
901                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
902                         Assert.AreEqual ("    <xs:complexType>", substring, "test#24");
903
904                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
905                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
906                         Assert.AreEqual ("      <xs:choice maxOccurs=\"unbounded\" minOccurs=\"0\">", substring, "test#25");
907
908                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
909                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
910                         Assert.AreEqual ("        <xs:element ref=\"bookstore\" />", substring, "test#26");
911
912                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
913                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
914                         Assert.AreEqual ("        <xs:element name=\"Region\">", substring, "test#27");
915
916                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
917                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
918                         Assert.AreEqual ("          <xs:complexType>", substring, "test#28");
919                         
920                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
921                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
922                         Assert.AreEqual ("            <xs:sequence>", substring, "test#29");
923                         
924                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
925                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
926                         // This is original DataSet.WriteXmlSchema() output
927 //                      Assert.AreEqual ("              <xs:element name=\"RegionID\" type=\"xs:string\" minOccurs=\"0\" />", substring, "test#30");
928                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" name=\"RegionID\" type=\"xs:string\" />", substring, "test#30");
929                         
930                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
931                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
932                         // This is original DataSet.WriteXmlSchema() output
933 //                      Assert.AreEqual ("              <xs:element name=\"RegionDescription\" type=\"xs:string\" minOccurs=\"0\" />", substring, "test#31");
934                         Assert.AreEqual ("              <xs:element minOccurs=\"0\" name=\"RegionDescription\" type=\"xs:string\" />", substring, "test#31");
935                         
936                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
937                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
938                         Assert.AreEqual ("            </xs:sequence>", substring, "test#32");
939                         
940                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
941                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
942                         Assert.AreEqual ("          </xs:complexType>", substring, "test#33");
943                         
944                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
945                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
946                         Assert.AreEqual ("        </xs:element>", substring, "test#34");
947                         
948                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
949                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
950                         Assert.AreEqual ("      </xs:choice>", substring, "test#35");
951                         
952                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
953                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
954                         Assert.AreEqual ("    </xs:complexType>", substring, "test#36");
955                         
956                         substring = TextString.Substring (0, TextString.IndexOf(EOL));
957                         TextString = TextString.Substring (TextString.IndexOf(EOL) + EOL.Length);
958                         Assert.AreEqual ("  </xs:element>", substring, "test#37");
959
960                         Assert.AreEqual ("</xs:schema>", TextString, "test#38");
961                 }
962
963                 [Test]
964                 [Category ("NotWorking")]
965                 public void WriteDifferentNamespaceSchema ()
966                 {
967                         string schema = @"<?xml version='1.0' encoding='utf-16'?>
968 <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'>
969   <!--ATTENTION: This schema contains references to other imported schemas-->
970   <xs:import namespace='urn:baz' schemaLocation='_app1.xsd' />
971   <xs:import namespace='urn:foo' schemaLocation='_app2.xsd' />
972   <xs:element name='NewDataSet' msdata:IsDataSet='true' msdata:Locale='fi-FI'>
973     <xs:complexType>
974       <xs:choice minOccurs='0' maxOccurs='unbounded'>
975         <xs:element ref='app2:NS1Table' />
976         <xs:element name='NS2Table'>
977           <xs:complexType>
978           </xs:complexType>
979         </xs:element>
980       </xs:choice>
981     </xs:complexType>
982   </xs:element>
983 </xs:schema>";
984                         DataSet ds = new DataSet();
985                         DataTable dt = new DataTable ();
986                         dt.TableName = "NS1Table";
987                         dt.Namespace = "urn:foo";
988                         dt.Columns.Add ("column1");
989                         dt.Columns.Add ("column2");
990                         dt.Columns [1].Namespace = "urn:baz";
991                         ds.Tables.Add (dt);
992                         DataTable dt2 = new DataTable ();
993                         dt2.TableName = "NS2Table";
994                         dt2.Namespace = "urn:bar";
995                         ds.Tables.Add (dt2);
996                         ds.Namespace = "urn:bar";
997                         StringWriter sw = new StringWriter ();
998                         XmlTextWriter xw = new XmlTextWriter (sw);
999                         xw.Formatting = Formatting.Indented;
1000                         xw.QuoteChar = '\'';
1001                         ds.WriteXmlSchema (xw);
1002
1003                         string result = sw.ToString ();
1004                         Assert.AreEqual (result.Replace ("\r\n", "\n"), schema.Replace ("\r\n", "\n"));
1005                 }
1006
1007                 [Test]
1008                 public void IgnoreColumnEmptyNamespace ()
1009                 {
1010                         DataColumn col = new DataColumn ("TEST");
1011                         col.Namespace = "urn:foo";
1012                         DataSet ds = new DataSet ("DS");
1013                         ds.Namespace = "urn:foo";
1014                         DataTable dt = new DataTable ("tab");
1015                         ds.Tables.Add (dt);
1016                         dt.Columns.Add (col);
1017                         dt.Rows.Add (new object [] {"test"});
1018                         StringWriter sw = new StringWriter ();
1019                         ds.WriteXml (new XmlTextWriter (sw));
1020                         string xml = @"<DS xmlns=""urn:foo""><tab><TEST>test</TEST></tab></DS>";
1021                         Assert.AreEqual (xml, sw.ToString ());
1022                 }
1023
1024                 [Test]
1025                 public void SerializeDataSet ()
1026                 {
1027                         // see GetReady() for current culture
1028
1029                         string xml = "<?xml version='1.0' encoding='utf-16'?><DataSet><xs:schema id='DS' xmlns='' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'><xs:element name='DS' msdata:IsDataSet='true' " + 
1030                           "msdata:UseCurrentLocale='true'"
1031                           + "><xs:complexType><xs:choice minOccurs='0' maxOccurs='unbounded' /></xs:complexType></xs:element></xs:schema><diffgr:diffgram xmlns:msdata='urn:schemas-microsoft-com:xml-msdata' xmlns:diffgr='urn:schemas-microsoft-com:xml-diffgram-v1' /></DataSet>";
1032                         DataSet ds = new DataSet ();
1033                         ds.DataSetName = "DS";
1034                         XmlSerializer ser = new XmlSerializer (typeof (DataSet));
1035                         StringWriter sw = new StringWriter ();
1036                         XmlTextWriter xw = new XmlTextWriter (sw);
1037                         xw.QuoteChar = '\'';
1038                         ser.Serialize (xw, ds);
1039
1040                         string result = sw.ToString ();
1041                         Assert.AreEqual (result.Replace ("\r\n", "\n"), xml.Replace ("\r\n", "\n"));
1042                 }
1043
1044                 // bug #70961
1045                 [Test]
1046                 public void SerializeDataSet2 ()
1047                 {
1048                         DataSet quota = new DataSet ("Quota");
1049
1050                         // Dimension
1051                         DataTable dt = new DataTable ("Dimension");
1052                         quota.Tables.Add (dt);
1053
1054                         dt.Columns.Add ("Number", typeof(int));
1055                         dt.Columns ["Number"].AllowDBNull = false;
1056                         dt.Columns ["Number"].ColumnMapping = MappingType.Attribute;
1057
1058                         dt.Columns.Add ("Title", typeof(string));
1059                         dt.Columns ["Title"].AllowDBNull = false;
1060                         dt.Columns ["Title"].ColumnMapping = 
1061                         MappingType.Attribute;
1062
1063                         dt.Rows.Add (new object [] {0, "Hospitals"});
1064                         dt.Rows.Add (new object [] {1, "Doctors"});
1065
1066                         dt.Constraints.Add ("PK_Dimension", dt.Columns ["Number"], true);
1067
1068                         quota.AcceptChanges ();
1069
1070                         XmlSerializer ser = new XmlSerializer (quota.GetType ());
1071
1072                         StringWriter sw = new StringWriter ();
1073                         ser.Serialize (sw, quota);
1074
1075                         DataSet ds = (DataSet) ser.Deserialize (new StringReader (sw.ToString ()));
1076                 }
1077
1078                 // bug #68007
1079                 public void SerializeDataSet3 ()
1080                 {
1081                         string xml = @"<?xml version=""1.0"" encoding=""utf-8""?><DataSet><xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata""><xs:element name=""Example"" msdata:IsDataSet=""true""><xs:complexType><xs:choice maxOccurs=""unbounded"" minOccurs=""0""><xs:element name=""Packages""><xs:complexType><xs:attribute name=""ID"" type=""xs:int"" use=""required"" /><xs:attribute name=""ShipDate"" type=""xs:dateTime"" /><xs:attribute name=""Message"" type=""xs:string"" /><xs:attribute name=""Handlers"" type=""xs:int"" /></xs:complexType></xs:element></xs:choice></xs:complexType></xs:element></xs:schema><diffgr:diffgram xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"" xmlns:diffgr=""urn:schemas-microsoft-com:xml-diffgram-v1""><Example><Packages diffgr:id=""Packages1"" msdata:rowOrder=""0"" ID=""0"" ShipDate=""2004-10-11T17:46:18.6962302-05:00"" Message=""Received with no breakage!"" Handlers=""3"" /><Packages diffgr:id=""Packages2"" msdata:rowOrder=""1"" ID=""1"" /></Example></diffgr:diffgram></DataSet>";
1082
1083                         DataSet ds = new DataSet ("Example");
1084
1085                         // Add a DataTable
1086                         DataTable dt = new DataTable ("Packages");
1087                         ds.Tables.Add (dt);
1088
1089                         // Add an ID DataColumn w/ ColumnMapping = MappingType.Attribute
1090                         dt.Columns.Add (new DataColumn ("ID", typeof(int), "", 
1091                                 MappingType.Attribute));
1092                         dt.Columns ["ID"].AllowDBNull = false;
1093
1094                         // Add a nullable DataColumn w/ ColumnMapping = MappingType.Attribute
1095                         dt.Columns.Add (new DataColumn ("ShipDate",
1096                                 typeof (DateTime), "", MappingType.Attribute));
1097                         dt.Columns ["ShipDate"].AllowDBNull = true;
1098
1099                         // Add a nullable DataColumn w/ ColumnMapping = MappingType.Attribute
1100                         dt.Columns.Add (new DataColumn ("Message",
1101                                 typeof (string), "", MappingType.Attribute));
1102                         dt.Columns ["Message"].AllowDBNull = true;
1103
1104                         // Add a nullable DataColumn w/ ColumnMapping = MappingType.Attribute
1105                         dt.Columns.Add (new DataColumn ("Handlers",
1106                                 typeof (int), "", MappingType.Attribute));
1107                         dt.Columns ["Handlers"].AllowDBNull = true;
1108
1109                         // Add a non-null value row
1110                         DataRow newRow = dt.NewRow();
1111                         newRow ["ID"] = 0;
1112                         newRow ["ShipDate"] = DateTime.Now;
1113                         newRow ["Message"] = "Received with no breakage!";
1114                         newRow ["Handlers"] = 3;
1115                         dt.Rows.Add (newRow);
1116
1117                         // Add a null value row
1118                         newRow = dt.NewRow ();
1119                         newRow ["ID"] = 1;
1120                         newRow ["ShipDate"] = DBNull.Value;
1121                         newRow ["Message"] = DBNull.Value;
1122                         newRow ["Handlers"] = DBNull.Value;
1123                         dt.Rows.Add (newRow);
1124
1125                         ds.AcceptChanges ();
1126
1127                         XmlSerializer ser = new XmlSerializer (ds.GetType());
1128                         StringWriter sw = new StringWriter ();
1129                         ser.Serialize (sw, ds);
1130
1131                         string result = sw.ToString ();
1132
1133                         Assert.AreEqual (xml, result);
1134                 }
1135
1136                 [Test]
1137                 public void DeserializeDataSet ()
1138                 {
1139                         string xml = @"<DataSet>
1140   <diffgr:diffgram xmlns:msdata='urn:schemas-microsoft-com:xml-msdata' xmlns:diffgr='urn:schemas-microsoft-com:xml-diffgram-v1'>
1141     <Quota>
1142       <Dimension diffgr:id='Dimension1' msdata:rowOrder='0' Number='0' Title='Hospitals' />
1143       <Dimension diffgr:id='Dimension2' msdata:rowOrder='1' Number='1' Title='Doctors' />
1144     </Quota>
1145   </diffgr:diffgram>
1146 </DataSet>";
1147                         XmlSerializer ser = new XmlSerializer (typeof (DataSet));
1148                         ser.Deserialize (new XmlTextReader (
1149                                 xml, XmlNodeType.Document, null));
1150                 }
1151
1152                 /* To be added
1153                 [Test]
1154                 public void WriteDiffReadAutoWriteSchema ()
1155                 {
1156                         DataSet ds = new DataSet ();
1157                         ds.Tables.Add ("Table1");
1158                         ds.Tables.Add ("Table2");
1159                         ds.Tables [0].Columns.Add ("Column1_1");
1160                         ds.Tables [0].Columns.Add ("Column1_2");
1161                         ds.Tables [0].Columns.Add ("Column1_3");
1162                         ds.Tables [1].Columns.Add ("Column2_1");
1163                         ds.Tables [1].Columns.Add ("Column2_2");
1164                         ds.Tables [1].Columns.Add ("Column2_3");
1165                         ds.Tables [0].Rows.Add (new object [] {"ppp", "www", "xxx"});
1166
1167                         // save as diffgram
1168                         StringWriter sw = new StringWriter ();
1169                         ds.WriteXml (sw, XmlWriteMode.DiffGram);
1170                         string xml = sw.ToString ();
1171                         string result = new StreamReader ("Test/System.Data/DataSetReadXmlTest1.xml", Encoding.ASCII).ReadToEnd ();
1172                         Assert.AreEqual (result, xml, "#01");
1173
1174                         // load diffgram above
1175                         ds.ReadXml (new StringReader (sw.ToString ()));
1176                         sw = new StringWriter ();
1177                         ds.WriteXml (sw, XmlWriteMode.WriteSchema);
1178                         xml = sw.ToString ();
1179                         result = new StreamReader ("Test/System.Data/DataSetReadXmlTest2.xml", Encoding.ASCII).ReadToEnd ();
1180                         Assert.AreEqual (result, xml, "#02");
1181                 }
1182                 */
1183
1184                 [Test]
1185                 public void CloneCopy ()
1186                 {
1187                         DataTable table = new DataTable ("pTable");
1188                         DataTable table1 = new DataTable ("cTable");
1189                         DataSet set = new DataSet ();
1190
1191                         set.Tables.Add (table);
1192                         set.Tables.Add (table1);
1193
1194                         DataColumn col = new DataColumn ();
1195                         col.ColumnName = "Id";
1196                         col.DataType = Type.GetType ("System.Int32");
1197                         table.Columns.Add (col);
1198                         UniqueConstraint uc = new UniqueConstraint ("UK1", table.Columns[0] );
1199                         table.Constraints.Add (uc);
1200
1201                         col = new DataColumn ();
1202                         col.ColumnName = "Name";
1203                         col.DataType = Type.GetType ("System.String");
1204                         table.Columns.Add (col);
1205
1206                         col = new DataColumn ();
1207                         col.ColumnName = "Id";
1208                         col.DataType = Type.GetType ("System.Int32");
1209                         table1.Columns.Add (col);
1210
1211                         col = new DataColumn ();
1212                         col.ColumnName = "Name";
1213                         col.DataType = Type.GetType ("System.String");
1214                         table1.Columns.Add (col);
1215                           ForeignKeyConstraint fc = new ForeignKeyConstraint ("FK1", table.Columns[0], table1.Columns[0] );
1216                         table1.Constraints.Add (fc);
1217
1218
1219                         DataRow row = table.NewRow ();
1220
1221                         row ["Id"] = 147;
1222                         row ["name"] = "Row1";
1223                         row.RowError = "Error#1";
1224                         table.Rows.Add (row);
1225
1226                         // Set column to RO as commonly used by auto-increment fields.
1227                         // ds.Copy() has to omit the RO check when cloning DataRows 
1228                         table.Columns["Id"].ReadOnly = true;
1229                         
1230                         row = table1.NewRow ();
1231                         row ["Id"] = 147;
1232                         row ["Name"] = "Row1";
1233                         table1.Rows.Add (row);
1234
1235                         //Setting properties of DataSet
1236                         set.CaseSensitive = true;
1237                         set.DataSetName = "My DataSet";
1238                         set.EnforceConstraints = false;
1239                         set.Namespace = "Namespace#1";
1240                         set.Prefix = "Prefix:1";
1241                         DataRelation dr = new DataRelation ("DR", table.Columns [0],table1.Columns [0]);
1242                         set.Relations.Add (dr);
1243                         set.ExtendedProperties.Add ("TimeStamp", DateTime.Now);
1244                         CultureInfo cultureInfo = new CultureInfo( "ar-SA" );
1245                         set.Locale = cultureInfo;
1246
1247                         //Testing Copy ()
1248                         DataSet copySet = set.Copy ();
1249                         Assert.AreEqual (set.CaseSensitive, copySet.CaseSensitive, "#A01");
1250                         Assert.AreEqual (set.DataSetName, copySet.DataSetName, "#A02");
1251                         Assert.AreEqual (set.EnforceConstraints, copySet.EnforceConstraints, "#A03");
1252                         Assert.AreEqual (set.HasErrors, copySet.HasErrors, "#A04");
1253                         Assert.AreEqual (set.Namespace, copySet.Namespace, "#A05");
1254                         Assert.AreEqual (set.Prefix, copySet.Prefix, "#A06");
1255                         Assert.AreEqual (set.Relations.Count, copySet.Relations.Count, "#A07");
1256                         Assert.AreEqual (set.Tables.Count, copySet.Tables.Count, "#A08");
1257                         Assert.AreEqual (set.ExtendedProperties ["TimeStamp"], copySet.ExtendedProperties ["TimeStamp"], "#A09");
1258                         for (int i = 0;i < copySet.Tables.Count; i++) {
1259                                 Assert.AreEqual (set.Tables [i].Rows.Count, copySet.Tables [i].Rows.Count, "#A10");
1260                                 Assert.AreEqual (set.Tables [i].Columns.Count, copySet.Tables [i].Columns.Count, "#A11");
1261                         }
1262                         //Testing Clone ()
1263                         copySet = set.Clone ();
1264                         Assert.AreEqual (set.CaseSensitive, copySet.CaseSensitive, "#A12");
1265                         Assert.AreEqual (set.DataSetName, copySet.DataSetName, "#A13");
1266                         Assert.AreEqual (set.EnforceConstraints, copySet.EnforceConstraints, "#A14");
1267                         Assert.IsFalse (copySet.HasErrors, "#A15");
1268                         Assert.AreEqual (set.Namespace, copySet.Namespace, "#A16");
1269                         Assert.AreEqual (set.Prefix, copySet.Prefix, "#A17");
1270                         Assert.AreEqual (set.Relations.Count, copySet.Relations.Count, "#A18");
1271                         Assert.AreEqual (set.Tables.Count, copySet.Tables.Count, "#A19");
1272                         Assert.AreEqual (set.ExtendedProperties ["TimeStamp"], copySet.ExtendedProperties ["TimeStamp"], "#A20");
1273                         for (int i = 0;i < copySet.Tables.Count; i++) {
1274                                 Assert.AreEqual (0, copySet.Tables [i].Rows.Count, "#A21");
1275                                 Assert.AreEqual (set.Tables [i].Columns.Count, copySet.Tables [i].Columns.Count, "#A22");
1276                         }
1277                 }
1278
1279                 [Test]
1280                 public void CloneCopy2 ()
1281                 {
1282                         DataSet ds = new DataSet ();
1283                         ds.ReadXmlSchema ("Test/System.Data/store.xsd");
1284                         ds.Clone ();
1285                 }
1286
1287                 [Test]
1288                 public void CloneCopy_TestForeignKeyConstraints ()
1289                 {
1290                         DataTable dirTable = new DataTable("Directories");
1291
1292                         DataColumn dir_UID = new DataColumn("UID", typeof(int));
1293                         dir_UID.Unique = true;
1294                         dir_UID.AllowDBNull = false;
1295
1296                         dirTable.Columns.Add(dir_UID);
1297
1298                         // Build a simple Files table
1299                         DataTable fileTable = new DataTable("Files");
1300
1301                         DataColumn file_DirID = new DataColumn("DirectoryID", typeof(int));
1302                         file_DirID.Unique = false;
1303                         file_DirID.AllowDBNull = false;
1304
1305                         fileTable.Columns.Add(file_DirID);
1306
1307                         // Build the DataSet
1308                         DataSet ds = new DataSet("TestDataset");
1309                         ds.Tables.Add(dirTable);
1310                         ds.Tables.Add(fileTable);
1311
1312                         // Add a foreign key constraint
1313                         DataColumn[] parentColumns = new DataColumn[1];
1314                         parentColumns[0] = ds.Tables["Directories"].Columns["UID"];
1315
1316                         DataColumn[] childColumns = new DataColumn[1];
1317                         childColumns[0] = ds.Tables["Files"].Columns["DirectoryID"];
1318
1319                         ForeignKeyConstraint fk = new ForeignKeyConstraint("FK_Test", parentColumns, childColumns);
1320                         ds.Tables["Files"].Constraints.Add(fk);         
1321                         ds.EnforceConstraints = true;
1322
1323                         Assert.AreEqual (1, ds.Tables["Directories"].Constraints.Count, "#1");
1324                         Assert.AreEqual (1, ds.Tables["Files"].Constraints.Count, "#2");
1325
1326                         // check clone works fine
1327                         DataSet cloned_ds = ds.Clone ();
1328                         Assert.AreEqual (1, cloned_ds.Tables["Directories"].Constraints.Count, "#3");
1329                         Assert.AreEqual (1, cloned_ds.Tables["Files"].Constraints.Count, "#4");
1330
1331                         ForeignKeyConstraint clonedFk =  (ForeignKeyConstraint)cloned_ds.Tables["Files"].Constraints[0];
1332                         Assert.AreEqual ("FK_Test", clonedFk.ConstraintName, "#5");
1333                         Assert.AreEqual (1, clonedFk.Columns.Length, "#6");
1334                         Assert.AreEqual ("DirectoryID", clonedFk.Columns[0].ColumnName, "#7");
1335
1336                         UniqueConstraint clonedUc = (UniqueConstraint)cloned_ds.Tables ["Directories"].Constraints[0];
1337                         UniqueConstraint origUc = (UniqueConstraint)ds.Tables ["Directories"].Constraints[0];
1338                         Assert.AreEqual (origUc.ConstraintName, clonedUc.ConstraintName, "#8");
1339                         Assert.AreEqual (1, clonedUc.Columns.Length, "#9");
1340                         Assert.AreEqual ("UID", clonedUc.Columns[0].ColumnName, "#10");
1341
1342                         // check copy works fine
1343                         DataSet copy_ds = ds.Copy ();
1344                         Assert.AreEqual (1, copy_ds.Tables["Directories"].Constraints.Count, "#11");
1345                         Assert.AreEqual (1, copy_ds.Tables["Files"].Constraints.Count, "#12");
1346
1347                         ForeignKeyConstraint copyFk =  (ForeignKeyConstraint)copy_ds.Tables["Files"].Constraints[0];
1348                         Assert.AreEqual ("FK_Test", copyFk.ConstraintName, "#13");
1349                         Assert.AreEqual (1, copyFk.Columns.Length, "#14");
1350                         Assert.AreEqual ("DirectoryID", copyFk.Columns[0].ColumnName, "#15");
1351
1352                         UniqueConstraint copyUc = (UniqueConstraint)copy_ds.Tables ["Directories"].Constraints[0];
1353                         origUc = (UniqueConstraint)ds.Tables ["Directories"].Constraints[0];
1354                         Assert.AreEqual (origUc.ConstraintName, copyUc.ConstraintName, "#16");
1355                         Assert.AreEqual (1, copyUc.Columns.Length, "#17");
1356                         Assert.AreEqual ("UID", copyUc.Columns[0].ColumnName, "#18");
1357                 }
1358
1359                 [Test]
1360                 public void WriteNestedTableXml ()
1361                 {
1362                         string xml = @"<NewDataSet>
1363   <tab1>
1364     <ident>1</ident>
1365     <name>hoge</name>
1366     <tab2>
1367       <timestamp>2004-05-05</timestamp>
1368     </tab2>
1369   </tab1>
1370   <tab1>
1371     <ident>2</ident>
1372     <name>fuga</name>
1373     <tab2>
1374       <timestamp>2004-05-06</timestamp>
1375     </tab2>
1376   </tab1>
1377 </NewDataSet>";
1378                         DataSet ds = new DataSet ();
1379                         DataTable dt = new DataTable ("tab1");
1380                         dt.Columns.Add ("ident");
1381                         dt.Columns.Add ("name");
1382                         dt.Rows.Add (new object [] {"1", "hoge"});
1383                         dt.Rows.Add (new object [] {"2", "fuga"});
1384                         DataTable dt2 = new DataTable ("tab2");
1385                         dt2.Columns.Add ("idref");
1386                         dt2.Columns [0].ColumnMapping = MappingType.Hidden;
1387                         dt2.Columns.Add ("timestamp");
1388                         dt2.Rows.Add (new object [] {"1", "2004-05-05"});
1389                         dt2.Rows.Add (new object [] {"2", "2004-05-06"});
1390                         ds.Tables.Add (dt);
1391                         ds.Tables.Add (dt2);
1392                         DataRelation rel = new DataRelation ("rel", dt.Columns [0], dt2.Columns [0]);
1393                         rel.Nested = true;
1394                         ds.Relations.Add (rel);
1395                         StringWriter sw = new StringWriter ();
1396                         ds.WriteXml (sw);
1397                         Assert.AreEqual (sw.ToString ().Replace ("\r\n", "\n"), xml.Replace ("\r\n", "\n"));
1398                 }
1399
1400                 [Test]
1401                 public void WriteXmlToStream ()
1402                 {
1403                         string xml = "<set><table1><col1>sample text</col1><col2/></table1><table2 attr='value'><col3>sample text 2</col3></table2></set>";
1404                         DataSet ds = new DataSet ();
1405                         ds.ReadXml (new StringReader (xml));
1406                         MemoryStream ms = new MemoryStream ();
1407                         ds.WriteXml (ms);
1408                         MemoryStream ms2 = new MemoryStream (ms.ToArray ());
1409                         StreamReader sr = new StreamReader (ms2, Encoding.UTF8);
1410                         string result = @"<set>
1411   <table1>
1412     <col1>sample text</col1>
1413     <col2 />
1414   </table1>
1415   <table2 attr=""value"">
1416     <col3>sample text 2</col3>
1417   </table2>
1418 </set>";
1419                         Assert.AreEqual (sr.ReadToEnd ().Replace ("\r\n", "\n"), result.Replace ("\r\n", "\n"));
1420                 }
1421
1422                 [Test]
1423                 public void WtiteXmlEncodedXml ()
1424                 {
1425                         string xml = @"<an_x0020_example_x0020_dataset.>
1426   <WOW_x0021__x0020_that_x0027_s_x0020_nasty...>
1427     <URL_x0020_is_x0020_http_x003A__x002F__x002F_www.go-mono.com>content string.</URL_x0020_is_x0020_http_x003A__x002F__x002F_www.go-mono.com>
1428   </WOW_x0021__x0020_that_x0027_s_x0020_nasty...>
1429 </an_x0020_example_x0020_dataset.>";
1430                         DataSet ds = new DataSet ("an example dataset.");
1431                         ds.Tables.Add (new DataTable ("WOW! that's nasty..."));
1432                         ds.Tables [0].Columns.Add ("URL is http://www.go-mono.com");
1433                         ds.Tables [0].Rows.Add (new object [] {"content string."});
1434                         StringWriter sw = new StringWriter ();
1435                         ds.WriteXml (sw);
1436                         Assert.AreEqual (sw.ToString ().Replace ("\r\n", "\n"), xml.Replace ("\r\n", "\n"));
1437                 }
1438
1439                 [Test]
1440                 public void ReadWriteXml2 ()
1441                 {
1442                         string xml = "<FullTextResponse><Domains><AvailResponse info='y' name='novell-ximian-group' /><AvailResponse info='n' name='ximian' /></Domains></FullTextResponse>";
1443                         DataSet ds = new DataSet ();
1444                         ds.ReadXml (new StringReader (xml));
1445                         AssertDataSet ("ds", ds, "FullTextResponse", 2, 1);
1446                         DataTable dt = ds.Tables [0];
1447                         AssertDataTable ("dt1", dt, "Domains", 1, 1, 0, 1, 1, 1);
1448                         dt = ds.Tables [1];
1449                         AssertDataTable ("dt2", dt, "AvailResponse", 3, 2, 1, 0, 1, 0);
1450                         StringWriter sw = new StringWriter ();
1451                         XmlTextWriter xtw = new XmlTextWriter (sw);
1452                         xtw.QuoteChar = '\'';
1453                         ds.WriteXml (xtw);
1454                         Assert.AreEqual (xml, sw.ToString ());
1455                 }
1456
1457                 // bug #53959.
1458                 [Test]
1459                 public void ReadWriteXml3 ()
1460                 {
1461                         string input = @"<FullTextResponse>
1462   <Domains>
1463     <AvailResponse info='y' name='novell-ximian-group' />
1464     <AvailResponse info='n' name='ximian' />
1465   </Domains>
1466 </FullTextResponse>";
1467                         DataSet ds = new DataSet ();
1468                         ds.ReadXml (new StringReader (input));
1469
1470                         StringWriter sw = new StringWriter ();
1471                         XmlTextWriter xtw = new XmlTextWriter (sw);
1472                         xtw.Formatting = Formatting.Indented;
1473                         xtw.QuoteChar = '\'';
1474                         ds.WriteXml (xtw);
1475                         xtw.Flush ();
1476                         Assert.AreEqual (input.Replace ("\r\n", "\n"), sw.ToString ().Replace ("\r\n", "\n"));
1477                 }
1478
1479                 [Test] // bug #60469
1480                 public void WriteXmlSchema2 ()
1481                 {
1482                         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>";
1483                         string schema = @"<?xml version='1.0' encoding='utf-16'?>
1484 <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'>
1485   <xs:element name='myDataSet' msdata:IsDataSet='true' " +
1486                         "msdata:UseCurrentLocale='true'"
1487                         + @">
1488     <xs:complexType>
1489       <xs:choice minOccurs='0' maxOccurs='unbounded'>
1490         <xs:element name='myTable'>
1491           <xs:complexType>
1492             <xs:sequence>
1493               <xs:element name='id' msdata:AutoIncrement='true' type='xs:int' minOccurs='0' />
1494               <xs:element name='item' type='xs:string' minOccurs='0' />
1495             </xs:sequence>
1496           </xs:complexType>
1497         </xs:element>
1498       </xs:choice>
1499     </xs:complexType>
1500   </xs:element>
1501 </xs:schema>";
1502                         DataSet OriginalDataSet = new DataSet ("myDataSet"); 
1503                         OriginalDataSet.Namespace= "NetFrameWork"; 
1504                         DataTable myTable = new DataTable ("myTable"); 
1505                         DataColumn c1 = new DataColumn ("id", typeof (int)); 
1506                         c1.AutoIncrement = true;
1507                         DataColumn c2 = new DataColumn ("item"); 
1508                         myTable.Columns.Add (c1);
1509                         myTable.Columns.Add (c2);
1510                         OriginalDataSet.Tables.Add (myTable);
1511                         // Add ten rows.
1512                         DataRow newRow;
1513                         for(int i = 0; i < 10; i++) {
1514                                 newRow = myTable.NewRow ();
1515                                 newRow ["item"] = "item " + i;
1516                                 myTable.Rows.Add (newRow);
1517                         } 
1518                         OriginalDataSet.AcceptChanges ();
1519
1520                         StringWriter sw = new StringWriter ();
1521                         XmlTextWriter xtw = new XmlTextWriter (sw);
1522                         xtw.QuoteChar = '\'';
1523                         OriginalDataSet.WriteXml (xtw);
1524                         string result = sw.ToString ();
1525
1526                         Assert.AreEqual (xml, result);
1527
1528                         sw = new StringWriter ();
1529                         xtw = new XmlTextWriter (sw);
1530                         xtw.Formatting = Formatting.Indented;
1531                         OriginalDataSet.WriteXmlSchema (xtw);
1532                         result = sw.ToString ();
1533
1534                         result = result.Replace ("\r\n", "\n").Replace ('"', '\'');
1535                         Assert.AreEqual (schema.Replace ("\r\n", "\n"), result);
1536                 }
1537
1538                 // bug #66366
1539                 [Test]
1540                 public void WriteXmlSchema3 ()
1541                 {
1542                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
1543 <xs:schema id=""ExampleDataSet"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
1544   <xs:element name=""ExampleDataSet"" msdata:IsDataSet=""true"" ";
1545                         xmlschema = xmlschema + "msdata:UseCurrentLocale=\"true\"";
1546                         xmlschema = xmlschema + @">
1547     <xs:complexType>
1548       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
1549         <xs:element name=""ExampleDataTable"">
1550           <xs:complexType>
1551             <xs:attribute name=""PrimaryKeyColumn"" type=""xs:int"" use=""required"" />
1552           </xs:complexType>
1553         </xs:element>
1554       </xs:choice>
1555     </xs:complexType>
1556     <xs:unique name=""PK_ExampleDataTable"" msdata:PrimaryKey=""true"">
1557       <xs:selector xpath="".//ExampleDataTable"" />
1558       <xs:field xpath=""@PrimaryKeyColumn"" />
1559     </xs:unique>
1560   </xs:element>
1561 </xs:schema>";
1562                         DataSet ds = new DataSet ("ExampleDataSet");
1563
1564                         ds.Tables.Add (new DataTable ("ExampleDataTable"));
1565                         ds.Tables ["ExampleDataTable"].Columns.Add (
1566                                 new DataColumn ("PrimaryKeyColumn", typeof(int), "", MappingType.Attribute));
1567                         ds.Tables ["ExampleDataTable"].Columns ["PrimaryKeyColumn"].AllowDBNull = false;
1568
1569                         ds.Tables ["ExampleDataTable"].Constraints.Add (
1570                                 "PK_ExampleDataTable", 
1571                                 ds.Tables ["ExampleDataTable"].Columns ["PrimaryKeyColumn"],
1572                                 true);
1573
1574                         ds.AcceptChanges ();
1575                         StringWriter sw = new StringWriter ();
1576                         ds.WriteXmlSchema (sw);
1577
1578                         string result = sw.ToString ();
1579
1580                         Assert.AreEqual (result.Replace ("\r\n", "\n"), xmlschema.Replace ("\r\n", "\n"));
1581                 }
1582
1583                 // bug #67792.
1584                 [Test]
1585                 public void WriteXmlSchema4 ()
1586                 {
1587                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
1588 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
1589 ";
1590                         xmlschema = xmlschema + "  <xs:element name=\"Example\" msdata:IsDataSet=\"true\" msdata:UseCurrentLocale=\"true\"";
1591                         xmlschema = xmlschema + @">
1592     <xs:complexType>
1593       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
1594         <xs:element name=""MyType"">
1595           <xs:complexType>
1596             <xs:attribute name=""ID"" type=""xs:int"" use=""required"" />
1597             <xs:attribute name=""Desc"" type=""xs:string"" />
1598           </xs:complexType>
1599         </xs:element>
1600       </xs:choice>
1601     </xs:complexType>
1602   </xs:element>
1603 </xs:schema>";
1604                         DataSet ds = new DataSet ("Example");
1605
1606                         // Add MyType DataTable
1607                         DataTable dt = new DataTable ("MyType");
1608                         ds.Tables.Add (dt);
1609
1610                         dt.Columns.Add (new DataColumn ("ID", typeof(int), "",
1611                                 MappingType.Attribute));
1612                         dt.Columns ["ID"].AllowDBNull = false;
1613
1614                         dt.Columns.Add (new DataColumn ("Desc", typeof
1615                                 (string), "", MappingType.Attribute));
1616
1617                         ds.AcceptChanges ();
1618
1619                         StringWriter sw = new StringWriter ();
1620                         ds.WriteXmlSchema (sw);
1621
1622                         string result = sw.ToString ();
1623
1624                         Assert.AreEqual (result.Replace ("\r\n", "\n"), xmlschema.Replace ("\r\n", "\n"));
1625                 }
1626
1627                 // bug # 68432
1628                 [Test]
1629                 public void WriteXmlSchema5 ()
1630                 {
1631                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
1632 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
1633 "+
1634 "  <xs:element name=\"Example\" msdata:IsDataSet=\"true\" msdata:UseCurrentLocale=\"true\""
1635                           + @">
1636     <xs:complexType>
1637       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
1638         <xs:element name=""StandAlone"">
1639           <xs:complexType>
1640             <xs:attribute name=""ID"" type=""xs:int"" use=""required"" />
1641             <xs:attribute name=""Desc"" type=""xs:string"" use=""required"" />
1642           </xs:complexType>
1643         </xs:element>
1644         <xs:element name=""Dimension"">
1645           <xs:complexType>
1646             <xs:attribute name=""Number"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
1647             <xs:attribute name=""Title"" type=""xs:string"" use=""required"" />
1648           </xs:complexType>
1649         </xs:element>
1650         <xs:element name=""Element"">
1651           <xs:complexType>
1652             <xs:attribute name=""Dimension"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
1653             <xs:attribute name=""Number"" msdata:ReadOnly=""true"" type=""xs:int"" use=""required"" />
1654             <xs:attribute name=""Title"" type=""xs:string"" use=""required"" />
1655           </xs:complexType>
1656         </xs:element>
1657       </xs:choice>
1658     </xs:complexType>
1659     <xs:unique name=""PK_Dimension"" msdata:PrimaryKey=""true"">
1660       <xs:selector xpath="".//Dimension"" />
1661       <xs:field xpath=""@Number"" />
1662     </xs:unique>
1663     <xs:unique name=""PK_Element"" msdata:PrimaryKey=""true"">
1664       <xs:selector xpath="".//Element"" />
1665       <xs:field xpath=""@Dimension"" />
1666       <xs:field xpath=""@Number"" />
1667     </xs:unique>
1668     <xs:keyref name=""FK_Element_To_Dimension"" refer=""PK_Dimension"">
1669       <xs:selector xpath="".//Element"" />
1670       <xs:field xpath=""@Dimension"" />
1671     </xs:keyref>
1672   </xs:element>
1673 </xs:schema>";
1674                         DataSet ds = new DataSet("Example");
1675
1676                         // Add a DataTable with no ReadOnly columns
1677                         DataTable dt1 = new DataTable ("StandAlone");
1678                         ds.Tables.Add (dt1);
1679
1680                         // Add a ReadOnly column
1681                         dt1.Columns.Add (new DataColumn ("ID", typeof(int), "", 
1682                                 MappingType.Attribute));
1683                         dt1.Columns ["ID"].AllowDBNull = false;
1684
1685                         dt1.Columns.Add (new DataColumn ("Desc", typeof
1686                                 (string), "", MappingType.Attribute));
1687                         dt1.Columns ["Desc"].AllowDBNull = false;
1688
1689                         // Add related DataTables with ReadOnly columns
1690                         DataTable dt2 = new DataTable ("Dimension");
1691                         ds.Tables.Add (dt2);
1692                         dt2.Columns.Add (new DataColumn ("Number", typeof
1693                                 (int), "", MappingType.Attribute));
1694                         dt2.Columns ["Number"].AllowDBNull = false;
1695                         dt2.Columns ["Number"].ReadOnly = true;
1696
1697                         dt2.Columns.Add (new DataColumn ("Title", typeof
1698                                 (string), "", MappingType.Attribute));
1699                         dt2.Columns ["Title"].AllowDBNull = false;
1700
1701                         dt2.Constraints.Add ("PK_Dimension", dt2.Columns ["Number"], true);
1702
1703                         DataTable dt3 = new DataTable ("Element");
1704                         ds.Tables.Add(dt3);
1705                         
1706                         dt3.Columns.Add (new DataColumn ("Dimension", typeof
1707                                 (int), "", MappingType.Attribute));
1708                         dt3.Columns ["Dimension"].AllowDBNull = false;
1709                         dt3.Columns ["Dimension"].ReadOnly = true;
1710
1711                         dt3.Columns.Add (new DataColumn ("Number", typeof
1712                                 (int), "", MappingType.Attribute));
1713                         dt3.Columns ["Number"].AllowDBNull = false;
1714                         dt3.Columns ["Number"].ReadOnly = true;
1715
1716                         dt3.Columns.Add (new DataColumn ("Title", typeof
1717                                 (string), "", MappingType.Attribute));
1718                         dt3.Columns ["Title"].AllowDBNull = false;
1719
1720                         dt3.Constraints.Add ("PK_Element", new DataColumn[] { 
1721                                 dt3.Columns ["Dimension"],
1722                                 dt3.Columns ["Number"] }, true);
1723
1724                         ds.Relations.Add ("FK_Element_To_Dimension",
1725                                 dt2.Columns ["Number"], dt3.Columns["Dimension"]);
1726
1727                         ds.AcceptChanges ();
1728
1729                         StringWriter sw = new StringWriter ();
1730                         ds.WriteXmlSchema (sw);
1731
1732                         string result = sw.ToString ();
1733
1734                         Assert.AreEqual (result.Replace ("\r\n", "\n"), xmlschema.Replace ("\r\n", "\n"));
1735                 }
1736
1737                 // bug #67793
1738                 [Test]
1739                 public void WriteXmlSchema6 ()
1740                 {
1741                         string xmlschema = @"<?xml version=""1.0"" encoding=""utf-16""?>
1742 <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
1743 "+
1744                           @"  <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:UseCurrentLocale=""true"""
1745                           + @">
1746     <xs:complexType>
1747       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
1748         <xs:element name=""MyType"">
1749           <xs:complexType>
1750             <xs:attribute name=""Desc"">
1751               <xs:simpleType>
1752                 <xs:restriction base=""xs:string"">
1753                   <xs:maxLength value=""32"" />
1754                 </xs:restriction>
1755               </xs:simpleType>
1756             </xs:attribute>
1757           </xs:complexType>
1758         </xs:element>
1759       </xs:choice>
1760     </xs:complexType>
1761   </xs:element>
1762 </xs:schema>";
1763                         DataSet ds = new DataSet("Example");
1764
1765                         // Add MyType DataTable
1766                         ds.Tables.Add ("MyType");
1767
1768                         ds.Tables ["MyType"].Columns.Add (new DataColumn(
1769                                 "Desc", typeof (string), "", MappingType.Attribute));
1770                         ds.Tables ["MyType"].Columns ["Desc"].MaxLength = 32;
1771
1772                         ds.AcceptChanges ();
1773
1774                         StringWriter sw = new StringWriter ();
1775                         ds.WriteXmlSchema (sw);
1776
1777                         string result = sw.ToString ();
1778
1779                         Assert.AreEqual (result.Replace ("\r\n", "\n"), xmlschema.Replace ("\r\n", "\n"));
1780                 }
1781
1782                 // bug #68008
1783                 [Test]
1784                 public void WriteXmlSchema7 ()
1785                 {
1786                         DataSet ds = new DataSet ();
1787                         DataTable dt = new DataTable ("table");
1788                         dt.Columns.Add ("col1");
1789                         dt.Columns.Add ("col2");
1790                         ds.Tables.Add (dt);
1791                         dt.Rows.Add (new object [] {"foo", "bar"});
1792                         StringWriter sw = new StringWriter ();
1793                         ds.WriteXmlSchema (sw);
1794                         Assert.IsTrue (sw.ToString ().IndexOf ("xmlns=\"\"") > 0);
1795                 }
1796
1797                 // bug #61233
1798                 [Test]
1799                 public void WriteXmlExtendedProperties ()
1800                 {
1801                         string xml = @"<?xml version=""1.0"" encoding=""utf-16""?>
1802 <xs:schema id=""NewDataSet"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"" xmlns:msprop=""urn:schemas-microsoft-com:xml-msprop"">
1803 " +
1804 @"  <xs:element name=""NewDataSet"" msdata:IsDataSet=""true"" msdata:UseCurrentLocale=""true"" msprop:version=""version 2.1"">"
1805                           + @"
1806     <xs:complexType>
1807       <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
1808         <xs:element name=""Foo"">
1809           <xs:complexType>
1810             <xs:sequence>
1811               <xs:element name=""col1"" type=""xs:string"" minOccurs=""0"" />
1812             </xs:sequence>
1813           </xs:complexType>
1814         </xs:element>
1815       </xs:choice>
1816     </xs:complexType>
1817   </xs:element>
1818 </xs:schema>";
1819                         DataSet ds = new DataSet ();
1820                         ds.ExtendedProperties ["version"] = "version 2.1";
1821                         DataTable dt = new DataTable ("Foo");
1822                         dt.Columns.Add ("col1");
1823                         dt.Rows.Add (new object [] {"foo"});
1824                         ds.Tables.Add (dt);
1825
1826                         StringWriter sw = new StringWriter ();
1827                         ds.WriteXmlSchema (sw);
1828
1829                         string result = sw.ToString ();
1830
1831                         Assert.AreEqual (result.Replace ("\r\n", "\n"), xml.Replace ("\r\n", "\n"));
1832                 }
1833
1834                 [Test]
1835                 public void WriteXmlModeSchema ()
1836                 {
1837                         // This is the MS output of WriteXmlSchema().
1838
1839                         string xml = @"<Example>
1840   <xs:schema id=""Example"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
1841 " +
1842 @"    <xs:element name=""Example"" msdata:IsDataSet=""true"" msdata:UseCurrentLocale=""true"">"
1843                           + @"
1844       <xs:complexType>
1845         <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
1846           <xs:element name=""Dimension"">
1847             <xs:complexType>
1848               <xs:sequence>
1849                 <xs:element name=""Number"" type=""xs:int"" />
1850               </xs:sequence>
1851             </xs:complexType>
1852           </xs:element>
1853           <xs:element name=""Element"">
1854             <xs:complexType>
1855               <xs:sequence>
1856                 <xs:element name=""Dimension"" type=""xs:int"" />
1857                 <xs:element name=""Number"" type=""xs:int"" />
1858               </xs:sequence>
1859             </xs:complexType>
1860           </xs:element>
1861         </xs:choice>
1862       </xs:complexType>
1863       <xs:unique name=""PK_Dimension"" msdata:PrimaryKey=""true"">
1864         <xs:selector xpath="".//Dimension"" />
1865         <xs:field xpath=""Number"" />
1866       </xs:unique>
1867       <xs:unique name=""PK_Element"" msdata:PrimaryKey=""true"">
1868         <xs:selector xpath="".//Element"" />
1869         <xs:field xpath=""Dimension"" />
1870         <xs:field xpath=""Number"" />
1871       </xs:unique>
1872       <xs:keyref name=""FK_Element_To_Dimension"" refer=""PK_Dimension"">
1873         <xs:selector xpath="".//Element"" />
1874         <xs:field xpath=""Dimension"" />
1875       </xs:keyref>
1876     </xs:element>
1877   </xs:schema>
1878   <Dimension>
1879     <Number>0</Number>
1880   </Dimension>
1881   <Dimension>
1882     <Number>1</Number>
1883   </Dimension>
1884   <Element>
1885     <Dimension>0</Dimension>
1886     <Number>0</Number>
1887   </Element>
1888   <Element>
1889     <Dimension>0</Dimension>
1890     <Number>1</Number>
1891   </Element>
1892   <Element>
1893     <Dimension>0</Dimension>
1894     <Number>2</Number>
1895   </Element>
1896   <Element>
1897     <Dimension>0</Dimension>
1898     <Number>3</Number>
1899   </Element>
1900   <Element>
1901     <Dimension>1</Dimension>
1902     <Number>0</Number>
1903   </Element>
1904   <Element>
1905     <Dimension>1</Dimension>
1906     <Number>1</Number>
1907   </Element>
1908 </Example>";
1909                         DataSet ds = new DataSet("Example");
1910
1911                         // Dimension DataTable
1912                         DataTable dt1 = new DataTable ("Dimension");
1913                         ds.Tables.Add (dt1);
1914
1915                         dt1.Columns.Add (new DataColumn ("Number", typeof (int)));
1916                         dt1.Columns ["Number"].AllowDBNull = false;
1917
1918                         dt1.Constraints.Add ("PK_Dimension", dt1.Columns ["Number"], true);
1919
1920                         // Element DataTable
1921                         DataTable dt2 = new DataTable ("Element");
1922                         ds.Tables.Add (dt2);
1923
1924                         dt2.Columns.Add (new DataColumn ("Dimension", typeof (int)));
1925                         dt2.Columns ["Dimension"].AllowDBNull = false;
1926
1927                         dt2.Columns.Add (new DataColumn ("Number", typeof (int)));
1928                         dt2.Columns ["Number"].AllowDBNull = false;
1929
1930                         dt2.Constraints.Add ("PK_Element", new DataColumn[] {
1931                                 dt2.Columns ["Dimension"],
1932                                 dt2.Columns ["Number"] },
1933                                 true);
1934                         
1935                         // Add DataRelations
1936                         ds.Relations.Add ("FK_Element_To_Dimension",
1937                                 dt1.Columns ["Number"],
1938                                 dt2.Columns ["Dimension"], true);
1939
1940                         // Add 2 Dimensions
1941                         for (int i = 0; i < 2; i++) {
1942                                 DataRow newRow = dt1.NewRow ();
1943                                 newRow ["Number"] = i;
1944                                 dt1.Rows.Add (newRow);
1945                         }
1946
1947                         // Dimension 0 => 4 Elements
1948                         for (int i = 0; i < 4; i++) {
1949                                 DataRow newRow = dt2.NewRow();
1950                                 newRow ["Dimension"] = 0;
1951                                 newRow ["Number"] = i;
1952                                 dt2.Rows.Add (newRow);
1953                         }
1954
1955                         // Dimension 1 => 2 Elements
1956                         for (int i = 0; i < 2; i++) {
1957                                 DataRow newRow = dt2.NewRow();
1958                                 newRow ["Dimension"] = 1;
1959                                 newRow ["Number"] = i;
1960                                 dt2.Rows.Add (newRow);
1961                         }
1962
1963                         ds.AcceptChanges ();
1964
1965                         StringWriter sw = new StringWriter ();
1966                         ds.WriteXml(sw, XmlWriteMode.WriteSchema);
1967
1968                         string result = sw.ToString ();
1969
1970                         Assert.AreEqual (result.Replace ("\r\n", "\n"), xml.Replace ("\r\n", "\n"));
1971                 }
1972
1973                 [Test]
1974                 public void WriteXmlModeSchema1 () {
1975                         string SerializedDataTable =
1976 @"<rdData>
1977   <MyDataTable CustomerID='VINET' CompanyName='Vins et alcools Chevalier' ContactName='Paul Henriot' />
1978 </rdData>";
1979                         string expected =
1980 @"<rdData>
1981   <xs:schema id=""rdData"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"">
1982     <xs:element name=""rdData"" msdata:IsDataSet=""true"" " +
1983                           @"msdata:Locale=""en-US"">" +
1984 @"
1985       <xs:complexType>
1986         <xs:choice minOccurs=""0"" maxOccurs=""unbounded"">
1987           <xs:element name=""MyDataTable"">
1988             <xs:complexType>
1989               <xs:attribute name=""CustomerID"" type=""xs:string"" />
1990               <xs:attribute name=""CompanyName"" type=""xs:string"" />
1991               <xs:attribute name=""ContactName"" type=""xs:string"" />
1992             </xs:complexType>
1993           </xs:element>
1994         </xs:choice>
1995       </xs:complexType>
1996     </xs:element>
1997   </xs:schema>
1998   <MyDataTable CustomerID=""VINET"" CompanyName=""Vins et alcools Chevalier"" ContactName=""Paul Henriot"" />
1999 </rdData>";
2000                         DataSet set;
2001                         set = new DataSet ();
2002                         set.ReadXml (new StringReader (SerializedDataTable));
2003
2004                         StringWriter w = new StringWriter ();
2005                         set.WriteXml (w, XmlWriteMode.WriteSchema);
2006                         string result = w.ToString ();
2007                         Assert.AreEqual (expected.Replace ("\r", ""), result.Replace ("\r", ""));
2008                 }
2009
2010                 [Test]
2011                 public void DeserializeModifiedDataSet ()
2012                 {
2013                         // Serialization begins
2014                         DataSet prevDs = new DataSet ();
2015                         DataTable dt = prevDs.Tables.Add ();
2016                         dt.Columns.Add(new DataColumn("Id", typeof(string)));
2017                                                                                                                              
2018                         DataRow dr = dt.NewRow();
2019                         dr [0] = "a";
2020                         dt.Rows.Add (dr);
2021                         prevDs.AcceptChanges ();
2022                         dr = prevDs.Tables[0].Rows[0];
2023                         dr [0] = "b";
2024                                                                                                                              
2025                         XmlSerializer serializer = new XmlSerializer (typeof (DataSet));
2026                         StringWriter sw = new StringWriter ();
2027                         XmlTextWriter xw = new XmlTextWriter (sw);
2028                         xw.QuoteChar = '\'';
2029                         serializer.Serialize (xw, prevDs);
2030
2031                         // Deserialization begins
2032                         StringReader sr = new StringReader (sw.ToString ());
2033                         XmlTextReader reader = new XmlTextReader (sr);
2034                         XmlSerializer serializer1 = new XmlSerializer (typeof (DataSet));
2035                         DataSet ds = serializer1.Deserialize (reader) as DataSet;
2036                         Assert.AreEqual (
2037                                 prevDs.Tables[0].Rows [0][0,DataRowVersion.Original].ToString (), 
2038                                 ds.Tables[0].Rows [0][0,DataRowVersion.Original].ToString (),
2039                                 "deserialization after modification does not give original values");
2040                         Assert.AreEqual (
2041                                 prevDs.Tables[0].Rows [0][0,DataRowVersion.Current].ToString (), 
2042                                 ds.Tables[0].Rows [0][0,DataRowVersion.Current].ToString (),
2043                                 "deserialization after modification oes not give current values");
2044                 }
2045
2046                 [Test]
2047                 public void Bug420862 ()
2048                 {
2049                         DataSet ds = new DataSet ("d");
2050                         DataTable dt = ds.Tables.Add ("t");
2051                         dt.Columns.Add ("c", typeof (ushort));
2052
2053                         XmlSchema xs = XmlSchema.Read (new StringReader (ds.GetXmlSchema ()), null);
2054                         xs.Compile (null);
2055
2056                         // follow the nesting of the schema in the foreach
2057                         foreach (XmlSchemaElement d in xs.Items) {
2058                                 Assert.AreEqual ("d", d.Name);
2059                                 XmlSchemaChoice dsc = (XmlSchemaChoice) ((XmlSchemaComplexType) d.SchemaType).Particle;
2060                                 foreach (XmlSchemaElement t in dsc.Items) {
2061                                         Assert.AreEqual ("t", t.Name);
2062                                         XmlSchemaSequence tss = (XmlSchemaSequence) ((XmlSchemaComplexType) t.SchemaType).Particle;
2063                                         foreach (XmlSchemaElement c in tss.Items) {
2064                                                 Assert.AreEqual ("c", c.Name);
2065                                                 Assert.AreEqual ("unsignedShort", c.SchemaTypeName.Name);
2066                                                 return;
2067                                         }
2068                                 }
2069                         }
2070                         Assert.Fail ();
2071                 }
2072
2073                 /// <summary>
2074                 /// Test for testing DataSet.Clear method with foriegn key relations
2075                 /// This is expected to clear all the related datatable rows also
2076                 /// </summary>
2077                 [Test]
2078                 public void DataSetClearTest ()
2079                 {
2080                         DataSet ds = new DataSet ();
2081                         DataTable parent = ds.Tables.Add ("Parent");
2082                         DataTable child = ds.Tables.Add ("Child");
2083                         
2084                         parent.Columns.Add ("id", typeof (int));
2085                         child.Columns.Add ("ref_id", typeof(int));
2086                         
2087                         child.Constraints.Add (new ForeignKeyConstraint ("fk_constraint", parent.Columns [0], child.Columns [0]));
2088                         
2089                         DataRow dr = parent.NewRow ();
2090                         dr [0] = 1;
2091                         parent.Rows.Add (dr);
2092                         dr.AcceptChanges ();
2093                         
2094                         dr = child.NewRow ();
2095                         dr [0] = 1;
2096                         child.Rows.Add (dr);
2097                         dr.AcceptChanges ();
2098                         
2099                         try {
2100                                 ds.Clear (); // this should clear all the rows in parent & child tables
2101                         } catch (Exception e) {
2102                                 throw (new Exception ("Exception should not have been thrown at Clear method" + e.ToString ()));
2103                         }
2104                         Assert.AreEqual (0, parent.Rows.Count, "parent table rows should not exist!");
2105                         Assert.AreEqual (0, child.Rows.Count, "child table rows should not exist!");
2106                 }
2107
2108                 [Test]
2109                 public void CloneSubClassTest()
2110                 {
2111                         MyDataSet ds1 = new MyDataSet();
2112                         MyDataSet ds = (MyDataSet)(ds1.Clone());
2113                         Assert.AreEqual (2, MyDataSet.count, "A#01");
2114                 }
2115
2116                 #region DataSet.GetChanges Tests
2117                 public void GetChanges_Relations_DifferentRowStatesTest ()
2118                 {
2119                         DataSet ds = new DataSet ("ds");
2120                         DataTable parent = ds.Tables.Add ("parent");
2121                         DataTable child = ds.Tables.Add ("child");
2122                         
2123                         parent.Columns.Add ("id", typeof (int));
2124                         parent.Columns.Add ("name", typeof (string));
2125                         
2126
2127                         child.Columns.Add ("id", typeof (int));
2128                         child.Columns.Add ("parent", typeof (int));
2129                         child.Columns.Add ("name", typeof (string));
2130
2131                         parent.Rows.Add (new object [] { 1, "mono parent 1" } );
2132                         parent.Rows.Add (new object [] { 2, "mono parent 2" } );
2133                         parent.Rows.Add (new object [] { 3, "mono parent 3" } );
2134                         parent.Rows.Add (new object [] { 4, "mono parent 4" } );
2135                         parent.AcceptChanges ();
2136
2137                         child.Rows.Add (new object [] { 1, 1, "mono child 1" } );
2138                         child.Rows.Add (new object [] { 2, 2, "mono child 2" } );
2139                         child.Rows.Add (new object [] { 3, 3, "mono child 3" } );
2140                         child.AcceptChanges ();
2141
2142                         DataRelation relation = ds.Relations.Add ("parent_child", 
2143                                                                   parent.Columns ["id"],
2144                                                                   child.Columns ["parent"]);
2145                         
2146                         // modify the parent and get changes
2147                         child.Rows [1]["parent"] = 4;
2148                         DataSet changes = ds.GetChanges ();
2149                         DataRow row = changes.Tables ["parent"].Rows[0];
2150                         Assert.AreEqual ((int) parent.Rows [3][0], (int) row [0], "#RT1");
2151                         Assert.AreEqual (1, changes.Tables ["parent"].Rows.Count, "#RT2 only get parent row with current version");
2152                         ds.RejectChanges ();
2153
2154                         // delete a child row and get changes.
2155                         child.Rows [0].Delete ();
2156                         changes = ds.GetChanges ();
2157                         
2158                         Assert.AreEqual (changes.Tables.Count, 2, "#RT3 Should import parent table as well");
2159                         Assert.AreEqual (1, changes.Tables ["parent"].Rows.Count, "#RT4 only get parent row with original version");
2160                         Assert.AreEqual (1, (int) changes.Tables ["parent"].Rows [0][0], "#RT5 parent row based on original version");
2161                 }
2162                 #endregion // DataSet.GetChanges Tests
2163
2164                 [Test]
2165                 public void RuleTest ()
2166                 {
2167                         DataSet ds = new DataSet ("testds");
2168                         DataTable parent = ds.Tables.Add ("parent");
2169                         DataTable child = ds.Tables.Add ("child");
2170                         
2171                         parent.Columns.Add ("id", typeof (int));
2172                         parent.Columns.Add ("name", typeof (string));
2173                         parent.PrimaryKey = new DataColumn [] {parent.Columns ["id"]} ;
2174
2175                         child.Columns.Add ("id", typeof (int));
2176                         child.Columns.Add ("parent", typeof (int));
2177                         child.Columns.Add ("name", typeof (string));
2178                         child.PrimaryKey = new DataColumn [] {child.Columns ["id"]} ;
2179
2180                         DataRelation relation = ds.Relations.Add ("parent_child", 
2181                                                                   parent.Columns ["id"],
2182                                                                   child.Columns ["parent"]);
2183
2184                         parent.Rows.Add (new object [] {1, "mono test 1"});
2185                         parent.Rows.Add (new object [] {2, "mono test 2"});
2186                         parent.Rows.Add (new object [] {3, "mono test 3"});
2187                         
2188                         child.Rows.Add (new object [] {1, 1, "mono child test 1"});
2189                         child.Rows.Add (new object [] {2, 2, "mono child test 2"});
2190                         child.Rows.Add (new object [] {3, 3, "mono child test 3"});
2191                         
2192                         ds.AcceptChanges ();
2193                         
2194                         parent.Rows [0] ["name"] = "mono changed test 1";
2195                         
2196                         Assert.AreEqual (DataRowState.Unchanged, parent.Rows [0].GetChildRows (relation) [0].RowState,
2197                                          "#RT1 child should not be modified");
2198
2199                         ds.RejectChanges ();
2200                         parent.Rows [0] ["id"] = "4";
2201
2202                         DataRow childRow =  parent.Rows [0].GetChildRows (relation) [0];
2203                         Assert.AreEqual (DataRowState.Modified, childRow.RowState, "#RT2 child should be modified");
2204                         Assert.AreEqual (4, (int) childRow ["parent"], "#RT3 child should point to modified row");
2205                 }
2206
2207                 [Test] // from bug #76480
2208                 public void WriteXmlEscapeName ()
2209                 {
2210                         // create dataset
2211                         DataSet data = new DataSet();
2212
2213                         DataTable mainTable = data.Tables.Add ("main");
2214                         DataColumn mainkey = mainTable.Columns.Add ("mainkey", typeof(Guid));
2215                         mainTable.Columns.Add ("col.2<hi/>", typeof (string));
2216                         mainTable.Columns.Add ("#col3", typeof (string));
2217
2218                         // populate data
2219                         mainTable.Rows.Add (new object [] { Guid.NewGuid (), "hi there", "my friend" } );
2220                         mainTable.Rows.Add (new object [] { Guid.NewGuid (), "what is", "your name" } );
2221                         mainTable.Rows.Add (new object [] { Guid.NewGuid (), "I have", "a bean" } );
2222
2223                         // write xml
2224                         StringWriter writer = new StringWriter ();
2225                         data.WriteXml (writer, XmlWriteMode.WriteSchema);
2226                         string xml = writer.ToString ();
2227                         Assert.IsTrue (xml.IndexOf ("name=\"col.2_x003C_hi_x002F__x003E_\"") > 0, "#1");
2228                         Assert.IsTrue (xml.IndexOf ("name=\"_x0023_col3\"") > 0, "#2");
2229                         Assert.IsTrue (xml.IndexOf ("<col.2_x003C_hi_x002F__x003E_>hi there</col.2_x003C_hi_x002F__x003E_>") > 0, "#3");
2230
2231                         // read xml
2232                         DataSet data2 = new DataSet();
2233                         data2.ReadXml (new StringReader (
2234                                 writer.GetStringBuilder ().ToString ()));
2235                 }
2236
2237
2238                 // it is basically a test for XmlSerializer, but I need it
2239                 // here to not add dependency on sys.data.dll in sys.xml test.
2240                 [Test]
2241                 public void ReflectTypedDataSet ()
2242                 {
2243                         XmlReflectionImporter imp = new XmlReflectionImporter ();
2244                         // it used to cause "missing GetDataSetSchema" error.
2245                         imp.ImportTypeMapping (typeof (MonkeyDataSet));
2246                 }
2247
2248                 #region DataSet.CreateDataReader Tests and DataSet.Load Tests
2249
2250                 private DataSet ds;
2251                 private DataTable dt1, dt2;
2252
2253                 private void localSetup () {
2254                         ds = new DataSet ("test");
2255                         dt1 = new DataTable ("test1");
2256                         dt1.Columns.Add ("id1", typeof (int));
2257                         dt1.Columns.Add ("name1", typeof (string));
2258                         //dt1.PrimaryKey = new DataColumn[] { dt1.Columns["id"] };
2259                         dt1.Rows.Add (new object[] { 1, "mono 1" });
2260                         dt1.Rows.Add (new object[] { 2, "mono 2" });
2261                         dt1.Rows.Add (new object[] { 3, "mono 3" });
2262                         dt1.AcceptChanges ();
2263                         dt2 = new DataTable ("test2");
2264                         dt2.Columns.Add ("id2", typeof (int));
2265                         dt2.Columns.Add ("name2", typeof (string));
2266                         dt2.Columns.Add ("name3", typeof (string));
2267                         //dt2.PrimaryKey = new DataColumn[] { dt2.Columns["id"] };
2268                         dt2.Rows.Add (new object[] { 4, "mono 4", "four" });
2269                         dt2.Rows.Add (new object[] { 5, "mono 5", "five" });
2270                         dt2.Rows.Add (new object[] { 6, "mono 6", "six" });
2271                         dt2.AcceptChanges ();
2272                         ds.Tables.Add (dt1);
2273                         ds.Tables.Add (dt2);
2274                         ds.AcceptChanges ();
2275                 }
2276
2277                 [Test]
2278                 public void CreateDataReader1 () {
2279                         // For First CreateDataReader Overload
2280                         localSetup ();
2281                         DataTableReader dtr = ds.CreateDataReader ();
2282                         Assert.IsTrue (dtr.HasRows, "HasRows");
2283                         int ti = 0;
2284                         do {
2285                                 Assert.AreEqual (ds.Tables[ti].Columns.Count, dtr.FieldCount, "CountCols-" + ti);
2286                                 int ri = 0;
2287                                 while (dtr.Read ()) {
2288                                         for (int i = 0; i < dtr.FieldCount; i++)
2289                                                 Assert.AreEqual (ds.Tables[ti].Rows[ri][i], dtr[i], "RowData-"+ti+"-"+ri+"-"+i);
2290                                         ri++;
2291                                 }
2292                                 ti++;
2293                         } while (dtr.NextResult ());
2294                 }
2295
2296                 [Test]
2297                 public void CreateDataReader2 () {
2298                         // For Second CreateDataReader Overload -
2299                         // compare to ds.Tables
2300                         localSetup ();
2301                         DataTableReader dtr = ds.CreateDataReader (dt1, dt2);
2302                         Assert.IsTrue (dtr.HasRows, "HasRows");
2303                         int ti = 0;
2304                         do {
2305                                 Assert.AreEqual (ds.Tables[ti].Columns.Count, dtr.FieldCount, "CountCols-" + ti);
2306                                 int ri = 0;
2307                                 while (dtr.Read ()) {
2308                                         for (int i = 0; i < dtr.FieldCount; i++)
2309                                                 Assert.AreEqual (ds.Tables[ti].Rows[ri][i], dtr[i], "RowData-" + ti + "-" + ri + "-" + i);
2310                                         ri++;
2311                                 }
2312                                 ti++;
2313                         } while (dtr.NextResult ());
2314                 }
2315
2316                 [Test]
2317                 public void CreateDataReader3 () {
2318                         // For Second CreateDataReader Overload -
2319                         // compare to dt1 and dt2
2320                         localSetup ();
2321                         ds.Tables.Clear ();
2322                         DataTableReader dtr = ds.CreateDataReader (dt1, dt2);
2323                         Assert.IsTrue (dtr.HasRows, "HasRows");
2324                         string name = "dt1";
2325                         DataTable dtn = dt1;
2326                         do {
2327                                 Assert.AreEqual (dtn.Columns.Count, dtr.FieldCount, "CountCols-" + name);
2328                                 int ri = 0;
2329                                 while (dtr.Read ()) {
2330                                         for (int i = 0; i < dtr.FieldCount; i++)
2331                                                 Assert.AreEqual (dtn.Rows[ri][i], dtr[i], "RowData-" + name + "-" + ri + "-" + i);
2332                                         ri++;
2333                                 }
2334                                 if (dtn == dt1) {
2335                                         dtn = dt2;
2336                                         name = "dt2";
2337                                 } else {
2338                                         dtn = null;
2339                                         name = null;
2340                                 }
2341                         } while (dtr.NextResult ());
2342                 }
2343
2344                 [Test]
2345                 [ExpectedException (typeof (ArgumentException))]
2346                 public void CreateDataReaderNoTable () {
2347                         DataSet dsr = new DataSet ();
2348                         DataTableReader dtr = dsr.CreateDataReader ();
2349                 }
2350
2351                 internal struct fillErrorStruct {
2352                         internal string error;
2353                         internal string tableName;
2354                         internal int rowKey;
2355                         internal bool contFlag;
2356                         internal void init (string tbl, int row, bool cont, string err) {
2357                                 tableName = tbl;
2358                                 rowKey = row;
2359                                 contFlag = cont;
2360                                 error = err;
2361                         }
2362                 }
2363                 private fillErrorStruct[] fillErr = new fillErrorStruct[3];
2364                 private int fillErrCounter;
2365                 private void fillErrorHandler (object sender, FillErrorEventArgs e) {
2366                         e.Continue = fillErr[fillErrCounter].contFlag;
2367                         Assert.AreEqual (fillErr[fillErrCounter].tableName, e.DataTable.TableName, "fillErr-T");
2368                         Assert.AreEqual (fillErr[fillErrCounter].contFlag, e.Continue, "fillErr-C");
2369                         fillErrCounter++;
2370                 }
2371
2372                 [Test]
2373                 public void Load_Basic () {
2374                         localSetup ();
2375                         DataSet dsLoad = new DataSet ("LoadBasic");
2376                         DataTable table1 = new DataTable ();
2377                         dsLoad.Tables.Add (table1);
2378                         DataTable table2 = new DataTable ();
2379                         dsLoad.Tables.Add (table2);
2380                         DataTableReader dtr = ds.CreateDataReader ();
2381                         dsLoad.Load (dtr, LoadOption.OverwriteChanges, table1, table2);
2382                         CompareTables (dsLoad);
2383                 }
2384
2385                 [Test]
2386                 [ExpectedException (typeof (ArgumentException))]
2387                 public void Load_TableUnknown () {
2388                         localSetup ();
2389                         DataSet dsLoad = new DataSet ("LoadTableUnknown");
2390                         DataTable table1 = new DataTable ();
2391                         dsLoad.Tables.Add (table1);
2392                         DataTable table2 = new DataTable ();
2393                         // table2 is not added to dsLoad [dsLoad.Tables.Add (table2);]
2394                         DataTableReader dtr = ds.CreateDataReader ();
2395                         dsLoad.Load (dtr, LoadOption.OverwriteChanges, table1, table2);
2396                 }
2397
2398                 [Test]
2399                 public void Load_TableConflictT () {
2400                         fillErrCounter = 0;
2401                         fillErr[0].init ("Table1", 1, true,
2402                                 "Input string was not in a correct format.Couldn't store <mono 1> in name1 Column.  Expected type is Double.");
2403                         fillErr[1].init ("Table1", 2, true,
2404                                 "Input string was not in a correct format.Couldn't store <mono 2> in name1 Column.  Expected type is Double.");
2405                         fillErr[2].init ("Table1", 3, true,
2406                                 "Input string was not in a correct format.Couldn't store <mono 3> in name1 Column.  Expected type is Double.");
2407                         localSetup ();
2408                         DataSet dsLoad = new DataSet ("LoadTableConflict");
2409                         DataTable table1 = new DataTable ();
2410                         table1.Columns.Add ("name1", typeof (double));
2411                         dsLoad.Tables.Add (table1);
2412                         DataTable table2 = new DataTable ();
2413                         dsLoad.Tables.Add (table2);
2414                         DataTableReader dtr = ds.CreateDataReader ();
2415                         dsLoad.Load (dtr, LoadOption.PreserveChanges,
2416                                      fillErrorHandler, table1, table2);
2417                 }
2418                 [Test]
2419                 [ExpectedException (typeof (ArgumentException))]
2420                 public void Load_TableConflictF () {
2421                         fillErrCounter = 0;
2422                         fillErr[0].init ("Table1", 1, false,
2423                                 "Input string was not in a correct format.Couldn't store <mono 1> in name1 Column.  Expected type is Double.");
2424                         localSetup ();
2425                         DataSet dsLoad = new DataSet ("LoadTableConflict");
2426                         DataTable table1 = new DataTable ();
2427                         table1.Columns.Add ("name1", typeof (double));
2428                         dsLoad.Tables.Add (table1);
2429                         DataTable table2 = new DataTable ();
2430                         dsLoad.Tables.Add (table2);
2431                         DataTableReader dtr = ds.CreateDataReader ();
2432                         dsLoad.Load (dtr, LoadOption.Upsert,
2433                                      fillErrorHandler, table1, table2);
2434                 }
2435
2436                 [Test]
2437                 public void Load_StringsAsc () {
2438                         localSetup ();
2439                         DataSet dsLoad = new DataSet ("LoadStrings");
2440                         DataTable table1 = new DataTable ("First");
2441                         dsLoad.Tables.Add (table1);
2442                         DataTable table2 = new DataTable ("Second");
2443                         dsLoad.Tables.Add (table2);
2444                         DataTableReader dtr = ds.CreateDataReader ();
2445                         dsLoad.Load (dtr, LoadOption.OverwriteChanges, "First", "Second");
2446                         CompareTables (dsLoad);
2447                 }
2448
2449                 [Test]
2450                 public void Load_StringsDesc () {
2451                         localSetup ();
2452                         DataSet dsLoad = new DataSet ("LoadStrings");
2453                         DataTable table1 = new DataTable ("First");
2454                         dsLoad.Tables.Add (table1);
2455                         DataTable table2 = new DataTable ("Second");
2456                         dsLoad.Tables.Add (table2);
2457                         DataTableReader dtr = ds.CreateDataReader ();
2458                         dsLoad.Load (dtr, LoadOption.PreserveChanges, "Second", "First");
2459                         Assert.AreEqual (2, dsLoad.Tables.Count, "Tables");
2460                         Assert.AreEqual (3, dsLoad.Tables[0].Rows.Count, "T1-Rows");
2461                         Assert.AreEqual (3, dsLoad.Tables[0].Columns.Count, "T1-Columns");
2462                         Assert.AreEqual (3, dsLoad.Tables[1].Rows.Count, "T2-Rows");
2463                         Assert.AreEqual (2, dsLoad.Tables[1].Columns.Count, "T2-Columns");
2464                 }
2465
2466                 [Test]
2467                 public void Load_StringsNew () {
2468                         localSetup ();
2469                         DataSet dsLoad = new DataSet ("LoadStrings");
2470                         DataTable table1 = new DataTable ("First");
2471                         dsLoad.Tables.Add (table1);
2472                         DataTable table2 = new DataTable ("Second");
2473                         dsLoad.Tables.Add (table2);
2474                         DataTableReader dtr = ds.CreateDataReader ();
2475                         dsLoad.Load (dtr, LoadOption.Upsert, "Third", "Fourth");
2476                         Assert.AreEqual (4, dsLoad.Tables.Count, "Tables");
2477                         Assert.AreEqual ("First", dsLoad.Tables[0].TableName, "T1-Name");
2478                         Assert.AreEqual (0, dsLoad.Tables[0].Rows.Count, "T1-Rows");
2479                         Assert.AreEqual (0, dsLoad.Tables[0].Columns.Count, "T1-Columns");
2480                         Assert.AreEqual ("Second", dsLoad.Tables[1].TableName, "T2-Name");
2481                         Assert.AreEqual (0, dsLoad.Tables[1].Rows.Count, "T2-Rows");
2482                         Assert.AreEqual (0, dsLoad.Tables[1].Columns.Count, "T2-Columns");
2483                         Assert.AreEqual ("Third", dsLoad.Tables[2].TableName, "T3-Name");
2484                         Assert.AreEqual (3, dsLoad.Tables[2].Rows.Count, "T3-Rows");
2485                         Assert.AreEqual (2, dsLoad.Tables[2].Columns.Count, "T3-Columns");
2486                         Assert.AreEqual ("Fourth", dsLoad.Tables[3].TableName, "T4-Name");
2487                         Assert.AreEqual (3, dsLoad.Tables[3].Rows.Count, "T4-Rows");
2488                         Assert.AreEqual (3, dsLoad.Tables[3].Columns.Count, "T4-Columns");
2489                 }
2490
2491                 [Test]
2492                 public void Load_StringsNewMerge () {
2493                         localSetup ();
2494                         DataSet dsLoad = new DataSet ("LoadStrings");
2495                         DataTable table1 = new DataTable ("First");
2496                         table1.Columns.Add ("col1", typeof (string));
2497                         table1.Rows.Add (new object[] { "T1Row1" });
2498                         dsLoad.Tables.Add (table1);
2499                         DataTable table2 = new DataTable ("Second");
2500                         table2.Columns.Add ("col2", typeof (string));
2501                         table2.Rows.Add (new object[] { "T2Row1" });
2502                         table2.Rows.Add (new object[] { "T2Row2" });
2503                         dsLoad.Tables.Add (table2);
2504                         DataTableReader dtr = ds.CreateDataReader ();
2505                         dsLoad.Load (dtr, LoadOption.OverwriteChanges, "Third", "First");
2506                         Assert.AreEqual (3, dsLoad.Tables.Count, "Tables");
2507                         Assert.AreEqual ("First", dsLoad.Tables[0].TableName, "T1-Name");
2508                         Assert.AreEqual (4, dsLoad.Tables[0].Rows.Count, "T1-Rows");
2509                         Assert.AreEqual (4, dsLoad.Tables[0].Columns.Count, "T1-Columns");
2510                         Assert.AreEqual ("Second", dsLoad.Tables[1].TableName, "T2-Name");
2511                         Assert.AreEqual (2, dsLoad.Tables[1].Rows.Count, "T2-Rows");
2512                         Assert.AreEqual (1, dsLoad.Tables[1].Columns.Count, "T2-Columns");
2513                         Assert.AreEqual ("Third", dsLoad.Tables[2].TableName, "T3-Name");
2514                         Assert.AreEqual (3, dsLoad.Tables[2].Rows.Count, "T3-Rows");
2515                         Assert.AreEqual (2, dsLoad.Tables[2].Columns.Count, "T3-Columns");
2516                 }
2517
2518                 [Test]
2519                 public void ReadDiff ()
2520                 {
2521                         DataSet dsTest = new DataSet ("MonoTouchTest");
2522                         var dt = new DataTable ("123");
2523                         dt.Columns.Add (new DataColumn ("Value1"));
2524                         dt.Columns.Add (new DataColumn ("Value2"));
2525                         dsTest.Tables.Add (dt);
2526                         dsTest.ReadXml (new StringReader (@"
2527 <diffgr:diffgram
2528    xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'
2529    xmlns:diffgr='urn:schemas-microsoft-com:xml-diffgram-v1'>
2530   <MonoTouchTest>
2531     <_x0031_23 diffgr:id='1231' msdata:rowOrder='0'>
2532       <Value1>Row1Value1</Value1>
2533       <Value2>Row1Value2</Value2>
2534     </_x0031_23>
2535   </MonoTouchTest>
2536 </diffgr:diffgram>
2537 "));
2538                         Assert.AreEqual ("123", dsTest.Tables [0].TableName, "#1");
2539                         Assert.AreEqual (1, dsTest.Tables [0].Rows.Count, "#2");
2540                 }
2541
2542                 private void CompareTables (DataSet dsLoad) {
2543                         Assert.AreEqual (ds.Tables.Count, dsLoad.Tables.Count, "NumTables");
2544                         for (int tc = 0; tc < dsLoad.Tables.Count; tc++) {
2545                                 Assert.AreEqual (ds.Tables[tc].Columns.Count, dsLoad.Tables[tc].Columns.Count, "Table" + tc + "-NumCols");
2546                                 Assert.AreEqual (ds.Tables[tc].Rows.Count, dsLoad.Tables[tc].Rows.Count, "Table" + tc + "-NumRows");
2547                                 for (int cc = 0; cc < dsLoad.Tables[tc].Columns.Count; cc++) {
2548                                         Assert.AreEqual (ds.Tables[tc].Columns[cc].ColumnName,
2549                                                          dsLoad.Tables[tc].Columns[cc].ColumnName,
2550                                                          "Table" + tc + "-" + "Col" + cc + "-Name");
2551                                 }
2552                                 for (int rc = 0; rc < dsLoad.Tables[tc].Rows.Count; rc++) {
2553                                         for (int cc = 0; cc < dsLoad.Tables[tc].Columns.Count; cc++) {
2554                                                 Assert.AreEqual (ds.Tables[tc].Rows[rc].ItemArray[cc],
2555                                                                  dsLoad.Tables[tc].Rows[rc].ItemArray[cc],
2556                                                                  "Table" + tc + "-Row" + rc + "-Col" + cc + "-Data");
2557                                         }
2558                                 }
2559                         }
2560                 }
2561
2562                 #endregion // DataSet.CreateDataReader Tests and DataSet.Load Tests
2563
2564         }
2565
2566          public  class MyDataSet:DataSet {
2567
2568              public static int count = 0;
2569                                                                                                     
2570              public MyDataSet() {
2571
2572                     count++;
2573              }
2574                                                                                                     
2575          }
2576         
2577
2578 }