CompareUtilTest.java
package zserio.runtime;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.math.BigInteger;
import org.junit.jupiter.api.Test;
import zserio.runtime.array.Array;
import zserio.runtime.array.ArrayTraits;
import zserio.runtime.array.ArrayType;
import zserio.runtime.array.RawArray;
import zserio.runtime.io.BitBuffer;
public class CompareUtilTest
{
@Test
public void simpleType()
{
assertTrue(CompareUtil.compare(false, true) < 0);
assertEquals(0, CompareUtil.compare(true, true));
assertTrue(CompareUtil.compare(Boolean.TRUE, Boolean.FALSE) > 0);
assertTrue(CompareUtil.compare((Boolean)null, Boolean.FALSE) < 0);
assertTrue(CompareUtil.compare((byte)-1, (byte)1) < 0);
assertEquals(0, CompareUtil.compare(Byte.valueOf((byte)1), Byte.valueOf((byte)1)));
assertTrue(CompareUtil.compare(Byte.valueOf((byte)1), (Byte)null) > 0);
assertTrue(CompareUtil.compare((short)-1, (short)1) < 0);
assertTrue(CompareUtil.compare(Short.valueOf((short)2), Short.valueOf((short)1)) > 0);
assertEquals(0, CompareUtil.compare((Short)null, (Short)null));
assertTrue(CompareUtil.compare(-1, 1) < 0);
assertTrue(CompareUtil.compare(Integer.valueOf(2), Integer.valueOf(1)) > 0);
assertTrue(CompareUtil.compare((Integer)null, Integer.valueOf(0)) < 0);
assertTrue(CompareUtil.compare(-1L, 1L) < 0);
assertTrue(CompareUtil.compare(Long.valueOf(2), Long.valueOf(1)) > 0);
assertTrue(CompareUtil.compare((Long)null, Long.valueOf(0)) < 0);
assertTrue(CompareUtil.compare(BigInteger.ONE, BigInteger.TEN) < 0);
assertEquals(0, CompareUtil.compare(BigInteger.TEN, BigInteger.valueOf(10)));
assertTrue(CompareUtil.compare((BigInteger)null, BigInteger.ZERO) < 0);
}
@Test
public void floatType()
{
assertTrue(CompareUtil.compare(1.0f, 2.0f) < 0);
assertTrue(CompareUtil.compare(-0.0f, 0.0f) < 0);
assertEquals(0, CompareUtil.compare(Float.NaN, Float.NaN));
assertTrue(CompareUtil.compare(Float.POSITIVE_INFINITY, Float.NaN) < 0);
assertTrue(CompareUtil.compare(Float.valueOf(2.0f), Float.valueOf(1.0f)) > 0);
assertTrue(CompareUtil.compare((Float)null, Float.valueOf(0.0f)) < 0);
assertTrue(CompareUtil.compare(1.0, 2.0) < 0);
assertTrue(CompareUtil.compare(-0.0, 0.0) < 0);
assertEquals(0, CompareUtil.compare(Double.NaN, Double.NaN));
assertTrue(CompareUtil.compare(Double.valueOf(2.0), Double.valueOf(1.0)) > 0);
assertTrue(CompareUtil.compare((Double)null, Double.valueOf(0.0)) < 0);
}
@Test
public void stringType()
{
assertEquals(0, CompareUtil.compare("", ""));
assertTrue(CompareUtil.compare("", "a") < 0);
assertTrue(CompareUtil.compare("ab", "a") > 0);
assertTrue(CompareUtil.compare("ab", "b") < 0);
assertTrue(CompareUtil.compare((String)null, "") < 0);
// U+FF61 is less than U+1F600 (surrogate pair) by code point, but greater by UTF-16 code unit
final String bmpString = "。";
final String supplementaryString = "😀";
assertTrue(bmpString.compareTo(supplementaryString) > 0);
assertTrue(CompareUtil.compare(bmpString, supplementaryString) < 0);
assertTrue(CompareUtil.compare(supplementaryString, bmpString) > 0);
assertTrue(CompareUtil.compare("a" + supplementaryString, "a" + supplementaryString + "a") < 0);
}
@Test
public void bytesType()
{
assertEquals(0, CompareUtil.compare(new byte[] {}, new byte[] {}));
assertTrue(CompareUtil.compare(new byte[] {}, new byte[] {0}) < 0);
assertTrue(CompareUtil.compare(new byte[] {1, 2}, new byte[] {1}) > 0);
assertTrue(CompareUtil.compare(new byte[] {1, 2}, new byte[] {2}) < 0);
// bytes are unsigned
assertTrue(CompareUtil.compare(new byte[] {(byte)0x01}, new byte[] {(byte)0xFF}) < 0);
// int8 arrays are signed
assertTrue(new RawArray.ByteRawArray(new byte[] {-1})
.compareTo(new RawArray.ByteRawArray(new byte[] {1})) < 0);
assertTrue(CompareUtil.compare((byte[])null, new byte[] {}) < 0);
}
@Test
public void bitBufferType()
{
final BitBuffer bitBuffer1 = new BitBuffer(new byte[] {(byte)0xAB, (byte)0xE0}, 11);
final BitBuffer bitBuffer2 = new BitBuffer(new byte[] {(byte)0xAB, (byte)0xF0}, 11);
final BitBuffer bitBuffer3 = new BitBuffer(new byte[] {(byte)0xAB, (byte)0x00}, 11);
assertEquals(0, CompareUtil.compare(bitBuffer1, bitBuffer2));
assertTrue(CompareUtil.compare(bitBuffer3, bitBuffer1) < 0);
assertTrue(CompareUtil.compare((BitBuffer)null, bitBuffer1) < 0);
}
@Test
public void enumType()
{
// compared by value, not by declaration order
assertTrue(Color.BLUE.compareTo(Color.RED) > 0);
assertTrue(CompareUtil.compare(Color.BLUE, Color.RED) < 0);
assertTrue(CompareUtil.compare(Color.NONE, Color.BLACK) < 0);
assertEquals(0, CompareUtil.compare(Color.RED, Color.RED));
assertTrue(CompareUtil.compare((Color)null, Color.NONE) < 0);
assertTrue(CompareUtil.compare(BigColor.BIG, BigColor.SMALL) > 0);
assertEquals(0, CompareUtil.compare(BigColor.SMALL, BigColor.SMALL));
}
@Test
public void objectType()
{
assertTrue(CompareUtil.compare(Permissions.Values.READ, Permissions.Values.WRITE) < 0);
assertEquals(0, CompareUtil.compare(Permissions.Values.WRITE, new Permissions(2)));
assertTrue(CompareUtil.compare(Permissions.Values.CREATE, Permissions.Values.WRITE) > 0);
assertTrue(CompareUtil.compare((Permissions)null, Permissions.Values.READ) < 0);
assertTrue(CompareUtil.compare(new DummyObject(3), new DummyObject(7)) < 0);
assertTrue(CompareUtil.compare(new DummyObject(7), (DummyObject)null) > 0);
}
@Test
public void arrayType()
{
final Array array1 = new Array(new RawArray.IntRawArray(new int[] {3, 7}),
new ArrayTraits.SignedBitFieldIntArrayTraits(32), ArrayType.NORMAL);
final Array array2 = new Array(new RawArray.IntRawArray(new int[] {3, 8}),
new ArrayTraits.SignedBitFieldIntArrayTraits(32), ArrayType.NORMAL);
final Array array3 = new Array(new RawArray.IntRawArray(new int[] {3, 7}),
new ArrayTraits.SignedBitFieldIntArrayTraits(32), ArrayType.AUTO);
assertTrue(CompareUtil.compare(array1, array2) < 0);
assertEquals(0, CompareUtil.compare(array1, array3));
assertTrue(CompareUtil.compare((Array)null, array1) < 0);
}
@Test
public void simpleArrayType()
{
assertTrue(CompareUtil.compare(new boolean[] {true}, new boolean[] {true, false}) < 0);
assertTrue(CompareUtil.compare(new boolean[] {true}, new boolean[] {false, false}) > 0);
assertEquals(0, CompareUtil.compare(new boolean[] {true}, new boolean[] {true}));
assertTrue(CompareUtil.compare((boolean[])null, new boolean[] {}) < 0);
assertTrue(CompareUtil.compare(new short[] {-1}, new short[] {1}) < 0);
assertTrue(CompareUtil.compare(new short[] {1, 2}, new short[] {1}) > 0);
assertTrue(CompareUtil.compare((short[])null, new short[] {}) < 0);
assertTrue(CompareUtil.compare(new int[] {-1}, new int[] {1}) < 0);
assertTrue(CompareUtil.compare(new int[] {1, 2}, new int[] {1}) > 0);
assertTrue(CompareUtil.compare((int[])null, new int[] {}) < 0);
assertTrue(CompareUtil.compare(new long[] {-1}, new long[] {1}) < 0);
assertTrue(CompareUtil.compare(new long[] {1, 2}, new long[] {1}) > 0);
assertTrue(CompareUtil.compare((long[])null, new long[] {}) < 0);
assertTrue(CompareUtil.compare(new float[] {-0.0f}, new float[] {0.0f}) < 0);
assertTrue(CompareUtil.compare(new float[] {1.0f, 2.0f}, new float[] {1.0f}) > 0);
assertTrue(CompareUtil.compare((float[])null, new float[] {}) < 0);
assertTrue(CompareUtil.compare(new double[] {-0.0}, new double[] {0.0}) < 0);
assertTrue(CompareUtil.compare(new double[] {1.0, 2.0}, new double[] {1.0}) > 0);
assertTrue(CompareUtil.compare((double[])null, new double[] {}) < 0);
assertTrue(
CompareUtil.compare(new BigInteger[] {BigInteger.ONE}, new BigInteger[] {BigInteger.TEN}) < 0);
assertTrue(CompareUtil.compare(new BigInteger[] {BigInteger.ONE, BigInteger.ONE},
new BigInteger[] {BigInteger.ONE}) > 0);
assertTrue(CompareUtil.compare((BigInteger[])null, new BigInteger[] {}) < 0);
}
@Test
public void objectArrayType()
{
assertTrue(CompareUtil.compare(new byte[][] {{(byte)0x01}}, new byte[][] {{(byte)0xFF}}) < 0);
assertTrue(CompareUtil.compare(new byte[][] {{}, {}}, new byte[][] {{}}) > 0);
assertTrue(CompareUtil.compare((byte[][])null, new byte[][] {}) < 0);
assertTrue(CompareUtil.compare(new String[] {"。"}, new String[] {"😀"}) < 0);
assertTrue(CompareUtil.compare(new String[] {"a", "b"}, new String[] {"a"}) > 0);
assertTrue(CompareUtil.compare((String[])null, new String[] {}) < 0);
final BitBuffer bitBuffer1 = new BitBuffer(new byte[] {(byte)0xAB});
final BitBuffer bitBuffer2 = new BitBuffer(new byte[] {(byte)0xAC});
assertTrue(CompareUtil.compare(new BitBuffer[] {bitBuffer1}, new BitBuffer[] {bitBuffer2}) < 0);
assertTrue(CompareUtil.compare(new BitBuffer[] {bitBuffer1, bitBuffer1}, new BitBuffer[] {bitBuffer1}) >
0);
assertTrue(CompareUtil.compare((BitBuffer[])null, new BitBuffer[] {}) < 0);
assertTrue(CompareUtil.compare(new Color[] {Color.BLUE}, new Color[] {Color.RED}) < 0);
assertTrue(CompareUtil.compare(new Color[] {Color.RED, Color.RED}, new Color[] {Color.RED}) > 0);
assertTrue(CompareUtil.compare((Color[])null, new Color[] {}) < 0);
assertTrue(CompareUtil.compare(
new DummyObject[] {new DummyObject(3)}, new DummyObject[] {new DummyObject(7)}) < 0);
assertEquals(0,
CompareUtil.compare(
new DummyObject[] {new DummyObject(3)}, new DummyObject[] {new DummyObject(3)}));
assertTrue(CompareUtil.compare((DummyObject[])null, new DummyObject[] {}) < 0);
}
@Test
public void compareObjects()
{
assertEquals(0, CompareUtil.compareObjects(null, null));
assertTrue(CompareUtil.compareObjects(null, Integer.valueOf(0)) < 0);
assertTrue(CompareUtil.compareObjects(Integer.valueOf(0), null) > 0);
assertTrue(CompareUtil.compareObjects(Integer.valueOf(1), Integer.valueOf(2)) < 0);
assertTrue(CompareUtil.compareObjects("。", "😀") < 0);
assertTrue(CompareUtil.compareObjects(new byte[] {(byte)0x01}, new byte[] {(byte)0xFF}) < 0);
assertTrue(CompareUtil.compareObjects(Color.BLUE, Color.RED) < 0);
assertTrue(CompareUtil.compareObjects(new DummyObject(3), new DummyObject(7)) < 0);
// different classes are ordered by class names
assertTrue(CompareUtil.compareObjects(Integer.valueOf(1), "a") < 0);
assertTrue(CompareUtil.compareObjects("a", Integer.valueOf(1)) > 0);
}
// enum with values not in declaration order
private static enum Color implements ZserioEnum, SizeOf {
NONE(0),
RED(7),
BLUE(3),
BLACK(9);
private Color(int value)
{
this.value = value;
}
@Override
public Number getGenericValue()
{
return value;
}
@Override
public int bitSizeOf()
{
return 0;
}
@Override
public int bitSizeOf(long position)
{
return 0;
}
private int value;
}
// enum with BigInteger values
private static enum BigColor implements ZserioEnum, SizeOf {
BIG(new BigInteger("18446744073709551615")),
SMALL(BigInteger.ONE);
private BigColor(BigInteger value)
{
this.value = value;
}
@Override
public Number getGenericValue()
{
return value;
}
@Override
public int bitSizeOf()
{
return 0;
}
@Override
public int bitSizeOf(long position)
{
return 0;
}
private BigInteger value;
}
// bitmask
private static class Permissions implements ZserioBitmask, SizeOf, Comparable<Permissions>
{
public Permissions(int value)
{
this.value = value;
}
@Override
public boolean equals(Object other)
{
if (!(other instanceof Permissions))
return false;
return value == ((Permissions)other).value;
}
@Override
public int hashCode()
{
return value;
}
@Override
public int compareTo(Permissions other)
{
return CompareUtil.compare(value, other.value);
}
@Override
public java.lang.Number getGenericValue()
{
return value;
}
@Override
public int bitSizeOf()
{
return 0;
}
@Override
public int bitSizeOf(long position)
{
return 0;
}
public static final class Values
{
public static final Permissions READ = new Permissions(1);
public static final Permissions WRITE = new Permissions(2);
public static final Permissions CREATE = new Permissions(4);
}
private int value;
}
private static class DummyObject implements SizeOf, Comparable<DummyObject>
{
public DummyObject(int value)
{
this.value = value;
}
@Override
public boolean equals(Object other)
{
if (!(other instanceof DummyObject))
return false;
return value == ((DummyObject)other).value;
}
@Override
public int hashCode()
{
return value;
}
@Override
public int compareTo(DummyObject other)
{
return CompareUtil.compare(value, other.value);
}
@Override
public int bitSizeOf()
{
return 0;
}
@Override
public int bitSizeOf(long position)
{
return 0;
}
private final int value;
}
}