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.output;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.IOException;
21  
22  import junit.framework.TestCase;
23  
24  /**
25   * Basic unit tests for the alternative ByteArrayOutputStream implementation.
26   *
27   * @author <a href="mailto:jeremias@apache.org">Jeremias Maerki</a>
28   */
29  public class ByteArrayOutputStreamTestCase extends TestCase {
30  
31      private static final byte[] DATA;
32      
33      static {
34          DATA = new byte[64];
35          for (byte i = 0; i < 64; i++) {
36              DATA[i] = i;
37          }
38      }
39  
40      public ByteArrayOutputStreamTestCase(String name) {
41          super(name);
42      }
43  
44      private int writeData(ByteArrayOutputStream baout, 
45                  java.io.ByteArrayOutputStream ref,
46                  int count) throws IOException {
47          if (count > DATA.length) {
48              throw new IllegalArgumentException("Requesting too many bytes");
49          }
50          if (count == 0) {
51              baout.write(100);
52              ref.write(100);
53              return 1;
54          } else {
55              baout.write(DATA, 0, count);
56              ref.write(DATA, 0, count);
57              return count;
58          }
59      }
60      
61      private int writeData(ByteArrayOutputStream baout, 
62                  java.io.ByteArrayOutputStream ref, 
63                  int[] instructions) throws IOException {
64          int written = 0;
65          for (int i = 0; i < instructions.length; i++) {
66              written += writeData(baout, ref, instructions[i]);
67          }
68          return written;
69      }
70  
71      private static boolean byteCmp(byte[] src, byte[] cmp) {
72          for (int i = 0; i < cmp.length; i++) {
73              if (src[i] != cmp[i]) {
74                  return false;
75              }
76          }
77          return true;
78      }
79  
80      private void checkByteArrays(byte[] expected, byte[] actual) {
81          if (expected.length != actual.length) {
82              fail("Resulting byte arrays are not equally long");
83          }
84          if (!byteCmp(expected, actual)) {
85              fail("Resulting byte arrays are not equal");
86          }
87      }
88  
89      private void checkStreams(
90              ByteArrayOutputStream actual,
91              java.io.ByteArrayOutputStream expected) {
92          assertEquals("Sizes are not equal", expected.size(), actual.size());
93          byte[] buf = actual.toByteArray();
94          byte[] refbuf = expected.toByteArray();
95          checkByteArrays(buf, refbuf);
96      }
97                
98      public void testStream() throws Exception {
99          int written;
100         
101         //The ByteArrayOutputStream is initialized with 32 bytes to match
102         //the original more closely for this test.
103         ByteArrayOutputStream baout = new ByteArrayOutputStream(32);
104         java.io.ByteArrayOutputStream ref = new java.io.ByteArrayOutputStream();
105         
106         //First three writes
107         written = writeData(baout, ref, new int[] {4, 10, 22});
108         assertEquals(36, written);
109         checkStreams(baout, ref);
110 
111         //Another two writes to see if there are any bad effects after toByteArray()
112         written = writeData(baout, ref, new int[] {20, 12});
113         assertEquals(32, written);
114         checkStreams(baout, ref);
115 
116         //Now reset the streams        
117         baout.reset();
118         ref.reset();
119         
120         //Test again to see if reset() had any bad effects
121         written = writeData(baout, ref, new int[] {5, 47, 33, 60, 1, 0, 8});
122         assertEquals(155, written);
123         checkStreams(baout, ref);
124 
125         //Test the readFrom(InputStream) method
126         baout.reset();
127         written = baout.write(new ByteArrayInputStream(ref.toByteArray()));
128         assertEquals(155, written);
129         checkStreams(baout, ref);
130 
131         //Write the commons Byte[]OutputStream to a java.io.Byte[]OutputStream 
132         //and vice-versa to test the writeTo() method.
133         ByteArrayOutputStream baout1 = new ByteArrayOutputStream(32);
134         ref.writeTo(baout1);
135         java.io.ByteArrayOutputStream ref1 = new java.io.ByteArrayOutputStream();
136         baout.writeTo(ref1);
137         checkStreams(baout1, ref1);
138         
139         //Testing toString(String)
140         String baoutString = baout.toString("ASCII");
141         String refString = ref.toString("ASCII");
142         assertEquals("ASCII decoded String must be equal", refString, baoutString);
143         
144         //Make sure that empty ByteArrayOutputStreams really don't create garbage
145         //on toByteArray()
146         assertSame(new ByteArrayOutputStream().toByteArray(),
147             new ByteArrayOutputStream().toByteArray());
148     }
149 }
150