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