1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io.input;
18  
19  import java.io.EOFException;
20  import java.io.IOException;
21  import java.io.Reader;
22  
23  import junit.framework.TestCase;
24  
25  /**
26   * JUnit Test Case for {@link NullReader}.
27   *
28   * @version $Id: NullReaderTest.java 463529 2006-10-13 00:37:09Z niallp $
29   */
30  public class NullReaderTest extends TestCase {
31  
32      /** Constructor */
33      public NullReaderTest(String name) {
34          super(name);
35      }
36  
37      /** Set up */
38      protected void setUp() throws Exception {
39          super.setUp();
40      }
41  
42      /** Tear Down */
43      protected void tearDown() throws Exception {
44          super.tearDown();
45      }
46  
47      /**
48       * Test <code>available()</code> method.
49       */
50      public void testRead() throws Exception {
51          int size = 5;
52          TestNullReader reader = new TestNullReader(size);
53          for (int i = 0; i < size; i++) {
54              assertEquals("Check Value [" + i + "]", i, reader.read());
55          }
56  
57          // Check End of File
58          assertEquals("End of File", -1, reader.read());
59  
60          // Test reading after the end of file
61          try {
62              int result = reader.read();
63              fail("Should have thrown an IOException, value=[" + result + "]");
64          } catch (IOException e) {
65              assertEquals("Read after end of file", e.getMessage());
66          }
67  
68          // Close - should reset
69          reader.close();
70          assertEquals("Available after close", 0, reader.getPosition());
71      }
72  
73      /**
74       * Test <code>read(char[])</code> method.
75       */
76      public void testReadCharArray() throws Exception {
77          char[] chars = new char[10];
78          Reader reader = new TestNullReader(15);
79  
80          // Read into array
81          int count1 = reader.read(chars);
82          assertEquals("Read 1", chars.length, count1);
83          for (int i = 0; i < count1; i++) {
84              assertEquals("Check Chars 1", i, chars[i]);
85          }
86  
87          // Read into array
88          int count2 = reader.read(chars);
89          assertEquals("Read 2", 5, count2);
90          for (int i = 0; i < count2; i++) {
91              assertEquals("Check Chars 2", count1 + i, chars[i]);
92          }
93  
94          // End of File
95          int count3 = reader.read(chars);
96          assertEquals("Read 3 (EOF)", -1, count3);
97  
98          // Test reading after the end of file
99          try {
100             int count4 = reader.read(chars);
101             fail("Should have thrown an IOException, value=[" + count4 + "]");
102         } catch (IOException e) {
103             assertEquals("Read after end of file", e.getMessage());
104         }
105 
106         // reset by closing
107         reader.close();
108     
109         // Read into array using offset & length
110         int offset = 2;
111         int lth    = 4;
112         int count5 = reader.read(chars, offset, lth);
113         assertEquals("Read 5", lth, count5);
114         for (int i = offset; i < lth; i++) {
115             assertEquals("Check Chars 3", i, chars[i]);
116         }
117     }
118 
119     /**
120      * Test when configured to throw an EOFException at the end of file
121      * (rather than return -1).
122      */
123     public void testEOFException() throws Exception {
124         Reader reader = new TestNullReader(2, false, true);
125         assertEquals("Read 1",  0, reader.read());
126         assertEquals("Read 2",  1, reader.read());
127         try {
128             int result = reader.read();
129             fail("Should have thrown an EOFException, value=[" + result + "]");
130         } catch (EOFException e) {
131             // expected
132         }
133     }
134 
135     /**
136      * Test <code>mark()</code> and <code>reset()</code> methods.
137      */
138     public void testMarkAndReset() throws Exception {
139         int position = 0;
140         int readlimit = 10;
141         Reader reader = new TestNullReader(100, true, false);
142         
143         assertTrue("Mark Should be Supported", reader.markSupported());
144 
145         // No Mark
146         try {
147             reader.reset();
148             fail("Read limit exceeded, expected IOException ");
149         } catch (Exception e) {
150             assertEquals("No Mark IOException message",
151                          "No position has been marked",
152                          e.getMessage());
153         }
154 
155         for (; position < 3; position++) {
156             assertEquals("Read Before Mark [" + position +"]",  position, reader.read());
157         }
158 
159         // Mark
160         reader.mark(readlimit);
161 
162         // Read further
163         for (int i = 0; i < 3; i++) {
164             assertEquals("Read After Mark [" + i +"]",  (position + i), reader.read());
165         }
166 
167         // Reset
168         reader.reset();
169 
170         // Read From marked position
171         for (int i = 0; i < readlimit + 1; i++) {
172             assertEquals("Read After Reset [" + i +"]",  (position + i), reader.read());
173         }
174 
175         // Reset after read limit passed
176         try {
177             reader.reset();
178             fail("Read limit exceeded, expected IOException ");
179         } catch (Exception e) {
180             assertEquals("Read limit IOException message",
181                          "Marked position [" + position
182                          + "] is no longer valid - passed the read limit ["
183                          + readlimit + "]",
184                          e.getMessage());
185         }
186     }
187 
188     /**
189      * Test <code>mark()</code> not supported.
190      */
191     public void testMarkNotSupported() throws Exception {
192         Reader reader = new TestNullReader(100, false, true);
193         assertFalse("Mark Should NOT be Supported", reader.markSupported());
194 
195         try {
196             reader.mark(5);
197             fail("mark() should throw UnsupportedOperationException");
198         } catch (UnsupportedOperationException e) {
199             assertEquals("mark() error message",  "Mark not supported", e.getMessage());
200         }
201 
202         try {
203             reader.reset();
204             fail("reset() should throw UnsupportedOperationException");
205         } catch (UnsupportedOperationException e) {
206             assertEquals("reset() error message",  "Mark not supported", e.getMessage());
207         }
208     }
209 
210     /**
211      * Test <code>skip()</code> method.
212      */
213    public void testSkip() throws Exception {
214         Reader reader = new TestNullReader(10, true, false);
215         assertEquals("Read 1", 0, reader.read());
216         assertEquals("Read 2", 1, reader.read());
217         assertEquals("Skip 1", 5, reader.skip(5));
218         assertEquals("Read 3", 7, reader.read());
219         assertEquals("Skip 2", 2, reader.skip(5)); // only 2 left to skip
220         assertEquals("Skip 3 (EOF)", -1, reader.skip(5)); // End of file
221         try {
222             reader.skip(5); //
223             fail("Expected IOException for skipping after end of file");
224         } catch (Exception e) {
225             assertEquals("Skip after EOF IOException message",
226                     "Skip after end of file",
227                     e.getMessage());
228         }
229     }
230 
231 
232     // ------------- Test NullReader implementation -------------
233 
234     private static final class TestNullReader extends NullReader {
235         public TestNullReader(int size) {
236             super(size);
237         }
238         public TestNullReader(int size, boolean markSupported, boolean throwEofException) {
239             super(size, markSupported, throwEofException);
240         }
241         protected int processChar() {
242             return ((int)getPosition() - 1);
243         }
244         protected void processChars(char[] chars, int offset, int length) {
245             int startPos = (int)getPosition() - length;
246             for (int i = offset; i < length; i++) {
247                 chars[i] = (char)(startPos + i);
248             }
249         }
250         
251     }
252 }