X-Git-Url: http://git.nikiroo.be/?p=fanfix.git;a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Ftest_code%2FSerialTest.java;fp=src%2Fbe%2Fnikiroo%2Futils%2Ftest_code%2FSerialTest.java;h=bf08f5c1b4dbd19f146bdd5af4b480c3fa4fd531;hp=0000000000000000000000000000000000000000;hb=d46b7b96f94e88a776bcd2dfd756549ffb300cc9;hpb=c9994f27667bc421bcd448d39e55774fddf5c431 diff --git a/src/be/nikiroo/utils/test_code/SerialTest.java b/src/be/nikiroo/utils/test_code/SerialTest.java new file mode 100644 index 0000000..bf08f5c --- /dev/null +++ b/src/be/nikiroo/utils/test_code/SerialTest.java @@ -0,0 +1,281 @@ +package be.nikiroo.utils.test_code; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.NotSerializableException; +import java.net.URL; +import java.util.Arrays; + +import be.nikiroo.utils.serial.Exporter; +import be.nikiroo.utils.serial.Importer; +import be.nikiroo.utils.test.TestCase; +import be.nikiroo.utils.test.TestLauncher; + +class SerialTest extends TestLauncher { + /** + * Required for Import/Export of objects. + */ + public SerialTest() { + this(null); + } + + private void encodeRecodeTest(TestCase test, Object data) throws Exception { + byte[] encoded = toBytes(data, true); + Object redata = fromBytes(toBytes(data, false)); + byte[] reencoded = toBytes(redata, true); + + // We suppose text mode + if (encoded.length < 256 && reencoded.length < 256) { + test.assertEquals("Different data after encode/decode/encode", + new String(encoded, "UTF-8"), + new String(reencoded, "UTF-8")); + } else { + test.assertEquals("Different data after encode/decode/encode", + true, Arrays.equals(encoded, reencoded)); + } + } + + // try to remove pointer addresses + private byte[] toBytes(Object data, boolean clearRefs) + throws NotSerializableException, IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + new Exporter(out).append(data); + out.flush(); + + if (clearRefs) { + String tmp = new String(out.toByteArray(), "UTF-8"); + tmp = tmp.replaceAll("@[0-9]*", "@REF"); + return tmp.getBytes("UTF-8"); + } + + return out.toByteArray(); + } + + private Object fromBytes(byte[] data) throws NoSuchFieldException, + NoSuchMethodException, ClassNotFoundException, + NullPointerException, IOException { + + InputStream in = new ByteArrayInputStream(data); + try { + return new Importer().read(in).getValue(); + } finally { + in.close(); + } + } + + public SerialTest(String[] args) { + super("Serial test", args); + + addTest(new TestCase("Simple class Import/Export") { + @Override + public void test() throws Exception { + Data data = new Data(42); + encodeRecodeTest(this, data); + } + }); + + addTest(new TestCase() { + @SuppressWarnings("unused") + private TestCase me = setName("Anonymous inner class"); + + @Override + public void test() throws Exception { + Data data = new Data() { + @SuppressWarnings("unused") + int value = 42; + }; + encodeRecodeTest(this, data); + } + }); + addTest(new TestCase() { + @SuppressWarnings("unused") + private TestCase me = setName("Array of anonymous inner classes"); + + @Override + public void test() throws Exception { + Data[] data = new Data[] { new Data() { + @SuppressWarnings("unused") + int value = 42; + } }; + + byte[] encoded = toBytes(data, false); + Object redata = fromBytes(encoded); + + // Comparing the 2 arrays won't be useful, because the @REFs + // will be ZIP-encoded; so we parse and re-encode each object + + byte[] encoded1 = toBytes(data[0], true); + byte[] reencoded1 = toBytes(((Object[]) redata)[0], true); + + assertEquals("Different data after encode/decode/encode", true, + Arrays.equals(encoded1, reencoded1)); + } + }); + addTest(new TestCase("URL Import/Export") { + @Override + public void test() throws Exception { + URL data = new URL("https://fanfan.be/"); + encodeRecodeTest(this, data); + } + }); + addTest(new TestCase("URL-String Import/Export") { + @Override + public void test() throws Exception { + String data = new URL("https://fanfan.be/").toString(); + encodeRecodeTest(this, data); + } + }); + addTest(new TestCase("URL/URL-String arrays Import/Export") { + @Override + public void test() throws Exception { + final String url = "https://fanfan.be/"; + Object[] data = new Object[] { new URL(url), url }; + + byte[] encoded = toBytes(data, false); + Object redata = fromBytes(encoded); + + // Comparing the 2 arrays won't be useful, because the @REFs + // will be ZIP-encoded; so we parse and re-encode each object + + byte[] encoded1 = toBytes(data[0], true); + byte[] reencoded1 = toBytes(((Object[]) redata)[0], true); + byte[] encoded2 = toBytes(data[1], true); + byte[] reencoded2 = toBytes(((Object[]) redata)[1], true); + + assertEquals("Different data 1 after encode/decode/encode", + true, Arrays.equals(encoded1, reencoded1)); + assertEquals("Different data 2 after encode/decode/encode", + true, Arrays.equals(encoded2, reencoded2)); + } + }); + addTest(new TestCase("Import/Export with nested objects") { + @Override + public void test() throws Exception { + Data data = new DataObject(new Data(21)); + encodeRecodeTest(this, data); + } + }); + addTest(new TestCase("Import/Export String in object") { + @Override + public void test() throws Exception { + Data data = new DataString("fanfan"); + encodeRecodeTest(this, data); + data = new DataString("http://example.com/query.html"); + encodeRecodeTest(this, data); + data = new DataString("Test|Ché|http://|\"\\\"Pouch\\"); + encodeRecodeTest(this, data); + data = new DataString("Test|Ché\\n|\nhttp://|\"\\\"Pouch\\"); + encodeRecodeTest(this, data); + } + }); + addTest(new TestCase("Import/Export with nested objects forming a loop") { + @Override + public void test() throws Exception { + DataLoop data = new DataLoop("looping"); + data.next = new DataLoop("level 2"); + data.next.next = data; + encodeRecodeTest(this, data); + } + }); + addTest(new TestCase("Array in Object Import/Export") { + @Override + public void test() throws Exception { + Object data = new DataArray();// new String[] { "un", "deux" }; + encodeRecodeTest(this, data); + } + }); + addTest(new TestCase("Array Import/Export") { + @Override + public void test() throws Exception { + Object data = new String[] { "un", "deux" }; + encodeRecodeTest(this, data); + } + }); + addTest(new TestCase("Enum Import/Export") { + @Override + public void test() throws Exception { + Object data = EnumToSend.FANFAN; + encodeRecodeTest(this, data); + } + }); + } + + class DataArray { + public String[] data = new String[] { "un", "deux" }; + } + + class Data { + private int value; + + private Data() { + } + + public Data(int value) { + this.value = value; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Data) { + Data other = (Data) obj; + return other.value == this.value; + } + + return false; + } + + @Override + public int hashCode() { + return new Integer(value).hashCode(); + } + } + + @SuppressWarnings("unused") + class DataObject extends Data { + private Data data; + + @SuppressWarnings("synthetic-access") + private DataObject() { + } + + @SuppressWarnings("synthetic-access") + public DataObject(Data data) { + this.data = data; + } + } + + @SuppressWarnings("unused") + class DataString extends Data { + private String data; + + @SuppressWarnings("synthetic-access") + private DataString() { + } + + @SuppressWarnings("synthetic-access") + public DataString(String data) { + this.data = data; + } + } + + @SuppressWarnings("unused") + class DataLoop extends Data { + public DataLoop next; + private String value; + + @SuppressWarnings("synthetic-access") + private DataLoop() { + } + + @SuppressWarnings("synthetic-access") + public DataLoop(String value) { + this.value = value; + } + } + + enum EnumToSend { + FANFAN, TULIPE, + } +}