/*
* Copyright 2012 NGDATA nv
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lilyproject.bytes.impl.test;
import java.util.Random;
import junit.framework.TestCase;
import org.junit.Assert;
import org.lilyproject.bytes.api.DataInput;
import org.lilyproject.bytes.api.DataOutput;
import org.lilyproject.bytes.impl.DataInputImpl;
import org.lilyproject.bytes.impl.DataOutputImpl;
/**
* Test the encodings used in DataInputImpl and DataOutputImpl
*
* <p>The code to generate the randomUnicodeString has been based on code from Lucene class :
* <code>org.apache.lucene.util._TestUtil.java</code>
*/
public class TestDataInputOutput extends TestCase {
private Random random = new Random(System.currentTimeMillis());
/**
* start and end are BOTH inclusive
*/
public int nextInt(int start, int end) {
return start + random.nextInt(end - start + 1);
}
/**
* Returns random string, including full unicode range.
*/
public String randomUnicodeString() {
return randomUnicodeString(20);
}
/**
* Returns a random string up to a certain length.
*/
public String randomUnicodeString(int maxLength) {
final int end = random.nextInt(maxLength);
if (end == 0) {
// allow 0 length
return "";
}
final char[] buffer = new char[end];
randomFixedLengthUnicodeString(buffer, 0, buffer.length);
return new String(buffer, 0, end);
}
/**
* Fills provided char[] with valid random unicode code
* unit sequence.
*/
public void randomFixedLengthUnicodeString(char[] chars, int offset, int length) {
int i = offset;
final int end = offset + length;
while (i < end) {
final int t = random.nextInt(5);
if (0 == t && i < length - 1) {
// Make a surrogate pair
// High surrogate
chars[i++] = (char) nextInt(0xd800, 0xdbff);
// Low surrogate
chars[i++] = (char) nextInt(0xdc00, 0xdfff);
} else if (t <= 1) {
chars[i++] = (char) random.nextInt(0x80);
} else if (2 == t) {
chars[i++] = (char) nextInt(0x80, 0x800);
} else if (3 == t) {
chars[i++] = (char) nextInt(0x800, 0xd7ff);
} else if (4 == t) {
chars[i++] = (char) nextInt(0xe000, 0xffff);
}
}
}
public void testRandomString() {
for (int i = 0; i < 1000; i++) {
String string = randomUnicodeString();
DataOutput dataOutput = new DataOutputImpl();
dataOutput.writeUTF(string);
byte[] bytes = dataOutput.toByteArray();
DataInput dataInput = new DataInputImpl(bytes);
String result = dataInput.readUTF();
Assert.assertEquals(string, result);
}
}
public void testRandomVString() {
for (int i = 0; i < 1000; i++) {
String string = randomUnicodeString();
DataOutput dataOutput = new DataOutputImpl();
dataOutput.writeVUTF(string);
byte[] bytes = dataOutput.toByteArray();
DataInput dataInput = new DataInputImpl(bytes);
String result = dataInput.readVUTF();
Assert.assertEquals(string, result);
}
}
public void testAllCombinations() {
char[] chars = new char[6];
int i = 0;
// Make a surrogate pair
// High surrogate
chars[i++] = (char) nextInt(0xd800, 0xdbff);
// Low surrogate
chars[i++] = (char) nextInt(0xdc00, 0xdfff);
// 1
chars[i++] = (char) random.nextInt(0x80);
// 2
chars[i++] = (char) nextInt(0x80, 0x800);
// 3
chars[i++] = (char) nextInt(0x800, 0xd7ff);
// 4
chars[i++] = (char) nextInt(0xe000, 0xffff);
String string = new String(chars);
DataOutputImpl dataOutputImpl = new DataOutputImpl();
dataOutputImpl.writeUTF(string);
byte[] data = dataOutputImpl.toByteArray();
DataInputImpl dataInputImpl = new DataInputImpl(data);
String readUTF = dataInputImpl.readUTF();
Assert.assertEquals(string, readUTF);
}
public void testHyphen() {
DataOutputImpl dataOutputImpl = new DataOutputImpl();
String string =
"Mary Shelley (30 August 1797 – 1 February 1851) was a British novelist"; // Note, the hyphen is not just a minus sign
dataOutputImpl.writeUTF(string);
byte[] data = dataOutputImpl.toByteArray();
DataInputImpl dataInputImpl = new DataInputImpl(data);
String readUTF = dataInputImpl.readUTF();
Assert.assertEquals(string, readUTF);
}
public void testRussian() {
DataOutputImpl dataOutputImpl = new DataOutputImpl();
String string = "ТЕСТ"; // Note, these are russian characters
dataOutputImpl.writeUTF(string);
byte[] data = dataOutputImpl.toByteArray();
DataInputImpl dataInputImpl = new DataInputImpl(data);
String readUTF = dataInputImpl.readUTF();
Assert.assertEquals(string, readUTF);
}
public void testAllTypes() {
DataOutput dataOutput = new DataOutputImpl();
boolean b = random.nextBoolean();
dataOutput.writeBoolean(b);
byte[] bytes = new byte[10];
random.nextBytes(bytes);
dataOutput.writeByte(bytes[0]);
dataOutput.writeBytes(bytes);
double d = random.nextDouble();
dataOutput.writeDouble(d);
float f = random.nextFloat();
dataOutput.writeFloat(f);
int i = random.nextInt();
dataOutput.writeInt(i);
long l = random.nextLong();
dataOutput.writeLong(l);
short s = (short) 4;
dataOutput.writeShort(s);
String string = randomUnicodeString();
dataOutput.writeUTF(string);
dataOutput.writeVInt(Math.abs(i));
dataOutput.writeVLong(Math.abs(l));
byte[] data = dataOutput.toByteArray();
DataInput dataInput = new DataInputImpl(data);
Assert.assertEquals(b, dataInput.readBoolean());
Assert.assertEquals(bytes[0], dataInput.readByte());
Assert.assertArrayEquals(bytes, dataInput.readBytes(10));
Assert.assertEquals(d, dataInput.readDouble(), 0.0001);
Assert.assertEquals(f, dataInput.readFloat(), 0.0001);
Assert.assertEquals(i, dataInput.readInt());
Assert.assertEquals(l, dataInput.readLong());
Assert.assertEquals(s, dataInput.readShort());
Assert.assertEquals(string, dataInput.readUTF());
Assert.assertEquals(Math.abs(i), dataInput.readVInt());
Assert.assertEquals(Math.abs(l), dataInput.readVLong());
}
public void testIndexOf() {
byte[] source = {0x09, 0x08, 0x07, 0x06, 0x00, 0x05, 0x04, 0x03, 0x02, 0x01};
Assert.assertEquals(4, new DataInputImpl(source, 0, 10).indexOf((byte) 0x00));
Assert.assertEquals(2, new DataInputImpl(source, 2, 8).indexOf((byte) 0x00));
Assert.assertEquals(-1, new DataInputImpl(source, 7, 3).indexOf((byte) 0x00));
}
}