and generally updated cpp's to V-D look(include order, spelling fixes, and whatnot) Also, commented out pointless using namespace std.
788 lines
22 KiB
C++
788 lines
22 KiB
C++
/**
|
|
* @file llsd_new_tut.cpp
|
|
* @date February 2006
|
|
* @brief LLSD unit tests
|
|
*
|
|
* $LicenseInfo:firstyear=2006&license=viewergpl$
|
|
*
|
|
* Copyright (c) 2006-2009, Linden Research, Inc.
|
|
*
|
|
* Second Life Viewer Source Code
|
|
* The source code in this file ("Source Code") is provided by Linden Lab
|
|
* to you under the terms of the GNU General Public License, version 2.0
|
|
* ("GPL"), unless you have obtained a separate licensing agreement
|
|
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
|
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
|
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
|
*
|
|
* There are special exceptions to the terms and conditions of the GPL as
|
|
* it is applied to this Source Code. View the full text of the exception
|
|
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
|
* online at
|
|
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
*
|
|
* By copying, modifying or distributing this software, you acknowledge
|
|
* that you have read and understood your obligations described above,
|
|
* and agree to abide by those obligations.
|
|
*
|
|
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
|
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
|
* COMPLETENESS OR PERFORMANCE.
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include <tut/tut.hpp>
|
|
#include "linden_common.h"
|
|
#include "lltut.h"
|
|
|
|
#include "llsdtraits.h"
|
|
#include "llstring.h"
|
|
|
|
#if LL_WINDOWS
|
|
#include <float.h>
|
|
namespace
|
|
{
|
|
int fpclassify(double x)
|
|
{
|
|
return _fpclass(x);
|
|
}
|
|
}
|
|
#else
|
|
using std::fpclassify;
|
|
#endif
|
|
|
|
namespace tut
|
|
{
|
|
class SDCleanupCheck
|
|
{
|
|
private:
|
|
U32 mOutstandingAtStart;
|
|
public:
|
|
SDCleanupCheck() : mOutstandingAtStart(LLSD::outstandingCount()) { }
|
|
~SDCleanupCheck()
|
|
{
|
|
ensure_equals("SDCleanupCheck",
|
|
LLSD::outstandingCount(), mOutstandingAtStart);
|
|
}
|
|
};
|
|
|
|
class SDAllocationCheck : public SDCleanupCheck
|
|
{
|
|
private:
|
|
std::string mMessage;
|
|
U32 mExpectedAllocations;
|
|
U32 mAllocationAtStart;
|
|
public:
|
|
SDAllocationCheck(const std::string& message, int expectedAllocations)
|
|
: mMessage(message),
|
|
mExpectedAllocations(expectedAllocations),
|
|
mAllocationAtStart(LLSD::allocationCount())
|
|
{ }
|
|
~SDAllocationCheck()
|
|
{
|
|
ensure_equals(mMessage + " SDAllocationCheck",
|
|
LLSD::allocationCount() - mAllocationAtStart,
|
|
mExpectedAllocations);
|
|
}
|
|
};
|
|
|
|
struct SDTestData {
|
|
template<class T>
|
|
static void ensureTypeAndValue(const char* msg, const LLSD& actual,
|
|
T expectedValue)
|
|
{
|
|
LLSDTraits<T> traits;
|
|
|
|
std::string s(msg);
|
|
|
|
ensure( s + " type", traits.checkType(actual));
|
|
ensure_equals( s + " value", traits.get(actual), expectedValue);
|
|
}
|
|
};
|
|
|
|
typedef test_group<SDTestData> SDTestGroup;
|
|
typedef SDTestGroup::object SDTestObject;
|
|
|
|
SDTestGroup sdTestGroup("LLSD(new)");
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<1>()
|
|
// construction and test of undefined
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD u;
|
|
ensure("is undefined", u.isUndefined());
|
|
}
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<2>()
|
|
// setting and fetching scalar types
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD v;
|
|
|
|
v = true; ensureTypeAndValue("set true", v, true);
|
|
v = false; ensureTypeAndValue("set false", v, false);
|
|
v = true; ensureTypeAndValue("set true again", v, true);
|
|
|
|
v = 42; ensureTypeAndValue("set to 42", v, 42);
|
|
v = 0; ensureTypeAndValue("set to zero", v, 0);
|
|
v = -12345; ensureTypeAndValue("set to neg", v, -12345);
|
|
v = 2000000000; ensureTypeAndValue("set to big", v, 2000000000);
|
|
|
|
v = 3.14159265359;
|
|
ensureTypeAndValue("set to pi", v, 3.14159265359);
|
|
ensure_not_equals("isn't float", v.asReal(),
|
|
(float)3.14159265359);
|
|
v = 6.7e256; ensureTypeAndValue("set to big", v, 6.7e256);
|
|
|
|
LLUUID nullUUID;
|
|
LLUUID newUUID;
|
|
newUUID.generate();
|
|
|
|
v = nullUUID; ensureTypeAndValue("set to null UUID", v, nullUUID);
|
|
v = newUUID; ensureTypeAndValue("set to new UUID", v, newUUID);
|
|
v = nullUUID; ensureTypeAndValue("set to null again", v, nullUUID);
|
|
|
|
// strings must be tested with two types of string objects
|
|
std::string s = "now is the time";
|
|
const char* cs = "for all good zorks";
|
|
|
|
v = s; ensureTypeAndValue("set to std::string", v, s);
|
|
v = cs; ensureTypeAndValue("set to const char*", v, cs);
|
|
|
|
LLDate epoch;
|
|
LLDate aDay("2001-10-22T10:11:12.00Z");
|
|
|
|
v = epoch; ensureTypeAndValue("set to epoch", v, epoch);
|
|
v = aDay; ensureTypeAndValue("set to a day", v, aDay);
|
|
|
|
LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
|
|
|
|
v = path; ensureTypeAndValue("set to a uri", v, path);
|
|
|
|
const char source[] = "once in a blue moon";
|
|
std::vector<U8> data;
|
|
copy(&source[0], &source[sizeof(source)], back_inserter(data));
|
|
|
|
v = data; ensureTypeAndValue("set to data", v, data);
|
|
|
|
v.clear();
|
|
ensure("reset to undefined", v.type() == LLSD::TypeUndefined);
|
|
}
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<3>()
|
|
// construction via scalar values
|
|
// tests both constructor and initialize forms
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD b1(true); ensureTypeAndValue("construct boolean", b1, true);
|
|
LLSD b2 = true; ensureTypeAndValue("initialize boolean", b2, true);
|
|
LLSD i1(42); ensureTypeAndValue("construct int", i1, 42);
|
|
LLSD i2 =42; ensureTypeAndValue("initialize int", i2, 42);
|
|
LLSD d1(1.2); ensureTypeAndValue("construct double", d1, 1.2);
|
|
LLSD d2 = 1.2; ensureTypeAndValue("initialize double", d2, 1.2);
|
|
|
|
LLUUID newUUID;
|
|
newUUID.generate();
|
|
LLSD u1(newUUID);
|
|
ensureTypeAndValue("construct UUID", u1, newUUID);
|
|
LLSD u2 = newUUID;
|
|
ensureTypeAndValue("initialize UUID", u2, newUUID);
|
|
|
|
LLSD ss1(std::string("abc"));
|
|
ensureTypeAndValue("construct std::string", ss1, "abc");
|
|
LLSD ss2 = std::string("abc");
|
|
ensureTypeAndValue("initialize std::string",ss2, "abc");
|
|
LLSD sl1(std::string("def"));
|
|
ensureTypeAndValue("construct std::string", sl1, "def");
|
|
LLSD sl2 = std::string("def");
|
|
ensureTypeAndValue("initialize std::string", sl2, "def");
|
|
LLSD sc1("ghi");
|
|
ensureTypeAndValue("construct const char*", sc1, "ghi");
|
|
LLSD sc2 = "ghi";
|
|
ensureTypeAndValue("initialize const char*",sc2, "ghi");
|
|
|
|
LLDate aDay("2001-10-22T10:11:12.00Z");
|
|
LLSD t1(aDay); ensureTypeAndValue("construct LLDate", t1, aDay);
|
|
LLSD t2 = aDay; ensureTypeAndValue("initialize LLDate", t2, aDay);
|
|
|
|
LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
|
|
LLSD p1(path); ensureTypeAndValue("construct LLURI", p1, path);
|
|
LLSD p2 = path; ensureTypeAndValue("initialize LLURI", p2, path);
|
|
|
|
const char source[] = "once in a blue moon";
|
|
std::vector<U8> data;
|
|
copy(&source[0], &source[sizeof(source)], back_inserter(data));
|
|
LLSD x1(data); ensureTypeAndValue("construct vector<U8>", x1, data);
|
|
LLSD x2 = data; ensureTypeAndValue("initialize vector<U8>", x2, data);
|
|
}
|
|
|
|
void checkConversions(const char* msg, const LLSD& v,
|
|
LLSD::Boolean eBoolean, LLSD::Integer eInteger,
|
|
LLSD::Real eReal, const LLSD::String& eString)
|
|
{
|
|
std::string s(msg);
|
|
|
|
ensure_equals(s+" to bool", v.asBoolean(), eBoolean);
|
|
ensure_equals(s+" to int", v.asInteger(), eInteger);
|
|
if (eReal == eReal)
|
|
{
|
|
ensure_equals(s+" to real", v.asReal(), eReal);
|
|
ensure_equals(s+" to string", v.asString(), eString);
|
|
}
|
|
else
|
|
{
|
|
int left = fpclassify(v.asReal());
|
|
int right = fpclassify(eReal);
|
|
|
|
ensure_equals(s+" to real", left, right);
|
|
// ensure_equals(s+" to string", v.asString(), eString);
|
|
// I've commented this check out, since there doesn't
|
|
// seem to be uniform string representation for NaN on
|
|
// all platforms. For example, on my Ubuntu 8.10 laptop
|
|
// with libc 2.11.1, sqrt(-1.0) will return '-nan', not
|
|
// 'nan'.
|
|
}
|
|
}
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<4>()
|
|
// conversion between undefined and basic scalar types:
|
|
// boolean, integer, real and string
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD v; checkConversions("untitled", v, false, 0, 0.0, "");
|
|
|
|
v = false; checkConversions("false", v, false, 0, 0.0, "");
|
|
v = true; checkConversions("true", v, true, 1, 1.0, "true");
|
|
|
|
v = 0; checkConversions("zero", v, false, 0, 0.0, "0");
|
|
v = 1; checkConversions("one", v, true, 1, 1.0, "1");
|
|
v = -33; checkConversions("neg33", v, true, -33, -33.0, "-33");
|
|
|
|
v = 0.0; checkConversions("0.0", v, false, 0, 0.0, "0");
|
|
v = 0.5; checkConversions("point5", v, true, 0, 0.5, "0.5");
|
|
v = 0.9; checkConversions("point9", v, true, 0, 0.9, "0.9");
|
|
v = -3.9; checkConversions("neg3dot9", v, true, -3, -3.9, "-3.9");
|
|
v = sqrt(-1.0); checkConversions("NaN", v, false, 0, sqrt(-1.0), "nan");
|
|
|
|
v = ""; checkConversions("empty", v, false, 0, 0.0, "");
|
|
v = "0"; checkConversions("digit0", v, true, 0, 0.0, "0");
|
|
v = "10"; checkConversions("digit10", v, true, 10, 10.0, "10");
|
|
v = "-2.345"; checkConversions("decdigits", v,
|
|
true, -2, -2.345, "-2.345");
|
|
v = "apple"; checkConversions("apple", v, true, 0, 0.0, "apple");
|
|
v = "33bob"; checkConversions("digialpha", v, true, 0, 0.0, "33bob");
|
|
v = " "; checkConversions("space", v, true, 0, 0.0, " ");
|
|
v = "\n"; checkConversions("newline", v, true, 0, 0.0, "\n");
|
|
}
|
|
|
|
template<class T>
|
|
void checkRoundTrip(const std::string& msg, const LLSD& actual,
|
|
const char* sExpected, T vExpected)
|
|
{
|
|
std::string str = actual.asString();
|
|
|
|
if (sExpected) {
|
|
ensure_equals(msg + " string", str, sExpected);
|
|
}
|
|
|
|
LLSD u(str);
|
|
LLSDTraits<T> traits;
|
|
|
|
ensure_equals(msg + " value", traits.get(u), vExpected);
|
|
}
|
|
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<5>()
|
|
// conversion of String to and from UUID, Date and URI.
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD v;
|
|
|
|
LLUUID nullUUID;
|
|
LLUUID someUUID;
|
|
someUUID.generate();
|
|
|
|
v = nullUUID; checkRoundTrip("null uuid", v,
|
|
"00000000-0000-0000-0000-000000000000", nullUUID);
|
|
v = someUUID; checkRoundTrip("random uuid", v, 0, someUUID);
|
|
|
|
LLDate epoch;
|
|
LLDate beta("2003-04-30T04:00:00Z");
|
|
LLDate oneOh("2003-06-23T04:00:00Z");
|
|
|
|
v = epoch; checkRoundTrip("epoch date", v, 0, epoch);
|
|
v = beta; checkRoundTrip("beta date", v,
|
|
"2003-04-30T04:00:00Z", beta);
|
|
v = oneOh; checkRoundTrip("1.0 date", v,
|
|
"2003-06-23T04:00:00Z", oneOh);
|
|
|
|
LLURI empty;
|
|
LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/");
|
|
LLURI mail("mailto:zero.linden@secondlife.com");
|
|
|
|
v = empty; checkRoundTrip("empty URI", v, 0, empty);
|
|
v = path; checkRoundTrip("path URI", v,
|
|
"http://slurl.com/secondlife/Ambleside/57/104/26/",
|
|
path);
|
|
v = mail; checkRoundTrip("mail URI", v,
|
|
"mailto:zero.linden@secondlife.com", mail);
|
|
}
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<6>()
|
|
// copy construction and assignment
|
|
// checking for shared values after constr. or assignment
|
|
// checking in both the same type and change of type case
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
{
|
|
LLSD v = 42;
|
|
|
|
LLSD w0(v);
|
|
ensureTypeAndValue("int constr.", w0, 42);
|
|
|
|
LLSD w1(v);
|
|
w1 = 13;
|
|
ensureTypeAndValue("int constr. change case 1", w1, 13);
|
|
ensureTypeAndValue("int constr. change case 2", v, 42);
|
|
|
|
LLSD w2(v);
|
|
v = 7;
|
|
ensureTypeAndValue("int constr. change case 3", w2, 42);
|
|
ensureTypeAndValue("int constr. change case 4", v, 7);
|
|
}
|
|
|
|
{
|
|
LLSD v = 42;
|
|
|
|
LLSD w1(v);
|
|
w1 = "bob";
|
|
ensureTypeAndValue("string constr. change case 1", w1, "bob");
|
|
ensureTypeAndValue("string constr. change case 2", v, 42);
|
|
|
|
LLSD w2(v);
|
|
v = "amy";
|
|
ensureTypeAndValue("string constr. change case 3", w2, 42);
|
|
ensureTypeAndValue("string constr. change case 4", v, "amy");
|
|
}
|
|
|
|
{
|
|
LLSD v = 42;
|
|
|
|
LLSD w0;
|
|
w0 = v;
|
|
ensureTypeAndValue("int assign", w0, 42);
|
|
|
|
LLSD w1;
|
|
w1 = v;
|
|
w1 = 13;
|
|
ensureTypeAndValue("int assign change case 1", w1, 13);
|
|
ensureTypeAndValue("int assign change case 2", v, 42);
|
|
|
|
LLSD w2;
|
|
w2 = v;
|
|
v = 7;
|
|
ensureTypeAndValue("int assign change case 3", w2, 42);
|
|
ensureTypeAndValue("int assign change case 4", v, 7);
|
|
}
|
|
|
|
{
|
|
LLSD v = 42;
|
|
|
|
LLSD w1;
|
|
w1 = v;
|
|
w1 = "bob";
|
|
ensureTypeAndValue("string assign change case 1", w1, "bob");
|
|
ensureTypeAndValue("string assign change case 2", v, 42);
|
|
|
|
LLSD w2;
|
|
w2 = v;
|
|
v = "amy";
|
|
ensureTypeAndValue("string assign change case 3", w2, 42);
|
|
ensureTypeAndValue("string assign change case 4", v, "amy");
|
|
}
|
|
}
|
|
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<7>()
|
|
// Test assignment and casting to various scalar types. These
|
|
// assignments should invoke the right conversion without it being
|
|
// mentioned explicitly. The few exceptions are marked SAD.
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD v(" 42.375");
|
|
|
|
bool b = false;
|
|
b = v; ensure_equals("assign to bool", b, true);
|
|
b = (bool)v; ensure_equals("cast to bool", b, true);
|
|
|
|
int i = 99;
|
|
i = v; ensure_equals("assign to int", i, 42);
|
|
i = (int)v; ensure_equals("cast to int", i, 42);
|
|
|
|
double d = 3.14159;
|
|
d = v; ensure_equals("assign to double", d, 42.375);
|
|
d = (double)v; ensure_equals("cast to double", d, 42.375);
|
|
|
|
std::string s = "yo";
|
|
// SAD s = v; ensure_equals("assign to string", s, " 42.375");
|
|
s = (std::string)v; ensure_equals("cast to string", s, " 42.375");
|
|
|
|
std::string uuidStr = "b1e50c2b-b627-4d23-8a86-a65d97b6319b";
|
|
v = uuidStr;
|
|
LLUUID u;
|
|
u = v;
|
|
ensure_equals("assign to LLUUID", u, LLUUID(uuidStr));
|
|
// SAD u = (LLUUID)v;
|
|
// ensure_equals("cast to LLUUID", u, LLUUID(uuidStr));
|
|
|
|
std::string dateStr = "2005-10-24T15:00:00Z";
|
|
v = dateStr;
|
|
LLDate date;
|
|
date = v;
|
|
ensure_equals("assign to LLDate", date.asString(), dateStr);
|
|
// SAD date = (LLDate)v;
|
|
// ensure_equals("cast to LLDate", date.asString(), dateStr);
|
|
|
|
std::string uriStr = "http://secondlife.com";
|
|
v = uriStr;
|
|
LLURI uri;
|
|
uri = v;
|
|
ensure_equals("assign to LLURI", uri.asString(), uriStr);
|
|
// SAD uri = (LLURI)v;
|
|
// ensure_equals("cast to LLURI", uri.asString(), uriStr);
|
|
}
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<8>()
|
|
// Test construction of various scalar types from LLSD.
|
|
// Test both construction and initialization forms.
|
|
// These should invoke the right conversion without it being
|
|
// mentioned explicitly. The few exceptions are marked SAD.
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD v(" 42.375");
|
|
|
|
bool b1(v); ensure_equals("contruct bool", b1, true);
|
|
bool b2 = v; ensure_equals("initialize bool", b2, true);
|
|
|
|
int i1(v); ensure_equals("contruct int", i1, 42);
|
|
int i2 = v; ensure_equals("initialize int", i2, 42);
|
|
|
|
double d1(v); ensure_equals("contruct double", d1, 42.375);
|
|
double d2 = v; ensure_equals("initialize double", d2, 42.375);
|
|
|
|
std::string s1(v);
|
|
std::string s2 = v;
|
|
ensure_equals("contruct string", s1, " 42.375");
|
|
ensure_equals("initialize string", s2, " 42.375");
|
|
|
|
std::string t1(v);
|
|
std::string t2 = v.asString(); // SAD
|
|
ensure_equals("contruct std::string", t1, " 42.375");
|
|
ensure_equals("initialize std::string", t2, " 42.375");
|
|
|
|
std::string uuidStr = "b1e50c2b-b627-4d23-8a86-a65d97b6319b";
|
|
v = uuidStr;
|
|
LLUUID uuid1(v.asUUID()); // SAD
|
|
LLUUID uuid2 = v;
|
|
ensure_equals("contruct LLUUID", uuid1, LLUUID(uuidStr));
|
|
ensure_equals("initialize LLUUID", uuid2, LLUUID(uuidStr));
|
|
|
|
std::string dateStr = "2005-10-24T15:00:00Z";
|
|
v = dateStr;
|
|
LLDate date1(v.asDate()); // SAD
|
|
LLDate date2 = v;
|
|
ensure_equals("contruct LLDate", date1.asString(), dateStr);
|
|
ensure_equals("initialize LLDate", date2.asString(), dateStr);
|
|
|
|
std::string uriStr = "http://secondlife.com";
|
|
v = uriStr;
|
|
LLURI uri1(v.asURI()); // SAD
|
|
LLURI uri2 = v;
|
|
ensure_equals("contruct LLURI", uri1.asString(), uriStr);
|
|
ensure_equals("initialize LLURI", uri2.asString(), uriStr);
|
|
}
|
|
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<9>()
|
|
// test to make sure v is interpreted as a bool in a various
|
|
// scenarios.
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD v = "0";
|
|
// magic value that is interpreted as boolean true, but integer false!
|
|
|
|
ensure_equals("trinary operator bool", (v ? true : false), true);
|
|
ensure_equals("convert to int, then bool",
|
|
((int)v ? true : false), false);
|
|
|
|
if(v)
|
|
{
|
|
ensure("if converted to bool", true);
|
|
}
|
|
else
|
|
{
|
|
fail("bool did not convert to a bool in if statement.");
|
|
}
|
|
|
|
if(!v)
|
|
{
|
|
fail("bool did not convert to a bool in negated if statement.");
|
|
}
|
|
}
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<10>()
|
|
// map operations
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD v;
|
|
ensure("undefined has no members", !v.has("amy"));
|
|
ensure("undefined get() is undefined", v.get("bob").isUndefined());
|
|
|
|
v = LLSD::emptyMap();
|
|
ensure("empty map is a map", v.isMap());
|
|
ensure("empty map has no members", !v.has("cam"));
|
|
ensure("empty map get() is undefined", v.get("don").isUndefined());
|
|
|
|
v.clear();
|
|
v.insert("eli", 43);
|
|
ensure("insert converts to map", v.isMap());
|
|
ensure("inserted key is present", v.has("eli"));
|
|
ensureTypeAndValue("inserted value", v.get("eli"), 43);
|
|
|
|
v.insert("fra", false);
|
|
ensure("first key still present", v.has("eli"));
|
|
ensure("second key is present", v.has("fra"));
|
|
ensureTypeAndValue("first value", v.get("eli"), 43);
|
|
ensureTypeAndValue("second value", v.get("fra"), false);
|
|
|
|
v.erase("eli");
|
|
ensure("first key now gone", !v.has("eli"));
|
|
ensure("second key still present", v.has("fra"));
|
|
ensure("first value gone", v.get("eli").isUndefined());
|
|
ensureTypeAndValue("second value sill there", v.get("fra"), false);
|
|
|
|
v.erase("fra");
|
|
ensure("second key now gone", !v.has("fra"));
|
|
ensure("second value gone", v.get("fra").isUndefined());
|
|
|
|
v["gil"] = (std::string)"good morning";
|
|
ensure("third key present", v.has("gil"));
|
|
ensureTypeAndValue("third key value", v.get("gil"), "good morning");
|
|
|
|
const LLSD& cv = v; // FIX ME IF POSSIBLE
|
|
ensure("missing key", cv["ham"].isUndefined());
|
|
ensure("key not present", !v.has("ham"));
|
|
|
|
LLSD w = 43;
|
|
const LLSD& cw = w; // FIX ME IF POSSIBLE
|
|
int i = cw["ian"];
|
|
ensureTypeAndValue("other missing value", i, 0);
|
|
ensure("other missing key", !w.has("ian"));
|
|
ensure("no conversion", w.isInteger());
|
|
|
|
LLSD x;
|
|
x = v;
|
|
ensure("copy map type", x.isMap());
|
|
ensureTypeAndValue("copy map value gil", x.get("gil"), "good morning");
|
|
}
|
|
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<11>()
|
|
// array operations
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD v;
|
|
ensure_equals("undefined has no size", v.size(), 0);
|
|
ensure("undefined get() is undefined", v.get(0).isUndefined());
|
|
|
|
v = LLSD::emptyArray();
|
|
ensure("empty array is an array", v.isArray());
|
|
ensure_equals("empty array has no size", v.size(), 0);
|
|
ensure("empty map get() is undefined", v.get(0).isUndefined());
|
|
|
|
v.clear();
|
|
v.append(88);
|
|
v.append("noodle");
|
|
v.append(true);
|
|
ensure_equals("appened array size", v.size(), 3);
|
|
ensure("append array is an array", v.isArray());
|
|
ensureTypeAndValue("append 0", v[0], 88);
|
|
ensureTypeAndValue("append 1", v[1], "noodle");
|
|
ensureTypeAndValue("append 2", v[2], true);
|
|
|
|
v.insert(0, 77);
|
|
v.insert(2, "soba");
|
|
v.insert(4, false);
|
|
ensure_equals("inserted array size", v.size(), 6);
|
|
ensureTypeAndValue("post insert 0", v[0], 77);
|
|
ensureTypeAndValue("post insert 1", v[1], 88);
|
|
ensureTypeAndValue("post insert 2", v[2], "soba");
|
|
ensureTypeAndValue("post insert 3", v[3], "noodle");
|
|
ensureTypeAndValue("post insert 4", v[4], false);
|
|
ensureTypeAndValue("post insert 5", v[5], true);
|
|
|
|
ensureTypeAndValue("get 1", v.get(1), 88);
|
|
v.set(1, "hot");
|
|
ensureTypeAndValue("set 1", v.get(1), "hot");
|
|
|
|
v.erase(3);
|
|
ensure_equals("post erase array size", v.size(), 5);
|
|
ensureTypeAndValue("post erase 0", v[0], 77);
|
|
ensureTypeAndValue("post erase 1", v[1], "hot");
|
|
ensureTypeAndValue("post erase 2", v[2], "soba");
|
|
ensureTypeAndValue("post erase 3", v[3], false);
|
|
ensureTypeAndValue("post erase 4", v[4], true);
|
|
|
|
v.append(34);
|
|
ensure_equals("size after append", v.size(), 6);
|
|
ensureTypeAndValue("post append 5", v[5], 34);
|
|
|
|
LLSD w;
|
|
w = v;
|
|
ensure("copy array type", w.isArray());
|
|
ensure_equals("copy array size", w.size(), 6);
|
|
ensureTypeAndValue("copy array 0", w[0], 77);
|
|
ensureTypeAndValue("copy array 1", w[1], "hot");
|
|
ensureTypeAndValue("copy array 2", w[2], "soba");
|
|
ensureTypeAndValue("copy array 3", w[3], false);
|
|
ensureTypeAndValue("copy array 4", w[4], true);
|
|
ensureTypeAndValue("copy array 5", w[5], 34);
|
|
}
|
|
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<12>()
|
|
// no sharing
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
LLSD a = 99;
|
|
LLSD b = a;
|
|
a = 34;
|
|
ensureTypeAndValue("top level original changed", a, 34);
|
|
ensureTypeAndValue("top level copy unaltered", b, 99);
|
|
b = a;
|
|
b = 66;
|
|
ensureTypeAndValue("top level original unaltered", a, 34);
|
|
ensureTypeAndValue("top level copy changed", b, 66);
|
|
|
|
a[0] = "uno";
|
|
a[1] = 99;
|
|
a[2] = 1.414;
|
|
b = a;
|
|
a[1] = 34;
|
|
ensureTypeAndValue("array member original changed", a[1], 34);
|
|
ensureTypeAndValue("array member copy unaltered", b[1], 99);
|
|
b = a;
|
|
b[1] = 66;
|
|
ensureTypeAndValue("array member original unaltered", a[1], 34);
|
|
ensureTypeAndValue("array member copy changed", b[1], 66);
|
|
|
|
a["alpha"] = "uno";
|
|
a["beta"] = 99;
|
|
a["gamma"] = 1.414;
|
|
b = a;
|
|
a["beta"] = 34;
|
|
ensureTypeAndValue("map member original changed", a["beta"], 34);
|
|
ensureTypeAndValue("map member copy unaltered", b["beta"], 99);
|
|
b = a;
|
|
b["beta"] = 66;
|
|
ensureTypeAndValue("map member original unaltered", a["beta"], 34);
|
|
ensureTypeAndValue("map member copy changed", b["beta"], 66);
|
|
}
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<13>()
|
|
// sharing implementation
|
|
{
|
|
SDCleanupCheck check;
|
|
|
|
{
|
|
SDAllocationCheck check("copy construct undefinded", 0);
|
|
LLSD v;
|
|
LLSD w = v;
|
|
}
|
|
|
|
{
|
|
SDAllocationCheck check("assign undefined", 0);
|
|
LLSD v;
|
|
LLSD w;
|
|
w = v;
|
|
}
|
|
|
|
{
|
|
SDAllocationCheck check("assign integer value", 1);
|
|
LLSD v = 45;
|
|
v = 33;
|
|
v = 0;
|
|
}
|
|
|
|
{
|
|
SDAllocationCheck check("copy construct integer", 1);
|
|
LLSD v = 45;
|
|
LLSD w = v;
|
|
}
|
|
|
|
{
|
|
SDAllocationCheck check("assign integer", 1);
|
|
LLSD v = 45;
|
|
LLSD w;
|
|
w = v;
|
|
}
|
|
|
|
{
|
|
SDAllocationCheck check("avoids extra clone", 2);
|
|
LLSD v = 45;
|
|
LLSD w = v;
|
|
w = "nice day";
|
|
}
|
|
}
|
|
|
|
template<> template<>
|
|
void SDTestObject::test<14>()
|
|
// make sure that assignment of char* NULL in a string does not crash.
|
|
{
|
|
LLSD v;
|
|
v = (const char*)NULL;
|
|
ensure("type is a string", v.isString());
|
|
}
|
|
|
|
/* TO DO:
|
|
conversion of undefined to UUID, Date, URI and Binary
|
|
conversion of undefined to map and array
|
|
test map operations
|
|
test array operations
|
|
test array extension
|
|
|
|
test copying and assign maps and arrays (clone)
|
|
test iteration over map
|
|
test iteration over array
|
|
test iteration over scalar
|
|
|
|
test empty map and empty array are indeed shared
|
|
test serializations
|
|
*/
|
|
}
|