1 module plist.tests.deserialization;
2 import plist;
3 import plist.types;
4 
5 unittest {
6     /* Test deserialization of strings */
7     {
8         struct DeserdeTest {
9             @PlistKey("Hello") string hi;
10         }
11           string xml = `<?xml version="1.0" encoding="UTF-8"?>
12 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
13 <plist version="1.0">
14     <dict>
15         <key>Hello</key>
16         <string>World</string>
17     </dict>
18 </plist>`;
19           Plist parse = new Plist();
20           parse.read(xml);
21           assert(parse.length == 1, "Expected length of 1");
22 
23           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
24           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
25 
26           PlistElementDict dict = cast(PlistElementDict)parse[0];
27 
28           DeserdeTest obj;
29 
30           dict.coerceToNative!DeserdeTest(obj);
31 
32           import std.stdio;
33           assert(obj.hi == "World", "Expected different result from deserialization");
34     }
35     /* Deserialize reals */
36     {
37         struct DeserdeTest_2 {
38             @PlistKey("Hello") real hi;
39         }
40           string xml = `<?xml version="1.0" encoding="UTF-8"?>
41 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
42 <plist version="1.0">
43     <dict>
44         <key>Hello</key>
45         <real>1.0001</real>
46     </dict>
47 </plist>`;
48           Plist parse = new Plist();
49           parse.read(xml);
50           assert(parse.length == 1, "Expected length of 1");
51           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
52           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
53 
54           PlistElementDict dict = cast(PlistElementDict)parse[0];
55 
56           DeserdeTest_2 obj;
57 
58           dict.coerceToNative!DeserdeTest_2(obj);
59 
60           assert(obj.hi == 1.0001, "Expected different result from deserialization");
61     }
62     /* Deserialize integers */
63     {
64         struct DeserdeTest_3 {
65             @PlistKey("Hello") long hi;
66         }
67           string xml = `<?xml version="1.0" encoding="UTF-8"?>
68 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
69 <plist version="1.0">
70     <dict>
71         <key>Hello</key>
72         <integer>1337</integer>
73     </dict>
74 </plist>`;
75           Plist parse = new Plist();
76           parse.read(xml);
77           assert(parse.length == 1, "Expected length of 1");
78           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
79           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
80 
81           PlistElementDict dict = cast(PlistElementDict)parse[0];
82 
83           DeserdeTest_3 obj;
84 
85           dict.coerceToNative!DeserdeTest_3(obj);
86 
87           assert(obj.hi == 1337, "Expected different result from deserialization");
88     }
89     /* Deserialize integers (with precision) */
90     {
91         struct DeserdeTest_4 {
92             @PlistKey("Hello") int hi;
93         }
94           string xml = `<?xml version="1.0" encoding="UTF-8"?>
95 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
96 <plist version="1.0">
97     <dict>
98         <key>Hello</key>
99         <integer>1337</integer>
100     </dict>
101 </plist>`;
102           Plist parse = new Plist();
103           parse.read(xml);
104           assert(parse.length == 1, "Expected length of 1");
105           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
106           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
107 
108           PlistElementDict dict = cast(PlistElementDict)parse[0];
109 
110           DeserdeTest_4 obj;
111 
112           bool failed = false;
113           try {
114               dict.coerceToNative!DeserdeTest_4(obj);
115           } catch (PlistSerdeException e) {
116               failed = true;
117           }
118 
119           assert(failed, "Should NOT deserialize");
120 
121           assert(obj.hi == 0, "Expected different result from deserialization");
122     }
123 
124     /* Deserialize dates */
125     {
126         import std.datetime : SysTime;
127         struct DeserdeTest_5 {
128             @PlistKey("Hello") SysTime hi;
129         }
130           string xml = `<?xml version="1.0" encoding="UTF-8"?>
131 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
132 <plist version="1.0">
133     <dict>
134         <key>Hello</key>
135         <date>1970-01-01T00:00:00Z</date>
136     </dict>
137 </plist>`;
138           Plist parse = new Plist();
139           parse.read(xml);
140           assert(parse.length == 1, "Expected length of 1");
141           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
142           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
143 
144           PlistElementDict dict = cast(PlistElementDict)parse[0];
145 
146           DeserdeTest_5 obj;
147 
148           dict.coerceToNative!DeserdeTest_5(obj);
149 
150           assert(obj.hi.toUnixTime() == 0, "Expected different result from deserialization");
151     }
152     /* Deserialize booleans */
153     {
154         struct DeserdeTest_6 {
155             @PlistKey("Hello") bool hi;
156             @PlistKey("World") bool bye;
157         }
158           string xml = `<?xml version="1.0" encoding="UTF-8"?>
159 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
160 <plist version="1.0">
161     <dict>
162         <key>Hello</key>
163         <true/>
164         <key>World</key>
165         <false/>
166     </dict>
167 </plist>`;
168           Plist parse = new Plist();
169           parse.read(xml);
170           assert(parse.length == 1, "Expected length of 1");
171           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
172           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
173 
174           PlistElementDict dict = cast(PlistElementDict)parse[0];
175 
176           DeserdeTest_6 obj;
177 
178           dict.coerceToNative!DeserdeTest_6(obj);
179 
180           assert(obj.hi, "Expected different result from deserialization");
181           assert(!obj.bye, "Expected different result from deserialization");
182     }
183     /* Deserialize a dict within a dict */
184     {
185         struct DeserdeTest_8 {
186             @PlistKey("Hello") bool hi;
187             @PlistKey("World") bool bye;
188         }
189 
190         struct DeserdeTest_9 {
191             @PlistKey("Leet") string msg;
192         }
193 
194         struct DeserdeTest_7 {
195             @PlistKey("Foo") DeserdeTest_8 bar;
196             @PlistKey("Bar") DeserdeTest_9 meat;
197         }
198 
199               string xml = `<?xml version="1.0" encoding="UTF-8"?>
200 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
201 <plist version="1.0">
202     <dict>
203         <key>Bar</key>
204         <dict>
205             <key>Leet</key>
206             <string>Code</string>
207         </dict>
208         <key>Foo</key>
209         <dict>
210             <key>Hello</key>
211             <true/>
212             <key>World</key>
213             <false/>
214         </dict>
215     </dict>
216 </plist>`;
217           Plist parse = new Plist();
218           parse.read(xml);
219           assert(parse.length == 1, "Expected length of 1");
220           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
221           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
222 
223           PlistElementDict dict = cast(PlistElementDict)parse[0];
224 
225           DeserdeTest_7 obj;
226 
227           dict.coerceToNative!DeserdeTest_7(obj);
228 
229           assert(obj.bar.hi, "Expected different value");
230 
231           assert(!obj.bar.bye, "Expected different value");
232 
233           assert(obj.meat.msg == "Code", "Expected different value");
234     }
235     /* Ensure that exceptions and such are passed down through the insane amount of redirection we do */
236     {
237         struct DeserdeTest_10 {
238             @PlistKey("Hello") bool hi;
239             @PlistKey("World") bool bye;
240         }
241 
242         struct DeserdeTest_11 {
243             @PlistKey("Foobar") DeserdeTest_10 foobar;
244         }
245           string xml = `<?xml version="1.0" encoding="UTF-8"?>
246 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
247 <plist version="1.0">
248     <dict>
249         <key>Foobar</key>
250         <dict>
251             <key>Hello</key>
252             <string>Hmm</string>
253             <key>World</key>
254             <false/>
255         </dict>
256     </dict>
257 </plist>`;
258           Plist parse = new Plist();
259           parse.read(xml);
260           assert(parse.length == 1, "Expected length of 1");
261           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
262           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
263 
264           PlistElementDict dict = cast(PlistElementDict)parse[0];
265 
266           DeserdeTest_11 obj;
267 
268           bool failed = false;
269           try {
270             dict.coerceToNative!DeserdeTest_11(obj);
271           } catch(PlistSerdeException e) {
272               failed = true;
273           }
274 
275 
276           assert(failed, "Should've failed");
277     }
278     /* Deserialize arrays */
279     {
280         struct DeserdeTest_12 {
281             @PlistKey("Hello") PlistElementArray array;
282         }
283           string xml = `<?xml version="1.0" encoding="UTF-8"?>
284 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
285 <plist version="1.0">
286     <dict>
287         <key>Hello</key>
288         <array>
289             <string>Pied Piper's revolutionary compression</string>
290             <true/>
291         </array>
292     </dict>
293 </plist>`;
294           Plist parse = new Plist();
295           parse.read(xml);
296           assert(parse.length == 1, "Expected length of 1");
297           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
298           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
299 
300           PlistElementDict dict = cast(PlistElementDict)parse[0];
301 
302           DeserdeTest_12 obj;
303 
304           dict.coerceToNative!DeserdeTest_12(obj);
305 
306           assert(obj.array.length == 2);
307 
308           assert(obj.array[0].type() == "string");
309 
310           assert(obj.array[1].type() == "bool");
311     }
312     /* Deserialize arrays (type 2)  */
313     {
314         struct DeserdeTest_13 {
315             @PlistKey("Hello") long hello;
316             @PlistKey("Bar") @PlistOptional long bar;
317         }
318         struct DeserdeTest_14 {
319             @PlistKey("Foo") DeserdeTest_13[] bar;
320         }
321           string xml = `<?xml version="1.0" encoding="UTF-8"?>
322 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
323 <plist version="1.0">
324     <dict>
325         <key>Foo</key>
326         <array>
327             <dict>
328                 <key>Bar</key>
329                 <integer>420</integer>
330                 <key>Hello</key>
331                 <integer>1337</integer>
332             </dict>
333         </array>
334     </dict>
335 </plist>`;
336           Plist parse = new Plist();
337           parse.read(xml);
338           assert(parse.length == 1, "Expected length of 1");
339           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
340           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
341 
342           PlistElementDict dict = cast(PlistElementDict)parse[0];
343 
344           DeserdeTest_14 obj;
345           dict.coerceToNative!DeserdeTest_14(obj);
346           assert(obj.bar.length == 1, "Expected length of 1");
347           assert(obj.bar[0].hello == 1337, "Expected different value");
348           assert(obj.bar[0].bar == 420, "expected diff value");
349     }
350     /* Deserialize data as a static array */
351     {
352         struct DeserdeTest_15 {
353             @PlistKey("Hello") ubyte[8] hi;
354         }
355           string xml = `<?xml version="1.0" encoding="UTF-8"?>
356 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
357 <plist version="1.0">
358     <dict>
359         <key>Hello</key>
360         <data>Q3B1MElzdAA=</data>
361     </dict>
362 </plist>`;
363           Plist parse = new Plist();
364           parse.read(xml);
365           assert(parse.length == 1, "Expected length of 1");
366           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
367           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
368 
369           PlistElementDict dict = cast(PlistElementDict)parse[0];
370 
371           DeserdeTest_15 obj;
372 
373           dict.coerceToNative!DeserdeTest_15(obj);
374     }
375     /* Deserialize data as a dynamic array */
376     {
377         struct DeserdeTest_16 {
378             @PlistKey("Hello") ubyte[] hi;
379         }
380           string xml = `<?xml version="1.0" encoding="UTF-8"?>
381 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
382 <plist version="1.0">
383     <dict>
384         <key>Hello</key>
385         <data>Q3B1MElzdAA=</data>
386     </dict>
387 </plist>`;
388           Plist parse = new Plist();
389           parse.read(xml);
390           assert(parse.length == 1, "Expected length of 1");
391           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
392           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
393 
394           PlistElementDict dict = cast(PlistElementDict)parse[0];
395 
396           DeserdeTest_16 obj;
397 
398           dict.coerceToNative!DeserdeTest_16(obj);
399 
400           assert(obj.hi.length == 8);
401     }
402     /* Deserialize data as a dynamic array WITHIN an array */
403     /* Arrayception */
404     {
405         struct DeserdeTest_17 {
406             @PlistKey("Hello") ubyte[] hi;
407         }
408 
409         struct DeserdeTest_18 {
410             @PlistKey("Arrays") DeserdeTest_17[] arrays;
411         }
412           string xml = `<?xml version="1.0" encoding="UTF-8"?>
413 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
414 <plist version="1.0">
415     <dict>
416         <key>Arrays</key>
417         <array>
418             <dict>
419                 <key>Hello</key>
420                 <data>Q3B1MElzdAA=</data>
421             </dict>
422         </array>
423     </dict>
424 </plist>`;
425           Plist parse = new Plist();
426           parse.read(xml);
427           assert(parse.length == 1, "Expected length of 1");
428           assert(parse.write() == xml, "Writing doesn't output the same what we put in");
429           assert(parse[0].type() == PlistElementType.PLIST_ELEMENT_DICT, "Expected dict at index 0");
430 
431           PlistElementDict dict = cast(PlistElementDict)parse[0];
432 
433           DeserdeTest_18 obj;
434 
435           dict.coerceToNative!DeserdeTest_18(obj);
436 
437           assert(obj.arrays.length == 1);
438           assert(obj.arrays[0].hi.length == 8);
439     }
440 
441 
442 }