test now all compile
[nikiroo-utils.git] / src / be / nikiroo / utils / test_code / SerialTest.java
1 package be.nikiroo.utils.test_code;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.NotSerializableException;
8 import java.net.URL;
9 import java.util.Arrays;
10
11 import be.nikiroo.utils.serial.Exporter;
12 import be.nikiroo.utils.serial.Importer;
13 import be.nikiroo.utils.test.TestCase;
14 import be.nikiroo.utils.test.TestLauncher;
15
16 class SerialTest extends TestLauncher {
17 /**
18 * Required for Import/Export of objects.
19 */
20 public SerialTest() {
21 this(null);
22 }
23
24 private void encodeRecodeTest(TestCase test, Object data) throws Exception {
25 byte[] encoded = toBytes(data, true);
26 Object redata = fromBytes(encoded);
27 byte[] reencoded = toBytes(redata, true);
28
29 test.assertEquals("Different data after encode/decode/encode", true,
30 Arrays.equals(encoded, reencoded));
31 }
32
33 // try to remove pointer addresses
34 private byte[] toBytes(Object data, boolean clearRefs)
35 throws NotSerializableException, IOException {
36 ByteArrayOutputStream out = new ByteArrayOutputStream();
37 new Exporter(out).append(data);
38 out.flush();
39
40 if (clearRefs) {
41 String tmp = new String(out.toByteArray(), "UTF-8");
42 tmp = tmp.replaceAll("@[0-9]*", "@REF");
43 return tmp.getBytes("UTF-8");
44 }
45
46 return out.toByteArray();
47 }
48
49 private Object fromBytes(byte[] data) throws NoSuchFieldException,
50 NoSuchMethodException, ClassNotFoundException,
51 NullPointerException, IOException {
52
53 InputStream in = new ByteArrayInputStream(data);
54 try {
55 return new Importer().read(in).getValue();
56 } finally {
57 in.close();
58 }
59 }
60
61 public SerialTest(String[] args) {
62 super("Serial test", args);
63
64 addTest(new TestCase("Simple class Import/Export") {
65 @Override
66 public void test() throws Exception {
67 Data data = new Data(42);
68 encodeRecodeTest(this, data);
69 }
70 });
71
72 addTest(new TestCase() {
73 @SuppressWarnings("unused")
74 private TestCase me = setName("Anonymous inner class");
75
76 @Override
77 public void test() throws Exception {
78 Data data = new Data() {
79 @SuppressWarnings("unused")
80 int value = 42;
81 };
82 encodeRecodeTest(this, data);
83 }
84 });
85 addTest(new TestCase() {
86 @SuppressWarnings("unused")
87 private TestCase me = setName("Array of anonymous inner classes");
88
89 @Override
90 public void test() throws Exception {
91 Data[] data = new Data[] { new Data() {
92 @SuppressWarnings("unused")
93 int value = 42;
94 } };
95
96 byte[] encoded = toBytes(data, false);
97 Object redata = fromBytes(encoded);
98
99 // Comparing the 2 arrays won't be useful, because the @REFs
100 // will be ZIP-encoded; so we parse and re-encode each object
101
102 byte[] encoded1 = toBytes(data[0], true);
103 byte[] reencoded1 = toBytes(((Object[]) redata)[0], true);
104
105 assertEquals("Different data after encode/decode/encode", true,
106 Arrays.equals(encoded1, reencoded1));
107 }
108 });
109 addTest(new TestCase("URL Import/Export") {
110 @Override
111 public void test() throws Exception {
112 URL data = new URL("https://fanfan.be/");
113 encodeRecodeTest(this, data);
114 }
115 });
116 addTest(new TestCase("URL-String Import/Export") {
117 @Override
118 public void test() throws Exception {
119 String data = new URL("https://fanfan.be/").toString();
120 encodeRecodeTest(this, data);
121 }
122 });
123 addTest(new TestCase("URL/URL-String arrays Import/Export") {
124 @Override
125 public void test() throws Exception {
126 final String url = "https://fanfan.be/";
127 Object[] data = new Object[] { new URL(url), url };
128
129 byte[] encoded = toBytes(data, false);
130 Object redata = fromBytes(encoded);
131
132 // Comparing the 2 arrays won't be useful, because the @REFs
133 // will be ZIP-encoded; so we parse and re-encode each object
134
135 byte[] encoded1 = toBytes(data[0], true);
136 byte[] reencoded1 = toBytes(((Object[]) redata)[0], true);
137 byte[] encoded2 = toBytes(data[0], true);
138 byte[] reencoded2 = toBytes(((Object[]) redata)[1], true);
139
140 assertEquals("Different data 1 after encode/decode/encode",
141 true, Arrays.equals(encoded1, reencoded1));
142 assertEquals("Different data 2 after encode/decode/encode",
143 true, Arrays.equals(encoded2, reencoded2));
144 }
145 });
146 addTest(new TestCase("Import/Export with nested objects") {
147 @Override
148 public void test() throws Exception {
149 Data data = new DataObject(new Data(21));
150 encodeRecodeTest(this, data);
151 }
152 });
153 addTest(new TestCase("Import/Export with nested objects forming a loop") {
154 @Override
155 public void test() throws Exception {
156 DataLoop data = new DataLoop("looping");
157 data.next = new DataLoop("level 2");
158 data.next.next = data;
159 encodeRecodeTest(this, data);
160 }
161 });
162 addTest(new TestCase("Array in Object Import/Export") {
163 @Override
164 public void test() throws Exception {
165 Object data = new DataArray();// new String[] { "un", "deux" };
166 encodeRecodeTest(this, data);
167 }
168 });
169 addTest(new TestCase("Array Import/Export") {
170 @Override
171 public void test() throws Exception {
172 Object data = new String[] { "un", "deux" };
173 encodeRecodeTest(this, data);
174 }
175 });
176 addTest(new TestCase("Enum Import/Export") {
177 @Override
178 public void test() throws Exception {
179 Object data = EnumToSend.FANFAN;
180 encodeRecodeTest(this, data);
181 }
182 });
183 }
184
185 class DataArray {
186 public String[] data = new String[] { "un", "deux" };
187 }
188
189 class Data {
190 private int value;
191
192 private Data() {
193 }
194
195 public Data(int value) {
196 this.value = value;
197 }
198
199 @Override
200 public boolean equals(Object obj) {
201 if (obj instanceof Data) {
202 Data other = (Data) obj;
203 return other.value == this.value;
204 }
205
206 return false;
207 }
208
209 @Override
210 public int hashCode() {
211 return new Integer(value).hashCode();
212 }
213 }
214
215 @SuppressWarnings("unused")
216 class DataObject extends Data {
217 private Data data;
218
219 @SuppressWarnings("synthetic-access")
220 private DataObject() {
221 }
222
223 @SuppressWarnings("synthetic-access")
224 public DataObject(Data data) {
225 this.data = data;
226 }
227 }
228
229 @SuppressWarnings("unused")
230 class DataLoop extends Data {
231 public DataLoop next;
232 private String value;
233
234 @SuppressWarnings("synthetic-access")
235 private DataLoop() {
236 }
237
238 @SuppressWarnings("synthetic-access")
239 public DataLoop(String value) {
240 this.value = value;
241 }
242 }
243
244 enum EnumToSend {
245 FANFAN, TULIPE,
246 }
247 }