aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/test/llsdserialize_tut.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/test/llsdserialize_tut.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/test/llsdserialize_tut.cpp')
-rw-r--r--linden/indra/test/llsdserialize_tut.cpp558
1 files changed, 558 insertions, 0 deletions
diff --git a/linden/indra/test/llsdserialize_tut.cpp b/linden/indra/test/llsdserialize_tut.cpp
new file mode 100644
index 0000000..c87d7d1
--- /dev/null
+++ b/linden/indra/test/llsdserialize_tut.cpp
@@ -0,0 +1,558 @@
1/**
2 * @file llsdserialize_tut.cpp
3 * @date April 2006
4 * @brief LLSDSerialize unit tests
5 *
6 * Copyright (c) 2006-2007, Linden Research, Inc.
7 *
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28
29#include <math.h>
30#include <sstream>
31#include <tut/tut.h>
32
33#include "llsd.h"
34#include "llsdserialize.h"
35#include "lltut.h"
36
37
38namespace tut
39{
40 struct sd_xml_data
41 {
42 sd_xml_data()
43 {
44 mFormatter = new LLSDXMLFormatter;
45 }
46 LLSD mSD;
47 LLPointer<LLSDXMLFormatter> mFormatter;
48 void xml_test(const char* name, const std::string& expected)
49 {
50 std::ostringstream ostr;
51 mFormatter->format(mSD, ostr);
52 ensure_equals(name, ostr.str(), expected);
53 }
54 };
55
56 typedef test_group<sd_xml_data> sd_xml_test;
57 typedef sd_xml_test::object sd_xml_object;
58 tut::sd_xml_test sd_xml_stream("sd_xml_serialization");
59
60 template<> template<>
61 void sd_xml_object::test<1>()
62 {
63 // random atomic tests
64 std::string expected;
65
66 expected = "<llsd><undef /></llsd>\n";
67 xml_test("undef", expected);
68
69 mSD = 3463;
70 expected = "<llsd><integer>3463</integer></llsd>\n";
71 xml_test("integer", expected);
72
73 mSD = "";
74 expected = "<llsd><string /></llsd>\n";
75 xml_test("empty string", expected);
76
77 mSD = "foobar";
78 expected = "<llsd><string>foobar</string></llsd>\n";
79 xml_test("string", expected);
80
81 mSD = LLUUID::null;
82 expected = "<llsd><uuid /></llsd>\n";
83 xml_test("null uuid", expected);
84
85 mSD = LLUUID("c96f9b1e-f589-4100-9774-d98643ce0bed");
86 expected = "<llsd><uuid>c96f9b1e-f589-4100-9774-d98643ce0bed</uuid></llsd>\n";
87 xml_test("uuid", expected);
88
89 mSD = LLURI("https://secondlife.com/login");
90 expected = "<llsd><uri>https://secondlife.com/login</uri></llsd>\n";
91 xml_test("uri", expected);
92
93 mSD = LLDate("2006-04-24T16:11:33Z");
94 expected = "<llsd><date>2006-04-24T16:11:33Z</date></llsd>\n";
95 xml_test("date", expected);
96
97 // *FIX: test binary
98 }
99
100 template<> template<>
101 void sd_xml_object::test<2>()
102 {
103 // tests with boolean values.
104 std::string expected;
105
106 mFormatter->boolalpha(true);
107 mSD = true;
108 expected = "<llsd><boolean>true</boolean></llsd>\n";
109 xml_test("bool alpha true", expected);
110 mSD = false;
111 expected = "<llsd><boolean>false</boolean></llsd>\n";
112 xml_test("bool alpha false", expected);
113
114 mFormatter->boolalpha(false);
115 mSD = true;
116 expected = "<llsd><boolean>1</boolean></llsd>\n";
117 xml_test("bool true", expected);
118 mSD = false;
119 expected = "<llsd><boolean>0</boolean></llsd>\n";
120 xml_test("bool false", expected);
121 }
122
123
124 template<> template<>
125 void sd_xml_object::test<3>()
126 {
127 // tests with real values.
128 std::string expected;
129
130 mFormatter->realFormat("%.2f");
131 mSD = 1.0;
132 expected = "<llsd><real>1.00</real></llsd>\n";
133 xml_test("real 1", expected);
134
135 mSD = -34379.0438;
136 expected = "<llsd><real>-34379.04</real></llsd>\n";
137 xml_test("real reduced precision", expected);
138 mFormatter->realFormat("%.4f");
139 expected = "<llsd><real>-34379.0438</real></llsd>\n";
140 xml_test("higher precision", expected);
141
142 mFormatter->realFormat("%.0f");
143 mSD = 0.0;
144 expected = "<llsd><real>0</real></llsd>\n";
145 xml_test("no decimal 0", expected);
146 mSD = 3287.4387;
147 expected = "<llsd><real>3287</real></llsd>\n";
148 xml_test("no decimal real number", expected);
149 }
150
151 template<> template<>
152 void sd_xml_object::test<4>()
153 {
154 // tests with arrays
155 std::string expected;
156
157 mSD = LLSD::emptyArray();
158 expected = "<llsd><array /></llsd>\n";
159 xml_test("empty array", expected);
160
161 mSD.append(LLSD());
162 expected = "<llsd><array><undef /></array></llsd>\n";
163 xml_test("1 element array", expected);
164
165 mSD.append(1);
166 expected = "<llsd><array><undef /><integer>1</integer></array></llsd>\n";
167 xml_test("2 element array", expected);
168 }
169
170 template<> template<>
171 void sd_xml_object::test<5>()
172 {
173 // tests with arrays
174 std::string expected;
175
176 mSD = LLSD::emptyMap();
177 expected = "<llsd><map /></llsd>\n";
178 xml_test("empty map", expected);
179
180 mSD["foo"] = "bar";
181 expected = "<llsd><map><key>foo</key><string>bar</string></map></llsd>\n";
182 xml_test("1 element map", expected);
183
184 mSD["baz"] = LLSD();
185 expected = "<llsd><map><key>baz</key><undef /><key>foo</key><string>bar</string></map></llsd>\n";
186 xml_test("2 element map", expected);
187 }
188
189
190 class TestLLSDSerializeData
191 {
192 public:
193 TestLLSDSerializeData();
194 ~TestLLSDSerializeData();
195
196 void doRoundTripTests(const std::string&);
197 void checkRoundTrip(const std::string&, const LLSD& v);
198
199 LLPointer<LLSDFormatter> mFormatter;
200 LLPointer<LLSDParser> mParser;
201 };
202
203 TestLLSDSerializeData::TestLLSDSerializeData()
204 {
205 }
206
207 TestLLSDSerializeData::~TestLLSDSerializeData()
208 {
209 }
210
211 void TestLLSDSerializeData::checkRoundTrip(const std::string& msg, const LLSD& v)
212 {
213 std::stringstream stream;
214 mFormatter->format(v, stream);
215 LLSD w;
216 mParser->parse(stream, w);
217
218 try
219 {
220 ensure_equals(msg, w, v);
221 }
222 catch (...)
223 {
224 std::cerr << "the serialized string was:" << std::endl;
225 std::cerr << stream.str() << std::endl;
226 throw;
227 }
228 }
229
230 void TestLLSDSerializeData::doRoundTripTests(const std::string& msg)
231 {
232 LLSD v;
233 checkRoundTrip(msg + " undefined", v);
234
235 v = true;
236 checkRoundTrip(msg + " true bool", v);
237
238 v = false;
239 checkRoundTrip(msg + " false bool", v);
240
241 v = 1;
242 checkRoundTrip(msg + " positive int", v);
243
244 v = 0;
245 checkRoundTrip(msg + " zero int", v);
246
247 v = -1;
248 checkRoundTrip(msg + " negative int", v);
249
250 v = 1234.5f;
251 checkRoundTrip(msg + " positive float", v);
252
253 v = 0.0f;
254 checkRoundTrip(msg + " zero float", v);
255
256 v = -1234.5f;
257 checkRoundTrip(msg + " negative float", v);
258
259 // FIXME: need a NaN test
260
261 v = LLUUID::null;
262 checkRoundTrip(msg + " null uuid", v);
263
264 LLUUID newUUID;
265 newUUID.generate();
266 v = newUUID;
267 checkRoundTrip(msg + " new uuid", v);
268
269 v = "";
270 checkRoundTrip(msg + " empty string", v);
271
272 v = "some string";
273 checkRoundTrip(msg + " non-empty string", v);
274
275 v =
276"Second Life is a 3-D virtual world entirely built and owned by its residents. "
277"Since opening to the public in 2003, it has grown explosively and today is "
278"inhabited by nearly 100,000 people from around the globe.\n"
279"\n"
280"From the moment you enter the World you’ll discover a vast digital continent, "
281"teeming with people, entertainment, experiences and opportunity. Once you’ve "
282"explored a bit, perhaps you’ll find a perfect parcel of land to build your "
283"house or business.\n"
284"\n"
285"You’ll also be surrounded by the Creations of your fellow residents. Because "
286"residents retain the rights to their digital creations, they can buy, sell "
287"and trade with other residents.\n"
288"\n"
289"The Marketplace currently supports millions of US dollars in monthly "
290"transactions. This commerce is handled with the in-world currency, the Linden "
291"dollar, which can be converted to US dollars at several thriving online "
292"currency exchanges.\n"
293"\n"
294"Welcome to Second Life. We look forward to seeing you in-world!\n"
295 ;
296 checkRoundTrip(msg + " long string", v);
297
298 static const U32 block_size = 0x000020;
299 for (U32 block = 0x000000; block <= 0x10ffff; block += block_size)
300 {
301 std::ostringstream out;
302
303 for (U32 c = block; c < block + block_size; ++c)
304 {
305 if (c <= 0x000001f
306 && c != 0x000009
307 && c != 0x00000a)
308 {
309 // see XML standard, sections 2.2 and 4.1
310 continue;
311 }
312 if (0x00d800 <= c && c <= 0x00dfff) { continue; }
313 if (0x00fdd0 <= c && c <= 0x00fdef) { continue; }
314 if ((c & 0x00fffe) == 0x00fffe) { continue; }
315 // see Unicode standard, section 15.8
316
317 if (c <= 0x00007f)
318 {
319 out << (char)(c & 0x7f);
320 }
321 else if (c <= 0x0007ff)
322 {
323 out << (char)(0xc0 | ((c >> 6) & 0x1f));
324 out << (char)(0x80 | ((c >> 0) & 0x3f));
325 }
326 else if (c <= 0x00ffff)
327 {
328 out << (char)(0xe0 | ((c >> 12) & 0x0f));
329 out << (char)(0x80 | ((c >> 6) & 0x3f));
330 out << (char)(0x80 | ((c >> 0) & 0x3f));
331 }
332 else
333 {
334 out << (char)(0xf0 | ((c >> 18) & 0x07));
335 out << (char)(0x80 | ((c >> 12) & 0x3f));
336 out << (char)(0x80 | ((c >> 6) & 0x3f));
337 out << (char)(0x80 | ((c >> 0) & 0x3f));
338 }
339 }
340
341 v = out.str();
342
343 std::ostringstream blockmsg;
344 blockmsg << msg << " unicode string block 0x" << std::hex << block;
345 checkRoundTrip(blockmsg.str(), v);
346 }
347
348 LLDate epoch;
349 v = epoch;
350 checkRoundTrip(msg + " epoch date", v);
351
352 LLDate aDay("2002-12-07T05:07:15.00Z");
353 v = aDay;
354 checkRoundTrip(msg + " date", v);
355
356 LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
357 v = path;
358 checkRoundTrip(msg + " url", v);
359
360 const char source[] = "it must be a blue moon again";
361 std::vector<U8> data;
362 copy(&source[0], &source[sizeof(source)], back_inserter(data));
363
364 v = data;
365 checkRoundTrip(msg + " binary", v);
366
367 v = LLSD::emptyMap();
368 checkRoundTrip(msg + " empty map", v);
369
370 v = LLSD::emptyMap();
371 v["name"] = "luke"; //v.insert("name", "luke");
372 v["age"] = 3; //v.insert("age", 3);
373 checkRoundTrip(msg + " map", v);
374
375 v.clear();
376 v["a"]["1"] = true;
377 v["b"]["0"] = false;
378 checkRoundTrip(msg + " nested maps", v);
379
380 v = LLSD::emptyArray();
381 checkRoundTrip(msg + " empty array", v);
382
383 v = LLSD::emptyArray();
384 v.append("ali");
385 v.append(28);
386 checkRoundTrip(msg + " array", v);
387
388 v.clear();
389 v[0][0] = true;
390 v[1][0] = false;
391 checkRoundTrip(msg + " nested arrays", v);
392 }
393
394 typedef tut::test_group<TestLLSDSerializeData> TestLLSDSerialzeGroup;
395 typedef TestLLSDSerialzeGroup::object TestLLSDSerializeObject;
396 TestLLSDSerialzeGroup gTestLLSDSerializeGroup("llsd serialization");
397
398 template<> template<>
399 void TestLLSDSerializeObject::test<1>()
400 {
401 mFormatter = new LLSDNotationFormatter();
402 mParser = new LLSDNotationParser();
403 doRoundTripTests("notation serialization");
404 }
405
406 template<> template<>
407 void TestLLSDSerializeObject::test<2>()
408 {
409 mFormatter = new LLSDXMLFormatter();
410 mParser = new LLSDXMLParser();
411 doRoundTripTests("xml serialization");
412 }
413
414 template<> template<>
415 void TestLLSDSerializeObject::test<3>()
416 {
417 mFormatter = new LLSDBinaryFormatter();
418 mParser = new LLSDBinaryParser();
419 doRoundTripTests("binary serialization");
420 }
421
422
423
424
425 class TestLLSDXMLParsing
426 {
427 public:
428 TestLLSDXMLParsing()
429 {
430 mParser = new LLSDXMLParser;
431 }
432 void ensureParse(const std::string& msg, const char* xml, const LLSD& expected);
433
434 LLPointer<LLSDXMLParser> mParser;
435 };
436
437 void TestLLSDXMLParsing::ensureParse(
438 const std::string& msg, const char* xmlstring, const LLSD& expected)
439 {
440 std::stringstream input;
441 input.str(xmlstring);
442
443 LLSD parsedResult;
444 mParser->parse(input, parsedResult);
445
446 ensure_equals(msg, parsedResult, expected);
447 }
448
449
450 typedef tut::test_group<TestLLSDXMLParsing> TestLLSDXMLParsingGroup;
451 typedef TestLLSDXMLParsingGroup::object TestLLSDXMLParsingObject;
452 TestLLSDXMLParsingGroup gTestLLSDXMLParsingGroup("llsd XML parsing");
453
454 template<> template<>
455 void TestLLSDXMLParsingObject::test<1>()
456 {
457 // test handling of xml not recognized as llsd results in an LLSD Undefined"
458
459 ensureParse("malformed xml", "<llsd><string>ha ha</string>", LLSD());
460 ensureParse("not llsd", "<html><body><p>ha ha</p></body></html>", LLSD());
461 ensureParse("value without llsd", "<string>ha ha</string>", LLSD());
462 ensureParse("key without llsd", "<key>ha ha</key>", LLSD());
463 }
464
465
466 template<> template<>
467 void TestLLSDXMLParsingObject::test<2>()
468 {
469 // test handling of unrecognized or unparseable llsd values
470
471 LLSD v;
472 v["amy"] = 23;
473 v["bob"] = LLSD();
474 v["cam"] = 1.23;
475
476 ensureParse("unknown data type",
477 "<llsd><map>"
478 "<key>amy</key><integer>23</integer>"
479 "<key>bob</key><bigint>99999999999999999</bigint>"
480 "<key>cam</key><real>1.23</real>"
481 "</map></llsd>", v);
482 }
483
484 template<> template<>
485 void TestLLSDXMLParsingObject::test<3>()
486 {
487 // test handling of nested bad data
488
489 LLSD v;
490 v["amy"] = 23;
491 v["cam"] = 1.23;
492
493 ensureParse("map with html",
494 "<llsd><map>"
495 "<key>amy</key><integer>23</integer>"
496 "<html><body>ha ha</body></html>"
497 "<key>cam</key><real>1.23</real>"
498 "</map></llsd>", v);
499
500 v.clear();
501 v["amy"] = 23;
502 v["cam"] = 1.23;
503 ensureParse("map with value for key",
504 "<llsd><map>"
505 "<key>amy</key><integer>23</integer>"
506 "<string>ha ha</string>"
507 "<key>cam</key><real>1.23</real>"
508 "</map></llsd>", v);
509
510 v.clear();
511 v["amy"] = 23;
512 v["bob"] = LLSD::emptyMap();
513 v["cam"] = 1.23;
514 ensureParse("map with map of html",
515 "<llsd><map>"
516 "<key>amy</key><integer>23</integer>"
517 "<key>bob</key>"
518 "<map>"
519 "<html><body>ha ha</body></html>"
520 "</map>"
521 "<key>cam</key><real>1.23</real>"
522 "</map></llsd>", v);
523
524 v.clear();
525 v[0] = 23;
526 v[1] = LLSD();
527 v[2] = 1.23;
528
529 ensureParse("array value of html",
530 "<llsd><array>"
531 "<integer>23</integer>"
532 "<html><body>ha ha</body></html>"
533 "<real>1.23</real>"
534 "</array></llsd>", v);
535
536 v.clear();
537 v[0] = 23;
538 v[1] = LLSD::emptyMap();
539 v[2] = 1.23;
540 ensureParse("array with map of html",
541 "<llsd><array>"
542 "<integer>23</integer>"
543 "<map>"
544 "<html><body>ha ha</body></html>"
545 "</map>"
546 "<real>1.23</real>"
547 "</array></llsd>", v);
548 }
549
550
551 /*
552 TODO:
553 test XML parsing
554 binary with unrecognized encoding
555 nested LLSD tags
556 multiple values inside an LLSD
557 */
558}