Merge branch 'bugfix-main-thread-root'
[mono.git] / mcs / class / Managed.Windows.Forms / Test / System.Resources / ResXResourceReaderTest.cs
1 //
2 // ResXResourceReaderTest.cs: Unit Tests for ResXResourceReader.
3 //
4 // Authors:
5 //     Gert Driesen <drieseng@users.sourceforge.net>
6 //     Olivier Dufour <olivier.duff@gmail.com>
7 //
8
9 using System;
10 using System.Collections;
11 using System.Drawing;
12 using System.Globalization;
13 using System.IO;
14 using System.Resources;
15 using System.Text;
16 using System.Windows.Forms;
17 using System.Xml;
18
19 using NUnit.Framework;
20 using System.Reflection;
21
22 namespace MonoTests.System.Resources
23 {
24         [TestFixture]
25         public class ResXResourceReaderTest : MonoTests.System.Windows.Forms.TestHelper
26         {
27                 private string _tempDirectory;
28                 private string _otherTempDirectory;
29
30                 [SetUp]
31                 protected override void SetUp ()
32                 {
33                         _tempDirectory = Path.Combine (Path.GetTempPath (), "ResXResourceReaderTest");
34                         _otherTempDirectory = Path.Combine (_tempDirectory, "in");
35                         if (!Directory.Exists (_otherTempDirectory)) {
36                                 Directory.CreateDirectory (_otherTempDirectory);
37                         }
38                         base.SetUp ();
39                 }
40
41                 [TearDown]
42                 protected override void TearDown ()
43                 {
44                         if (Directory.Exists (_tempDirectory))
45                                 Directory.Delete (_tempDirectory, true);
46                         base.TearDown ();
47                 }
48
49                 [Test] // ctor (Stream)
50                 public void Constructor1_Stream_InvalidContent ()
51                 {
52                         MemoryStream ms = new MemoryStream ();
53                         ms.WriteByte (byte.MaxValue);
54                         ms.Position = 0;
55                         ResXResourceReader r = new ResXResourceReader (ms);
56                         try {
57                                 r.GetEnumerator ();
58                                 Assert.Fail ("#1");
59                         } catch (ArgumentException ex) {
60                                 // Invalid ResX input
61                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
62                                 Assert.IsNotNull (ex.Message, "#3");
63                                 Assert.IsNull (ex.ParamName, "#4");
64                                 Assert.IsNotNull (ex.InnerException, "#5");
65                         }
66                 }
67
68                 [Test] // ctor (Stream)
69                 [Category ("NotDotNet")] // MS throws a NullReferenceException in GetEnumerator ()
70                 public void Constructor1_Stream_Null ()
71                 {
72                         try {
73                                 new ResXResourceReader ((Stream) null);
74                                 Assert.Fail ("#1");
75                         } catch (ArgumentNullException ex) {
76                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
77                                 Assert.IsNull (ex.InnerException, "#3");
78                                 Assert.IsNotNull (ex.Message, "#4");
79                                 Assert.AreEqual ("stream", ex.ParamName, "#5");
80                         }
81                 }
82
83                 [Test] // ctor (String)
84                 public void Constructor2_FileName_DoesNotExist ()
85                 {
86                         ResXResourceReader r = new ResXResourceReader ((string) "definitelydoesnotexist.zzz");
87                         try {
88                                 r.GetEnumerator ();
89                                 Assert.Fail ("#1");
90                         } catch (FileNotFoundException ex) {
91                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#2");
92                                 Assert.IsNotNull (ex.FileName, "#3");
93                                 Assert.IsNotNull (ex.Message, "#4");
94                                 Assert.IsNull (ex.InnerException, "#5");
95                         }
96                 }
97
98                 [Test] // ctor (TextReader)
99                 public void Constructor3_Reader_InvalidContent ()
100                 {
101                         StringReader sr = new StringReader ("</definitelyinvalid<");
102                         ResXResourceReader r = new ResXResourceReader (sr);
103                         try {
104                                 r.GetEnumerator ();
105                                 Assert.Fail ("#1");
106                         } catch (ArgumentException ex) {
107                                 // Invalid ResX input
108                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
109                                 Assert.IsNotNull (ex.Message, "#3");
110                                 Assert.IsNull (ex.ParamName, "#4");
111                                 Assert.IsNotNull (ex.InnerException, "#5");
112                                 Assert.AreEqual (typeof (XmlException), ex.InnerException.GetType (), "#6");
113                         }
114                 }
115
116                 [Test]
117                 public void Close_FileName ()
118                 {
119                         string fileName = Path.Combine (Path.Combine ("Test", "System.Resources"), "compat_1_1.resx");
120                         if (!File.Exists (fileName))
121                                 fileName = String.Format ("..{0}System.Resources{0}compat_1_1.resx", Path.DirectorySeparatorChar);
122
123                         ResXResourceReader r1 = new ResXResourceReader (fileName);
124                         r1.GetEnumerator ();
125                         r1.Close ();
126                         r1.GetEnumerator ();
127
128                         ResXResourceReader r2 = new ResXResourceReader (fileName);
129                         r2.Close ();
130                         r2.GetEnumerator ();
131                         r2.Close ();
132                 }
133
134                 [Test]
135                 public void Close_Reader ()
136                 {
137                         string fileName = Path.Combine (Path.Combine ("Test", "System.Resources"), "compat_1_1.resx");
138                         if (!File.Exists (fileName))
139                                 fileName = String.Format ("..{0}System.Resources{0}compat_1_1.resx", Path.DirectorySeparatorChar);
140
141                         using (StreamReader sr = new StreamReader (fileName)) {
142                                 ResXResourceReader r = new ResXResourceReader (sr);
143                                 Assert.IsFalse (sr.Peek () == -1, "#A1");
144                                 r.GetEnumerator ();
145                                 Assert.IsTrue (sr.Peek () == -1, "#A2");
146                                 r.Close ();
147                                 try {
148                                         sr.Peek ();
149                                         Assert.Fail ("#A3");
150                                 } catch (ObjectDisposedException) {
151                                 }
152                                 r.GetEnumerator ();
153                         }
154
155                         using (StreamReader sr = new StreamReader (fileName)) {
156                                 ResXResourceReader r = new ResXResourceReader (sr);
157                                 r.Close ();
158                                 try {
159                                         sr.Peek ();
160                                         Assert.Fail ("#B1");
161                                 } catch (ObjectDisposedException) {
162                                 }
163                                 try {
164                                         r.GetEnumerator ();
165                                         Assert.Fail ("#B2");
166                                 } catch (NullReferenceException) { // MS
167                                 } catch (InvalidOperationException) { // Mono
168                                 }
169                         }
170                 }
171
172                 [Test]
173                 public void Close_Stream ()
174                 {
175                         string fileName = Path.Combine (Path.Combine ("Test", "System.Resources"), "compat_1_1.resx");
176                         if (!File.Exists (fileName))
177                                 fileName = String.Format ("..{0}System.Resources{0}compat_1_1.resx", Path.DirectorySeparatorChar);
178
179                         using (FileStream fs = File.OpenRead (fileName)) {
180                                 ResXResourceReader r = new ResXResourceReader (fs);
181                                 Assert.AreEqual (0, fs.Position, "#A1");
182                                 r.GetEnumerator ();
183                                 Assert.IsFalse (fs.Position == 0, "#A2");
184                                 Assert.IsTrue (fs.CanRead, "#A3");
185                                 r.Close ();
186                                 Assert.IsTrue (fs.CanRead, "#A4");
187                                 r.GetEnumerator ().MoveNext ();
188                         }
189
190                         using (FileStream fs = File.OpenRead (fileName)) {
191                                 ResXResourceReader r = new ResXResourceReader (fs);
192                                 r.Close ();
193                                 Assert.AreEqual (0, fs.Position, "#B1");
194                                 r.GetEnumerator ();
195                                 Assert.IsFalse (fs.Position == 0, "#B2");
196                         }
197                 }
198
199                 [Test]
200                 public void ExternalFileReference_Icon ()
201                 {
202                         string refFile = Path.Combine (_tempDirectory, "32x32.ico");
203                         WriteEmbeddedResource ("32x32.ico", refFile);
204
205                         string resxFile = Path.Combine (_tempDirectory, "resources.resx");
206                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
207                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
208                                         _resXFileRefTemplate, ResXResourceWriter.ResMimeType, "1.0",
209                                         Consts.AssemblySystem_Windows_Forms, refFile,
210                                         typeof (Bitmap).AssemblyQualifiedName, string.Empty,
211                                         Consts.AssemblyCorlib));
212                         }
213
214                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
215                                 IDictionaryEnumerator enumerator = r.GetEnumerator ();
216                                 enumerator.MoveNext ();
217                                 Assert.IsNotNull (enumerator.Current, "#A1");
218                                 Assert.AreEqual ("foo", enumerator.Key, "#A2");
219                                 Bitmap bitmap = enumerator.Value as Bitmap;
220                                 Assert.IsNotNull (bitmap, "#A3");
221 #if NET_2_0
222                                 Assert.AreEqual (32, bitmap.Height, "#A4");
223                                 Assert.AreEqual (32, bitmap.Width, "#A5");
224 #else
225                                 Assert.AreEqual (96, bitmap.Height, "#A4");
226                                 Assert.AreEqual (96, bitmap.Width, "#A5");
227 #endif
228                         }
229
230                         File.Delete (refFile);
231                         File.Delete (resxFile);
232
233                         refFile = Path.Combine (_tempDirectory, "32x32.ICO");
234                         WriteEmbeddedResource ("32x32.ico", refFile);
235
236                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
237                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
238                                         _resXFileRefTemplate, ResXResourceWriter.ResMimeType, "1.0",
239                                         Consts.AssemblySystem_Windows_Forms, refFile,
240                                         typeof (Bitmap).AssemblyQualifiedName, string.Empty,
241                                         Consts.AssemblyCorlib));
242                         }
243
244                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
245                                 IDictionaryEnumerator enumerator = r.GetEnumerator ();
246                                 enumerator.MoveNext ();
247                                 Assert.IsNotNull (enumerator.Current, "#B1");
248                                 Assert.AreEqual ("foo", enumerator.Key, "#B2");
249                                 Bitmap bitmap = enumerator.Value as Bitmap;
250                                 Assert.IsNotNull (bitmap, "#B3");
251                                 Assert.AreEqual (96, bitmap.Height, "#B4");
252                                 Assert.AreEqual (96, bitmap.Width, "#B5");
253                         }
254                 }
255
256                 [Test]
257                 public void ExternalFileReference_RelativePath ()
258                 {
259                         string refFile = Path.Combine (_otherTempDirectory, "string.txt");
260                         string relRefFile = Path.Combine ("in", "string.txt");
261                         using (StreamWriter sw = new StreamWriter (refFile, false, Encoding.UTF8)) {
262                                 sw.Write ("hello");
263                         }
264
265                         string resxFile = Path.Combine (_tempDirectory, "resources.resx");
266                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
267                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
268                                         _resXFileRefTemplate, ResXResourceWriter.ResMimeType, "1.0",
269                                         Consts.AssemblySystem_Windows_Forms, 
270                                         "in" + Path.DirectorySeparatorChar + "string.txt", 
271                                         typeof (StreamReader).AssemblyQualifiedName, string.Empty,
272                                         Consts.AssemblyCorlib));
273                         }
274
275                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
276                                 try {
277                                         r.GetEnumerator ();
278                                         Assert.Fail ("#A1");
279                                 } catch (ArgumentException ex) {
280                                         // Invalid ResX input
281                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
282                                         Assert.IsNotNull (ex.InnerException, "#A3");
283                                         Assert.IsNotNull (ex.Message, "#A4");
284                                         Assert.IsNull (ex.ParamName, "#A5");
285
286 #if NET_2_0
287                                         // Could not find a part of the path "<current dir>\in\string.txt".
288                                         // Line 1, position 821
289                                         XmlException inner = ex.InnerException as XmlException;
290                                         Assert.IsNotNull (inner, "#A6");
291                                         Assert.AreEqual (typeof (XmlException), inner.GetType (), "#A7");
292                                         Assert.IsNotNull (inner.InnerException, "#A8");
293                                         Assert.AreEqual (1, inner.LineNumber, "#A9");
294 //                                      Assert.AreEqual (821, inner.LinePosition, "#A10");
295                                         Assert.IsNotNull (inner.Message, "#A11");
296                                         Assert.IsTrue (inner.Message.IndexOf (Path.Combine (
297                                                 Directory.GetCurrentDirectory (), relRefFile)) != -1, "#A12");
298
299                                         // Could not find a part of the path "<current dir>\in\string.txt"
300                                         Exception inner2 = inner.InnerException;
301                                         Assert.AreEqual (typeof (DirectoryNotFoundException), inner2.GetType (), "#A13");
302                                         Assert.IsNull (inner2.InnerException, "#A14");
303                                         Assert.IsNotNull (inner2.Message, "#A15");
304                                         Assert.IsTrue (inner2.Message.IndexOf (Path.Combine (
305                                                 Directory.GetCurrentDirectory (), relRefFile)) != -1, "#A16");
306 #else
307                                         // Could not find a part of the path "<current dir>\in\string.txt"
308                                         Exception inner = ex.InnerException;
309                                         Assert.AreEqual (typeof (DirectoryNotFoundException), inner.GetType (), "#A6");
310                                         Assert.IsNull (inner.InnerException, "#A7");
311                                         Assert.IsNotNull (inner.Message, "#A8");
312                                         Assert.IsTrue (inner.Message.IndexOf (Path.Combine (
313                                                 Directory.GetCurrentDirectory (), relRefFile)) != -1, "#A9");
314 #endif
315                                 }
316 #if NET_2_0
317                                 Assert.IsNull (r.BasePath, "#A17");
318 #endif
319                         }
320
321                         string originalCurrentDir = Directory.GetCurrentDirectory ();
322                         Directory.SetCurrentDirectory (_tempDirectory);
323                         try {
324                                 using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
325                                         IDictionaryEnumerator enumerator = r.GetEnumerator ();
326                                         enumerator.MoveNext ();
327                                         Assert.IsNotNull (enumerator.Current, "#B1");
328                                         Assert.AreEqual ("foo", enumerator.Key, "#B2");
329                                         using (StreamReader sr = enumerator.Value as StreamReader) {
330                                                 Assert.IsNotNull (sr, "#B3");
331                                                 Assert.AreEqual ("hello", sr.ReadToEnd (), "#B4");
332                                         }
333 #if NET_2_0
334                                         Assert.IsNull (r.BasePath, "#B5");
335 #endif
336                                 }
337                         } finally {
338                                 // restore original current directory
339                                 Directory.SetCurrentDirectory (originalCurrentDir);
340                         }
341
342 #if NET_2_0
343                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
344                                 r.BasePath = _tempDirectory;
345                                 IDictionaryEnumerator enumerator = r.GetEnumerator ();
346                                 enumerator.MoveNext ();
347                                 Assert.IsNotNull (enumerator.Current, "#C1");
348                                 Assert.AreEqual ("foo", enumerator.Key, "#C2");
349                                 using (StreamReader sr = enumerator.Value as StreamReader) {
350                                         Assert.IsNotNull (sr, "#C3");
351                                         Assert.AreEqual ("hello", sr.ReadToEnd (), "#C4");
352                                 }
353                                 Assert.AreEqual (_tempDirectory, r.BasePath, "#C5");
354                         }
355
356                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
357                                 r.BasePath = Path.GetTempPath ();
358                                 try {
359                                         r.GetEnumerator ();
360                                         Assert.Fail ("#D1");
361                                 } catch (ArgumentException ex) {
362                                         // Invalid ResX input
363                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
364                                         Assert.IsNotNull (ex.InnerException, "#D3");
365                                         Assert.IsNotNull (ex.Message, "#D4");
366                                         Assert.IsNull (ex.ParamName, "#D5");
367
368                                         // Could not find a part of the path "<temp path>\in\string.txt".
369                                         // Line 1, position 821
370                                         XmlException inner = ex.InnerException as XmlException;
371                                         Assert.IsNotNull (inner, "#D6");
372                                         Assert.AreEqual (typeof (XmlException), inner.GetType (), "#D7");
373                                         Assert.IsNotNull (inner.InnerException, "#D8");
374                                         Assert.AreEqual (1, inner.LineNumber, "#D9");
375 //                                      Assert.AreEqual (821, inner.LinePosition, "#D10");
376                                         Assert.IsNotNull (inner.Message, "#D11");
377                                         Assert.IsTrue (inner.Message.IndexOf (Path.Combine (
378                                                 Path.GetTempPath (), relRefFile)) != -1, "#D12");
379
380                                         // Could not find a part of the path "<temp path>\in\string.txt"
381                                         Exception inner2 = inner.InnerException as Exception;
382                                         Assert.AreEqual (typeof (DirectoryNotFoundException), inner2.GetType (), "#D13");
383                                         Assert.IsNull (inner2.InnerException, "#D14");
384                                         Assert.IsNotNull (inner2.Message, "#D15");
385                                         Assert.IsTrue (inner2.Message.IndexOf (Path.Combine (
386                                                 Path.GetTempPath (), relRefFile)) != -1, "#D16");
387                                 }
388                                 Assert.AreEqual (Path.GetTempPath (), r.BasePath, "#D17");
389                         }
390 #endif
391                 }
392
393                 [Test]
394                 public void FileRef_String_UTF7 ()
395                 {
396                         string refFile = Path.Combine (_otherTempDirectory, "string.txt");
397                         using (StreamWriter sw = new StreamWriter (refFile, false, Encoding.UTF7)) {
398                                 sw.Write ("\u0021\u0026\u002A\u003B");
399                         }
400
401                         string resxFile = Path.Combine (_tempDirectory, "resources.resx");
402                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
403                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
404                                         _resXFileRefTemplate, ResXResourceWriter.ResMimeType, "1.0",
405                                         Consts.AssemblySystem_Windows_Forms, refFile, 
406                                         typeof (string).AssemblyQualifiedName, string.Empty,
407                                         Consts.AssemblyCorlib));
408                         }
409
410                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
411 #if NET_2_0
412                                 IDictionaryEnumerator enumerator = r.GetEnumerator ();
413                                 enumerator.MoveNext ();
414                                 Assert.IsNotNull (enumerator.Current, "#A1");
415                                 Assert.AreEqual ("foo", enumerator.Key, "#A2");
416                                 Assert.IsFalse ("\u0021\u0026\u002A\u003B" == (string) enumerator.Value, "#A3");
417 #else
418                                 try {
419                                         r.GetEnumerator ();
420                                         Assert.Fail ("#A1");
421                                 } catch (ArgumentException ex) {
422                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
423                                         Assert.IsNotNull (ex.InnerException, "#A3");
424                                         Assert.IsNotNull (ex.Message, "#A4");
425                                         Assert.IsNull (ex.ParamName, "#A5");
426
427                                         Assert.AreEqual (typeof (MissingMethodException), ex.InnerException.GetType (), "#A6");
428                                 }
429 #endif
430                         }
431
432                         resxFile = Path.Combine (_tempDirectory, "resources.resx");
433                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
434                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
435                                         _resXFileRefTemplate, ResXResourceWriter.ResMimeType, "1.0",
436                                         Consts.AssemblySystem_Windows_Forms, refFile,
437                                         typeof (string).AssemblyQualifiedName, ";utf-7",
438                                         Consts.AssemblyCorlib));
439                         }
440
441                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
442 #if NET_2_0
443                                 IDictionaryEnumerator enumerator = r.GetEnumerator ();
444                                 enumerator.MoveNext ();
445                                 Assert.IsNotNull (enumerator.Current, "#B1");
446                                 Assert.AreEqual ("foo", enumerator.Key, "#B2");
447                                 Assert.AreEqual ("\u0021\u0026\u002A\u003B", (string) enumerator.Value, "#B3");
448 #else
449                                 try {
450                                         r.GetEnumerator ();
451                                         Assert.Fail ("#B1");
452                                 } catch (ArgumentException ex) {
453                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
454                                         Assert.IsNotNull (ex.InnerException, "#B3");
455                                         Assert.IsNotNull (ex.Message, "#B4");
456                                         Assert.IsNull (ex.ParamName, "#B5");
457
458                                         Assert.AreEqual (typeof (MissingMethodException), ex.InnerException.GetType (), "#B6");
459                                 }
460 #endif
461                         }
462                 }
463
464                 [Test]
465                 public void FileRef_String_UTF8 ()
466                 {
467                         string refFile = Path.Combine (_otherTempDirectory, "string.txt");
468                         using (StreamWriter sw = new StreamWriter (refFile, false, Encoding.UTF8)) {
469                                 sw.Write ("\u0041\u2262\u0391\u002E");
470                         }
471
472                         string resxFile = Path.Combine (_tempDirectory, "resources.resx");
473                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
474                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
475                                         _resXFileRefTemplate, ResXResourceWriter.ResMimeType, "1.0",
476                                         Consts.AssemblySystem_Windows_Forms, refFile,
477                                         typeof (string).AssemblyQualifiedName, string.Empty,
478                                         Consts.AssemblyCorlib));
479                         }
480
481                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
482 #if NET_2_0
483                                 IDictionaryEnumerator enumerator = r.GetEnumerator ();
484                                 enumerator.MoveNext ();
485                                 Assert.IsNotNull (enumerator.Current, "#A1");
486                                 Assert.AreEqual ("foo", enumerator.Key, "#A2");
487                                 Assert.AreEqual ("\u0041\u2262\u0391\u002E", (string) enumerator.Value, "#A3");
488 #else
489                                 try {
490                                         r.GetEnumerator ();
491                                         Assert.Fail ("#A1");
492                                 } catch (ArgumentException ex) {
493                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
494                                         Assert.IsNotNull (ex.InnerException, "#A3");
495                                         Assert.IsNotNull (ex.Message, "#A4");
496                                         Assert.IsNull (ex.ParamName, "#A5");
497
498                                         Assert.AreEqual (typeof (MissingMethodException), ex.InnerException.GetType (), "#A6");
499                                 }
500 #endif
501                         }
502
503                         resxFile = Path.Combine (_tempDirectory, "resources.resx");
504                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
505                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
506                                         _resXFileRefTemplate, ResXResourceWriter.ResMimeType, "1.0",
507                                         Consts.AssemblySystem_Windows_Forms, refFile,
508                                         typeof (string).AssemblyQualifiedName, ";utf-8",
509                                         Consts.AssemblyCorlib));
510                         }
511
512                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
513 #if NET_2_0
514                                 IDictionaryEnumerator enumerator = r.GetEnumerator ();
515                                 enumerator.MoveNext ();
516                                 Assert.IsNotNull (enumerator.Current, "#B1");
517                                 Assert.AreEqual ("foo", enumerator.Key, "#B2");
518                                 Assert.AreEqual ("\u0041\u2262\u0391\u002E", (string) enumerator.Value, "#B3");
519 #else
520                                 try {
521                                         r.GetEnumerator ();
522                                         Assert.Fail ("#B1");
523                                 } catch (ArgumentException ex) {
524                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
525                                         Assert.IsNotNull (ex.InnerException, "#B3");
526                                         Assert.IsNotNull (ex.Message, "#B4");
527                                         Assert.IsNull (ex.ParamName, "#B5");
528
529                                         Assert.AreEqual (typeof (MissingMethodException), ex.InnerException.GetType (), "#B6");
530                                 }
531 #endif
532                         }
533                 }
534
535                 [Test]
536                 public void Namespaces ()
537                 {
538                         const string resXTemplate =
539                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
540                                 "<o:Document xmlns:x=\"http://www.mono-project.com\" xmlns:o=\"http://tempuri.org\">" +
541                                 "       <o:Content>" +
542                                 "               <x:DaTa name=\"name\">" +
543                                 "                       <o:value>de Icaza</o:value>" +
544                                 "               </x:DaTa>" +
545                                 "               <x:data name=\"firstName\">" +
546                                 "                       <x:value />" +
547                                 "               </x:data>" +
548                                 "               <o:data name=\"Address\" />" +
549                                 "               <o:data name=\"city\">" +
550                                 "                       <x:value>Boston </x:value>" +
551                                 "               </o:data>" +
552                                 "               <o:data name=\"country\">" +
553                                 "                        United States " +
554                                 "               </o:data>" +
555                                 "               <o:data name=\"\">" +
556                                 "                       BO    " +
557                                 "               </o:data>" +
558                                 "               <o:data name=\"country\">" +
559                                 "                       <x:value>Belgium</x:value>" +
560                                 "               </o:data>" +
561                                 "               <data name=\"zip\">" +
562                                 "                       <value><![CDATA[ <3510> ]]></value>" +
563                                 "               </data>" +
564                                 "       </o:Content>" +
565                                 "       <o:Paragraph>" +
566                                 "               <o:resheader name=\"resmimetype\">" +
567                                 "                       <o:value>{0}</o:value>" +
568                                 "               </o:resheader>" +
569                                 "               <x:resheader name=\"version\">" +
570                                 "                       <o:value>{1}</o:value>" +
571                                 "               </x:resheader>" +
572                                 "       </o:Paragraph>" +
573                                 "       <x:Section>" +
574                                 "               <o:resheader name=\"reader\">" +
575                                 "                       <x:value>System.Resources.ResXResourceReader, {2}</x:value>" +
576                                 "               </o:resheader>" +
577                                 "               <x:resheader name=\"writer\">" +
578                                 "                       <x:value>System.Resources.ResXResourceWriter, {2}</x:value>" +
579                                 "               </x:resheader>" +
580                                 "       </x:Section>" +
581                                 "</o:Document>";
582
583                         string resxFile = Path.Combine (_tempDirectory, "resources.resx");
584                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
585                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
586                                         resXTemplate, ResXResourceWriter.ResMimeType, "1.0",
587                                         Consts.AssemblySystem_Windows_Forms));
588                         }
589
590                         // Stream
591                         using (FileStream fs = new FileStream (resxFile, FileMode.Open, FileAccess.Read, FileShare.Read)) {
592                                 using (ResXResourceReader r = new ResXResourceReader (fs)) {
593                                         IDictionaryEnumerator enumerator = r.GetEnumerator ();
594                                         int entries = 0;
595                                         while (enumerator.MoveNext ()) {
596                                                 entries++;
597                                                 switch ((string) enumerator.Key) {
598                                                 case "":
599                                                         Assert.IsNotNull (enumerator.Value, "#A1");
600                                                         Assert.AreEqual ("BO", enumerator.Value, "#A2");
601                                                         break;
602                                                 case "Address":
603                                                         Assert.IsNotNull (enumerator.Value, "#B1");
604 #if NET_2_0
605                                                         Assert.AreEqual (string.Empty, enumerator.Value, "#B2");
606 #else
607                                                         Assert.AreEqual ("Boston ", enumerator.Value, "#B2");
608 #endif
609                                                         break;
610                                                 case "country":
611                                                         Assert.IsNotNull (enumerator.Value, "#C1");
612 #if NET_2_0
613                                                         Assert.AreEqual (string.Empty, enumerator.Value, "#C2");
614 #else
615                                                         Assert.AreEqual ("Belgium", enumerator.Value, "#C2");
616 #endif
617                                                         break;
618                                                 case "firstName":
619 #if NET_2_0
620                                                         Assert.IsNull (enumerator.Value, "#D");
621 #else
622                                                         Assert.IsNotNull (enumerator.Value, "#D1");
623                                                         Assert.AreEqual (string.Empty, enumerator.Value, "#D2");
624 #endif
625                                                         break;
626                                                 case "zip":
627                                                         Assert.IsNotNull (enumerator.Value, "#E1");
628                                                         Assert.AreEqual (" <3510> ", enumerator.Value, "#E2");
629                                                         break;
630                                                 default:
631                                                         Assert.Fail ("#F:" + enumerator.Key);
632                                                         break;
633                                                 }
634                                         }
635                                         Assert.AreEqual (5, entries, "#G");
636                                 }
637                         }
638                 }
639
640                 [Test]
641                 public void ResHeader_Missing ()
642                 {
643                         const string resXTemplate =
644                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
645                                 "<root>" +
646                                 "       <data name=\"name\">" +
647                                 "               <value>de Icaza</value>" +
648                                 "       </data>" +
649                                 "       <data name=\"firstName\">" +
650                                 "               <value />" +
651                                 "       </data>" +
652                                 "       <data name=\"address\" />" +
653                                 "</root>";
654
655                         string resxFile = Path.Combine (_tempDirectory, "resources.resx");
656                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
657                                 sw.Write (resXTemplate);
658                         }
659
660                         // Stream
661                         using (FileStream fs = new FileStream (resxFile, FileMode.Open, FileAccess.Read, FileShare.Read)) {
662                                 using (ResXResourceReader r = new ResXResourceReader (fs)) {
663                                         try {
664                                                 r.GetEnumerator ();
665                                                 Assert.Fail ("#A1");
666                                         } catch (ArgumentException ex) {
667                                                 //Invalid ResX input.  Could not find valid \"resheader\"
668                                                 // tags for the ResX reader & writer type names
669                                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
670                                                 Assert.IsNull (ex.InnerException, "#A3");
671                                                 Assert.IsNotNull (ex.Message, "#A4");
672                                                 Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#A5");
673                                                 Assert.IsNull (ex.ParamName, "#A6");
674                                         }
675                                 }
676                         }
677
678                         // File
679                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
680                                 try {
681                                         r.GetEnumerator ();
682                                         Assert.Fail ("#B1");
683                                 } catch (ArgumentException ex) {
684                                         //Invalid ResX input.  Could not find valid \"resheader\"
685                                         // tags for the ResX reader & writer type names
686                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
687                                         Assert.IsNull (ex.InnerException, "#B3");
688                                         Assert.IsNotNull (ex.Message, "#B4");
689                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#B5");
690                                         Assert.IsNull (ex.ParamName, "#B6");
691                                 }
692                         }
693
694                         // TextReader
695                         using (StreamReader sr = new StreamReader (resxFile, Encoding.UTF8)) {
696                                 using (ResXResourceReader r = new ResXResourceReader (sr)) {
697                                         try {
698                                                 r.GetEnumerator ();
699                                                 Assert.Fail ("#C1");
700                                         } catch (ArgumentException ex) {
701                                                 //Invalid ResX input.  Could not find valid \"resheader\"
702                                                 // tags for the ResX reader & writer type names
703                                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
704                                                 Assert.IsNull (ex.InnerException, "#C3");
705                                                 Assert.IsNotNull (ex.Message, "#C4");
706                                                 Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#C5");
707                                                 Assert.IsNull (ex.ParamName, "#C6");
708                                         }
709                                 }
710                         }
711                 }
712
713                 [Test]
714                 public void ResHeader_ResMimeType ()
715                 {
716                         const string resXTemplate =
717                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
718                                 "<root>" +
719                                 "       <resheader name=\"resMIMEtype\">" +
720                                 "               {0}" +
721                                 "       </resheader>" +
722                                 "       <resheader name=\"version\">" +
723                                 "               <value>{1}</value>" +
724                                 "       </resheader>" +
725                                 "       <resheader name=\"reAder\">" +
726                                 "               <value>System.Resources.ResXResourceReader, {2}</value>" +
727                                 "       </resheader>" +
728                                 "       <resheader name=\"wriTer\">" +
729                                 "               <value>System.Resources.ResXResourceWriter, {2}</value>" +
730                                 "       </resheader>" +
731                                 "</root>";
732
733                         string resXContent = null;
734
735                         // <value> element, exact case
736                         resXContent = string.Format (CultureInfo.InvariantCulture,
737                                 resXTemplate, ResXResourceWriter.ResMimeType, "1.0", 
738                                 Consts.AssemblySystem_Windows_Forms);
739                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
740                                 r.GetEnumerator ();
741                         }
742
743                         // <value> element, uppercase
744                         resXContent = string.Format (CultureInfo.InvariantCulture,
745                                 resXTemplate, ResXResourceWriter.ResMimeType.ToUpper (), "1.0",
746                                 Consts.AssemblySystem_Windows_Forms);
747                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
748                                 try {
749                                         r.GetEnumerator ();
750                                         Assert.Fail ("#A1");
751                                 } catch (ArgumentException ex) {
752                                         //Invalid ResX input.  Could not find valid \"resheader\"
753                                         // tags for the ResX reader & writer type names
754                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
755                                         Assert.IsNull (ex.InnerException, "#A3");
756                                         Assert.IsNotNull (ex.Message, "#A4");
757                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#A5");
758                                         Assert.IsNull (ex.ParamName, "#A6");
759                                 }
760                         }
761
762                         // text, exact case
763                         resXContent = string.Format (CultureInfo.InvariantCulture,
764                                 resXTemplate, ResXResourceWriter.ResMimeType, "1.0",
765                                 Consts.AssemblySystem_Windows_Forms);
766                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
767                                 r.GetEnumerator ();
768                         }
769
770                         // text, uppercase
771                         resXContent = string.Format (CultureInfo.InvariantCulture,
772                                 resXTemplate, ResXResourceWriter.ResMimeType.ToUpper (), "1.0",
773                                 Consts.AssemblySystem_Windows_Forms);
774                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
775                                 try {
776                                         r.GetEnumerator ();
777                                         Assert.Fail ("#B1");
778                                 } catch (ArgumentException ex) {
779                                         //Invalid ResX input.  Could not find valid \"resheader\"
780                                         // tags for the ResX reader & writer type names
781                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
782                                         Assert.IsNull (ex.InnerException, "#B3");
783                                         Assert.IsNotNull (ex.Message, "#B4");
784                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#B5");
785                                         Assert.IsNull (ex.ParamName, "#B6");
786                                 }
787                         }
788
789                         // CDATA, exact case
790                         resXContent = string.Format (CultureInfo.InvariantCulture,
791                                 resXTemplate, "<![CDATA[" +ResXResourceWriter.ResMimeType + "]]>",
792                                 "1.0", Consts.AssemblySystem_Windows_Forms);
793                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
794                                 r.GetEnumerator ();
795                         }
796
797                         // CDATA, uppercase
798                         resXContent = string.Format (CultureInfo.InvariantCulture,
799                                 resXTemplate, "<![CDATA[" + ResXResourceWriter.ResMimeType.ToUpper () + "]]>",
800                                 "1.0", Consts.AssemblySystem_Windows_Forms);
801                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
802                                 try {
803                                         r.GetEnumerator ();
804                                         Assert.Fail ("#C1");
805                                 } catch (ArgumentException ex) {
806                                         //Invalid ResX input.  Could not find valid \"resheader\"
807                                         // tags for the ResX reader & writer type names
808                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
809                                         Assert.IsNull (ex.InnerException, "#C3");
810                                         Assert.IsNotNull (ex.Message, "#C4");
811                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#C5");
812                                         Assert.IsNull (ex.ParamName, "#C6");
813                                 }
814                         }
815
816                         // <whatever> element, exact case
817                         resXContent = string.Format (CultureInfo.InvariantCulture,
818                                 resXTemplate, "<whatever>" + ResXResourceWriter.ResMimeType + "</whatever>",
819                                 "1.0", Consts.AssemblySystem_Windows_Forms);
820                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
821                                 r.GetEnumerator ();
822                         }
823
824                         // <whatever> element, uppercase
825                         resXContent = string.Format (CultureInfo.InvariantCulture,
826                                 resXTemplate, "<whatever>" + ResXResourceWriter.ResMimeType.ToUpper () + "</whatever>",
827                                 "1.0", Consts.AssemblySystem_Windows_Forms);
828                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
829                                 try {
830                                         r.GetEnumerator ();
831                                         Assert.Fail ("#D1");
832                                 } catch (ArgumentException ex) {
833                                         //Invalid ResX input.  Could not find valid \"resheader\"
834                                         // tags for the ResX reader & writer type names
835                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
836                                         Assert.IsNull (ex.InnerException, "#D3");
837                                         Assert.IsNotNull (ex.Message, "#D4");
838                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#D5");
839                                         Assert.IsNull (ex.ParamName, "#D6");
840                                 }
841                         }
842                 }
843
844                 [Test]
845                 public void ResHeader_ResMimeType_Empty ()
846                 {
847                         const string resXTemplate =
848                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
849                                 "<root>" +
850                                 "       <resheader name=\"resmimetype\"></resheader>" +
851                                 "</root>";
852
853                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXTemplate))) {
854                                 try {
855                                         r.GetEnumerator ();
856                                         Assert.Fail ("#1");
857                                 } catch (ArgumentException ex) {
858                                         //Invalid ResX input.  Could not find valid \"resheader\"
859                                         // tags for the ResX reader & writer type names
860                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
861                                         Assert.IsNull (ex.InnerException, "#3");
862                                         Assert.IsNotNull (ex.Message, "#4");
863                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#5");
864                                         Assert.IsNull (ex.ParamName, "#6");
865                                 }
866                         }
867                 }
868
869                 [Test]
870                 public void ResHeader_ResMimeType_Invalid ()
871                 {
872                         const string resXTemplate =
873                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
874                                 "<root>" +
875                                 "       <resheader name=\"resmimetype\">" +
876                                 "               <value>{0}</value>" +
877                                 "       </resheader>" +
878                                 "       <resheader name=\"version\">" +
879                                 "               <value>{1}</value>" +
880                                 "       </resheader>" +
881                                 "       <resheader name=\"reader\">" +
882                                 "               <value>System.Resources.ResXResourceReader, {2}</value>" +
883                                 "       </resheader>" +
884                                 "       <resheader name=\"writer\">" +
885                                 "               <value>System.Resources.ResXResourceWriter, {2}</value>" +
886                                 "       </resheader>" +
887                                 "       <data name=\"name\">" +
888                                 "               <value>de Icaza</value>" +
889                                 "       </data>" +
890                                 "       <data name=\"firstName\">" +
891                                 "               <value />" +
892                                 "       </data>" +
893                                 "       <data name=\"Address\" />" +
894                                 "</root>";
895
896                         string resxFile = Path.Combine (_tempDirectory, "resources.resx");
897                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
898                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
899                                         resXTemplate, "notvalid", "1.0", Consts.AssemblySystem_Windows_Forms
900                                         ));
901                         }
902
903                         // Stream
904                         using (FileStream fs = new FileStream (resxFile, FileMode.Open, FileAccess.Read, FileShare.Read)) {
905                                 using (ResXResourceReader r = new ResXResourceReader (fs)) {
906                                         try {
907                                                 r.GetEnumerator ();
908                                                 Assert.Fail ("#A1");
909                                         } catch (ArgumentException ex) {
910                                                 //Invalid ResX input.  Could not find valid \"resheader\"
911                                                 // tags for the ResX reader & writer type names
912                                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
913                                                 Assert.IsNull (ex.InnerException, "#A3");
914                                                 Assert.IsNotNull (ex.Message, "#A4");
915                                                 Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#A5");
916                                                 Assert.IsNull (ex.ParamName, "#A6");
917                                         }
918                                 }
919                         }
920
921                         // File
922                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
923                                 try {
924                                         r.GetEnumerator ();
925                                         Assert.Fail ("#B1");
926                                 } catch (ArgumentException ex) {
927                                         //Invalid ResX input.  Could not find valid \"resheader\"
928                                         // tags for the ResX reader & writer type names
929                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
930                                         Assert.IsNull (ex.InnerException, "#B3");
931                                         Assert.IsNotNull (ex.Message, "#B4");
932                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#B5");
933                                         Assert.IsNull (ex.ParamName, "#B6");
934                                 }
935                         }
936
937                         // TextReader
938                         using (StreamReader sr = new StreamReader (resxFile, Encoding.UTF8)) {
939                                 using (ResXResourceReader r = new ResXResourceReader (sr)) {
940                                         try {
941                                                 r.GetEnumerator ();
942                                                 Assert.Fail ("#C1");
943                                         } catch (ArgumentException ex) {
944                                                 //Invalid ResX input.  Could not find valid \"resheader\"
945                                                 // tags for the ResX reader & writer type names
946                                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
947                                                 Assert.IsNull (ex.InnerException, "#C3");
948                                                 Assert.IsNotNull (ex.Message, "#C4");
949                                                 Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#C5");
950                                                 Assert.IsNull (ex.ParamName, "#C6");
951                                         }
952                                 }
953                         }
954                 }
955
956                 [Test]
957                 public void ResHeader_ResMimeType_Null ()
958                 {
959                         const string resXTemplate =
960                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
961                                 "<root>" +
962                                 "       <resheader name=\"resmimetype\" />" +
963                                 "</root>";
964
965                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXTemplate))) {
966                                 try {
967                                         r.GetEnumerator ();
968                                         Assert.Fail ("#1");
969                                 } catch (ArgumentException ex) {
970                                         //Invalid ResX input.  Could not find valid \"resheader\"
971                                         // tags for the ResX reader & writer type names
972                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
973                                         Assert.IsNull (ex.InnerException, "#3");
974                                         Assert.IsNotNull (ex.Message, "#4");
975                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#5");
976                                         Assert.IsNull (ex.ParamName, "#6");
977                                 }
978                         }
979                 }
980
981                 [Test]
982                 public void ResHeader_Reader_Invalid ()
983                 {
984                         const string resXTemplate =
985                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
986                                 "<root>" +
987                                 "       <resheader name=\"resmimetype\">" +
988                                 "               {0}" +
989                                 "       </resheader>" +
990                                 "       <resheader name=\"version\">" +
991                                 "               <value>{1}</value>" +
992                                 "       </resheader>" +
993                                 "       <resheader name=\"reader\">" +
994                                 "               <value>System.Resources.InvalidResXResourceReader, {2}</value>" +
995                                 "       </resheader>" +
996                                 "       <resheader name=\"writer\">" +
997                                 "               <value>System.Resources.ResXResourceWriter, {2}</value>" +
998                                 "       </resheader>" +
999                                 "</root>";
1000
1001                         string resXContent = string.Format (CultureInfo.InvariantCulture,
1002                                 resXTemplate, ResXResourceWriter.ResMimeType, "1.0",
1003                                 Consts.AssemblySystem_Windows_Forms);
1004                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
1005                                 try {
1006                                         r.GetEnumerator ();
1007                                         Assert.Fail ("#1");
1008                                 } catch (ArgumentException ex) {
1009                                         //Invalid ResX input.  Could not find valid \"resheader\"
1010                                         // tags for the ResX reader & writer type names
1011                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
1012                                         Assert.IsNull (ex.InnerException, "#3");
1013                                         Assert.IsNotNull (ex.Message, "#4");
1014                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#5");
1015                                         Assert.IsNull (ex.ParamName, "#6");
1016                                 }
1017                         }
1018                 }
1019
1020                 [Test]
1021                 public void ResHeader_Reader_Missing ()
1022                 {
1023                         const string resXTemplate =
1024                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1025                                 "<root>" +
1026                                 "       <resheader name=\"resmimetype\">" +
1027                                 "               {0}" +
1028                                 "       </resheader>" +
1029                                 "       <resheader name=\"version\">" +
1030                                 "               <value>{1}</value>" +
1031                                 "       </resheader>" +
1032                                 "       <resheader name=\"writer\">" +
1033                                 "               <value>System.Resources.ResXResourceWriter, {2}</value>" +
1034                                 "       </resheader>" +
1035                                 "</root>";
1036
1037                         string resXContent = string.Format (CultureInfo.InvariantCulture,
1038                                 resXTemplate, ResXResourceWriter.ResMimeType, "1.0",
1039                                 Consts.AssemblySystem_Windows_Forms);
1040                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
1041                                 try {
1042                                         r.GetEnumerator ();
1043                                         Assert.Fail ("#1");
1044                                 } catch (ArgumentException ex) {
1045                                         //Invalid ResX input.  Could not find valid \"resheader\"
1046                                         // tags for the ResX reader & writer type names
1047                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
1048                                         Assert.IsNull (ex.InnerException, "#3");
1049                                         Assert.IsNotNull (ex.Message, "#4");
1050                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#5");
1051                                         Assert.IsNull (ex.ParamName, "#6");
1052                                 }
1053                         }
1054                 }
1055
1056                 [Test]
1057                 public void ResHeader_Reader_Null ()
1058                 {
1059                         const string resXTemplate =
1060                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1061                                 "<root>" +
1062                                 "       <resheader name=\"resmimetype\">" +
1063                                 "               {0}" +
1064                                 "       </resheader>" +
1065                                 "       <resheader name=\"version\">" +
1066                                 "               <value>{1}</value>" +
1067                                 "       </resheader>" +
1068                                 "       <resheader name=\"reader\" />" +
1069                                 "       <resheader name=\"writer\">" +
1070                                 "               <value>System.Resources.ResXResourceWriter, {2}</value>" +
1071                                 "       </resheader>" +
1072                                 "</root>";
1073
1074                         string resXContent = string.Format (CultureInfo.InvariantCulture,
1075                                 resXTemplate, ResXResourceWriter.ResMimeType, "1.0",
1076                                 Consts.AssemblySystem_Windows_Forms);
1077                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
1078                                 try {
1079                                         r.GetEnumerator ();
1080                                         Assert.Fail ("#1");
1081                                 } catch (ArgumentException ex) {
1082                                         //Invalid ResX input.  Could not find valid \"resheader\"
1083                                         // tags for the ResX reader & writer type names
1084                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
1085                                         Assert.IsNull (ex.InnerException, "#3");
1086                                         Assert.IsNotNull (ex.Message, "#4");
1087                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#5");
1088                                         Assert.IsNull (ex.ParamName, "#6");
1089                                 }
1090                         }
1091                 }
1092
1093                 [Test]
1094                 public void ResHeader_Writer_Invalid ()
1095                 {
1096                         const string resXTemplate =
1097                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1098                                 "<root>" +
1099                                 "       <resheader name=\"resmimetype\">" +
1100                                 "               {0}" +
1101                                 "       </resheader>" +
1102                                 "       <resheader name=\"version\">" +
1103                                 "               <value>{1}</value>" +
1104                                 "       </resheader>" +
1105                                 "       <resheader name=\"reader\">" +
1106                                 "               <value>System.Resources.ResXResourceReader, {2}</value>" +
1107                                 "       </resheader>" +
1108                                 "       <resheader name=\"writer\">" +
1109                                 "               <value>System.Resources.InvalidResXResourceWriter, {2}</value>" +
1110                                 "       </resheader>" +
1111                                 "</root>";
1112
1113                         string resXContent = string.Format (CultureInfo.InvariantCulture,
1114                                 resXTemplate, ResXResourceWriter.ResMimeType, "1.0",
1115                                 Consts.AssemblySystem_Windows_Forms);
1116                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
1117                                 try {
1118                                         r.GetEnumerator ();
1119                                         Assert.Fail ("#1");
1120                                 } catch (ArgumentException ex) {
1121                                         //Invalid ResX input.  Could not find valid \"resheader\"
1122                                         // tags for the ResX reader & writer type names
1123                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
1124                                         Assert.IsNull (ex.InnerException, "#3");
1125                                         Assert.IsNotNull (ex.Message, "#4");
1126                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#5");
1127                                         Assert.IsNull (ex.ParamName, "#6");
1128                                 }
1129                         }
1130                 }
1131
1132                 [Test]
1133                 public void ResHeader_Writer_Missing ()
1134                 {
1135                         const string resXTemplate =
1136                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1137                                 "<root>" +
1138                                 "       <resheader name=\"resmimetype\">" +
1139                                 "               {0}" +
1140                                 "       </resheader>" +
1141                                 "       <resheader name=\"version\">" +
1142                                 "               <value>{1}</value>" +
1143                                 "       </resheader>" +
1144                                 "       <resheader name=\"reader\">" +
1145                                 "               <value>System.Resources.ResXResourceReader, {2}</value>" +
1146                                 "       </resheader>" +
1147                                 "</root>";
1148
1149                         string resXContent = string.Format (CultureInfo.InvariantCulture,
1150                                 resXTemplate, ResXResourceWriter.ResMimeType, "1.0",
1151                                 Consts.AssemblySystem_Windows_Forms);
1152                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
1153                                 try {
1154                                         r.GetEnumerator ();
1155                                         Assert.Fail ("#1");
1156                                 } catch (ArgumentException ex) {
1157                                         //Invalid ResX input.  Could not find valid \"resheader\"
1158                                         // tags for the ResX reader & writer type names
1159                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
1160                                         Assert.IsNull (ex.InnerException, "#3");
1161                                         Assert.IsNotNull (ex.Message, "#4");
1162                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#5");
1163                                         Assert.IsNull (ex.ParamName, "#6");
1164                                 }
1165                         }
1166                 }
1167
1168                 [Test]
1169                 public void ResHeader_Writer_Null ()
1170                 {
1171                         const string resXTemplate =
1172                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1173                                 "<root>" +
1174                                 "       <resheader name=\"resmimetype\">" +
1175                                 "               {0}" +
1176                                 "       </resheader>" +
1177                                 "       <resheader name=\"version\">" +
1178                                 "               <value>{1}</value>" +
1179                                 "       </resheader>" +
1180                                 "       <resheader name=\"reader\">" +
1181                                 "               <value>System.Resources.ResXResourceReader, {2}</value>" +
1182                                 "       </resheader>" +
1183                                 "       <resheader name=\"writer\" />" +
1184                                 "</root>";
1185
1186                         string resXContent = string.Format (CultureInfo.InvariantCulture,
1187                                 resXTemplate, ResXResourceWriter.ResMimeType, "1.0",
1188                                 Consts.AssemblySystem_Windows_Forms);
1189                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
1190                                 try {
1191                                         r.GetEnumerator ();
1192                                         Assert.Fail ("#1");
1193                                 } catch (ArgumentException ex) {
1194                                         //Invalid ResX input.  Could not find valid \"resheader\"
1195                                         // tags for the ResX reader & writer type names
1196                                         Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
1197                                         Assert.IsNull (ex.InnerException, "#3");
1198                                         Assert.IsNotNull (ex.Message, "#4");
1199                                         Assert.IsTrue (ex.Message.IndexOf ("\"resheader\"") != -1, "#5");
1200                                         Assert.IsNull (ex.ParamName, "#6");
1201                                 }
1202                         }
1203                 }
1204
1205                 [Test]
1206                 public void ResHeader_Unknown ()
1207                 {
1208                         const string resXTemplate =
1209                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1210                                 "<root>" +
1211                                 "       <resheader name=\"resmimetype\">" +
1212                                 "               {0}" +
1213                                 "       </resheader>" +
1214                                 "       <resheader name=\"version\">" + 
1215                                 "               <value>{1}</value>" +
1216                                 "       </resheader>" +
1217                                 "       <resheader name=\"reader\">" +
1218                                 "               <value>  System.Resources.ResXResourceReader  , {2}</value>" +
1219                                 "       </resheader>" +
1220                                 "       <resheader name=\"writer\">" +
1221                                 "               <value>  System.Resources.ResXResourceWriter  , {2}</value>" +
1222                                 "       </resheader>" +
1223                                 "       <resheader name=\"UNKNOWN\">" +
1224                                 "               <value>whatever</value>" +
1225                                 "       </resheader>" +
1226                                 "</root>";
1227
1228                         string resXContent = string.Format (CultureInfo.InvariantCulture,
1229                                 resXTemplate, ResXResourceWriter.ResMimeType, "1.0",
1230                                 Consts.AssemblySystem_Windows_Forms);
1231                         using (ResXResourceReader r = new ResXResourceReader (new StringReader (resXContent))) {
1232                                 r.GetEnumerator ();
1233                         }
1234                 }
1235
1236                 [Test]
1237                 public void ResName_Null ()
1238                 {
1239                         const string resXContent =
1240                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1241                                 "<root>" +
1242                                 "       <resheader name=\"resmimetype\">" +
1243                                 "               <value>invalid</value>" +
1244                                 "       </resheader>" +
1245                                 "       <data name=\"name\">" +
1246                                 "               <value>de Icaza</value>" +
1247                                 "       </data>" +
1248                                 "       <data>" +
1249                                 "               <value>whatever</value>" +
1250                                 "       </data>" +
1251                                 "</root>";
1252
1253                         using (StringReader sr = new StringReader (resXContent)) {
1254                                 using (ResXResourceReader r = new ResXResourceReader (sr)) {
1255                                         try {
1256                                                 r.GetEnumerator ();
1257                                                 Assert.Fail ("#1");
1258                                         } catch (ArgumentException ex) {
1259                                                 // Invalid ResX input.
1260                                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
1261                                                 Assert.IsNotNull (ex.InnerException, "#3");
1262                                                 Assert.IsNotNull (ex.Message, "#4");
1263                                                 Assert.IsNull (ex.ParamName, "#5");
1264
1265 #if NET_2_0
1266                                                 // Could not find a name for a resource. The resource
1267                                                 // value was 'whatever'. Line 1, position 200
1268                                                 XmlException inner = ex.InnerException as XmlException;
1269                                                 Assert.IsNotNull (inner, "#6");
1270                                                 Assert.AreEqual (typeof (XmlException), inner.GetType (), "#7");
1271                                                 Assert.IsNotNull (inner.InnerException, "#8");
1272                                                 Assert.AreEqual (1, inner.LineNumber, "#9");
1273 //                                              Assert.AreEqual (200, inner.LinePosition, "#10");
1274                                                 Assert.IsNotNull (inner.Message, "#11");
1275                                                 Assert.IsTrue (inner.Message.IndexOf ("'whatever'") != -1, "#12");
1276                                                 Assert.IsTrue (inner.Message.IndexOf (" 1") != -1, "#13");
1277                                                 //Assert.IsTrue (inner.Message.IndexOf ("200") != -1, "#14");
1278
1279                                                 // Could not find a name for a resource. The resource
1280                                                 // value was 'whatever'
1281                                                 ArgumentException inner2 = inner.InnerException as ArgumentException;
1282                                                 Assert.IsNotNull (inner2, "#15");
1283                                                 Assert.AreEqual (typeof (ArgumentException), inner2.GetType (), "#16");
1284                                                 Assert.IsNull (inner2.InnerException, "#17");
1285                                                 Assert.IsNotNull (inner2.Message, "#18");
1286                                                 Assert.IsTrue (inner2.Message.IndexOf ("'whatever'") != -1, "#19");
1287                                                 Assert.IsNull (inner2.ParamName, "#20");
1288 #else
1289                                                 // Could not find a name for a resource. The resource
1290                                                 // value was 'whatever'
1291                                                 ArgumentException inner = ex.InnerException as ArgumentException;
1292                                                 Assert.IsNotNull (inner, "#6");
1293                                                 Assert.AreEqual (typeof (ArgumentException), inner.GetType (), "#7");
1294                                                 Assert.IsNull (inner.InnerException, "#8");
1295                                                 Assert.IsNotNull (inner.Message, "#9");
1296                                                 Assert.IsTrue (inner.Message.IndexOf ("'whatever'") != -1, "#10");
1297                                                 Assert.IsNull (inner.ParamName, "#11");
1298 #endif
1299                                         }
1300                                 }
1301                         }
1302                 }
1303
1304                 [Test]
1305                 public void ResValue ()
1306                 {
1307                         string resXContent = string.Format (CultureInfo.CurrentCulture,
1308                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1309                                 "<root>" +
1310                                 "       <resheader name=\"resmimetype\">" +
1311                                 "               <value>{0}</value>" +
1312                                 "       </resheader>" +
1313                                 "       <resheader name=\"reader\">" +
1314                                 "               <value>System.Resources.ResXResourceReader, {1}</value>" +
1315                                 "       </resheader>" +
1316                                 "       <resheader name=\"writer\">" +
1317                                 "               <value>System.Resources.ResXResourceWriter, {1}</value>" +
1318                                 "       </resheader>" +
1319                                 "       <data name=\"name1\">" +
1320                                 "               <value><![CDATA[ <value1> ]]></value>" +
1321                                 "       </data>" +
1322                                 "       <data name=\"name2\">" +
1323                                 "               <value>  <![CDATA[<value2>]]>  </value>" +
1324                                 "       </data>" +
1325                                 "       <data name=\"name3\">" +
1326                                 "                 <![CDATA[<value3>]]>  " +
1327                                 "       </data>" +
1328                                 "       <data name=\"name4\">" +
1329                                 "               <value> value4 </value>" +
1330                                 "       </data>" +
1331                                 "       <data name=\"name5\">" +
1332                                 "               test<value>value5</value>" +
1333                                 "       </data>" +
1334                                 "       <data name=\"name6\">" +
1335                                 "               test1<value>value6</value>test2" +
1336                                 "       </data>" +
1337                                 "       <data name=\"name7\">" +
1338                                 "               <value>value7a</value>" +
1339                                 "               <whatever>value7b</whatever>" +
1340                                 "       </data>" +
1341                                 "       <data name=\"name8\">" +
1342                                 "               <whatever>value8</whatever>" +
1343                                 "       </data>" +
1344                                 "       <data name=\"name9\">" +
1345                                 "               <whatever>value9a</whatever>" +
1346                                 "               <whatever>value9b</whatever>" +
1347                                 "       </data>" +
1348                                 "       <data name=\"name10\">" +
1349                                 "               test<whatever>value10</whatever>" +
1350                                 "       </data>" +
1351                                 "       <data name=\"name11\">" +
1352                                 "               test1<whatever>value11</whatever>test2" +
1353                                 "       </data>" +
1354                                 "       <data name=\"name12\">" +
1355                                 "               <value> test  <![CDATA[<value12>]]>  </value>" +
1356                                 "       </data>" +
1357                                 "       <data name=\"name13\">" +
1358                                 "                test <![CDATA[<value13>]]>  " +
1359                                 "       </data>" +
1360                                 "       <data name=\"name14\" />" +
1361                                 "       <data name=\"name15\"></data>" +
1362                                 "       <data name=\"name16\">value16</data>" +
1363                                 "       <data name=\"name17\">value17</data>" +
1364                                 "       <data name=\"name18\">" +
1365                                 "               <value>value18</value>" +
1366                                 "               <data name=\"name19\">" +
1367                                 "                       <value>value18</value>" +
1368                                 "               </data>" +
1369                                 "       </data>" +
1370                                 "</root>",
1371                                 ResXResourceWriter.ResMimeType, Consts.AssemblySystem_Windows_Forms);
1372
1373                         using (StringReader sr = new StringReader (resXContent)) {
1374                                 using (ResXResourceReader r = new ResXResourceReader (sr)) {
1375
1376                                         IDictionaryEnumerator enumerator = r.GetEnumerator ();
1377                                         int entries = 0;
1378                                         while (enumerator.MoveNext ()) {
1379                                                 entries++;
1380                                                 switch ((string) enumerator.Key) {
1381                                                 case "name1":
1382                                                         Assert.IsNotNull (enumerator.Value, "#A1");
1383                                                         Assert.AreEqual (" <value1> ", enumerator.Value, "#A2");
1384                                                         break;
1385                                                 case "name2":
1386                                                         Assert.IsNotNull (enumerator.Value, "#B1");
1387                                                         Assert.AreEqual ("<value2>", enumerator.Value, "#B2");
1388                                                         break;
1389                                                 case "name3":
1390                                                         Assert.IsNotNull (enumerator.Value, "#C1");
1391                                                         Assert.AreEqual ("<value3>", enumerator.Value, "#C2");
1392                                                         break;
1393                                                 case "name4":
1394                                                         Assert.IsNotNull (enumerator.Value, "#D1");
1395                                                         Assert.AreEqual (" value4 ", enumerator.Value, "#D2");
1396                                                         break;
1397                                                 case "name5":
1398                                                         Assert.IsNotNull (enumerator.Value, "#E1");
1399 #if NET_2_0
1400                                                         Assert.AreEqual ("value5", enumerator.Value, "#E2");
1401 #else
1402                                                         Assert.AreEqual ("test", enumerator.Value, "#E2");
1403 #endif
1404                                                         break;
1405                                                 case "name6":
1406                                                         Assert.IsNotNull (enumerator.Value, "#F1");
1407 #if NET_2_0
1408                                                         Assert.AreEqual ("test2", enumerator.Value, "#F2");
1409 #else
1410                                                         Assert.AreEqual ("test1", enumerator.Value, "#F2");
1411 #endif
1412                                                         break;
1413                                                 case "name7":
1414                                                         Assert.IsNotNull (enumerator.Value, "#G1");
1415 #if NET_2_0
1416                                                         Assert.AreEqual (string.Empty, enumerator.Value, "#G2");
1417 #else
1418                                                         Assert.AreEqual ("value7a", enumerator.Value, "#G2");
1419 #endif
1420                                                         break;
1421                                                 case "name8":
1422                                                         Assert.IsNotNull (enumerator.Value, "#H1");
1423 #if NET_2_0
1424                                                         Assert.AreEqual (string.Empty, enumerator.Value, "#H2");
1425 #else
1426                                                         Assert.AreEqual ("value8", enumerator.Value, "#H2");
1427 #endif
1428                                                         break;
1429                                                 case "name9":
1430                                                         Assert.IsNotNull (enumerator.Value, "#I1");
1431 #if NET_2_0
1432                                                         Assert.AreEqual (string.Empty, enumerator.Value, "#I2");
1433 #else
1434                                                         Assert.AreEqual ("value9a", enumerator.Value, "#I2");
1435 #endif
1436                                                         break;
1437                                                 case "name10":
1438                                                         Assert.IsNotNull (enumerator.Value, "#J1");
1439 #if NET_2_0
1440                                                         Assert.AreEqual (string.Empty, enumerator.Value, "#J2");
1441 #else
1442                                                         Assert.AreEqual ("test", enumerator.Value, "#J2");
1443 #endif
1444                                                         break;
1445                                                 case "name11":
1446                                                         Assert.IsNotNull (enumerator.Value, "#K1");
1447 #if NET_2_0
1448                                                         Assert.AreEqual ("test2", enumerator.Value, "#K2");
1449 #else
1450                                                         Assert.AreEqual ("test1", enumerator.Value, "#K2");
1451 #endif
1452                                                         break;
1453                                                 case "name12":
1454                                                         Assert.IsNotNull (enumerator.Value, "#L1");
1455                                                         Assert.AreEqual (" test  <value12>", enumerator.Value, "#L2");
1456                                                         break;
1457                                                 case "name13":
1458                                                         Assert.IsNotNull (enumerator.Value, "#M1");
1459 #if NET_2_0
1460                                                         Assert.AreEqual ("<value13>", enumerator.Value, "#M2");
1461 #else
1462                                                         Assert.AreEqual ("test", enumerator.Value, "#M2");
1463 #endif
1464                                                         break;
1465                                                 case "name14":
1466 #if NET_2_0
1467                                                         Assert.IsNull (enumerator.Value, "#N1");
1468 #else
1469                                                         Assert.IsNotNull (enumerator.Value, "#N1");
1470                                                         Assert.AreEqual (string.Empty, enumerator.Value, "#N2");
1471 #endif
1472                                                         break;
1473 #if NET_2_0
1474                                                 case "name16":
1475                                                         Assert.IsNotNull (enumerator.Value, "#O1");
1476                                                         Assert.AreEqual ("value16", enumerator.Value, "#O2");
1477                                                         break;
1478 #endif
1479                                                 case "name17":
1480                                                         Assert.IsNotNull (enumerator.Value, "#P1");
1481                                                         Assert.AreEqual ("value17", enumerator.Value, "#P2");
1482                                                         break;
1483                                                 case "name18":
1484                                                         Assert.IsNotNull (enumerator.Value, "#Q1");
1485                                                         Assert.AreEqual ("value18", enumerator.Value, "#Q2");
1486                                                         break;
1487                                                 default:
1488                                                         Assert.Fail ("#Q:" + enumerator.Key);
1489                                                         break;
1490                                                 }
1491                                         }
1492 #if NET_2_0
1493                                         Assert.AreEqual (17, entries, "#Q");
1494 #else
1495                                         Assert.AreEqual (16, entries, "#Q");
1496 #endif
1497                                 }
1498                         }
1499                 }
1500
1501 #if NET_2_0
1502                 [Test]
1503                 public void UseResXDataNodes ()
1504                 {
1505                         string refFile = Path.Combine (_tempDirectory, "32x32.ico");
1506                         WriteEmbeddedResource ("32x32.ico", refFile);
1507
1508                         string resxFile = Path.Combine (_tempDirectory, "resources.resx");
1509                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
1510                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
1511                                         _resXFileRefTemplate, ResXResourceWriter.ResMimeType, "1.0",
1512                                         Consts.AssemblySystem_Windows_Forms, refFile,
1513                                         typeof (Bitmap).AssemblyQualifiedName, string.Empty,
1514                                         Consts.AssemblyCorlib));
1515                         }
1516
1517                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
1518                                 r.UseResXDataNodes = true;
1519                                 IDictionaryEnumerator enumerator = r.GetEnumerator ();
1520
1521                                 int entries = 0;
1522                                 while (enumerator.MoveNext ()) {
1523                                         entries++;
1524
1525                                         ResXDataNode node = enumerator.Value as ResXDataNode;
1526
1527                                         switch ((string) enumerator.Key) {
1528                                         case "foo":
1529                                                 Assert.AreEqual ("foo", node.Name, "#A1");
1530                                                 Bitmap bitmap = node.GetValue (new AssemblyName[] {typeof (Bitmap).Assembly.GetName ()}) as Bitmap;
1531                                                 Assert.IsNotNull (bitmap, "#A2");
1532                                                 break;
1533                                         case "panel_label.Locked":
1534                                                 Assert.AreEqual ("panel_label.Locked", node.Name, "#B1");
1535                                                 Assert.AreEqual (true, node.GetValue (new AssemblyName[] {typeof (int).Assembly.GetName ()}), "#B2");
1536                                                 break;
1537                                         default:
1538                                                 Assert.Fail ("#C:" + enumerator.Key);
1539                                                 break;
1540                                         }
1541                                 }
1542                                 Assert.AreEqual (2, entries, "#D");
1543                         }
1544                 }
1545                 
1546                 [Test]
1547                 [Category ("NotWorking")]
1548                 public void ResXDataNode_GetNodePosition ()
1549                 {
1550                         // This test relies on a hashtable's enumerator being ordered,
1551                         // when the ordering is not guaranteed.
1552                         string refFile = Path.Combine (_tempDirectory, "32x32.ico");
1553                         WriteEmbeddedResource ("32x32.ico", refFile);
1554
1555                         string resxFile = Path.Combine (_tempDirectory, "resources.resx");
1556                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
1557                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
1558                                         _resXFileRefTemplate, ResXResourceWriter.ResMimeType, "1.0",
1559                                         Consts.AssemblySystem_Windows_Forms, refFile,
1560                                         typeof (Bitmap).AssemblyQualifiedName, string.Empty,
1561                                         Consts.AssemblyCorlib));
1562                         }
1563
1564                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
1565                                 r.UseResXDataNodes = true;
1566                                 IDictionaryEnumerator enumerator = r.GetEnumerator ();
1567                                 enumerator.MoveNext ();
1568                                 ResXDataNode node = enumerator.Value as ResXDataNode;
1569                                 Assert.IsNotNull (node, "#A1");
1570                                 Assert.AreEqual(new Point(1, 717), node.GetNodePosition (), "#A2");
1571                         }
1572                 }
1573
1574                 [Test]
1575                 public void GetMetadataEnumerator ()
1576                 {
1577                         string refFile = Path.Combine (_tempDirectory, "32x32.ico");
1578                         WriteEmbeddedResource ("32x32.ico", refFile);
1579
1580                         string resxFile = Path.Combine (_tempDirectory, "resources.resx");
1581                         using (StreamWriter sw = new StreamWriter (resxFile, false, Encoding.UTF8)) {
1582                                 sw.Write (string.Format (CultureInfo.InvariantCulture,
1583                                         _resXFileRefTemplate, ResXResourceWriter.ResMimeType, "1.0",
1584                                         Consts.AssemblySystem_Windows_Forms, refFile,
1585                                         typeof (Bitmap).AssemblyQualifiedName, string.Empty,
1586                                         Consts.AssemblyCorlib));
1587                         }
1588
1589                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
1590                                 IDictionaryEnumerator enumerator = r.GetMetadataEnumerator ();
1591                                 Assert.IsTrue (enumerator.MoveNext (), "#A1");
1592                                 Assert.IsNotNull (enumerator.Current, "#A2");
1593                                 Assert.AreEqual ("panel_label.Locked", enumerator.Key, "#A3");
1594                                 Assert.AreEqual(typeof(bool), enumerator.Value.GetType(), "#A4");
1595                                 Assert.IsTrue ((bool) enumerator.Value, "#A5");
1596                                 Assert.IsFalse (enumerator.MoveNext (), "#A6");
1597                         }
1598
1599                         using (ResXResourceReader r = new ResXResourceReader (resxFile)) {
1600                                 r.UseResXDataNodes = true;
1601                                 IDictionaryEnumerator enumerator = r.GetMetadataEnumerator ();
1602                                 Assert.IsFalse (enumerator.MoveNext (), "#B1");
1603                         }
1604                 }
1605 #endif
1606
1607                 [Test]
1608                 public void TypeConversion ()
1609                 {
1610                         string resXContent = string.Format (CultureInfo.CurrentCulture,
1611                                 "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1612                                 "<root>" +
1613                                 "       <resheader name=\"resmimetype\">" +
1614                                 "               <value>{0}</value>" +
1615                                 "       </resheader>" +
1616                                 "       <resheader name=\"reader\">" +
1617                                 "               <value>System.Resources.ResXResourceReader, {1}</value>" +
1618                                 "       </resheader>" +
1619                                 "       <resheader name=\"writer\">" +
1620                                 "               <value>System.Resources.ResXResourceWriter, {1}</value>" +
1621                                 "       </resheader>" +
1622                                 "       <data name=\"AnchorStyle\" type=\"System.Windows.Forms.AnchorStyles, {1}\">" +
1623                                 "               <value>Bottom, Left</value>" +
1624                                 "       </data>" +
1625                                 "       <data name=\"BackgroundImage\" type=\"{2}\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">" +
1626                                 "               <value>" +
1627                                 "                       Qk12BQAAAAAAADYEAAAoAAAAEgAAABAAAAABAAgAAAAAAAAAAAAgHAAAIBwAAAABAAAAAQAAAAAA/wAA" +
1628                                 "                       M/8AAGb/AACZ/wAAzP8AAP//ADMA/wAzM/8AM2b/ADOZ/wAzzP8AM///AGYA/wBmM/8AZmb/AGaZ/wBm" +
1629                                 "                       zP8AZv//AJkA/wCZM/8AmWb/AJmZ/wCZzP8Amf//AMwA/wDMM/8AzGb/AMyZ/wDMzP8AzP//AP8A/wD/" +
1630                                 "                       M/8A/2b/AP+Z/wD/zP8A////MwAA/zMAM/8zAGb/MwCZ/zMAzP8zAP//MzMA/zMzM/8zM2b/MzOZ/zMz" +
1631                                 "                       zP8zM///M2YA/zNmM/8zZmb/M2aZ/zNmzP8zZv//M5kA/zOZM/8zmWb/M5mZ/zOZzP8zmf//M8wA/zPM" +
1632                                 "                       M/8zzGb/M8yZ/zPMzP8zzP//M/8A/zP/M/8z/2b/M/+Z/zP/zP8z////ZgAA/2YAM/9mAGb/ZgCZ/2YA" +
1633                                 "                       zP9mAP//ZjMA/2YzM/9mM2b/ZjOZ/2YzzP9mM///ZmYA/2ZmM/9mZmb/ZmaZ/2ZmzP9mZv//ZpkA/2aZ" +
1634                                 "                       M/9mmWb/ZpmZ/2aZzP9mmf//ZswA/2bMM/9mzGb/ZsyZ/2bMzP9mzP//Zv8A/2b/M/9m/2b/Zv+Z/2b/" +
1635                                 "                       zP9m////mQAA/5kAM/+ZAGb/mQCZ/5kAzP+ZAP//mTMA/5kzM/+ZM2b/mTOZ/5kzzP+ZM///mWYA/5lm" +
1636                                 "                       M/+ZZmb/mWaZ/5lmzP+ZZv//mZkA/5mZM/+ZmWb/mZmZ/5mZzP+Zmf//mcwA/5nMM/+ZzGb/mcyZ/5nM" +
1637                                 "                       zP+ZzP//mf8A/5n/M/+Z/2b/mf+Z/5n/zP+Z////zAAA/8wAM//MAGb/zACZ/8wAzP/MAP//zDMA/8wz" +
1638                                 "                       M//MM2b/zDOZ/8wzzP/MM///zGYA/8xmM//MZmb/zGaZ/8xmzP/MZv//zJkA/8yZM//MmWb/zJmZ/8yZ" +
1639                                 "                       zP/Mmf//zMwA/8zMM//MzGb/zMyZ/8zMzP/MzP//zP8A/8z/M//M/2b/zP+Z/8z/zP/M/////wAA//8A" +
1640                                 "                       M///AGb//wCZ//8AzP//AP///zMA//8zM///M2b//zOZ//8zzP//M////2YA//9mM///Zmb//2aZ//9m" +
1641                                 "                       zP//Zv///5kA//+ZM///mWb//5mZ//+ZzP//mf///8wA///MM///zGb//8yZ///MzP//zP////8A////" +
1642                                 "                       M////2b///+Z////zP//////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA" +
1643                                 "                       AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA" +
1644                                 "                       AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA" +
1645                                 "                       AAAAAAAAAAwMDAwAAAAAAAAAAAAAAAAAAAAAAAwMDAwAAAAAAAAAAAAAAAAAAAAAAAwMDAAAAAAAAAAA" +
1646                                 "                       AAAAAAAAAAAAAAwMDAAAAAAAAAAAAAAAAAAAAAAADAwMAAAAAAAAAAAADAAAAAAAAAAMDA0AAAAAAAAA" +
1647                                 "                       AAwMDQAAABMTExMTExMTNwAAAAAMDAwMDQAAABMTExMTExMAAAAANzc3Nzc3NwAAAD4+Pj4+AAAAAD4+" +
1648                                 "                       Pj4+Pj4+PgAAAGJiYgAAAAAAAAAAYmJiAAAAAAAAAGIAAAAAAAAAAABiYmIAAAAAAAAAAAAAAAAAAAAA" +
1649                                 "                       AGJiYgAAAAAAAAAAAAAAAAAAAAAAAGJiYgAAAAAAAAAAAAAAAAAAAAAAAGJiYgAAAAAAAAAAAAAAAAAA" +
1650                                 "                       AAAAAGJiYgAAAAAAAAAAAAAA" +
1651                                 "               </value>" +
1652                                 "       </data>" +
1653                                 "       <data name=\"Buffer\" type=\"{3}\">" +
1654                                 "               <value>BQIH</value>" +
1655                                 "       </data>" +
1656                                 "       <data name=\"Data\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">" +
1657                                 "               <value>Random Thoughts</value>" +
1658                                 "       </data>" +
1659                                 "       <data name=\"Foo\" type=\"System.Windows.Forms.Application, {1}\">" +
1660                                 "               <value>A B C</value>" +
1661                                 "       </data>" +
1662                                 "       <data name=\"Image\" type=\"{2}\">" +
1663                                 "               <value>Summer.jpg</value>" +
1664                                 "       </data>" +
1665                                 "       <data name=\"Text\">" +
1666                                 "               <value>OK</value>" +
1667                                 "       </data>" +
1668                                 "       <data name=\"Unknown\" mimetype=\"application/xxx\">" +
1669                                 "               <value>MIA</value>" +
1670                                 "       </data>" +
1671                                 "       <data name=\"Wrong\" typeof=\"{2}\" mimetype=\"application/xxx\">" +
1672                                 "               <value>SuperUnknown</value>" +
1673                                 "       </data>" +
1674                                 "       <data name=\"Xtra\" type=\"System.Windows.Forms.AnchorStyles, {1}\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">" +
1675                                 "               <value>LeftRight</value>" +
1676                                 "       </data>" +
1677                                 "</root>",
1678                                 ResXResourceWriter.ResMimeType, Consts.AssemblySystem_Windows_Forms,
1679                                 typeof (Bitmap).AssemblyQualifiedName, typeof (byte []).AssemblyQualifiedName);
1680
1681                         using (StringReader sr = new StringReader (resXContent)) {
1682                                 using (ResXResourceReader r = new ResXResourceReader (sr)) {
1683                                         IDictionaryEnumerator enumerator = r.GetEnumerator ();
1684                                         int entries = 0;
1685                                         while (enumerator.MoveNext ()) {
1686                                                 entries++;
1687                                                 switch ((string) enumerator.Key) {
1688                                                 case "AnchorStyle":
1689                                                         Assert.IsNotNull (enumerator.Value, "#A1");
1690                                                         Assert.AreEqual (AnchorStyles.Bottom | AnchorStyles.Left, enumerator.Value, "#A2");
1691                                                         break;
1692                                                 case "BackgroundImage":
1693                                                         Assert.IsNotNull (enumerator.Value, "#B1");
1694                                                         Assert.AreEqual (typeof (Bitmap), enumerator.Value.GetType (), "#B2");
1695                                                         break;
1696                                                 case "Buffer":
1697                                                         Assert.IsNotNull (enumerator.Value, "#C1");
1698                                                         Assert.AreEqual (new byte [] { 5, 2, 7 }, enumerator.Value, "#C2");
1699                                                         break;
1700                                                 case "Data":
1701 #if NET_2_0
1702                                                         Assert.IsNull (enumerator.Value, "#D1");
1703 #else
1704                                                         Assert.IsNotNull (enumerator.Value, "#D1");
1705                                                         Assert.AreEqual ("Random Thoughts", enumerator.Value, "#D2");
1706 #endif
1707                                                         break;
1708                                                 case "Foo":
1709 #if NET_2_0
1710                                                         Assert.IsNull (enumerator.Value, "#E1");
1711 #else
1712                                                         Assert.IsNotNull (enumerator.Value, "#E1");
1713                                                         Assert.AreEqual ("A B C", enumerator.Value, "#E2");
1714 #endif
1715                                                         break;
1716                                                 case "Image":
1717 #if NET_2_0
1718                                                         Assert.IsNull (enumerator.Value, "#F1");
1719 #else
1720                                                         Assert.IsNotNull (enumerator.Value, "#F1");
1721                                                         Assert.AreEqual ("Summer.jpg", enumerator.Value, "#F2");
1722 #endif
1723                                                         break;
1724                                                 case "Text":
1725                                                         Assert.IsNotNull (enumerator.Value, "#G1");
1726                                                         Assert.AreEqual ("OK", enumerator.Value, "#G2");
1727                                                         break;
1728                                                 case "Unknown":
1729 #if NET_2_0
1730                                                         Assert.IsNull (enumerator.Value, "#H1");
1731 #else
1732                                                         Assert.IsNotNull (enumerator.Value, "#H1");
1733                                                         Assert.AreEqual ("MIA", enumerator.Value, "#H2");
1734 #endif
1735                                                         break;
1736                                                 case "Wrong":
1737 #if NET_2_0
1738                                                         Assert.IsNull (enumerator.Value, "#I1");
1739 #else
1740                                                         Assert.IsNotNull (enumerator.Value, "#I1");
1741                                                         Assert.AreEqual ("SuperUnknown", enumerator.Value, "#I2");
1742 #endif
1743                                                         break;
1744                                                 case "Xtra":
1745 #if NET_2_0
1746                                                         Assert.IsNull (enumerator.Value, "#J1");
1747 #else
1748                                                         Assert.IsNotNull (enumerator.Value, "#J1");
1749                                                         Assert.AreEqual ("LeftRight", enumerator.Value, "#J2");
1750 #endif
1751                                                         break;
1752                                                 default:
1753                                                         Assert.Fail ("#J:" + enumerator.Key);
1754                                                         break;
1755                                                 }
1756                                         }
1757                                         Assert.AreEqual (10, entries, "#G");
1758                                 }
1759                         }
1760                 }
1761
1762                 private static void WriteEmbeddedResource (string name, string filename)
1763                 {
1764                         const int size = 512;
1765                         byte [] buffer = new byte [size];
1766                         int count = 0;
1767
1768                         Stream input = typeof (ResXResourceReaderTest).Assembly.
1769                                 GetManifestResourceStream (name);
1770                         Stream output = File.Open (filename, FileMode.Create);
1771
1772                         try {
1773                                 while ((count = input.Read (buffer, 0, size)) > 0) {
1774                                         output.Write (buffer, 0, count);
1775                                 }
1776                         } finally {
1777                                 output.Close ();
1778                         }
1779                 }
1780
1781                 private const string _resXFileRefTemplate =
1782                         "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
1783                         "<root>" +
1784                         "       <resheader name=\"resmimetype\">" +
1785                         "               <value>{0}</value>" +
1786                         "       </resheader>" +
1787                         "       <resheader name=\"version\">" +
1788                         "               <value>{1}</value>" +
1789                         "       </resheader>" +
1790                         "       <resheader name=\"reader\">" +
1791                         "               <value>System.Resources.ResXResourceReader, {2}</value>" +
1792                         "       </resheader>" +
1793                         "       <resheader name=\"writer\">" +
1794                         "               <value>System.Resources.ResXResourceWriter, {2}</value>" +
1795                         "       </resheader>" +
1796 #if NET_2_0
1797                         "       <metadata name=\"panel_label.Locked\" type=\"System.Boolean, {6}\">" +
1798                         "               <value>True</value>" +
1799                         "       </metadata>" +
1800 #endif
1801                         "       <data name=\"foo\" type=\"System.Resources.ResXFileRef, {2}\">" +
1802                         "               <value>{3};{4}{5}</value>" +
1803                         "       </data>" +
1804                         "</root>";
1805         }
1806 }