• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.io;
18 
19 import static com.google.common.io.SourceSinkFactory.ByteSourceFactory;
20 import static com.google.common.io.SourceSinkFactory.CharSourceFactory;
21 import static org.junit.Assert.assertArrayEquals;
22 
23 import com.google.common.base.Charsets;
24 import com.google.common.collect.ImmutableList;
25 import com.google.common.hash.HashCode;
26 import com.google.common.hash.Hashing;
27 
28 import junit.framework.TestSuite;
29 
30 import java.io.ByteArrayInputStream;
31 import java.io.ByteArrayOutputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.OutputStream;
35 import java.lang.reflect.Method;
36 import java.util.Map;
37 import java.util.Random;
38 
39 /**
40  * A generator of {@code TestSuite} instances for testing {@code ByteSource} implementations.
41  * Generates tests of a all methods on a {@code ByteSource} given various inputs the source is
42  * expected to contain as well as as sub-suites for testing the {@code CharSource} view and
43  * {@code slice()} views in the same way.
44  *
45  * @author Colin Decker
46  */
47 public class ByteSourceTester extends SourceSinkTester<ByteSource, byte[], ByteSourceFactory> {
48 
49   private static final ImmutableList<Method> testMethods
50       = getTestMethods(ByteSourceTester.class);
51 
tests(String name, ByteSourceFactory factory, boolean testAsCharSource)52   static TestSuite tests(String name, ByteSourceFactory factory, boolean testAsCharSource) {
53     TestSuite suite = new TestSuite(name);
54     for (Map.Entry<String, String> entry : TEST_STRINGS.entrySet()) {
55       if (testAsCharSource) {
56         suite.addTest(suiteForString(factory, entry.getValue(), name, entry.getKey()));
57       } else {
58         suite.addTest(suiteForBytes(
59             factory, entry.getValue().getBytes(Charsets.UTF_8), name, entry.getKey(), true));
60       }
61     }
62     return suite;
63   }
64 
suiteForString(ByteSourceFactory factory, String string, String name, String desc)65   private static TestSuite suiteForString(ByteSourceFactory factory, String string,
66       String name, String desc) {
67     TestSuite suite = suiteForBytes(factory, string.getBytes(Charsets.UTF_8), name, desc, true);
68     CharSourceFactory charSourceFactory = SourceSinkFactories.asCharSourceFactory(factory);
69     suite.addTest(CharSourceTester.suiteForString(charSourceFactory, string,
70         name + ".asCharSource[Charset]", desc));
71     return suite;
72   }
73 
suiteForBytes(ByteSourceFactory factory, byte[] bytes, String name, String desc, boolean slice)74   private static TestSuite suiteForBytes(ByteSourceFactory factory, byte[] bytes,
75       String name, String desc, boolean slice) {
76     TestSuite suite = new TestSuite(name + " [" + desc + "]");
77     for (Method method : testMethods) {
78       suite.addTest(new ByteSourceTester(factory, bytes, name, desc, method));
79     }
80 
81     if (slice && bytes.length > 0) {
82       // test a random slice() of the ByteSource
83       Random random = new Random();
84       byte[] expected = factory.getExpected(bytes);
85       // if expected.length == 0, off has to be 0 but length doesn't matter--result will be empty
86       int off = expected.length == 0 ? 0 : random.nextInt(expected.length);
87       int len = expected.length == 0 ? 4 : random.nextInt(expected.length - off);
88       ByteSourceFactory sliced = SourceSinkFactories.asSlicedByteSourceFactory(factory, off, len);
89       suite.addTest(suiteForBytes(sliced, bytes, name + ".slice[int, int]",
90           desc, false));
91     }
92 
93     return suite;
94   }
95 
96   private ByteSource source;
97 
ByteSourceTester(ByteSourceFactory factory, byte[] bytes, String suiteName, String caseDesc, Method method)98   public ByteSourceTester(ByteSourceFactory factory, byte[] bytes,
99       String suiteName, String caseDesc, Method method) {
100     super(factory, bytes, suiteName, caseDesc, method);
101   }
102 
103   @Override
setUp()104   public void setUp() throws IOException {
105     source = factory.createSource(data);
106   }
107 
testOpenStream()108   public void testOpenStream() throws IOException {
109     InputStream in = source.openStream();
110     try {
111       byte[] readBytes = ByteStreams.toByteArray(in);
112       assertExpectedBytes(readBytes);
113     } finally {
114       in.close();
115     }
116   }
117 
testOpenBufferedStream()118   public void testOpenBufferedStream() throws IOException {
119     InputStream in = source.openBufferedStream();
120     try {
121       byte[] readBytes = ByteStreams.toByteArray(in);
122       assertExpectedBytes(readBytes);
123     } finally {
124       in.close();
125     }
126   }
127 
testRead()128   public void testRead() throws IOException {
129     byte[] readBytes = source.read();
130     assertExpectedBytes(readBytes);
131   }
132 
testCopyTo_outputStream()133   public void testCopyTo_outputStream() throws IOException {
134     ByteArrayOutputStream out = new ByteArrayOutputStream();
135     source.copyTo(out);
136     assertExpectedBytes(out.toByteArray());
137   }
138 
testCopyTo_byteSink()139   public void testCopyTo_byteSink() throws IOException {
140     final ByteArrayOutputStream out = new ByteArrayOutputStream();
141     // HERESY! but it's ok just for this I guess
142     source.copyTo(new ByteSink() {
143       @Override
144       public OutputStream openStream() throws IOException {
145         return out;
146       }
147     });
148     assertExpectedBytes(out.toByteArray());
149   }
150 
testIsEmpty()151   public void testIsEmpty() throws IOException {
152     assertEquals(expected.length == 0, source.isEmpty());
153   }
154 
testSize()155   public void testSize() throws IOException {
156     assertEquals(expected.length, source.size());
157   }
158 
testContentEquals()159   public void testContentEquals() throws IOException {
160     assertTrue(source.contentEquals(new ByteSource() {
161       @Override
162       public InputStream openStream() throws IOException {
163         return new RandomAmountInputStream(
164             new ByteArrayInputStream(expected), new Random());
165       }
166     }));
167   }
168 
testRead_usingByteProcessor()169   public void testRead_usingByteProcessor() throws IOException {
170     byte[] readBytes = source.read(new ByteProcessor<byte[]>() {
171       final ByteArrayOutputStream out = new ByteArrayOutputStream();
172 
173       @Override
174       public boolean processBytes(byte[] buf, int off, int len) throws IOException {
175         out.write(buf, off, len);
176         return true;
177       }
178 
179       @Override
180       public byte[] getResult() {
181         return out.toByteArray();
182       }
183     });
184 
185     assertExpectedBytes(readBytes);
186   }
187 
testHash()188   public void testHash() throws IOException {
189     HashCode expectedHash = Hashing.md5().hashBytes(expected);
190     assertEquals(expectedHash, source.hash(Hashing.md5()));
191   }
192 
testSlice_illegalArguments()193   public void testSlice_illegalArguments() {
194     try {
195       source.slice(-1, 0);
196       fail("expected IllegalArgumentException for call to slice with offset -1: " + source);
197     } catch (IllegalArgumentException expected) {
198     }
199 
200     try {
201       source.slice(0, -1);
202       fail("expected IllegalArgumentException for call to slice with length -1: " + source);
203     } catch (IllegalArgumentException expected) {
204     }
205   }
206 
assertExpectedBytes(byte[] readBytes)207   private void assertExpectedBytes(byte[] readBytes) {
208     assertArrayEquals(expected, readBytes);
209   }
210 }
211