/*
* ome.util.mem.TestByteArray
*
* Copyright 2006 University of Dundee. All rights reserved.
* Use is subject to license terms supplied in LICENSE.txt
*/
package ome.util.mem;
import java.io.IOException;
import ome.util.tests.common.MockInputStream;
import org.testng.annotations.*;
import junit.framework.TestCase;
/**
* Tests the normal operation of <code>ByteArray</code> and possible
* exceptions.
*
* @author Jean-Marie Burel <a
* href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author <br>
* Andrea Falconi <a
* href="mailto:a.falconi@dundee.ac.uk"> a.falconi@dundee.ac.uk</a>
* @since OME2.2
*/
public class TestByteArray extends TestCase {
private void doTestSetBoundaryCases(ByteArray target) {
byte value = (byte) 25;
if (target.length == 0) {
try {
target.set(0, value);
fail("Shouldn't accept index 0 if length is 0.");
} catch (ArrayIndexOutOfBoundsException aiobe) {
}
}
try {
target.set(-1, value);
fail("Shouldn't accept negative index.");
} catch (ArrayIndexOutOfBoundsException aiobe) {
}
try {
target.set(target.length, value);
fail("Shouldn't accept index greater than length-1.");
} catch (ArrayIndexOutOfBoundsException aiobe) {
}
}
private void doTestSetBufferBoundaryCases(ByteArray target) {
try {
target.set(0, null); // Null always checked b/f index.
fail("Shouldn't accept null.");
} catch (NullPointerException npe) {
}
target.set(0, new byte[] {}); // buf.len == 0 always checked b/f
// index.
byte[] values = new byte[] { 25, -1 };
if (target.length == 0) {
try {
target.set(0, values);
fail("Shouldn't accept index 0 if length is 0.");
} catch (ArrayIndexOutOfBoundsException aiobe) {
}
}
try {
target.set(-1, values);
fail("Shouldn't accept negative index.");
} catch (ArrayIndexOutOfBoundsException aiobe) {
}
try {
target.set(target.length, values);
fail("Shouldn't accept index greater than length-1.");
} catch (ArrayIndexOutOfBoundsException aiobe) {
}
if (0 < target.length) {
byte original = target.get(target.length - 1);
values[0] = (byte) (original + 1);
try {
target.set(target.length - 1, values);
fail("Shouldn't accept a buffer that doesn't fit "
+ "into the slice.");
} catch (ArrayIndexOutOfBoundsException aiobe) {
// Ok, but check that no value has been copied:
assertEquals("No value should be copied if the buffer "
+ "doesn't fit into the slice.", original, target
.get(target.length - 1));
}
}
}
private void doTestSetStreamBoundaryCases(ByteArray target)
throws IOException {
MockInputStream stream = new MockInputStream();
try {
target.set(0, 0, null); // Null always checked b/f int args.
fail("Shouldn't accept null.");
} catch (NullPointerException npe) {
}
assertEquals("Should do nothing and return 0 if maxLength <= 0.", 0,
target.set(0, 0, stream));
assertEquals("Should do nothing and return 0 if maxLength <= 0.", 0,
target.set(0, -1, stream));
if (target.length == 0) {
try {
target.set(0, 1, stream);
fail("Shouldn't accept index 0 if length is 0.");
} catch (ArrayIndexOutOfBoundsException aiobe) {
}
}
try {
target.set(-1, 1, stream);
fail("Shouldn't accept negative index.");
} catch (ArrayIndexOutOfBoundsException aiobe) {
}
try {
target.set(target.length, 1, stream);
fail("Shouldn't accept index greater than length-1.");
} catch (ArrayIndexOutOfBoundsException aiobe) {
}
}
private void doTestSetStreamEndOfStream(ByteArray target, byte[] base,
int offset) throws IOException {
// Create mock, set up expected calls, and transition to
// verification mode.
MockInputStream stream = new MockInputStream();
stream.read(base, offset, 1, -1, null);
stream.activate();
// Test.
assertEquals("Failed to signal end of stream.", -1, target.set(0, 1,
stream));
// Make sure all expected calls were performed.
stream.verify();
}
// NB: This method assumes
// base == target.base
// offset == target.offset
// values.length == target.length
private void doTestSet(byte[] base, int offset, ByteArray target,
byte[] values) {
for (int i = 0; i < values.length; ++i) {
target.set(i, values[i]);
assertEquals("Set wrong value [index = " + i + "].", values[i],
target.get(i));
assertEquals("Didn't set value in original base array "
+ "[index = " + i + "].", values[i], base[offset + i]);
}
}
// NB: This method assumes
// base == target.base
// offset == target.offset
// offset+index+values.length <= target.length
private void doTestSetBuffer(byte[] base, int offset, int index,
ByteArray target, byte[] values) {
target.set(index, values);
for (int i = 0; i < values.length; ++i) {
assertEquals("Set wrong value [index = " + i + "].", values[i],
target.get(index + i));
assertEquals("Didn't set value in original base array "
+ "[index = " + i + "].", values[i], base[offset + index
+ i]);
}
}
// NB: This method assumes
// base == target.base
// offset == target.offset
// offset+index+values.length <= target.length
// valuesToCheck <= values.length
private void verifySetStream(byte[] base, int offset, int index,
ByteArray target, int valuesToCheck) {
for (int i = 0; i < valuesToCheck; ++i) {
assertEquals("Set wrong value [index = " + i + "].", 1, target
.get(index + i));
assertEquals("Didn't set value in original base array "
+ "[index = " + i + "].", 1, base[offset + index + i]);
}
// NOTE: expected value is 1 b/c mock read writes 1 into the buffer.
}
@Test
public void testByteArray() {
try {
new ByteArray(null, 0, 0);
fail("Shouldn't accept null base.");
} catch (NullPointerException npe) {
}
byte[] base = new byte[0];
try {
new ByteArray(base, -1, 0);
fail("Shouldn't accept negative offset.");
} catch (IllegalArgumentException iae) {
}
try {
new ByteArray(base, 0, -1);
fail("Shouldn't accept negative length.");
} catch (IllegalArgumentException iae) {
}
try {
new ByteArray(base, 1, 0);
fail("Shouldn't accept inconsistent [offset, offset+length].");
} catch (IllegalArgumentException iae) {
}
}
@Test
public void testSetWhenEmptySlice() {
byte[] base = new byte[] { 0 };
ByteArray target = new ByteArray(base, 1, 0);
doTestSetBoundaryCases(target);
}
@Test
public void testSetBufferWhenEmptySlice() {
byte[] base = new byte[] { 0 };
ByteArray target = new ByteArray(base, 1, 0);
doTestSetBufferBoundaryCases(target);
}
@Test
public void testSetStreamWhenEmptySlice() throws IOException {
byte[] base = new byte[] { 0 };
ByteArray target = new ByteArray(base, 1, 0);
doTestSetStreamBoundaryCases(target);
}
@Test
public void testSetWhen1LengthSlice() {
byte[] values = new byte[] { 25 };
byte[] base = new byte[] { 0, 1 };
ByteArray target = new ByteArray(base, 1, 1);
doTestSetBoundaryCases(target);
doTestSet(base, 1, target, values);
}
@Test
public void testSetBufferWhen1LengthSlice() {
byte[] values = new byte[] { 25 };
byte[] base = new byte[] { 0, 1 };
ByteArray target = new ByteArray(base, 1, 1);
doTestSetBufferBoundaryCases(target);
doTestSetBuffer(base, 1, 0, target, values);
}
@Test
public void testSetStreamWhen1LengthSlice() throws IOException {
// Create mock, set up expected calls, and transition to
// verification mode.
byte[] base = new byte[] { 0, 0 };
MockInputStream stream = new MockInputStream();
stream.read(base, 1, 1, 1, null); // Will set base[1]=1.
stream.activate();
// Test.
ByteArray target = new ByteArray(base, 1, 1);
doTestSetStreamBoundaryCases(target);
doTestSetStreamEndOfStream(target, base, 1);
assertEquals("Should return the bytes written.", 1, target.set(0, 1,
stream));
verifySetStream(base, 1, 0, target, 1);
// Make sure all expected calls were performed.
stream.verify();
}
@Test
public void testSetWhen2LengthSlice() {
byte[] values = new byte[] { 25, -1 };
byte[] base = new byte[] { 0, 1 };
ByteArray target = new ByteArray(base, 0, 2);
doTestSetBoundaryCases(target);
doTestSet(base, 0, target, values);
}
@Test
public void testSetBufferWhen2LengthSlice() {
byte[] values = new byte[] { 25, -1 };
byte[] base = new byte[] { 0, 1 };
ByteArray target = new ByteArray(base, 0, 2);
doTestSetBufferBoundaryCases(target);
doTestSetBuffer(base, 0, 0, target, values);
}
@Test
public void testSetStreamWhen2LengthSlice() throws IOException {
// Create mock, set up expected calls, and transition to
// verification mode.
byte[] base = new byte[] { 0, 0 };
MockInputStream stream = new MockInputStream();
stream.read(base, 0, 2, 2, null); // Will set base[0,1]=1.
stream.activate();
// Test.
ByteArray target = new ByteArray(base, 0, 2);
doTestSetStreamBoundaryCases(target);
doTestSetStreamEndOfStream(target, base, 0);
assertEquals("Should return the bytes written.", 2, target.set(0, 3,
stream)); // maxLen should be set to 2.
verifySetStream(base, 0, 0, target, 2);
// Make sure all expected calls were performed.
stream.verify();
}
@Test
public void testSetWhen3LengthSlice() {
byte[] values = new byte[] { 25, -1, 7 };
byte[] base = new byte[] { 0, 1, 2, 3 };
ByteArray target = new ByteArray(base, 1, 3);
doTestSetBoundaryCases(target);
doTestSet(base, 1, target, values);
}
@Test
public void testSetBufferWhen3LengthSlice() {
byte[] values = new byte[] { 25, -1, 7 };
byte[] base = new byte[] { 0, 1, 2, 3 };
ByteArray target = new ByteArray(base, 1, 3);
doTestSetBufferBoundaryCases(target);
doTestSetBuffer(base, 1, 0, target, values);
}
@Test
public void testSetStreamWhen3LengthSlice() throws IOException {
// Create mock, set up expected calls, and transition to
// verification mode.
byte[] base = new byte[] { 0, 0, 0, 0 };
MockInputStream stream = new MockInputStream();
stream.read(base, 2, 2, 1, null); // Will set base[2]=1.
stream.activate();
// Test.
ByteArray target = new ByteArray(base, 1, 3);
doTestSetStreamBoundaryCases(target);
doTestSetStreamEndOfStream(target, base, 1);
assertEquals("Should return the bytes written.", 1, target.set(1, 2,
stream)); // EOS reached b/f maxLen.
verifySetStream(base, 1, 1, target, 1);
// Make sure all expected calls were performed.
stream.verify();
}
}