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 }