1 // StreamReaderTest.cs - NUnit Test Cases for the SystemIO.StreamReader class
3 // David Brandt (bucky@keystreams.com)
5 // (C) Ximian, Inc. http://www.ximian.com
6 // Copyright (C) 2004 Novell (http://www.novell.com)
13 using System.Threading.Tasks;
16 using NUnit.Framework;
18 namespace MonoTests.System.IO
21 public class StreamReaderTest
23 static string TempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.System.IO.Tests");
24 private string _codeFileName = TempFolder + Path.DirectorySeparatorChar + "AFile.txt";
25 private const string TestString = "Hello World!";
30 if (!Directory.Exists (TempFolder))
31 Directory.CreateDirectory (TempFolder);
33 if (!File.Exists (_codeFileName))
34 File.Create (_codeFileName).Close ();
38 public void TearDown ()
40 if (Directory.Exists (TempFolder))
41 Directory.Delete (TempFolder, true);
46 public void TestCtor1() {
48 bool errorThrown = false;
50 new StreamReader((Stream)null);
51 } catch (ArgumentNullException) {
54 Assert.IsTrue (errorThrown, "null string error not thrown");
57 bool errorThrown = false;
58 FileStream f = new FileStream(_codeFileName, FileMode.Open, FileAccess.Write);
60 StreamReader r = new StreamReader(f);
62 } catch (ArgumentException) {
66 Assert.IsTrue (errorThrown, "no read error not thrown");
69 // this is probably incestuous, but, oh well.
70 FileStream f = new FileStream(_codeFileName,
73 StreamReader r = new StreamReader(f);
74 Assert.IsNotNull (r, "no stream reader");
81 public void TestCtor2() {
83 bool errorThrown = false;
86 } catch (ArgumentException) {
88 } catch (Exception e) {
89 Assert.Fail ("Incorrect exception thrown at 1: " + e.ToString());
91 Assert.IsTrue (errorThrown, "empty string error not thrown");
94 bool errorThrown = false;
96 new StreamReader((string)null);
97 } catch (ArgumentNullException) {
99 } catch (Exception e) {
100 Assert.Fail ("Incorrect exception thrown at 2: " + e.ToString());
102 Assert.IsTrue (errorThrown, "null string error not thrown");
105 bool errorThrown = false;
107 new StreamReader("nonexistentfile");
108 } catch (FileNotFoundException) {
110 } catch (Exception e) {
111 Assert.Fail ("Incorrect exception thrown at 3: " + e.ToString());
113 Assert.IsTrue (errorThrown, "fileNotFound error not thrown");
116 bool errorThrown = false;
118 new StreamReader("nonexistentdir/file");
119 } catch (DirectoryNotFoundException) {
121 } catch (Exception e) {
122 Assert.Fail ("Incorrect exception thrown at 4: " + e.ToString());
124 Assert.IsTrue (errorThrown, "dirNotFound error not thrown");
127 bool errorThrown = false;
129 new StreamReader("!$what? what? Huh? !$*#" + Path.InvalidPathChars[0]);
130 } catch (IOException) {
132 } catch (ArgumentException) {
133 // FIXME - the spec says 'IOExc', but the
134 // compiler says 'ArgExc'...
136 } catch (Exception e) {
137 Assert.Fail ("Incorrect exception thrown at 5: " + e.ToString());
139 Assert.IsTrue (errorThrown, "invalid filename error not thrown");
142 // this is probably incestuous, but, oh well.
143 StreamReader r = new StreamReader(_codeFileName);
144 Assert.IsNotNull (r, "no stream reader");
150 public void TestCtor3() {
152 bool errorThrown = false;
154 new StreamReader((Stream)null, false);
155 } catch (ArgumentNullException) {
157 } catch (Exception e) {
158 Assert.Fail ("Incorrect exception thrown at 1: " + e.ToString());
160 Assert.IsTrue (errorThrown, "null stream error not thrown");
163 bool errorThrown = false;
164 FileStream f = new FileStream(_codeFileName, FileMode.Open, FileAccess.Write);
166 StreamReader r = new StreamReader(f, false);
168 } catch (ArgumentException) {
170 } catch (Exception e) {
171 Assert.Fail ("Incorrect exception thrown at 2: " + e.ToString());
174 Assert.IsTrue (errorThrown, "no read error not thrown");
177 // this is probably incestuous, but, oh well.
178 FileStream f = new FileStream(_codeFileName,
181 StreamReader r = new StreamReader(f, false);
182 Assert.IsNotNull (r, "no stream reader");
187 bool errorThrown = false;
189 StreamReader r = new StreamReader((Stream)null, true);
190 } catch (ArgumentNullException) {
192 } catch (Exception e) {
193 Assert.Fail ("Incorrect exception thrown at 3: " + e.ToString());
195 Assert.IsTrue (errorThrown, "null string error not thrown");
198 bool errorThrown = false;
199 FileStream f = new FileStream(_codeFileName, FileMode.Open, FileAccess.Write);
201 StreamReader r = new StreamReader(f, true);
203 } catch (ArgumentException) {
205 } catch (Exception e) {
206 Assert.Fail ("Incorrect exception thrown at 4: " + e.ToString());
209 Assert.IsTrue (errorThrown, "no read error not thrown");
212 // this is probably incestuous, but, oh well.
213 FileStream f = new FileStream(_codeFileName,
216 StreamReader r = new StreamReader(f, true);
217 Assert.IsNotNull (r, "no stream reader");
224 public void TestCtor4() {
226 bool errorThrown = false;
228 new StreamReader("", false);
229 } catch (ArgumentException) {
231 } catch (Exception e) {
232 Assert.Fail ("Incorrect exception thrown at 1: " + e.ToString());
234 Assert.IsTrue (errorThrown, "empty string error not thrown");
237 bool errorThrown = false;
239 new StreamReader((string)null, false);
240 } catch (ArgumentNullException) {
242 } catch (Exception e) {
243 Assert.Fail ("Incorrect exception thrown at 2: " + e.ToString());
245 Assert.IsTrue (errorThrown, "null string error not thrown");
248 bool errorThrown = false;
250 new StreamReader(TempFolder + "/nonexistentfile", false);
251 } catch (FileNotFoundException) {
253 } catch (Exception e) {
254 Assert.Fail ("Incorrect exception thrown at 3: " + e.ToString());
256 Assert.IsTrue (errorThrown, "fileNotFound error not thrown");
259 bool errorThrown = false;
261 new StreamReader(TempFolder + "/nonexistentdir/file", false);
262 } catch (DirectoryNotFoundException) {
264 } catch (Exception e) {
265 Assert.Fail ("Incorrect exception thrown at 4: " + e.ToString());
267 Assert.IsTrue (errorThrown, "dirNotFound error not thrown");
270 bool errorThrown = false;
272 new StreamReader("!$what? what? Huh? !$*#" + Path.InvalidPathChars[0], false);
273 } catch (IOException) {
275 } catch (ArgumentException) {
276 // FIXME - the spec says 'IOExc', but the
277 // compiler says 'ArgExc'...
279 } catch (Exception e) {
280 Assert.Fail ("Incorrect exception thrown at 5: " + e.ToString());
282 Assert.IsTrue (errorThrown, "invalid filename error not thrown");
285 // this is probably incestuous, but, oh well.
286 StreamReader r = new StreamReader(_codeFileName, false);
287 Assert.IsNotNull (r, "no stream reader");
291 bool errorThrown = false;
293 new StreamReader("", true);
294 } catch (ArgumentException) {
296 } catch (Exception e) {
297 Assert.Fail ("Incorrect exception thrown at 6: " + e.ToString());
299 Assert.IsTrue (errorThrown, "empty string error not thrown");
302 bool errorThrown = false;
304 new StreamReader((string)null, true);
305 } catch (ArgumentNullException) {
307 } catch (Exception e) {
308 Assert.Fail ("Incorrect exception thrown at 7: " + e.ToString());
310 Assert.IsTrue (errorThrown, "null string error not thrown");
313 bool errorThrown = false;
315 new StreamReader(TempFolder + "/nonexistentfile", true);
316 } catch (FileNotFoundException) {
318 } catch (Exception e) {
319 Assert.Fail ("Incorrect exception thrown at 8: " + e.ToString());
321 Assert.IsTrue (errorThrown, "fileNotFound error not thrown");
324 bool errorThrown = false;
326 new StreamReader(TempFolder + "/nonexistentdir/file", true);
327 } catch (DirectoryNotFoundException) {
329 } catch (Exception e) {
330 Assert.Fail ("Incorrect exception thrown at 9: " + e.ToString());
332 Assert.IsTrue (errorThrown, "dirNotFound error not thrown");
335 bool errorThrown = false;
337 new StreamReader("!$what? what? Huh? !$*#" + Path.InvalidPathChars[0], true);
338 } catch (IOException) {
340 } catch (ArgumentException) {
341 // FIXME - the spec says 'IOExc', but the
342 // compiler says 'ArgExc'...
344 } catch (Exception e) {
345 Assert.Fail ("Incorrect exception thrown at 10: " + e.ToString());
347 Assert.IsTrue (errorThrown, "invalid filename error not thrown");
350 // this is probably incestuous, but, oh well.
351 StreamReader r = new StreamReader(_codeFileName, true);
352 Assert.IsNotNull (r, "no stream reader");
357 // TODO - Ctor with Encoding
360 public void TestBaseStream() {
362 MemoryStream m = new MemoryStream(b);
363 StreamReader r = new StreamReader(m);
364 Assert.AreSame (m, r.BaseStream, "wrong base stream ");
369 public void TestCurrentEncoding()
372 MemoryStream m = new MemoryStream(b);
373 StreamReader r = new StreamReader(m);
374 Assert.AreSame (Encoding.UTF8, r.CurrentEncoding, "wrong encoding");
377 // TODO - Close - annoying spec - won't commit to any exceptions. How to test?
378 // TODO - DiscardBufferedData - I have no clue how to test this function.
381 public void TestPeek() {
382 // FIXME - how to get an IO Exception?
389 m = new MemoryStream (b);
390 r = new StreamReader(m);
392 int nothing = r.Peek();
394 } catch (ObjectDisposedException) {
397 b = new byte [] {1, 2, 3, 4, 5, 6};
398 m = new MemoryStream (b);
399 r = new StreamReader(m);
400 for (int i = 1; i <= 6; i++) {
401 Assert.AreEqual (i, r.Peek(), "#2");
404 Assert.AreEqual (-1, r.Peek(), "#3");
408 public void TestRead() {
409 // FIXME - how to get an IO Exception?
411 bool errorThrown = false;
414 MemoryStream m = new MemoryStream(b);
415 StreamReader r = new StreamReader(m);
417 int nothing = r.Read();
418 } catch (ObjectDisposedException) {
420 } catch (Exception e) {
421 Assert.Fail ("Incorrect exception thrown at 1: " + e.ToString());
423 Assert.IsTrue (errorThrown, "nothing-to-read error not thrown");
426 Byte[] b = {1, 2, 3, 4, 5, 6};
427 MemoryStream m = new MemoryStream(b);
429 StreamReader r = new StreamReader(m);
430 for (int i = 1; i <= 6; i++) {
431 Assert.AreEqual (i, r.Read (), "read incorrect");
433 Assert.AreEqual (-1, r.Read (), "Should be none left");
437 bool errorThrown = false;
440 StreamReader r = new StreamReader(new MemoryStream(b));
442 } catch (ArgumentNullException) {
444 } catch (ArgumentException) {
446 } catch (Exception e) {
447 Assert.Fail ("Incorrect exception thrown at 2: " + e.ToString());
449 Assert.IsTrue (errorThrown, "null buffer error not thrown");
452 bool errorThrown = false;
455 StreamReader r = new StreamReader(new MemoryStream(b));
456 Char[] c = new Char[1];
458 } catch (ArgumentException) {
460 } catch (Exception e) {
461 Assert.Fail ("Incorrect exception thrown at 3: " + e.ToString());
463 Assert.IsTrue (errorThrown, "too-long range error not thrown");
466 bool errorThrown = false;
469 StreamReader r = new StreamReader(new MemoryStream(b));
470 Char[] c = new Char[1];
472 } catch (ArgumentOutOfRangeException) {
474 } catch (Exception e) {
475 Assert.Fail ("Incorrect exception thrown at 4: " + e.ToString());
477 Assert.IsTrue (errorThrown, "out of range error not thrown");
480 bool errorThrown = false;
483 StreamReader r = new StreamReader(new MemoryStream(b));
484 Char[] c = new Char[1];
486 } catch (ArgumentOutOfRangeException) {
488 } catch (Exception e) {
489 Assert.Fail ("Incorrect exception thrown at 5: " + e.ToString());
491 Assert.IsTrue (errorThrown, "out of range error not thrown");
496 Byte[] b = {(byte)'a', (byte)'b', (byte)'c',
497 (byte)'d', (byte)'e', (byte)'f',
499 MemoryStream m = new MemoryStream(b);
501 StreamReader r = new StreamReader(m);
504 char[] buffer = new Char[7];
506 char[] target = {'g','d','e','f','b','c','a'};
508 r.Read(buffer, 6, 1);
510 r.Read(buffer, 4, 2);
512 r.Read(buffer, 1, 3);
514 r.Read(buffer, 0, 1);
516 for (int i = 0; i < target.Length; i++) {
517 Assert.AreEqual (target[i], buffer[i], "read no work");
520 } catch (Exception e) {
521 Assert.Fail ("Caught when ii=" + ii + ". e:" + e.ToString());
527 public void TestReadLine() {
528 // TODO Out Of Memory Exc? IO Exc?
529 Byte[] b = new Byte[8];
538 MemoryStream m = new MemoryStream(b);
539 StreamReader r = new StreamReader(m);
540 Assert.AreEqual ("a", r.ReadLine(), "#1");
541 Assert.AreEqual ("b", r.ReadLine (), "#2");
542 Assert.AreEqual ("c", r.ReadLine (), "#3");
543 Assert.AreEqual ("d", r.ReadLine(), "#4");
544 Assert.IsNull (r.ReadLine (), "#5");
548 public void ReadLine1() {
549 Byte[] b = new Byte[10];
561 MemoryStream m = new MemoryStream(b);
562 StreamReader r = new StreamReader(m);
563 Assert.AreEqual ("a", r.ReadLine (), "#1");
564 Assert.AreEqual ("b", r.ReadLine (), "#2");
565 Assert.AreEqual ("c", r.ReadLine (), "#3");
566 Assert.AreEqual ("d", r.ReadLine (), "#4");
567 Assert.AreEqual (string.Empty, r.ReadLine (), "#5");
568 Assert.IsNull (r.ReadLine(), "#6");
572 public void ReadLine2() {
573 Byte[] b = new Byte[10];
585 MemoryStream m = new MemoryStream(b);
586 StreamReader r = new StreamReader(m);
587 Assert.AreEqual (string.Empty, r.ReadLine (), "#1");
588 Assert.AreEqual (string.Empty, r.ReadLine (), "#2");
589 Assert.AreEqual (string.Empty, r.ReadLine (), "#3");
590 Assert.AreEqual ("c", r.ReadLine (), "#4");
591 Assert.AreEqual ("d", r.ReadLine (), "#5");
592 Assert.AreEqual (string.Empty, r.ReadLine (), "#6");
593 Assert.IsNull (r.ReadLine (), "#7");
597 public void ReadLine3() {
598 StringBuilder sb = new StringBuilder ();
599 sb.Append (new string ('1', 32767));
602 sb.Append ("Hola\n");
603 byte [] bytes = Encoding.Default.GetBytes (sb.ToString ());
604 MemoryStream m = new MemoryStream(bytes);
605 StreamReader r = new StreamReader(m);
606 Assert.AreEqual (new string ('1', 32767), r.ReadLine(), "#1");
607 Assert.AreEqual ("Hola", r.ReadLine (), "#2");
608 Assert.IsNull (r.ReadLine (), "#3");
612 public void ReadLine4() {
613 StringBuilder sb = new StringBuilder ();
614 sb.Append (new string ('1', 32767));
617 sb.Append ("Hola\n");
618 sb.Append (sb.ToString ());
619 byte [] bytes = Encoding.Default.GetBytes (sb.ToString ());
620 MemoryStream m = new MemoryStream(bytes);
621 StreamReader r = new StreamReader(m);
622 Assert.AreEqual (new string ('1', 32767), r.ReadLine (), "#1");
623 Assert.AreEqual ("Hola", r.ReadLine (), "#2");
624 Assert.AreEqual (new string ('1', 32767), r.ReadLine (), "#3");
625 Assert.AreEqual ("Hola", r.ReadLine (), "#4");
626 Assert.IsNull (r.ReadLine (), "#5");
630 public void ReadLine5() {
631 StringBuilder sb = new StringBuilder ();
632 sb.Append (new string ('1', 32768));
635 sb.Append ("Hola\n");
636 byte [] bytes = Encoding.Default.GetBytes (sb.ToString ());
637 MemoryStream m = new MemoryStream(bytes);
638 StreamReader r = new StreamReader(m);
639 Assert.AreEqual (new string ('1', 32768), r.ReadLine (), "#1");
640 Assert.AreEqual ("Hola", r.ReadLine (), "#2");
641 Assert.IsNull (r.ReadLine (), "#3");
644 public void TestReadToEnd() {
645 // TODO Out Of Memory Exc? IO Exc?
646 Byte[] b = new Byte[8];
655 MemoryStream m = new MemoryStream(b);
656 StreamReader r = new StreamReader(m);
657 Assert.AreEqual ("a\nb\nc\nd\n", r.ReadToEnd (), "#1");
658 Assert.AreEqual (string.Empty, r.ReadToEnd (), "#2");
662 public void TestBaseStreamClosed ()
665 MemoryStream m = new MemoryStream (b);
666 StreamReader r = new StreamReader (m);
671 } catch (ObjectDisposedException) {
676 [ExpectedException (typeof (ArgumentNullException))]
677 public void Contructor_Stream_NullEncoding ()
679 new StreamReader (new MemoryStream (), null);
683 [ExpectedException (typeof (ArgumentNullException))]
684 public void Contructor_Path_NullEncoding ()
686 new StreamReader (_codeFileName, null);
690 [ExpectedException (typeof (ArgumentNullException))]
691 public void Read_Null ()
693 StreamReader r = new StreamReader (new MemoryStream ());
698 [ExpectedException (typeof (ArgumentException))]
699 public void Read_IndexOverflow ()
701 char[] array = new char [16];
702 StreamReader r = new StreamReader (new MemoryStream (16));
703 r.Read (array, 1, Int32.MaxValue);
707 [ExpectedException (typeof (ArgumentException))]
708 public void Read_CountOverflow ()
710 char[] array = new char [16];
711 StreamReader r = new StreamReader (new MemoryStream (16));
712 r.Read (array, Int32.MaxValue, 1);
716 public void Read_DoesntStopAtLineEndings ()
718 MemoryStream ms = new MemoryStream (Encoding.ASCII.GetBytes ("Line1\rLine2\r\nLine3\nLine4"));
719 StreamReader reader = new StreamReader (ms);
720 Assert.AreEqual (24, reader.Read (new char[24], 0, 24));
724 public void EncodingDetection()
726 if (!CheckEncodingDetected(Encoding.UTF8))
727 Assert.Fail ("Failed to detect UTF8 encoded string");
728 if (!CheckEncodingDetected(Encoding.Unicode))
729 Assert.Fail ("Failed to detect UTF16LE encoded string");
730 if (!CheckEncodingDetected(Encoding.BigEndianUnicode))
731 Assert.Fail ("Failed to detect UTF16BE encoded string");
732 if (!CheckEncodingDetected(Encoding.UTF32))
733 Assert.Fail ("Failed to detect UTF32LE encoded string");
734 if (!CheckEncodingDetected(new UTF32Encoding(true, true)))
735 Assert.Fail ("Failed to detect UTF32BE encoded string");
738 // This is a special case, where the StreamReader has less than 4 bytes at
739 // encoding detection time, so it tries to check for Unicode encoding, instead of
740 // waiting for more bytes to test against the UTF32 BOM.
742 public void EncodingDetectionUnicode ()
744 byte [] bytes = new byte [3];
748 MemoryStream inStream = new MemoryStream (bytes);
749 StreamReader reader = new StreamReader (inStream, Encoding.UTF8, true);
751 // It should start with the encoding we used in the .ctor
752 Assert.AreEqual (Encoding.UTF8, reader.CurrentEncoding, "#A1");
756 Assert.AreEqual (Encoding.Unicode, reader.CurrentEncoding, "#B1");
761 private bool CheckEncodingDetected(Encoding encoding)
763 MemoryStream outStream = new MemoryStream();
764 using (StreamWriter outWriter = new StreamWriter(outStream, encoding))
766 outWriter.Write(TestString);
768 byte[] testBytes = outStream.ToArray();
770 StreamReader inReader = new StreamReader(new MemoryStream(testBytes, false));
771 string decodedString = inReader.ReadToEnd();
773 return decodedString == TestString;
777 [Category ("MobileNotWorking")]
778 public void EndOfBufferIsCR ()
780 using (StreamReader reader = new StreamReader ("Test/resources/Fergie.GED")) {
783 while ((line = reader.ReadLine ()) != null) {
784 Assert.IsFalse (line.Length > 1000, "#1 " + count);
787 Assert.AreEqual (16107, count, "#2");
792 public void bug75526 ()
794 StreamReader sr = new StreamReader (new Bug75526Stream ());
795 int len = sr.Read (new char [10], 0, 10);
796 Assert.AreEqual (2, len);
799 class Bug75526Stream : MemoryStream
801 public override int Read (byte [] buffer, int offset, int count)
803 buffer [offset + 0] = (byte) 'a';
804 buffer [offset + 1] = (byte) 'b';
810 public void PeekWhileBlocking ()
812 StreamReader reader = new StreamReader (new MyStream ());
813 int c = reader.Read ();
814 Assert.IsFalse (reader.EndOfStream);
815 string str = reader.ReadToEnd ();
816 Assert.AreEqual ("bc", str);
820 public void EncodingChangedAuto ()
822 int testlines = 2048; // all data should larger than stream reader default buffer size
823 string testdata = "test";
824 MemoryStream ms = new MemoryStream();
825 // write utf8 encoding data.
826 using (StreamWriter sw = new StreamWriter (ms, Encoding.UTF8)) {
827 for (int i = 0; i < testlines; i++)
828 sw.WriteLine (testdata);
831 MemoryStream readms = new MemoryStream (ms.GetBuffer());
832 using (StreamReader sr = new StreamReader(readms, Encoding.Unicode, true)) {
833 for (int i = 0; i < testlines; i++) {
834 string line = sr.ReadLine ();
835 if (line != testdata)
836 Assert.Fail ("Wrong line content");
842 public void NullStream ()
844 var buffer = new char[2];
845 Assert.AreEqual (0, StreamReader.Null.ReadBlock (buffer, 0, buffer.Length));
850 public void ReadLineAsync ()
852 MemoryStream ms = new MemoryStream ();
853 StreamWriter sw = new StreamWriter (ms, Encoding.UTF8);
857 ms.Seek (0, SeekOrigin.Begin);
859 Func<Task<string>> res = async () => {
860 using (StreamReader reader = new StreamReader (ms)) {
861 return await reader.ReadLineAsync () + await reader.ReadToEndAsync () + await reader.ReadToEndAsync ();
866 Assert.IsTrue (result.Wait (3000), "#1");
867 Assert.AreEqual ("ab" + Environment.NewLine, result.Result);
872 class MyStream : Stream {
875 public override int Read (byte [] buffer, int offset, int size)
878 buffer [offset] = (byte) 'a';
882 buffer [offset] = (byte) 'b';
883 buffer [offset + 1] = (byte) 'c';
890 public override bool CanRead {
894 public override bool CanSeek {
895 get { return false; }
898 public override bool CanWrite {
899 get { return false; }
902 public override long Length {
906 public override long Position {
911 public override void Flush ()
915 public override long Seek (long offset, SeekOrigin origin)
920 public override void SetLength (long value)
924 public override void Write (byte[] buffer, int offset, int count)