860980f8376ca072afd4ff633cbe6d878b2dc77c
[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 // try to remove pointer addresses
25 private byte[] toBytes(Object data) throws NotSerializableException,
26 IOException {
27 ByteArrayOutputStream out = new ByteArrayOutputStream();
28 new Exporter(out).append(data);
29 out.flush();
30 String tmp = new String(out.toByteArray(), "UTF-8");
31 tmp = tmp.replaceAll("@[0-9]*", "@REF");
32 return tmp.getBytes("UTF-8");
33 }
34
35 private Object fromBytes(byte[] data) throws NoSuchFieldException,
36 NoSuchMethodException, ClassNotFoundException,
37 NullPointerException, IOException {
38
39 InputStream in = new ByteArrayInputStream(data);
40 try {
41 return new Importer().read(in).getValue();
42 } finally {
43 in.close();
44 }
45 }
46
47 public SerialTest(String[] args) {
48 super("Serial test", args);
49
50 addTest(new TestCase("Simple class Import/Export") {
51 @Override
52 public void test() throws Exception {
53 Data data = new Data(42);
54
55 byte[] encoded = toBytes(data);
56 Object redata = fromBytes(encoded);
57 byte[] reencoded = toBytes(redata);
58
59 assertEquals("Different data after encode/decode/encode", true,
60 Arrays.equals(encoded, reencoded));
61 }
62 });
63
64 addTest(new TestCase() {
65 @SuppressWarnings("unused")
66 private TestCase me = setName("Anonymous inner class");
67
68 @Override
69 public void test() throws Exception {
70 Data data = new Data() {
71 @SuppressWarnings("unused")
72 int value = 42;
73 };
74 String encoded = new Exporter().append(data).toString(false,
75 false);
76 Object redata = new Importer().read(encoded).getValue();
77 String reencoded = new Exporter().append(redata).toString(
78 false, false);
79 assertEquals(encoded.replaceAll("@[0-9]*", "@REF"),
80 reencoded.replaceAll("@[0-9]*", "@REF"));
81 }
82 });
83 addTest(new TestCase() {
84 @SuppressWarnings("unused")
85 private TestCase me = setName("Array of anonymous inner classes");
86
87 @Override
88 public void test() throws Exception {
89 Data[] data = new Data[] { new Data() {
90 @SuppressWarnings("unused")
91 int value = 42;
92 } };
93 String encoded = new Exporter().append(data).toString(false,
94 false);
95 Object redata = new Importer().read(encoded).getValue();
96 String reencoded = new Exporter().append(redata).toString(
97 false, false);
98 // Comparing the 2 strings won't be useful, because the @REFs
99 // will be ZIP-encoded; so we parse and re-encode the object
100 encoded = new Exporter().append(data[0]).toString(false, false);
101 try {
102 reencoded = new Exporter().append(((Data[]) redata)[0])
103 .toString(false, false);
104 } catch (Exception e) {
105 fail("Cannot cast the returned data into its original object",
106 e);
107 }
108 assertEquals(encoded.replaceAll("@[0-9]*", "@REF"),
109 reencoded.replaceAll("@[0-9]*", "@REF"));
110 }
111 });
112 addTest(new TestCase("URL Import/Export") {
113 @Override
114 public void test() throws Exception {
115 URL data = new URL("https://fanfan.be/");
116 String encoded = new Exporter().append(data).toString(false,
117 false);
118 Object redata = new Importer().read(encoded).getValue();
119 String reencoded = new Exporter().append(redata).toString(
120 false, false);
121 assertEquals(encoded.replaceAll("@[0-9]*", "@REF"),
122 reencoded.replaceAll("@[0-9]*", "@REF"));
123 }
124 });
125 addTest(new TestCase("URL-String Import/Export") {
126 @Override
127 public void test() throws Exception {
128 String data = new URL("https://fanfan.be/").toString();
129 String encoded = new Exporter().append(data).toString(false,
130 false);
131 Object redata = new Importer().read(encoded).getValue();
132 String reencoded = new Exporter().append(redata).toString(
133 false, false);
134 assertEquals(encoded.replaceAll("@[0-9]*", "@REF"),
135 reencoded.replaceAll("@[0-9]*", "@REF"));
136 assertEquals(data, redata);
137 }
138 });
139 addTest(new TestCase("URL/URL-String arrays Import/Export") {
140 @Override
141 public void test() throws Exception {
142 final String url = "https://fanfan.be/";
143 Object[] data = new Object[] { new URL(url), url };
144 String encoded = new Exporter().append(data).toString(false,
145 false);
146 Object redata = new Importer().read(encoded).getValue();
147 String reencoded = new Exporter().append(redata).toString(
148 false, false);
149 assertEquals(encoded.replaceAll("@[0-9]*", "@REF"),
150 reencoded.replaceAll("@[0-9]*", "@REF"));
151 assertEquals(data[0], ((Object[]) redata)[0]);
152 assertEquals(data[1], ((Object[]) redata)[1]);
153 }
154 });
155 addTest(new TestCase("Import/Export with nested objects") {
156 @Override
157 public void test() throws Exception {
158 Data data = new DataObject(new Data(21));
159 String encoded = new Exporter().append(data).toString(false,
160 false);
161 Object redata = new Importer().read(encoded).getValue();
162 String reencoded = new Exporter().append(redata).toString(
163 false, false);
164 assertEquals(encoded.replaceAll("@[0-9]*", "@REF"),
165 reencoded.replaceAll("@[0-9]*", "@REF"));
166 }
167 });
168 addTest(new TestCase("Import/Export with nested objects forming a loop") {
169 @Override
170 public void test() throws Exception {
171 DataLoop data = new DataLoop("looping");
172 data.next = new DataLoop("level 2");
173 data.next.next = data;
174 String encoded = new Exporter().append(data).toString(false,
175 false);
176 Object redata = new Importer().read(encoded).getValue();
177 String reencoded = new Exporter().append(redata).toString(
178 false, false);
179 assertEquals(encoded.replaceAll("@[0-9]*", "@REF"),
180 reencoded.replaceAll("@[0-9]*", "@REF"));
181 }
182 });
183 addTest(new TestCase("Array in Object Import/Export") {
184 @Override
185 public void test() throws Exception {
186 Object data = new DataArray();// new String[] { "un", "deux" };
187 String encoded = new Exporter().append(data).toString(false,
188 false);
189 Object redata = new Importer().read(encoded).getValue();
190 String reencoded = new Exporter().append(redata).toString(
191 false, false);
192 assertEquals(encoded.replaceAll("@[0-9]*", "@REF"),
193 reencoded.replaceAll("@[0-9]*", "@REF"));
194 }
195 });
196 addTest(new TestCase("Array Import/Export") {
197 @Override
198 public void test() throws Exception {
199 Object data = new String[] { "un", "deux" };
200 String encoded = new Exporter().append(data).toString(false,
201 false);
202 Object redata = new Importer().read(encoded).getValue();
203 String reencoded = new Exporter().append(redata).toString(
204 false, false);
205 assertEquals(encoded.replaceAll("@[0-9]*", "@REF"),
206 reencoded.replaceAll("@[0-9]*", "@REF"));
207 }
208 });
209 addTest(new TestCase("Enum Import/Export") {
210 @Override
211 public void test() throws Exception {
212 Object data = EnumToSend.FANFAN;
213 String encoded = new Exporter().append(data).toString(false,
214 false);
215 Object redata = new Importer().read(encoded).getValue();
216 String reencoded = new Exporter().append(redata).toString(
217 false, false);
218 assertEquals(encoded.replaceAll("@[0-9]*", "@REF"),
219 reencoded.replaceAll("@[0-9]*", "@REF"));
220 }
221 });
222 addTest(new TestCase("B64 and ZIP String test") {
223 @Override
224 public void test() throws Exception {
225 Object data = "Fanfan la tulipe";
226 String encoded = new Exporter().append(data).toString(true,
227 false);
228 String redata = (String) new Importer().read(encoded)
229 .getValue();
230 assertEquals("Items not identical after B64", data, redata);
231 encoded = new Exporter().append(data).toString(true, true);
232 redata = (String) new Importer().read(encoded).getValue();
233 assertEquals("Items not identical after ZIP", data, redata);
234 }
235 });
236 addTest(new TestCase("B64 and ZIP Data test") {
237 @Override
238 public void test() throws Exception {
239 Object data = new Data(55);
240 String encoded = new Exporter().append(data).toString(true,
241 false);
242 Data redata = (Data) new Importer().read(encoded).getValue();
243 assertEquals("Items not identical after B64", data, redata);
244 encoded = new Exporter().append(data).toString(true, true);
245 redata = (Data) new Importer().read(encoded).getValue();
246 assertEquals("Items not identical after ZIP", data, redata);
247 }
248 });
249 addTest(new TestCase("B64 and ZIP 70000 chars test") {
250 @Override
251 public void test() throws Exception {
252 StringBuilder builder = new StringBuilder();
253 for (int i = 0; i < 7000; i++) {
254 builder.append("0123456789");
255 }
256 Object data = builder.toString();
257 String encoded = new Exporter().append(data).toString(true,
258 false);
259 String redata = (String) new Importer().read(encoded)
260 .getValue();
261 assertEquals("Items not identical after B64", data, redata);
262 encoded = new Exporter().append(data).toString(true, true);
263 redata = (String) new Importer().read(encoded).getValue();
264 assertEquals("Items not identical after ZIP", data, redata);
265 }
266 });
267 }
268
269 class DataArray {
270 public String[] data = new String[] { "un", "deux" };
271 }
272
273 class Data {
274 private int value;
275
276 private Data() {
277 }
278
279 public Data(int value) {
280 this.value = value;
281 }
282
283 @Override
284 public boolean equals(Object obj) {
285 if (obj instanceof Data) {
286 Data other = (Data) obj;
287 return other.value == this.value;
288 }
289
290 return false;
291 }
292
293 @Override
294 public int hashCode() {
295 return new Integer(value).hashCode();
296 }
297 }
298
299 @SuppressWarnings("unused")
300 class DataObject extends Data {
301 private Data data;
302
303 @SuppressWarnings("synthetic-access")
304 private DataObject() {
305 }
306
307 @SuppressWarnings("synthetic-access")
308 public DataObject(Data data) {
309 this.data = data;
310 }
311 }
312
313 @SuppressWarnings("unused")
314 class DataLoop extends Data {
315 public DataLoop next;
316 private String value;
317
318 @SuppressWarnings("synthetic-access")
319 private DataLoop() {
320 }
321
322 @SuppressWarnings("synthetic-access")
323 public DataLoop(String value) {
324 this.value = value;
325 }
326 }
327
328 enum EnumToSend {
329 FANFAN, TULIPE,
330 }
331 }