1 // 2 // ResourceWriterTest.cs 3 // 4 // Author: 5 // Atsushi Enomoto <atsushi@ximian.com> 6 // 7 // Copyright (C) 2007 Novell, Inc. (http://www.novell.com) 8 // 9 10 using System; 11 using System.Collections; 12 using System.IO; 13 using System.Reflection; 14 using System.Resources; 15 using System.Text; 16 17 using NUnit.Framework; 18 19 namespace MonoTests.System.Resources 20 { 21 [TestFixture] 22 public class ResourceWriterTest 23 { 24 private string tempFolder = null; 25 26 [SetUp] SetUp()27 public void SetUp () 28 { 29 tempFolder = Path.Combine (Path.GetTempPath (), 30 "MonoTests.System.Resources.ResourceWriterTest"); 31 if (!Directory.Exists (tempFolder)) 32 Directory.CreateDirectory (tempFolder); 33 } 34 35 [TearDown] TearDown()36 public void TearDown () 37 { 38 if (Directory.Exists (tempFolder)) 39 Directory.Delete (tempFolder, true); 40 } 41 42 [Test] // ctor (Stream) Constructor0_Stream_NotWritable()43 public void Constructor0_Stream_NotWritable () 44 { 45 MemoryStream ms = new MemoryStream (new byte [0], false); 46 47 try { 48 new ResourceWriter (ms); 49 Assert.Fail ("#1"); 50 } catch (ArgumentException ex) { 51 // Stream was not writable 52 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); 53 Assert.IsNull (ex.InnerException, "#3"); 54 Assert.IsNotNull (ex.Message, "#4"); 55 Assert.IsNull (ex.ParamName, "#5"); 56 } 57 } 58 59 [Test] // ctor (Stream) Constructor0_Stream_Null()60 public void Constructor0_Stream_Null () 61 { 62 try { 63 new ResourceWriter ((Stream) null); 64 Assert.Fail ("#1"); 65 } catch (ArgumentNullException ex) { 66 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); 67 Assert.IsNull (ex.InnerException, "#3"); 68 Assert.IsNotNull (ex.Message, "#4"); 69 Assert.IsNotNull (ex.ParamName, "#5"); 70 Assert.AreEqual ("stream", ex.ParamName, "#6"); 71 } 72 } 73 74 [Test] // ctor (string) Constructor1_FileName_Null()75 public void Constructor1_FileName_Null () 76 { 77 try { 78 new ResourceWriter ((string) null); 79 Assert.Fail ("#1"); 80 } catch (ArgumentNullException ex) { 81 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); 82 Assert.IsNull (ex.InnerException, "#3"); 83 Assert.IsNotNull (ex.Message, "#4"); 84 Assert.IsNotNull (ex.ParamName, "#5"); 85 Assert.AreEqual ("fileName", ex.ParamName, "#6"); 86 } 87 } 88 89 [Test] // AddResource (string, byte []) AddResource0()90 public void AddResource0 () 91 { 92 byte [] value = new byte [] { 5, 7 }; 93 94 MemoryStream ms = new MemoryStream (); 95 ResourceWriter writer = new ResourceWriter (ms); 96 writer.AddResource ("Name", value); 97 writer.Generate (); 98 99 try { 100 writer.AddResource ("Address", new byte [] { 8, 12 }); 101 Assert.Fail ("#A1"); 102 } catch (InvalidOperationException ex) { 103 // The resource writer has already been closed 104 // and cannot be edited 105 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2"); 106 Assert.IsNull (ex.InnerException, "#A3"); 107 Assert.IsNotNull (ex.Message, "#A4"); 108 } 109 110 ms.Position = 0; 111 ResourceReader rr = new ResourceReader (ms); 112 IDictionaryEnumerator enumerator = rr.GetEnumerator (); 113 Assert.IsTrue (enumerator.MoveNext (), "#B1"); 114 Assert.AreEqual ("Name", enumerator.Key, "#B3"); 115 Assert.AreEqual (value, enumerator.Value, "#B4"); 116 Assert.IsFalse (enumerator.MoveNext (), "#B5"); 117 118 writer.Close (); 119 } 120 121 [Test] // AddResource (string, byte []) AddResource0_Name_Null()122 public void AddResource0_Name_Null () 123 { 124 byte [] value = new byte [] { 5, 7 }; 125 126 MemoryStream ms = new MemoryStream (); 127 ResourceWriter writer = new ResourceWriter (ms); 128 129 try { 130 writer.AddResource ((string) null, value); 131 Assert.Fail ("#1"); 132 } catch (ArgumentNullException ex) { 133 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); 134 Assert.IsNull (ex.InnerException, "#3"); 135 Assert.IsNotNull (ex.Message, "#4"); 136 Assert.IsNotNull (ex.ParamName, "#5"); 137 Assert.AreEqual ("name", ex.ParamName, "#6"); 138 } 139 140 writer.Close (); 141 } 142 143 [Test] // AddResource (string, byte []) AddResource0_Value_Null()144 public void AddResource0_Value_Null () 145 { 146 MemoryStream ms = new MemoryStream (); 147 ResourceWriter writer = new ResourceWriter (ms); 148 writer.AddResource ("Name", (byte []) null); 149 writer.Generate (); 150 151 ms.Position = 0; 152 ResourceReader rr = new ResourceReader (ms); 153 IDictionaryEnumerator enumerator = rr.GetEnumerator (); 154 Assert.IsTrue (enumerator.MoveNext (), "#1"); 155 Assert.AreEqual ("Name", enumerator.Key, "#2"); 156 Assert.IsNull (enumerator.Value, "#3"); 157 Assert.IsFalse (enumerator.MoveNext (), "#4"); 158 159 writer.Close (); 160 } 161 162 [Test] // AddResource (string, object) AddResource1()163 public void AddResource1 () 164 { 165 TimeSpan value = new TimeSpan (2, 5, 8); 166 167 MemoryStream ms = new MemoryStream (); 168 ResourceWriter writer = new ResourceWriter (ms); 169 writer.AddResource ("Interval", value); 170 writer.Generate (); 171 172 try { 173 writer.AddResource ("Start", value); 174 Assert.Fail ("#A1"); 175 } catch (InvalidOperationException ex) { 176 // The resource writer has already been closed 177 // and cannot be edited 178 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2"); 179 Assert.IsNull (ex.InnerException, "#A3"); 180 Assert.IsNotNull (ex.Message, "#A4"); 181 } 182 183 ms.Position = 0; 184 ResourceReader rr = new ResourceReader (ms); 185 IDictionaryEnumerator enumerator = rr.GetEnumerator (); 186 Assert.IsTrue (enumerator.MoveNext (), "#B1"); 187 Assert.AreEqual ("Interval", enumerator.Key, "#B3"); 188 Assert.AreEqual (value, enumerator.Value, "#B4"); 189 Assert.IsFalse (enumerator.MoveNext (), "#B5"); 190 191 writer.Close (); 192 } 193 194 [Test] // AddResource (string, object) AddResource1_Name_Null()195 public void AddResource1_Name_Null () 196 { 197 MemoryStream ms = new MemoryStream (); 198 ResourceWriter writer = new ResourceWriter (ms); 199 200 try { 201 writer.AddResource ((string) null, new object ()); 202 Assert.Fail ("#1"); 203 } catch (ArgumentNullException ex) { 204 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); 205 Assert.IsNull (ex.InnerException, "#3"); 206 Assert.IsNotNull (ex.Message, "#4"); 207 Assert.IsNotNull (ex.ParamName, "#5"); 208 Assert.AreEqual ("name", ex.ParamName, "#6"); 209 } 210 211 writer.Close (); 212 } 213 214 [Test] // AddResource (string, object) AddResource1_Value_Null()215 public void AddResource1_Value_Null () 216 { 217 MemoryStream ms = new MemoryStream (); 218 ResourceWriter writer = new ResourceWriter (ms); 219 writer.AddResource ("Name", (object) null); 220 writer.Generate (); 221 222 ms.Position = 0; 223 ResourceReader rr = new ResourceReader (ms); 224 IDictionaryEnumerator enumerator = rr.GetEnumerator (); 225 Assert.IsTrue (enumerator.MoveNext (), "#1"); 226 Assert.AreEqual ("Name", enumerator.Key, "#2"); 227 Assert.IsNull (enumerator.Value, "#3"); 228 Assert.IsFalse (enumerator.MoveNext (), "#4"); 229 230 writer.Close (); 231 } 232 233 [Test] // AddResource (string, string) AddResource2()234 public void AddResource2 () 235 { 236 String value = "Some\0Value\tOr\rAnother"; 237 238 MemoryStream ms = new MemoryStream (); 239 ResourceWriter writer = new ResourceWriter (ms); 240 writer.AddResource ("Text", value); 241 writer.Generate (); 242 243 try { 244 writer.AddResource ("Description", value); 245 Assert.Fail ("#A1"); 246 } catch (InvalidOperationException ex) { 247 // The resource writer has already been closed 248 // and cannot be edited 249 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2"); 250 Assert.IsNull (ex.InnerException, "#A3"); 251 Assert.IsNotNull (ex.Message, "#A4"); 252 } 253 254 ms.Position = 0; 255 ResourceReader rr = new ResourceReader (ms); 256 IDictionaryEnumerator enumerator = rr.GetEnumerator (); 257 Assert.IsTrue (enumerator.MoveNext (), "#B1"); 258 Assert.AreEqual ("Text", enumerator.Key, "#B3"); 259 Assert.AreEqual (value, enumerator.Value, "#B4"); 260 Assert.IsFalse (enumerator.MoveNext (), "#B5"); 261 262 writer.Close (); 263 } 264 265 [Test] // AddResource (string, string) AddResource2_Name_Null()266 public void AddResource2_Name_Null () 267 { 268 MemoryStream ms = new MemoryStream (); 269 ResourceWriter writer = new ResourceWriter (ms); 270 271 try { 272 writer.AddResource ((string) null, "abc"); 273 Assert.Fail ("#1"); 274 } catch (ArgumentNullException ex) { 275 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2"); 276 Assert.IsNull (ex.InnerException, "#3"); 277 Assert.IsNotNull (ex.Message, "#4"); 278 Assert.IsNotNull (ex.ParamName, "#5"); 279 Assert.AreEqual ("name", ex.ParamName, "#6"); 280 } 281 282 writer.Close (); 283 } 284 285 [Test] // AddResource (string, string) AddResource2_Value_Null()286 public void AddResource2_Value_Null () 287 { 288 MemoryStream ms = new MemoryStream (); 289 ResourceWriter writer = new ResourceWriter (ms); 290 writer.AddResource ("Name", (string) null); 291 writer.Generate (); 292 293 ms.Position = 0; 294 ResourceReader rr = new ResourceReader (ms); 295 IDictionaryEnumerator enumerator = rr.GetEnumerator (); 296 Assert.IsTrue (enumerator.MoveNext (), "#1"); 297 Assert.AreEqual ("Name", enumerator.Key, "#2"); 298 Assert.IsNull (enumerator.Value, "#3"); 299 Assert.IsFalse (enumerator.MoveNext (), "#4"); 300 301 writer.Close (); 302 } 303 304 [Test] AddResource_Closed()305 public void AddResource_Closed () 306 { 307 MemoryStream ms = new MemoryStream (); 308 ResourceWriter writer = new ResourceWriter (ms); 309 writer.AddResource ("Name", "Miguel"); 310 writer.Close (); 311 312 try { 313 writer.AddResource ("Address", "US"); 314 Assert.Fail ("#1"); 315 } catch (InvalidOperationException ex) { 316 // The resource writer has already been closed 317 // and cannot be edited 318 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2"); 319 Assert.IsNull (ex.InnerException, "#3"); 320 Assert.IsNotNull (ex.Message, "#4"); 321 } 322 } 323 324 [Test] AddResource_Name_Duplicate()325 public void AddResource_Name_Duplicate () 326 { 327 MemoryStream ms = new MemoryStream (); 328 ResourceWriter writer = new ResourceWriter (ms); 329 writer.AddResource ("FirstName", "Miguel"); 330 331 try { 332 writer.AddResource ("FirstNaMe", "Chris"); 333 Assert.Fail ("#1"); 334 } catch (ArgumentException ex) { 335 // Item has already been added. Key is dictionary: 336 // 'FirstName' Key being added: 'FirstNaMe' 337 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2"); 338 Assert.IsNull (ex.InnerException, "#3"); 339 Assert.IsNotNull (ex.Message, "#4"); 340 Assert.IsNull (ex.ParamName, "#5"); 341 } 342 343 writer.AddResource ("Name", "Miguel"); 344 writer.Close (); 345 } 346 347 // We are using a FileStream instead of a MemoryStream 348 // to test that we support all kind of Stream instances, 349 // and not only MemoryStream, as it used to be before 4.0. 350 [Test] 351 [Category ("MobileNotWorking")] AddResource_Stream_Default()352 public void AddResource_Stream_Default () 353 { 354 MemoryStream stream = new MemoryStream (); 355 byte [] buff = Encoding.Unicode.GetBytes ("Miguel"); 356 stream.Write (buff, 0, buff.Length); 357 stream.Position = 0; 358 359 ResourceWriter rw = new ResourceWriter ("Test/resources/AddResource_Stream.resources"); 360 rw.AddResource ("Name", (object)stream); 361 rw.Close (); 362 363 ResourceReader rr = new ResourceReader ("Test/resources/AddResource_Stream.resources"); 364 IDictionaryEnumerator enumerator = rr.GetEnumerator (); 365 366 // Get the first element 367 Assert.AreEqual (true, enumerator.MoveNext (), "#A0"); 368 369 DictionaryEntry de = enumerator.Entry; 370 Assert.AreEqual ("Name", enumerator.Key, "#A1"); 371 Stream result_stream = de.Value as Stream; 372 Assert.AreEqual (true, result_stream != null, "#A2"); 373 374 // Get the data and compare 375 byte [] result_buff = new byte [result_stream.Length]; 376 result_stream.Read (result_buff, 0, result_buff.Length); 377 string string_res = Encoding.Unicode.GetString (result_buff); 378 Assert.AreEqual ("Miguel", string_res, "#A3"); 379 380 rr.Close (); 381 stream.Close (); 382 } 383 384 [Test] AddResource_Stream_Errors()385 public void AddResource_Stream_Errors () 386 { 387 MemoryStream ms = new MemoryStream (); 388 ResourceWriter rw = new ResourceWriter (ms); 389 390 ResourceStream stream = new ResourceStream ("Test"); 391 stream.SetCanSeek (false); 392 393 // 394 // Seek not supported. 395 // 396 try { 397 rw.AddResource ("Name", stream); 398 Assert.Fail ("#Exc1"); 399 } catch (ArgumentException) { 400 } 401 402 // 403 // Even using the overload taking an object 404 // seems to check for that 405 // 406 try { 407 rw.AddResource ("Name", (object)stream); 408 Assert.Fail ("#Exc2"); 409 } catch (ArgumentException) { 410 } 411 412 rw.Close (); 413 } 414 415 [Test] AddResource_Stream_Details()416 public void AddResource_Stream_Details () 417 { 418 MemoryStream ms = new MemoryStream (); 419 ResourceWriter rw = new ResourceWriter (ms); 420 421 ResourceStream stream = new ResourceStream ("MonoTest"); 422 423 // Set Position so we can test the ResourceWriter is resetting 424 // it to 0 when generating. 425 stream.Position = 2; 426 rw.AddResource ("Name", stream); 427 rw.Generate (); 428 429 ms.Position = 0; 430 ResourceReader rr = new ResourceReader (ms); 431 string value = GetStringFromResource (rr, "Name"); 432 Assert.AreEqual ("MonoTest", value, "#A1"); 433 Assert.AreEqual (false, stream.IsDiposed, "#A2"); 434 435 // Test the second overload 436 stream.Reset (); 437 ms = new MemoryStream (); 438 rw = new ResourceWriter (ms); 439 rw.AddResource ("Name", stream, true); 440 rw.Generate (); 441 442 ms.Position = 0; 443 rr = new ResourceReader (ms); 444 value = GetStringFromResource (rr, "Name"); 445 Assert.AreEqual ("MonoTest", value, "#B1"); 446 Assert.AreEqual (true, stream.IsDiposed, "#B2"); 447 448 rr.Close (); 449 rw.Close (); 450 stream.Close (); 451 } 452 GetStringFromResource(ResourceReader reader, string name)453 string GetStringFromResource (ResourceReader reader, string name) 454 { 455 Stream s = null; 456 457 foreach (DictionaryEntry de in reader) 458 if ((string)de.Key == name) 459 s = (Stream)de.Value; 460 461 if (s == null) 462 return null; 463 464 byte [] buff = new byte [s.Length]; 465 s.Read (buff, 0, buff.Length); 466 return Encoding.Unicode.GetString (buff, 0, buff.Length); 467 } 468 469 class ResourceStream : Stream 470 { 471 bool can_seek; 472 bool disposed; 473 byte [] buff; 474 int pos; 475 ResourceStream(string src)476 public ResourceStream (string src) 477 { 478 buff = Encoding.Unicode.GetBytes (src); 479 Reset (); 480 } 481 Reset()482 public void Reset () 483 { 484 can_seek = true; 485 pos = 0; 486 } 487 488 public override bool CanRead 489 { 490 get { 491 return true; 492 } 493 } 494 495 public override bool CanWrite 496 { 497 get { 498 throw new NotSupportedException (); 499 } 500 } 501 502 public override bool CanSeek 503 { 504 get { 505 return can_seek; 506 } 507 } 508 SetCanSeek(bool value)509 public void SetCanSeek (bool value) 510 { 511 can_seek = value; 512 } 513 514 public override long Position 515 { 516 get { 517 return pos; 518 } 519 set { 520 pos = (int)value; 521 } 522 } 523 524 public override long Length { 525 get { 526 return buff.Length; 527 } 528 } 529 SetLength(long value)530 public override void SetLength (long value) 531 { 532 throw new NotSupportedException (); 533 } 534 Flush()535 public override void Flush () 536 { 537 // Nothing. 538 } 539 Dispose(bool disposing)540 protected override void Dispose (bool disposing) 541 { 542 base.Dispose (disposing); 543 disposed = true; 544 } 545 546 public bool IsDiposed { 547 get { 548 return disposed; 549 } 550 } 551 552 // We are going to be returning bytes in blocks of three 553 // Just to show a slightly anormal but correct behaviour. Read(byte [] buffer, int offset, int count)554 public override int Read (byte [] buffer, int offset, int count) 555 { 556 if (disposed) 557 throw new ObjectDisposedException ("ResourcesStream"); 558 559 // Check if we are done. 560 if (pos == buff.Length) 561 return 0; 562 563 if (buff.Length - pos < 3) 564 count = buff.Length - pos; 565 else 566 count = 3; 567 568 Buffer.BlockCopy (buff, pos, buffer, offset, count); 569 pos += count; 570 return count; 571 } 572 Write(byte [] buffer, int offset, int count)573 public override void Write (byte [] buffer, int offset, int count) 574 { 575 throw new NotSupportedException (); 576 } 577 Seek(long offset, SeekOrigin origin)578 public override long Seek (long offset, SeekOrigin origin) 579 { 580 throw new NotSupportedException (); 581 } 582 } 583 584 [Test] 585 [Category ("MobileNotWorking")] Bug81759()586 public void Bug81759 () 587 { 588 MemoryStream ms = new MemoryStream (); 589 using (ResourceReader xr = new ResourceReader ( 590 "Test/resources/bug81759.resources")) { 591 ResourceWriter rw = new ResourceWriter (ms); 592 foreach (DictionaryEntry de in xr) 593 rw.AddResource ((string) de.Key, de.Value); 594 rw.Close (); 595 } 596 ResourceReader rr = new ResourceReader (new MemoryStream (ms.ToArray ())); 597 foreach (DictionaryEntry de in rr) { 598 Assert.AreEqual ("imageList.ImageSize", de.Key as string, "#1"); 599 Assert.AreEqual ("Size", de.Value.GetType ().Name, "#2"); 600 } 601 } 602 603 [Test] Close()604 public void Close () 605 { 606 MemoryStream ms = new MemoryStream (); 607 ResourceWriter writer = new ResourceWriter (ms); 608 writer.AddResource ("Name", "Miguel"); 609 Assert.IsTrue (ms.CanWrite, "#A1"); 610 Assert.IsTrue (ms.GetBuffer ().Length == 0, "#A2"); 611 writer.Close (); 612 Assert.IsFalse (ms.CanWrite, "#B1"); 613 Assert.IsFalse (ms.GetBuffer ().Length == 0, "#B2"); 614 writer.Close (); 615 } 616 617 [Test] // bug #339074 Close_NoResources()618 public void Close_NoResources () 619 { 620 string tempFile = Path.Combine (Path.GetTempPath (), "test.resources"); 621 622 ResourceWriter writer = new ResourceWriter (tempFile); 623 writer.Close (); 624 625 using (FileStream fs = File.OpenRead (tempFile)) { 626 Assert.IsFalse (fs.Length == 0, "#1"); 627 628 using (ResourceReader reader = new ResourceReader (fs)) { 629 Assert.IsFalse (reader.GetEnumerator ().MoveNext (), "#2"); 630 } 631 } 632 633 File.Delete (tempFile); 634 } 635 636 [Test] Generate()637 public void Generate () 638 { 639 MemoryStream ms = new MemoryStream (); 640 ResourceWriter writer = new ResourceWriter (ms); 641 writer.AddResource ("Name", "Miguel"); 642 Assert.IsTrue (ms.Length == 0, "#A1"); 643 Assert.IsTrue (ms.CanWrite, "#A2"); 644 writer.Generate (); 645 Assert.IsFalse (ms.Length == 0, "#B2"); 646 Assert.IsTrue (ms.CanWrite, "#B2"); 647 648 try { 649 writer.Generate (); 650 Assert.Fail ("#C1"); 651 } catch (InvalidOperationException ex) { 652 // The resource writer has already been closed 653 // and cannot be edited 654 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2"); 655 Assert.IsNull (ex.InnerException, "#C3"); 656 Assert.IsNotNull (ex.Message, "#C4"); 657 } 658 659 writer.Close (); 660 } 661 662 [Test] Generate_Closed()663 public void Generate_Closed () 664 { 665 MemoryStream ms = new MemoryStream (); 666 ResourceWriter writer = new ResourceWriter (ms); 667 writer.AddResource ("Name", "Miguel"); 668 writer.Close (); 669 670 try { 671 writer.Generate (); 672 Assert.Fail ("#B1"); 673 } catch (InvalidOperationException ex) { 674 // The resource writer has already been closed 675 // and cannot be edited 676 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2"); 677 Assert.IsNull (ex.InnerException, "#B3"); 678 Assert.IsNotNull (ex.Message, "#B4"); 679 } 680 } 681 682 [Test] // bug #82566 WriteEnum()683 public void WriteEnum () 684 { 685 MemoryStream ms = new MemoryStream (); 686 687 ResourceWriter writer = new ResourceWriter (ms); 688 writer.AddResource ("Targets", AttributeTargets.Assembly); 689 writer.Generate (); 690 691 ms.Position = 0; 692 693 bool found = false; 694 695 ResourceReader reader = new ResourceReader (ms); 696 foreach (DictionaryEntry de in reader) { 697 string name = de.Key as string; 698 Assert.IsNotNull (name, "#1"); 699 Assert.AreEqual ("Targets", name, "#2"); 700 Assert.IsNotNull (de.Value, "#3"); 701 Assert.AreEqual (AttributeTargets.Assembly, de.Value, "#4"); 702 found = true; 703 } 704 705 Assert.IsTrue (found, "#5"); 706 707 writer.Dispose (); 708 } 709 710 } 711 } 712