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