PageRenderTime 41ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/test/llsd_new_tut.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 854 lines | 613 code | 153 blank | 88 comment | 6 complexity | d9334b91dea1f331636c7e3544192877 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsd_new_tut.cpp
  3. * @date February 2006
  4. * @brief LLSD unit tests
  5. *
  6. * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2006-2011, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #define LLSD_DEBUG_INFO
  28. #include <tut/tut.hpp>
  29. #include "linden_common.h"
  30. #include "lltut.h"
  31. #include "llsdtraits.h"
  32. #include "llstring.h"
  33. #if LL_WINDOWS
  34. #include <float.h>
  35. namespace
  36. {
  37. int fpclassify(double x)
  38. {
  39. return _fpclass(x);
  40. }
  41. }
  42. #else
  43. using std::fpclassify;
  44. #endif
  45. namespace tut
  46. {
  47. class SDCleanupCheck
  48. {
  49. private:
  50. U32 mOutstandingAtStart;
  51. public:
  52. SDCleanupCheck() : mOutstandingAtStart(llsd::outstandingCount()) { }
  53. ~SDCleanupCheck()
  54. {
  55. ensure_equals("SDCleanupCheck",
  56. llsd::outstandingCount(), mOutstandingAtStart);
  57. }
  58. };
  59. class SDAllocationCheck : public SDCleanupCheck
  60. {
  61. private:
  62. std::string mMessage;
  63. U32 mExpectedAllocations;
  64. U32 mAllocationAtStart;
  65. public:
  66. SDAllocationCheck(const std::string& message, int expectedAllocations)
  67. : mMessage(message),
  68. mExpectedAllocations(expectedAllocations),
  69. mAllocationAtStart(llsd::allocationCount())
  70. { }
  71. ~SDAllocationCheck()
  72. {
  73. ensure_equals(mMessage + " SDAllocationCheck",
  74. llsd::allocationCount() - mAllocationAtStart,
  75. mExpectedAllocations);
  76. }
  77. };
  78. struct SDTestData {
  79. template<class T>
  80. static void ensureTypeAndValue(const char* msg, const LLSD& actual,
  81. T expectedValue)
  82. {
  83. LLSDTraits<T> traits;
  84. std::string s(msg);
  85. ensure( s + " type", traits.checkType(actual));
  86. ensure_equals( s + " value", traits.get(actual), expectedValue);
  87. }
  88. };
  89. typedef test_group<SDTestData> SDTestGroup;
  90. typedef SDTestGroup::object SDTestObject;
  91. SDTestGroup sdTestGroup("LLSD(new)");
  92. template<> template<>
  93. void SDTestObject::test<1>()
  94. // construction and test of undefined
  95. {
  96. SDCleanupCheck check;
  97. LLSD u;
  98. ensure("is undefined", u.isUndefined());
  99. }
  100. template<> template<>
  101. void SDTestObject::test<2>()
  102. // setting and fetching scalar types
  103. {
  104. SDCleanupCheck check;
  105. LLSD v;
  106. v = true; ensureTypeAndValue("set true", v, true);
  107. v = false; ensureTypeAndValue("set false", v, false);
  108. v = true; ensureTypeAndValue("set true again", v, true);
  109. v = 42; ensureTypeAndValue("set to 42", v, 42);
  110. v = 0; ensureTypeAndValue("set to zero", v, 0);
  111. v = -12345; ensureTypeAndValue("set to neg", v, -12345);
  112. v = 2000000000; ensureTypeAndValue("set to big", v, 2000000000);
  113. v = 3.14159265359;
  114. ensureTypeAndValue("set to pi", v, 3.14159265359);
  115. ensure_not_equals("isn't float", v.asReal(),
  116. (float)3.14159265359);
  117. v = 6.7e256; ensureTypeAndValue("set to big", v, 6.7e256);
  118. LLUUID nullUUID;
  119. LLUUID newUUID;
  120. newUUID.generate();
  121. v = nullUUID; ensureTypeAndValue("set to null UUID", v, nullUUID);
  122. v = newUUID; ensureTypeAndValue("set to new UUID", v, newUUID);
  123. v = nullUUID; ensureTypeAndValue("set to null again", v, nullUUID);
  124. // strings must be tested with two types of string objects
  125. std::string s = "now is the time";
  126. const char* cs = "for all good zorks";
  127. v = s; ensureTypeAndValue("set to std::string", v, s);
  128. v = cs; ensureTypeAndValue("set to const char*", v, cs);
  129. LLDate epoch;
  130. LLDate aDay("2001-10-22T10:11:12.00Z");
  131. v = epoch; ensureTypeAndValue("set to epoch", v, epoch);
  132. v = aDay; ensureTypeAndValue("set to a day", v, aDay);
  133. LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
  134. v = path; ensureTypeAndValue("set to a uri", v, path);
  135. const char source[] = "once in a blue moon";
  136. std::vector<U8> data;
  137. copy(&source[0], &source[sizeof(source)], back_inserter(data));
  138. v = data; ensureTypeAndValue("set to data", v, data);
  139. v.clear();
  140. ensure("reset to undefined", v.type() == LLSD::TypeUndefined);
  141. }
  142. template<> template<>
  143. void SDTestObject::test<3>()
  144. // construction via scalar values
  145. // tests both constructor and initialize forms
  146. {
  147. SDCleanupCheck check;
  148. LLSD b1(true); ensureTypeAndValue("construct boolean", b1, true);
  149. LLSD b2 = true; ensureTypeAndValue("initialize boolean", b2, true);
  150. LLSD i1(42); ensureTypeAndValue("construct int", i1, 42);
  151. LLSD i2 =42; ensureTypeAndValue("initialize int", i2, 42);
  152. LLSD d1(1.2); ensureTypeAndValue("construct double", d1, 1.2);
  153. LLSD d2 = 1.2; ensureTypeAndValue("initialize double", d2, 1.2);
  154. LLUUID newUUID;
  155. newUUID.generate();
  156. LLSD u1(newUUID);
  157. ensureTypeAndValue("construct UUID", u1, newUUID);
  158. LLSD u2 = newUUID;
  159. ensureTypeAndValue("initialize UUID", u2, newUUID);
  160. LLSD ss1(std::string("abc"));
  161. ensureTypeAndValue("construct std::string", ss1, "abc");
  162. LLSD ss2 = std::string("abc");
  163. ensureTypeAndValue("initialize std::string",ss2, "abc");
  164. LLSD sl1(std::string("def"));
  165. ensureTypeAndValue("construct std::string", sl1, "def");
  166. LLSD sl2 = std::string("def");
  167. ensureTypeAndValue("initialize std::string", sl2, "def");
  168. LLSD sc1("ghi");
  169. ensureTypeAndValue("construct const char*", sc1, "ghi");
  170. LLSD sc2 = "ghi";
  171. ensureTypeAndValue("initialize const char*",sc2, "ghi");
  172. LLDate aDay("2001-10-22T10:11:12.00Z");
  173. LLSD t1(aDay); ensureTypeAndValue("construct LLDate", t1, aDay);
  174. LLSD t2 = aDay; ensureTypeAndValue("initialize LLDate", t2, aDay);
  175. LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
  176. LLSD p1(path); ensureTypeAndValue("construct LLURI", p1, path);
  177. LLSD p2 = path; ensureTypeAndValue("initialize LLURI", p2, path);
  178. const char source[] = "once in a blue moon";
  179. std::vector<U8> data;
  180. copy(&source[0], &source[sizeof(source)], back_inserter(data));
  181. LLSD x1(data); ensureTypeAndValue("construct vector<U8>", x1, data);
  182. LLSD x2 = data; ensureTypeAndValue("initialize vector<U8>", x2, data);
  183. }
  184. void checkConversions(const char* msg, const LLSD& v,
  185. LLSD::Boolean eBoolean, LLSD::Integer eInteger,
  186. LLSD::Real eReal, const LLSD::String& eString)
  187. {
  188. std::string s(msg);
  189. ensure_equals(s+" to bool", v.asBoolean(), eBoolean);
  190. ensure_equals(s+" to int", v.asInteger(), eInteger);
  191. if (eReal == eReal)
  192. {
  193. ensure_equals(s+" to real", v.asReal(), eReal);
  194. ensure_equals(s+" to string", v.asString(), eString);
  195. }
  196. else
  197. {
  198. int left = fpclassify(v.asReal());
  199. int right = fpclassify(eReal);
  200. ensure_equals(s+" to real", left, right);
  201. // ensure_equals(s+" to string", v.asString(), eString);
  202. // I've commented this check out, since there doesn't
  203. // seem to be uniform string representation for NaN on
  204. // all platforms. For example, on my Ubuntu 8.10 laptop
  205. // with libc 2.11.1, sqrt(-1.0) will return '-nan', not
  206. // 'nan'.
  207. }
  208. }
  209. template<> template<>
  210. void SDTestObject::test<4>()
  211. // conversion between undefined and basic scalar types:
  212. // boolean, integer, real and string
  213. {
  214. SDCleanupCheck check;
  215. LLSD v; checkConversions("untitled", v, false, 0, 0.0, "");
  216. v = false; checkConversions("false", v, false, 0, 0.0, "");
  217. v = true; checkConversions("true", v, true, 1, 1.0, "true");
  218. v = 0; checkConversions("zero", v, false, 0, 0.0, "0");
  219. v = 1; checkConversions("one", v, true, 1, 1.0, "1");
  220. v = -33; checkConversions("neg33", v, true, -33, -33.0, "-33");
  221. v = 0.0; checkConversions("0.0", v, false, 0, 0.0, "0");
  222. v = 0.5; checkConversions("point5", v, true, 0, 0.5, "0.5");
  223. v = 0.9; checkConversions("point9", v, true, 0, 0.9, "0.9");
  224. v = -3.9; checkConversions("neg3dot9", v, true, -3, -3.9, "-3.9");
  225. v = sqrt(-1.0); checkConversions("NaN", v, false, 0, sqrt(-1.0), "nan");
  226. v = ""; checkConversions("empty", v, false, 0, 0.0, "");
  227. v = "0"; checkConversions("digit0", v, true, 0, 0.0, "0");
  228. v = "10"; checkConversions("digit10", v, true, 10, 10.0, "10");
  229. v = "-2.345"; checkConversions("decdigits", v,
  230. true, -2, -2.345, "-2.345");
  231. v = "apple"; checkConversions("apple", v, true, 0, 0.0, "apple");
  232. v = "33bob"; checkConversions("digialpha", v, true, 0, 0.0, "33bob");
  233. v = " "; checkConversions("space", v, true, 0, 0.0, " ");
  234. v = "\n"; checkConversions("newline", v, true, 0, 0.0, "\n");
  235. }
  236. template<class T>
  237. void checkRoundTrip(const std::string& msg, const LLSD& actual,
  238. const char* sExpected, T vExpected)
  239. {
  240. std::string str = actual.asString();
  241. if (sExpected) {
  242. ensure_equals(msg + " string", str, sExpected);
  243. }
  244. LLSD u(str);
  245. LLSDTraits<T> traits;
  246. ensure_equals(msg + " value", traits.get(u), vExpected);
  247. }
  248. template<> template<>
  249. void SDTestObject::test<5>()
  250. // conversion of String to and from UUID, Date and URI.
  251. {
  252. SDCleanupCheck check;
  253. LLSD v;
  254. LLUUID nullUUID;
  255. LLUUID someUUID;
  256. someUUID.generate();
  257. v = nullUUID; checkRoundTrip("null uuid", v,
  258. "00000000-0000-0000-0000-000000000000", nullUUID);
  259. v = someUUID; checkRoundTrip("random uuid", v, 0, someUUID);
  260. LLDate epoch;
  261. LLDate beta("2003-04-30T04:00:00Z");
  262. LLDate oneOh("2003-06-23T04:00:00Z");
  263. v = epoch; checkRoundTrip("epoch date", v, 0, epoch);
  264. v = beta; checkRoundTrip("beta date", v,
  265. "2003-04-30T04:00:00Z", beta);
  266. v = oneOh; checkRoundTrip("1.0 date", v,
  267. "2003-06-23T04:00:00Z", oneOh);
  268. LLURI empty;
  269. LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
  270. LLURI mail("mailto:zero.linden@secondlife.com");
  271. v = empty; checkRoundTrip("empty URI", v, 0, empty);
  272. v = path; checkRoundTrip("path URI", v,
  273. "http://slurl.com/secondlife/Ambleside/57/104/26/",
  274. path);
  275. v = mail; checkRoundTrip("mail URI", v,
  276. "mailto:zero.linden@secondlife.com", mail);
  277. }
  278. template<> template<>
  279. void SDTestObject::test<6>()
  280. // copy construction and assignment
  281. // checking for shared values after constr. or assignment
  282. // checking in both the same type and change of type case
  283. {
  284. SDCleanupCheck check;
  285. {
  286. LLSD v = 42;
  287. LLSD w0(v);
  288. ensureTypeAndValue("int constr.", w0, 42);
  289. LLSD w1(v);
  290. w1 = 13;
  291. ensureTypeAndValue("int constr. change case 1", w1, 13);
  292. ensureTypeAndValue("int constr. change case 2", v, 42);
  293. LLSD w2(v);
  294. v = 7;
  295. ensureTypeAndValue("int constr. change case 3", w2, 42);
  296. ensureTypeAndValue("int constr. change case 4", v, 7);
  297. }
  298. {
  299. LLSD v = 42;
  300. LLSD w1(v);
  301. w1 = "bob";
  302. ensureTypeAndValue("string constr. change case 1", w1, "bob");
  303. ensureTypeAndValue("string constr. change case 2", v, 42);
  304. LLSD w2(v);
  305. v = "amy";
  306. ensureTypeAndValue("string constr. change case 3", w2, 42);
  307. ensureTypeAndValue("string constr. change case 4", v, "amy");
  308. }
  309. {
  310. LLSD v = 42;
  311. LLSD w0;
  312. w0 = v;
  313. ensureTypeAndValue("int assign", w0, 42);
  314. LLSD w1;
  315. w1 = v;
  316. w1 = 13;
  317. ensureTypeAndValue("int assign change case 1", w1, 13);
  318. ensureTypeAndValue("int assign change case 2", v, 42);
  319. LLSD w2;
  320. w2 = v;
  321. v = 7;
  322. ensureTypeAndValue("int assign change case 3", w2, 42);
  323. ensureTypeAndValue("int assign change case 4", v, 7);
  324. }
  325. {
  326. LLSD v = 42;
  327. LLSD w1;
  328. w1 = v;
  329. w1 = "bob";
  330. ensureTypeAndValue("string assign change case 1", w1, "bob");
  331. ensureTypeAndValue("string assign change case 2", v, 42);
  332. LLSD w2;
  333. w2 = v;
  334. v = "amy";
  335. ensureTypeAndValue("string assign change case 3", w2, 42);
  336. ensureTypeAndValue("string assign change case 4", v, "amy");
  337. }
  338. }
  339. template<> template<>
  340. void SDTestObject::test<7>()
  341. // Test assignment and casting to various scalar types. These
  342. // assignments should invoke the right conversion without it being
  343. // mentioned explicitly. The few exceptions are marked SAD.
  344. {
  345. SDCleanupCheck check;
  346. LLSD v(" 42.375");
  347. bool b = false;
  348. b = v; ensure_equals("assign to bool", b, true);
  349. b = (bool)v; ensure_equals("cast to bool", b, true);
  350. int i = 99;
  351. i = v; ensure_equals("assign to int", i, 42);
  352. i = (int)v; ensure_equals("cast to int", i, 42);
  353. double d = 3.14159;
  354. d = v; ensure_equals("assign to double", d, 42.375);
  355. d = (double)v; ensure_equals("cast to double", d, 42.375);
  356. std::string s = "yo";
  357. // SAD s = v; ensure_equals("assign to string", s, " 42.375");
  358. s = (std::string)v; ensure_equals("cast to string", s, " 42.375");
  359. std::string uuidStr = "b1e50c2b-b627-4d23-8a86-a65d97b6319b";
  360. v = uuidStr;
  361. LLUUID u;
  362. u = v;
  363. ensure_equals("assign to LLUUID", u, LLUUID(uuidStr));
  364. // SAD u = (LLUUID)v;
  365. // ensure_equals("cast to LLUUID", u, LLUUID(uuidStr));
  366. std::string dateStr = "2005-10-24T15:00:00Z";
  367. v = dateStr;
  368. LLDate date;
  369. date = v;
  370. ensure_equals("assign to LLDate", date.asString(), dateStr);
  371. // SAD date = (LLDate)v;
  372. // ensure_equals("cast to LLDate", date.asString(), dateStr);
  373. std::string uriStr = "http://secondlife.com";
  374. v = uriStr;
  375. LLURI uri;
  376. uri = v;
  377. ensure_equals("assign to LLURI", uri.asString(), uriStr);
  378. // SAD uri = (LLURI)v;
  379. // ensure_equals("cast to LLURI", uri.asString(), uriStr);
  380. }
  381. template<> template<>
  382. void SDTestObject::test<8>()
  383. // Test construction of various scalar types from LLSD.
  384. // Test both construction and initialization forms.
  385. // These should invoke the right conversion without it being
  386. // mentioned explicitly. The few exceptions are marked SAD.
  387. {
  388. SDCleanupCheck check;
  389. LLSD v(" 42.375");
  390. bool b1(v); ensure_equals("contruct bool", b1, true);
  391. bool b2 = v; ensure_equals("initialize bool", b2, true);
  392. int i1(v); ensure_equals("contruct int", i1, 42);
  393. int i2 = v; ensure_equals("initialize int", i2, 42);
  394. double d1(v); ensure_equals("contruct double", d1, 42.375);
  395. double d2 = v; ensure_equals("initialize double", d2, 42.375);
  396. std::string s1(v);
  397. std::string s2 = v;
  398. ensure_equals("contruct string", s1, " 42.375");
  399. ensure_equals("initialize string", s2, " 42.375");
  400. std::string t1(v);
  401. std::string t2 = v.asString(); // SAD
  402. ensure_equals("contruct std::string", t1, " 42.375");
  403. ensure_equals("initialize std::string", t2, " 42.375");
  404. std::string uuidStr = "b1e50c2b-b627-4d23-8a86-a65d97b6319b";
  405. v = uuidStr;
  406. LLUUID uuid1(v.asUUID()); // SAD
  407. LLUUID uuid2 = v;
  408. ensure_equals("contruct LLUUID", uuid1, LLUUID(uuidStr));
  409. ensure_equals("initialize LLUUID", uuid2, LLUUID(uuidStr));
  410. std::string dateStr = "2005-10-24T15:00:00Z";
  411. v = dateStr;
  412. LLDate date1(v.asDate()); // SAD
  413. LLDate date2 = v;
  414. ensure_equals("contruct LLDate", date1.asString(), dateStr);
  415. ensure_equals("initialize LLDate", date2.asString(), dateStr);
  416. std::string uriStr = "http://secondlife.com";
  417. v = uriStr;
  418. LLURI uri1(v.asURI()); // SAD
  419. LLURI uri2 = v;
  420. ensure_equals("contruct LLURI", uri1.asString(), uriStr);
  421. ensure_equals("initialize LLURI", uri2.asString(), uriStr);
  422. }
  423. template<> template<>
  424. void SDTestObject::test<9>()
  425. // test to make sure v is interpreted as a bool in a various
  426. // scenarios.
  427. {
  428. SDCleanupCheck check;
  429. LLSD v = "0";
  430. // magic value that is interpreted as boolean true, but integer false!
  431. ensure_equals("trinary operator bool", (v ? true : false), true);
  432. ensure_equals("convert to int, then bool",
  433. ((int)v ? true : false), false);
  434. if(v)
  435. {
  436. ensure("if converted to bool", true);
  437. }
  438. else
  439. {
  440. fail("bool did not convert to a bool in if statement.");
  441. }
  442. if(!v)
  443. {
  444. fail("bool did not convert to a bool in negated if statement.");
  445. }
  446. }
  447. template<> template<>
  448. void SDTestObject::test<10>()
  449. // map operations
  450. {
  451. SDCleanupCheck check;
  452. LLSD v;
  453. ensure("undefined has no members", !v.has("amy"));
  454. ensure("undefined get() is undefined", v.get("bob").isUndefined());
  455. v = LLSD::emptyMap();
  456. ensure("empty map is a map", v.isMap());
  457. ensure("empty map has no members", !v.has("cam"));
  458. ensure("empty map get() is undefined", v.get("don").isUndefined());
  459. v.clear();
  460. v.insert("eli", 43);
  461. ensure("insert converts to map", v.isMap());
  462. ensure("inserted key is present", v.has("eli"));
  463. ensureTypeAndValue("inserted value", v.get("eli"), 43);
  464. v.insert("fra", false);
  465. ensure("first key still present", v.has("eli"));
  466. ensure("second key is present", v.has("fra"));
  467. ensureTypeAndValue("first value", v.get("eli"), 43);
  468. ensureTypeAndValue("second value", v.get("fra"), false);
  469. v.erase("eli");
  470. ensure("first key now gone", !v.has("eli"));
  471. ensure("second key still present", v.has("fra"));
  472. ensure("first value gone", v.get("eli").isUndefined());
  473. ensureTypeAndValue("second value sill there", v.get("fra"), false);
  474. v.erase("fra");
  475. ensure("second key now gone", !v.has("fra"));
  476. ensure("second value gone", v.get("fra").isUndefined());
  477. v["gil"] = (std::string)"good morning";
  478. ensure("third key present", v.has("gil"));
  479. ensureTypeAndValue("third key value", v.get("gil"), "good morning");
  480. const LLSD& cv = v; // FIX ME IF POSSIBLE
  481. ensure("missing key", cv["ham"].isUndefined());
  482. ensure("key not present", !v.has("ham"));
  483. LLSD w = 43;
  484. const LLSD& cw = w; // FIX ME IF POSSIBLE
  485. int i = cw["ian"];
  486. ensureTypeAndValue("other missing value", i, 0);
  487. ensure("other missing key", !w.has("ian"));
  488. ensure("no conversion", w.isInteger());
  489. LLSD x;
  490. x = v;
  491. ensure("copy map type", x.isMap());
  492. ensureTypeAndValue("copy map value gil", x.get("gil"), "good morning");
  493. }
  494. template<> template<>
  495. void SDTestObject::test<11>()
  496. // array operations
  497. {
  498. SDCleanupCheck check;
  499. LLSD v;
  500. ensure_equals("undefined has no size", v.size(), 0);
  501. ensure("undefined get() is undefined", v.get(0).isUndefined());
  502. v = LLSD::emptyArray();
  503. ensure("empty array is an array", v.isArray());
  504. ensure_equals("empty array has no size", v.size(), 0);
  505. ensure("empty map get() is undefined", v.get(0).isUndefined());
  506. v.clear();
  507. v.append(88);
  508. v.append("noodle");
  509. v.append(true);
  510. ensure_equals("appened array size", v.size(), 3);
  511. ensure("append array is an array", v.isArray());
  512. ensureTypeAndValue("append 0", v[0], 88);
  513. ensureTypeAndValue("append 1", v[1], "noodle");
  514. ensureTypeAndValue("append 2", v[2], true);
  515. v.insert(0, 77);
  516. v.insert(2, "soba");
  517. v.insert(4, false);
  518. ensure_equals("inserted array size", v.size(), 6);
  519. ensureTypeAndValue("post insert 0", v[0], 77);
  520. ensureTypeAndValue("post insert 1", v[1], 88);
  521. ensureTypeAndValue("post insert 2", v[2], "soba");
  522. ensureTypeAndValue("post insert 3", v[3], "noodle");
  523. ensureTypeAndValue("post insert 4", v[4], false);
  524. ensureTypeAndValue("post insert 5", v[5], true);
  525. ensureTypeAndValue("get 1", v.get(1), 88);
  526. v.set(1, "hot");
  527. ensureTypeAndValue("set 1", v.get(1), "hot");
  528. v.erase(3);
  529. ensure_equals("post erase array size", v.size(), 5);
  530. ensureTypeAndValue("post erase 0", v[0], 77);
  531. ensureTypeAndValue("post erase 1", v[1], "hot");
  532. ensureTypeAndValue("post erase 2", v[2], "soba");
  533. ensureTypeAndValue("post erase 3", v[3], false);
  534. ensureTypeAndValue("post erase 4", v[4], true);
  535. v.append(34);
  536. ensure_equals("size after append", v.size(), 6);
  537. ensureTypeAndValue("post append 5", v[5], 34);
  538. LLSD w;
  539. w = v;
  540. ensure("copy array type", w.isArray());
  541. ensure_equals("copy array size", w.size(), 6);
  542. ensureTypeAndValue("copy array 0", w[0], 77);
  543. ensureTypeAndValue("copy array 1", w[1], "hot");
  544. ensureTypeAndValue("copy array 2", w[2], "soba");
  545. ensureTypeAndValue("copy array 3", w[3], false);
  546. ensureTypeAndValue("copy array 4", w[4], true);
  547. ensureTypeAndValue("copy array 5", w[5], 34);
  548. }
  549. template<> template<>
  550. void SDTestObject::test<12>()
  551. // no sharing
  552. {
  553. SDCleanupCheck check;
  554. LLSD a = 99;
  555. LLSD b = a;
  556. a = 34;
  557. ensureTypeAndValue("top level original changed", a, 34);
  558. ensureTypeAndValue("top level copy unaltered", b, 99);
  559. b = a;
  560. b = 66;
  561. ensureTypeAndValue("top level original unaltered", a, 34);
  562. ensureTypeAndValue("top level copy changed", b, 66);
  563. a[0] = "uno";
  564. a[1] = 99;
  565. a[2] = 1.414;
  566. b = a;
  567. a[1] = 34;
  568. ensureTypeAndValue("array member original changed", a[1], 34);
  569. ensureTypeAndValue("array member copy unaltered", b[1], 99);
  570. b = a;
  571. b[1] = 66;
  572. ensureTypeAndValue("array member original unaltered", a[1], 34);
  573. ensureTypeAndValue("array member copy changed", b[1], 66);
  574. a["alpha"] = "uno";
  575. a["beta"] = 99;
  576. a["gamma"] = 1.414;
  577. b = a;
  578. a["beta"] = 34;
  579. ensureTypeAndValue("map member original changed", a["beta"], 34);
  580. ensureTypeAndValue("map member copy unaltered", b["beta"], 99);
  581. b = a;
  582. b["beta"] = 66;
  583. ensureTypeAndValue("map member original unaltered", a["beta"], 34);
  584. ensureTypeAndValue("map member copy changed", b["beta"], 66);
  585. }
  586. template<> template<>
  587. void SDTestObject::test<13>()
  588. // sharing implementation
  589. {
  590. SDCleanupCheck check;
  591. {
  592. SDAllocationCheck check("copy construct undefinded", 0);
  593. LLSD v;
  594. LLSD w = v;
  595. }
  596. {
  597. SDAllocationCheck check("assign undefined", 0);
  598. LLSD v;
  599. LLSD w;
  600. w = v;
  601. }
  602. {
  603. SDAllocationCheck check("assign integer value", 1);
  604. LLSD v = 45;
  605. v = 33;
  606. v = 0;
  607. }
  608. {
  609. SDAllocationCheck check("copy construct integer", 1);
  610. LLSD v = 45;
  611. LLSD w = v;
  612. }
  613. {
  614. SDAllocationCheck check("assign integer", 1);
  615. LLSD v = 45;
  616. LLSD w;
  617. w = v;
  618. }
  619. {
  620. SDAllocationCheck check("avoids extra clone", 2);
  621. LLSD v = 45;
  622. LLSD w = v;
  623. w = "nice day";
  624. }
  625. {
  626. SDAllocationCheck check("shared values test for threaded work", 9);
  627. //U32 start_llsd_count = llsd::outstandingCount();
  628. LLSD m = LLSD::emptyMap();
  629. m["one"] = 1;
  630. m["two"] = 2;
  631. m["one_copy"] = m["one"]; // 3 (m, "one" and "two")
  632. m["undef_one"] = LLSD();
  633. m["undef_two"] = LLSD();
  634. m["undef_one_copy"] = m["undef_one"];
  635. { // Ensure first_array gets freed to avoid counting it
  636. LLSD first_array = LLSD::emptyArray();
  637. first_array.append(1.0f);
  638. first_array.append(2.0f);
  639. first_array.append(3.0f); // 7
  640. m["array"] = first_array;
  641. m["array_clone"] = first_array;
  642. m["array_copy"] = m["array"]; // 7
  643. }
  644. m["string_one"] = "string one value";
  645. m["string_two"] = "string two value";
  646. m["string_one_copy"] = m["string_one"]; // 9
  647. //U32 llsd_object_count = llsd::outstandingCount();
  648. //std::cout << "Using " << (llsd_object_count - start_llsd_count) << " LLSD objects" << std::endl;
  649. //m.dumpStats();
  650. }
  651. {
  652. SDAllocationCheck check("shared values test for threaded work", 9);
  653. //U32 start_llsd_count = LLSD::outstandingCount();
  654. LLSD m = LLSD::emptyMap();
  655. m["one"] = 1;
  656. m["two"] = 2;
  657. m["one_copy"] = m["one"]; // 3 (m, "one" and "two")
  658. m["undef_one"] = LLSD();
  659. m["undef_two"] = LLSD();
  660. m["undef_one_copy"] = m["undef_one"];
  661. { // Ensure first_array gets freed to avoid counting it
  662. LLSD first_array = LLSD::emptyArray();
  663. first_array.append(1.0f);
  664. first_array.append(2.0f);
  665. first_array.append(3.0f); // 7
  666. m["array"] = first_array;
  667. m["array_clone"] = first_array;
  668. m["array_copy"] = m["array"]; // 7
  669. }
  670. m["string_one"] = "string one value";
  671. m["string_two"] = "string two value";
  672. m["string_one_copy"] = m["string_one"]; // 9
  673. //U32 llsd_object_count = LLSD::outstandingCount();
  674. //std::cout << "Using " << (llsd_object_count - start_llsd_count) << " LLSD objects" << std::endl;
  675. //m.dumpStats();
  676. }
  677. }
  678. template<> template<>
  679. void SDTestObject::test<14>()
  680. // make sure that assignment of char* NULL in a string does not crash.
  681. {
  682. LLSD v;
  683. v = (const char*)NULL;
  684. ensure("type is a string", v.isString());
  685. }
  686. /* TO DO:
  687. conversion of undefined to UUID, Date, URI and Binary
  688. conversion of undefined to map and array
  689. test map operations
  690. test array operations
  691. test array extension
  692. test copying and assign maps and arrays (clone)
  693. test iteration over map
  694. test iteration over array
  695. test iteration over scalar
  696. test empty map and empty array are indeed shared
  697. test serializations
  698. */
  699. }