/*
* org.openmicroscopy.shoola.util.mem.TestByteArray
*
*------------------------------------------------------------------------------
* Copyright (C) 2006 University of Dundee. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package org.openmicroscopy.shoola.util.mem;
//Java imports
import java.io.IOException;
//Third-party libraries
import junit.framework.TestCase;
//Application-internal dependencies
import org.openmicroscopy.shoola.util.tests.common.MockInputStream;
/**
* 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>
* @version 2.2
* <small>
* (<b>Internal version:</b> $Revision$ $Date$)
* </small>
* @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.
}
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) {}
}
public void testSetWhenEmptySlice()
{
byte[] base = new byte[] {0};
ByteArray target = new ByteArray(base, 1, 0);
doTestSetBoundaryCases(target);
}
public void testSetBufferWhenEmptySlice()
{
byte[] base = new byte[] {0};
ByteArray target = new ByteArray(base, 1, 0);
doTestSetBufferBoundaryCases(target);
}
public void testSetStreamWhenEmptySlice()
throws IOException
{
byte[] base = new byte[] {0};
ByteArray target = new ByteArray(base, 1, 0);
doTestSetStreamBoundaryCases(target);
}
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);
}
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);
}
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();
}
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);
}
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);
}
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();
}
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);
}
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);
}
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();
}
}