Skip to content

Commit e3c1793

Browse files
committed
Add initial DataHandle unit tests
These tests are agnostic to the type of DataHandle, which should make it easier to get full test coverage of every concrete DataHandle implementation, as they are introduced.
1 parent ebca914 commit e3c1793

File tree

1 file changed

+227
-0
lines changed

1 file changed

+227
-0
lines changed
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2015 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.io;
33+
34+
import static org.junit.Assert.assertEquals;
35+
36+
import java.io.IOException;
37+
import java.io.OutputStream;
38+
import java.nio.ByteBuffer;
39+
import java.nio.ByteOrder;
40+
import java.util.Arrays;
41+
42+
import org.junit.Test;
43+
import org.scijava.Context;
44+
import org.scijava.util.Bytes;
45+
46+
/**
47+
* Abstract base class for {@link DataHandle} implementation tests.
48+
*
49+
* @author Curtis Rueden
50+
*/
51+
public abstract class DataHandleTest {
52+
53+
private static final byte[] BYTES = { //
54+
'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '\n', //
55+
9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -128, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, //
56+
125, 127, -127, -125, -3, -2, -1 };
57+
58+
// -- Test methods --
59+
60+
@Test
61+
public void testDataHandle() throws IOException {
62+
final Context context = new Context(DataHandleService.class);
63+
final DataHandleService dataHandleService =
64+
context.service(DataHandleService.class);
65+
66+
final Location loc = createLocation();
67+
final DataHandle<? extends Location> handle = dataHandleService.create(loc);
68+
assertEquals(getExpectedHandleType(), handle.getClass());
69+
70+
checkReads(handle);
71+
checkWrites(handle);
72+
handle.close();
73+
}
74+
75+
// -- DataHandleTest methods --
76+
77+
public abstract Class<? extends DataHandle<?>> getExpectedHandleType();
78+
79+
public abstract Location createLocation() throws IOException;
80+
81+
// -- Internal methods --
82+
83+
protected void populateData(final OutputStream out) throws IOException {
84+
out.write(BYTES);
85+
out.close();
86+
}
87+
88+
protected <L extends Location> void checkReads(final DataHandle<L> handle)
89+
throws IOException
90+
{
91+
assertEquals(0, handle.offset());
92+
assertEquals(BYTES.length, handle.length());
93+
assertEquals("UTF-8", handle.getEncoding());
94+
assertEquals(ByteOrder.BIG_ENDIAN, handle.getOrder());
95+
assertEquals(false, handle.isLittleEndian());
96+
97+
// test read()
98+
for (int i = 0; i < BYTES.length; i++) {
99+
assertEquals(msg(i), 0xff & BYTES[i], handle.read());
100+
}
101+
assertEquals(-1, handle.read());
102+
handle.seek(10);
103+
assertEquals(10, handle.offset());
104+
assertEquals(BYTES[10], handle.read());
105+
106+
// test read(byte[])
107+
final byte[] buf = new byte[10];
108+
handle.seek(1);
109+
assertBytesMatch(1, handle.read(buf), buf);
110+
111+
// test read(ByteBuffer)
112+
Arrays.fill(buf, (byte) 0);
113+
final ByteBuffer byteBuffer = ByteBuffer.wrap(buf);
114+
handle.seek(2);
115+
assertBytesMatch(2, handle.read(byteBuffer), byteBuffer.array());
116+
117+
// test readByte()
118+
handle.seek(0);
119+
for (int i = 0; i < BYTES.length; i++) {
120+
assertEquals(msg(i), BYTES[i], handle.readByte());
121+
}
122+
123+
// test readShort()
124+
handle.seek(0);
125+
for (int i = 0; i < BYTES.length / 2; i += 2) {
126+
assertEquals(msg(i), Bytes.toShort(BYTES, i, false), handle.readShort());
127+
}
128+
129+
// test readInt()
130+
handle.seek(0);
131+
for (int i = 0; i < BYTES.length / 4; i += 4) {
132+
assertEquals(msg(i), Bytes.toInt(BYTES, i, false), handle.readInt());
133+
}
134+
135+
// test readLong()
136+
handle.seek(0);
137+
for (int i = 0; i < BYTES.length / 8; i += 8) {
138+
assertEquals(msg(i), Bytes.toLong(BYTES, i, false), handle.readLong());
139+
}
140+
141+
// test readFloat()
142+
handle.seek(0);
143+
for (int i = 0; i < BYTES.length / 4; i += 4) {
144+
assertEquals(msg(i), Bytes.toFloat(BYTES, i, false), handle.readFloat(),
145+
0);
146+
}
147+
148+
// test readDouble()
149+
handle.seek(0);
150+
for (int i = 0; i < BYTES.length / 8; i += 8) {
151+
assertEquals(msg(i), Bytes.toDouble(BYTES, i, false),
152+
handle.readDouble(), 0);
153+
}
154+
155+
// test readBoolean()
156+
handle.seek(0);
157+
for (int i = 0; i < BYTES.length; i++) {
158+
assertEquals(msg(i), BYTES[i] == 0 ? false : true, handle.readBoolean());
159+
}
160+
161+
// test readChar()
162+
handle.seek(0);
163+
for (int i = 0; i < BYTES.length / 2; i += 2) {
164+
assertEquals(msg(i), (char) Bytes.toInt(BYTES, i, 2, false), handle
165+
.readChar());
166+
}
167+
168+
// test readFully(byte[])
169+
Arrays.fill(buf, (byte) 0);
170+
handle.seek(3);
171+
handle.readFully(buf);
172+
assertBytesMatch(3, buf.length, buf);
173+
174+
// test readCString() - _includes_ the null terminator!
175+
handle.seek(16);
176+
assertBytesMatch(16, 7, handle.readCString().getBytes());
177+
178+
// test readLine() - _excludes_ the newline terminator!
179+
handle.seek(7);
180+
assertBytesMatch(7, 5, handle.readLine().getBytes());
181+
182+
// test readString(String) - _includes_ the matching terminator!
183+
handle.seek(7);
184+
assertBytesMatch(7, 5, handle.readString("abcdefg").getBytes());
185+
186+
// test findString(String) - _includes_ the matching terminator!
187+
handle.seek(1);
188+
assertBytesMatch(1, 11, handle.findString("world").getBytes());
189+
}
190+
191+
protected <L extends Location> void checkWrites(final DataHandle<L> handle)
192+
throws IOException
193+
{
194+
final byte[] copy = BYTES.clone();
195+
196+
// change the data
197+
handle.seek(7);
198+
final String splice = "there";
199+
for (int i = 0; i < splice.length(); i++) {
200+
final char c = splice.charAt(i);
201+
handle.write(c);
202+
copy[7 + i] = (byte) c;
203+
}
204+
205+
// verify the changes
206+
handle.seek(0);
207+
for (int i = 0; i < copy.length; i++) {
208+
assertEquals(msg(i), 0xff & copy[i], handle.read());
209+
}
210+
}
211+
212+
// -- Helper methods --
213+
214+
private void assertBytesMatch(final int offset, final int length,
215+
final byte[] b)
216+
{
217+
assertEquals(length, b.length);
218+
for (int i = 0; i < length; i++) {
219+
assertEquals(msg(i), BYTES[i + offset], b[i]);
220+
}
221+
}
222+
223+
private String msg(final int i) {
224+
return "[" + i + "]:";
225+
}
226+
227+
}

0 commit comments

Comments
 (0)