diff options
Diffstat (limited to 'indra/llcommon')
| -rw-r--r-- | indra/llcommon/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | indra/llcommon/indra_constants.h | 4 | ||||
| -rw-r--r-- | indra/llcommon/llassettype.cpp | 10 | ||||
| -rw-r--r-- | indra/llcommon/lldate.h | 3 | ||||
| -rw-r--r-- | indra/llcommon/llinstancetracker.h | 15 | ||||
| -rw-r--r-- | indra/llcommon/tests/llbase64_test.cpp | 2 | ||||
| -rw-r--r-- | indra/llcommon/tests/lldate_test.cpp | 2 | ||||
| -rw-r--r-- | indra/llcommon/tests/lldependencies_test.cpp | 275 | ||||
| -rw-r--r-- | indra/llcommon/tests/llerror_test.cpp | 2 | ||||
| -rw-r--r-- | indra/llcommon/tests/llframetimer_test.cpp | 2 | ||||
| -rw-r--r-- | indra/llcommon/tests/llrand_test.cpp | 2 | ||||
| -rw-r--r-- | indra/llcommon/tests/llsdserialize_test.cpp | 2 | ||||
| -rw-r--r-- | indra/llcommon/tests/lluri_test.cpp | 2 | ||||
| -rw-r--r-- | indra/llcommon/tests/reflection_test.cpp | 226 | ||||
| -rw-r--r-- | indra/llcommon/tests/stringize_test.cpp | 110 | 
15 files changed, 643 insertions, 17 deletions
| diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 13778f0f3b..e7aaf3c984 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -300,6 +300,7 @@ LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}")  LL_ADD_INTEGRATION_TEST(bitpack "" "${test_libs}")  LL_ADD_INTEGRATION_TEST(llbase64 "" "${test_libs}")  LL_ADD_INTEGRATION_TEST(lldate "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(lldependencies "" "${test_libs}")  LL_ADD_INTEGRATION_TEST(llerror "" "${test_libs}")  LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}")  LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}") @@ -308,6 +309,8 @@ LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")  LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}")  LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}")  LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(reflection "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(stringize "" "${test_libs}")  # *TODO - reenable these once tcmalloc libs no longer break the build.  #ADD_BUILD_TEST(llallocator llcommon) diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 4836d41fb3..6b75a720af 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -253,6 +253,10 @@ const U8 SIM_ACCESS_MAX 	= SIM_ACCESS_ADULT;  // group constants  const S32 MAX_AGENT_GROUPS = 25; +// attachment constants +const S32 MAX_AGENT_ATTACHMENTS = 38; +const U8  ATTACHMENT_ADD = 0x80; +  // god levels  const U8 GOD_MAINTENANCE = 250;  const U8 GOD_FULL = 200; diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 78aa6f4f37..b2a92861cc 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -112,12 +112,12 @@ LLAssetDictionary::LLAssetDictionary()  		 ensemble_num <= S32(LLAssetType::AT_FOLDER_ENSEMBLE_END);   		 ensemble_num++)  	{ -		addEntry(LLAssetType::EType(ensemble_num), new AssetEntry("ENSEMBLE",		"ensemble", "ensemble", 		"New Folder", 		DAD_CATEGORY,	TRUE,		FALSE));  +		addEntry(LLAssetType::EType(ensemble_num), new AssetEntry("ENSEMBLE",		"ensemble", "ensemble", 		"New Folder", 		DAD_CATEGORY,	FALSE,		FALSE));   	} -	addEntry(LLAssetType::AT_CURRENT_OUTFIT, 	new AssetEntry("CURRENT",			"current",	"current outfit",	"Current Outfit", 	DAD_CATEGORY,	FALSE,		TRUE)); -	addEntry(LLAssetType::AT_OUTFIT, 			new AssetEntry("OUTFIT",			"outfit",	"outfit",			"New Outfit", 		DAD_CATEGORY,	TRUE,		FALSE)); -	addEntry(LLAssetType::AT_MY_OUTFITS, 		new AssetEntry("MY_OUTFITS",		"my_otfts",	"my outfits",		"My Outfits", 		DAD_CATEGORY,	FALSE,		TRUE)); +	addEntry(LLAssetType::AT_CURRENT_OUTFIT, 	new AssetEntry("CURRENT",			"current",	"current outfit",	"Current Look", 	DAD_CATEGORY,	FALSE,		TRUE)); +	addEntry(LLAssetType::AT_OUTFIT, 			new AssetEntry("OUTFIT",			"outfit",	"outfit",			"New Look", 		DAD_CATEGORY,	FALSE,		FALSE)); +	addEntry(LLAssetType::AT_MY_OUTFITS, 		new AssetEntry("MY_OUTFITS",		"my_otfts",	"my outfits",		"My Looks", 		DAD_CATEGORY,	FALSE,		TRUE));  	addEntry(LLAssetType::AT_NONE, 				new AssetEntry("NONE",				"-1",		NULL,		  		"New Folder", 		DAD_NONE,		FALSE,		FALSE));  }; @@ -211,7 +211,7 @@ LLAssetType::EType LLAssetType::lookupHumanReadable(const std::string& readable_  		 iter++)  	{  		const AssetEntry *entry = iter->second; -		if (readable_name == entry->mHumanName) +		if (entry->mHumanName && (readable_name == entry->mHumanName))  		{  			return iter->first;  		} diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h index 5b1ec9295f..f8b2f2f163 100644 --- a/indra/llcommon/lldate.h +++ b/indra/llcommon/lldate.h @@ -162,8 +162,5 @@ LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLDate& date);  LL_COMMON_API std::istream& operator>>(std::istream& s, LLDate& date); -const static std::string weekdays[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; - -const static std::string months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};  #endif // LL_LLDATE_H diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index de25e364fa..ea50acbbc5 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -71,13 +71,17 @@ private:      static std::map<KEY, T*>& getMap()      { -		static std::map<KEY, T*>* sInstances = new std::map<KEY, T*>(); +        if (! sInstances) +        { +            sInstances = new std::map<KEY, T*>; +        }          return *sInstances;      }  private:  	KEY mKey; +	static std::map<KEY, T*>* sInstances;  };  // explicit specialization for default case where KEY is T* @@ -101,10 +105,17 @@ protected:      static std::set<T*>& getSet()   // called after getReady() but before go()      { -		static std::set<T*>* sInstances = new std::set<T*>(); +        if (! sInstances) +        { +            sInstances = new std::set<T*>; +        }          return *sInstances;      } + +	static std::set<T*>* sInstances;  }; +template <typename T, typename KEY> std::map<KEY, T*>* LLInstanceTracker<T, KEY>::sInstances = NULL; +template <typename T> std::set<T*>* LLInstanceTracker<T, T*>::sInstances = NULL;  #endif diff --git a/indra/llcommon/tests/llbase64_test.cpp b/indra/llcommon/tests/llbase64_test.cpp index dde43b5169..6009788b22 100644 --- a/indra/llcommon/tests/llbase64_test.cpp +++ b/indra/llcommon/tests/llbase64_test.cpp @@ -1,5 +1,5 @@  /**  - * @file llbase64_tut.cpp + * @file llbase64_test.cpp   * @author James Cook   * @date 2007-02-04   * diff --git a/indra/llcommon/tests/lldate_test.cpp b/indra/llcommon/tests/lldate_test.cpp index 1e36fdd119..c31259227a 100644 --- a/indra/llcommon/tests/lldate_test.cpp +++ b/indra/llcommon/tests/lldate_test.cpp @@ -1,5 +1,5 @@  /** - * @file lldate_tut.cpp + * @file lldate_test.cpp   * @author Adroit   * @date 2007-02   * @brief LLDate test cases. diff --git a/indra/llcommon/tests/lldependencies_test.cpp b/indra/llcommon/tests/lldependencies_test.cpp new file mode 100644 index 0000000000..f3c25de8b5 --- /dev/null +++ b/indra/llcommon/tests/lldependencies_test.cpp @@ -0,0 +1,275 @@ +/** + * @file   lldependencies_tut.cpp + * @author Nat Goodspeed + * @date   2008-09-17 + * @brief  Test of lldependencies.h + *  + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * Copyright (c) 2008, Linden Research, Inc. + * $/LicenseInfo$ + */ + +// STL headers +#include <iostream> +#include <string> +// std headers +// external library headers +#include <boost/assign/list_of.hpp> +// Precompiled header +#include "linden_common.h" +// associated header +#include "../lldependencies.h" +// other Linden headers +#include "../test/lltut.h" + +using boost::assign::list_of; + +#if LL_WINDOWS +#pragma warning (disable : 4675) // "resolved by ADL" -- just as I want! +#endif + +typedef LLDependencies<> StringDeps; +typedef StringDeps::KeyList StringList; + +// We use the very cool boost::assign::list_of() construct to specify vectors +// of strings inline. For reasons on which I'm not entirely clear, though, it +// needs a helper function. You can use list_of() to construct an implicit +// StringList (std::vector<std::string>) by conversion, e.g. for a function +// parameter -- but if you simply write StringList(list_of("etc.")), you get +// ambiguity errors. Shrug! +template<typename CONTAINER> +CONTAINER make(const CONTAINER& data) +{ +    return data; +} + +// Display an arbitary value as itself... +template<typename T> +std::ostream& display(std::ostream& out, const T& value) +{ +    out << value; +    return out; +} + +// ...but display std::string enclosed in double quotes. +template<> +std::ostream& display(std::ostream& out, const std::string& value) +{ +    out << '"' << value << '"'; +    return out; +} + +// display any sequence compatible with Boost.Range +template<typename SEQUENCE> +std::ostream& display_seq(std::ostream& out, +                          const std::string& open, const SEQUENCE& seq, const std::string& close) +{ +    out << open; +    typename boost::range_const_iterator<SEQUENCE>::type +        sli = boost::begin(seq), +        slend = boost::end(seq); +    if (sli != slend) +    { +        display(out, *sli); +        while (++sli != slend) +        { +            out << ", "; +            display(out, *sli); +        } +    } +    out << close; +    return out; +} + +// helper to dump a StringList to std::cout if needed +template<typename ENTRY> +std::ostream& operator<<(std::ostream& out, const std::vector<ENTRY>& list) +{ +    display_seq(out, "(", list, ")"); +    return out; +} + +template<typename ENTRY> +std::ostream& operator<<(std::ostream& out, const std::set<ENTRY>& set) +{ +    display_seq(out, "{", set, "}"); +    return out; +} + +const std::string& extract_key(const LLDependencies<>::value_type& entry) +{ +    return entry.first; +} + +// helper to return a StringList of keys from LLDependencies::sort() +StringList sorted_keys(LLDependencies<>& deps) +{ +    // 1. Call deps.sort(), returning a value_type range of (key, node) pairs. +    // 2. Use make_transform_range() to obtain a range of just keys. +    // 3. Use instance_from_range to instantiate a StringList from that range. +    // 4. Return by value "slices" instance_from_range<StringList> (a subclass +    //    of StringList) to its base class StringList. +    return instance_from_range<StringList>(make_transform_range(deps.sort(), extract_key)); +} + +template<typename RANGE> +bool is_empty(const RANGE& range) +{ +    return boost::begin(range) == boost::end(range); +} + +/***************************************************************************** +*   tut test group +*****************************************************************************/ +namespace tut +{ +    struct deps_data +    { +    }; +    typedef test_group<deps_data> deps_group; +    typedef deps_group::object deps_object; +    tut::deps_group depsgr("lldependencies"); + +    template<> template<> +    void deps_object::test<1>() +    { +        StringDeps deps; +        StringList empty; +        // The quick brown fox jumps over the lazy yellow dog. +        // (note, "The" and "the" are distinct, else this test wouldn't work) +        deps.add("lazy"); +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("lazy"))); +        deps.add("jumps"); +        ensure("found lazy", deps.get("lazy")); +        ensure("not found dog.", ! deps.get("dog.")); +        // NOTE: Maybe it's overkill to test each of these intermediate +        // results before all the interdependencies have been specified. My +        // thought is simply that if the order changes, I'd like to know why. +        // A change to the implementation of boost::topological_sort() would +        // be an acceptable reason, and you can simply update the expected +        // test output. +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("lazy")("jumps"))); +        deps.add("The", 0, empty, list_of("fox")("dog.")); +        // Test key accessors +        ensure("empty before deps for missing key", is_empty(deps.get_before_range("bogus"))); +        ensure("empty before deps for jumps", is_empty(deps.get_before_range("jumps"))); +        ensure_equals(instance_from_range< std::set<std::string> >(deps.get_before_range("The")), +                      make< std::set<std::string> >(list_of("dog.")("fox"))); +        // resume building dependencies +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("lazy")("jumps")("The"))); +        deps.add("the", 0, list_of("The")); +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("lazy")("jumps")("The")("the"))); +        deps.add("fox", 0, list_of("The"), list_of("jumps")); +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("lazy")("The")("the")("fox")("jumps"))); +        deps.add("the", 0, list_of("The")); // same, see if cache works +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("lazy")("The")("the")("fox")("jumps"))); +        deps.add("jumps", 0, empty, list_of("over")); // update jumps deps +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("lazy")("The")("the")("fox")("jumps"))); +/*==========================================================================*| +        // It drives me nuts that this test doesn't work in the test +        // framework, because -- for reasons unknown -- running the test +        // framework on Mac OS X 10.5 Leopard and Windows XP Pro, the catch +        // clause below doesn't catch the exception. Something about the TUT +        // test framework?!? The identical code works fine in a standalone +        // test program. Commenting out the test for now, in hopes that our +        // real builds will be able to catch Cycle exceptions... +        try +        { +            // We've already specified fox -> jumps and jumps -> over. Try an +            // impossible constraint. +            deps.add("over", 0, empty, list_of("fox")); +        } +        catch (const StringDeps::Cycle& e) +        { +            std::cout << "Cycle detected: " << e.what() << '\n'; +            // It's legal to add() an impossible constraint because we don't +            // detect the cycle until sort(). So sort() can't know the minimum set +            // of nodes to remove to make the StringDeps object valid again. +            // Therefore we must break the cycle by hand. +            deps.remove("over"); +        } +|*==========================================================================*/ +        deps.add("dog.", 0, list_of("yellow")("lazy")); +        ensure_equals(instance_from_range< std::set<std::string> >(deps.get_after_range("dog.")), +                      make< std::set<std::string> >(list_of("lazy")("yellow"))); +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("lazy")("The")("the")("fox")("jumps")("dog."))); +        deps.add("quick", 0, list_of("The"), list_of("fox")("brown")); +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("lazy")("The")("the")("quick")("fox")("jumps")("dog."))); +        deps.add("over", 0, list_of("jumps"), list_of("yellow")("the")); +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("lazy")("The")("quick")("fox")("jumps")("over")("the")("dog."))); +        deps.add("yellow", 0, list_of("the"), list_of("lazy")); +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("The")("quick")("fox")("jumps")("over")("the")("yellow")("lazy")("dog."))); +        deps.add("brown"); +        // By now the dependencies are pretty well in place. A change to THIS +        // order should be viewed with suspicion. +        ensure_equals(sorted_keys(deps), make<StringList>(list_of("The")("quick")("brown")("fox")("jumps")("over")("the")("yellow")("lazy")("dog."))); + +        StringList keys(make<StringList>(list_of("The")("brown")("dog.")("fox")("jumps")("lazy")("over")("quick")("the")("yellow"))); +        ensure_equals(instance_from_range<StringList>(deps.get_key_range()), keys); +#if (! defined(__GNUC__)) || (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) +        // This is the succinct way, works on modern compilers +        ensure_equals(instance_from_range<StringList>(make_transform_range(deps.get_range(), extract_key)), keys); +#else   // gcc 3.3 +        StringDeps::range got_range(deps.get_range()); +        StringDeps::iterator kni = got_range.begin(), knend = got_range.end(); +        StringList::iterator ki = keys.begin(), kend = keys.end(); +        for ( ; kni != knend && ki != kend; ++kni, ++ki) +        { +            ensure_equals(kni->first, *ki); +        } +        ensure("get_range() returns proper length", kni == knend && ki == kend); +#endif  // gcc 3.3 +        // blow off get_node_range() because they're all LLDependenciesEmpty instances +    } + +    template<> template<> +    void deps_object::test<2>() +    { +        typedef LLDependencies<std::string, int> NameIndexDeps; +        NameIndexDeps nideps; +        const NameIndexDeps& const_nideps(nideps); +        nideps.add("def", 2, list_of("ghi")); +        nideps.add("ghi", 3); +        nideps.add("abc", 1, list_of("def")); +        NameIndexDeps::range range(nideps.get_range()); +        ensure_equals(range.begin()->first, "abc"); +        ensure_equals(range.begin()->second, 1); +        range.begin()->second = 0; +        range.begin()->second = 1; +        NameIndexDeps::const_range const_range(const_nideps.get_range()); +        NameIndexDeps::const_iterator const_iterator(const_range.begin()); +        ++const_iterator; +        ensure_equals(const_iterator->first, "def"); +        ensure_equals(const_iterator->second, 2); +        NameIndexDeps::node_range node_range(nideps.get_node_range()); +        ensure_equals(instance_from_range<std::vector<int> >(node_range), make< std::vector<int> >(list_of(1)(2)(3))); +        *node_range.begin() = 0; +        *node_range.begin() = 1; +        NameIndexDeps::const_node_range const_node_range(const_nideps.get_node_range()); +        ensure_equals(instance_from_range<std::vector<int> >(const_node_range), make< std::vector<int> >(list_of(1)(2)(3))); +        NameIndexDeps::const_key_range const_key_range(const_nideps.get_key_range()); +        ensure_equals(instance_from_range<StringList>(const_key_range), make<StringList>(list_of("abc")("def")("ghi"))); +        NameIndexDeps::sorted_range sorted(const_nideps.sort()); +        NameIndexDeps::sorted_iterator sortiter(sorted.begin()); +        ensure_equals(sortiter->first, "ghi"); +        ensure_equals(sortiter->second, 3); + +        // test all iterator-flavored versions of get_after_range() +        StringList def(make<StringList>(list_of("def"))); +        ensure("empty abc before list", is_empty(nideps.get_before_range(nideps.get_range().begin()))); +        ensure_equals(instance_from_range<StringList>(nideps.get_after_range(nideps.get_range().begin())), +                      def); +        ensure_equals(instance_from_range<StringList>(const_nideps.get_after_range(const_nideps.get_range().begin())), +                      def); +        ensure_equals(instance_from_range<StringList>(nideps.get_after_range(nideps.get_node_range().begin())), +                      def); +        ensure_equals(instance_from_range<StringList>(const_nideps.get_after_range(const_nideps.get_node_range().begin())), +                      def); +        ensure_equals(instance_from_range<StringList>(nideps.get_after_range(nideps.get_key_range().begin())), +                      def); +        // advance from "ghi" to "def", which must come after "ghi" +        ++sortiter; +        ensure_equals(instance_from_range<StringList>(const_nideps.get_after_range(sortiter)), +                      make<StringList>(list_of("ghi"))); +    } +} // namespace tut diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index 8055647b94..1558df231a 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -1,5 +1,5 @@  /**  - * @file llerror_tut.cpp + * @file llerror_test.cpp   * @date   December 2006   * @brief error unit tests   * diff --git a/indra/llcommon/tests/llframetimer_test.cpp b/indra/llcommon/tests/llframetimer_test.cpp index 737c996d0f..1d047e41f8 100644 --- a/indra/llcommon/tests/llframetimer_test.cpp +++ b/indra/llcommon/tests/llframetimer_test.cpp @@ -1,5 +1,5 @@  /**  - * @file lltiming_tut.cpp + * @file lltiming_test.cpp   * @date 2006-07-23   * @brief Tests the timers.   * diff --git a/indra/llcommon/tests/llrand_test.cpp b/indra/llcommon/tests/llrand_test.cpp index e5100e51dc..1f178d6fc9 100644 --- a/indra/llcommon/tests/llrand_test.cpp +++ b/indra/llcommon/tests/llrand_test.cpp @@ -1,5 +1,5 @@  /**  - * @file llrandom_tut.cpp + * @file llrandom_test.cpp   * @author Phoenix   * @date 2007-01-25   * diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp index 8f6d9d8e26..6ab48ec34a 100644 --- a/indra/llcommon/tests/llsdserialize_test.cpp +++ b/indra/llcommon/tests/llsdserialize_test.cpp @@ -1,5 +1,5 @@  /**  - * @file llsdserialize_tut.cpp + * @file llsdserialize_test.cpp   * @date 2006-04   * @brief LLSDSerialize unit tests   * diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp index 4e5ad0df58..0a7c37d4b9 100644 --- a/indra/llcommon/tests/lluri_test.cpp +++ b/indra/llcommon/tests/lluri_test.cpp @@ -1,5 +1,5 @@  /** - * @file   lluri_tut.cpp + * @file   lluri_test.cpp   * @brief  LLURI unit tests   * @date   September 2006   * diff --git a/indra/llcommon/tests/reflection_test.cpp b/indra/llcommon/tests/reflection_test.cpp new file mode 100644 index 0000000000..5263e7fa64 --- /dev/null +++ b/indra/llcommon/tests/reflection_test.cpp @@ -0,0 +1,226 @@ +/**  + * @file reflection_test.cpp + * @date   May 2006 + * @brief Reflection 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 "../linden_common.h" +#include "../reflective.h" +#include "../metaclasst.h" +#include "../metapropertyt.h" +#include "../stdtypes.h" + +#include "../test/lltut.h" + +namespace tut +{ +  class TestAggregatedData : public LLReflective +  { +  public: +	TestAggregatedData() {;} +	virtual const LLMetaClass& getMetaClass() const; +   +  private: +  }; +   +  class TestReflectionData : public LLReflective +  { +  public: +	TestReflectionData() : mInt(42), mString("foo"), mNullPtr(NULL), mPtr(new TestAggregatedData()), mRef(*(new TestAggregatedData)) {;} +	virtual ~TestReflectionData() {delete mPtr;} +	virtual const LLMetaClass& getMetaClass() const; +	 +	static U32 getPropertyCount() {return 5;} +	 +  private: +   +	friend class LLMetaClassT<TestReflectionData>; +    S32 mInt; +	std::string mString; +	TestAggregatedData* mNullPtr; +	TestAggregatedData* mPtr; +	TestAggregatedData mObj; +	TestAggregatedData& mRef; +  }; +} + +template <> +void LLMetaClassT<tut::TestReflectionData>::reflectProperties(LLMetaClass& meta_class) +{ +	reflectProperty(meta_class, "mInt", &tut::TestReflectionData::mInt); +	reflectProperty(meta_class, "mString", &tut::TestReflectionData::mString); +	reflectPtrProperty(meta_class, "mNullPtr", &tut::TestReflectionData::mNullPtr); +	reflectPtrProperty(meta_class, "mPtr", &tut::TestReflectionData::mPtr); +	reflectProperty(meta_class, "mObj", &tut::TestReflectionData::mObj); +	//reflectProperty(meta_class, "mRef", &tut::TestReflectionData::mRef); // AARGH! +} + +namespace tut +{ +	// virtual +	const LLMetaClass& TestReflectionData::getMetaClass() const +	{ +	   return LLMetaClassT<TestReflectionData>::instance(); +    } +	 +	const LLMetaClass& TestAggregatedData::getMetaClass() const +	{ +	   return LLMetaClassT<TestAggregatedData>::instance(); +    } +} + +namespace tut +{ +  typedef tut::test_group<TestReflectionData> TestReflectionGroup; +  typedef TestReflectionGroup::object TestReflectionObject; +  TestReflectionGroup gTestReflectionGroup("reflection"); + +  template<> template<> +  void TestReflectionObject::test<1>() +  { +	// Check properties can be found. +    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); +	const LLMetaProperty* null = NULL; +	ensure_not_equals(meta_class.findProperty("mInt"), null); +	ensure_not_equals(meta_class.findProperty("mString"), null); +  } +   +  template<> template<> +  void TestReflectionObject::test<2>() +  { +	// Check non-existent property cannot be found. +    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); +	const LLMetaProperty* null = NULL; +	ensure_equals(meta_class.findProperty("foo"), null); +  } +   +  template<> template<> +  void TestReflectionObject::test<3>() +  { +	// Check integer property has correct value.	 +    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); +	ensure_equals(meta_class.findProperty("mInt")->getLLSD(this).asInteger(), 42); +  } +   +  template<> template<> +  void TestReflectionObject::test<4>() +  { +	// Check string property has correct value.	 +    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); +	ensure_equals(meta_class.findProperty("mString")->getLLSD(this).asString(), std::string("foo")); +  } +   +  template<> template<> +  void TestReflectionObject::test<5>() +  { +	// Check NULL reference property has correct value. +	const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); +	const LLReflective* null = NULL; +	ensure_equals(meta_class.findProperty("mNullPtr")->get(this), null); +  } +   +  template<> template<> +  void TestReflectionObject::test<6>() +  { +	// Check reference property has correct value. +	const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); +	const LLReflective* null = NULL; +	const LLReflective* ref = meta_class.findProperty("mPtr")->get(this); +	ensure_not_equals(ref, null); +  } +   +  template<> template<> +  void TestReflectionObject::test<7>() +  { +	// Check reflective property has correct value. +	const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); +	const LLReflective* null = NULL; +	const LLReflective* ref = meta_class.findProperty("mObj")->get(this); +	ensure_not_equals(ref, null); +  } + +  template<> template<> +  void TestReflectionObject::test<8>() +  { +	// Check property count. +    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); +	ensure_equals(meta_class.getPropertyCount(), TestReflectionData::getPropertyCount()); +  } +   +  template<> template<> +  void TestReflectionObject::test<9>() +  { +	// Check property iteration. +    const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); +	U32 count = 0; +	LLMetaClass::PropertyIterator iter; +	for(iter = meta_class.beginProperties(); iter != meta_class.endProperties(); ++iter) +	{ +		++count; +	} +	ensure_equals(count, TestReflectionData::getPropertyCount()); +  } +   +  template<> template<> +  void TestReflectionObject::test<10>() +  { +	// Check meta classes of different types do not compare equal. +	const LLMetaClass* reflection_data_meta_class = &(LLMetaClassT<TestReflectionData>::instance()); +	const LLMetaClass* aggregated_data_meta_class = &(LLMetaClassT<TestAggregatedData>::instance()); +	ensure_not_equals(reflection_data_meta_class, aggregated_data_meta_class); +  } +   +  template<> template<> +  void TestReflectionObject::test<11>() +  { +	// Check class cast checks. +	const LLMetaClass& meta_class = LLMetaClassT<TestReflectionData>::instance(); +	TestAggregatedData* aggregated_data = new TestAggregatedData(); +	LLMetaClass::PropertyIterator iter; +	U32 exception_count = 0; +	for(iter = meta_class.beginProperties(); iter != meta_class.endProperties(); ++iter) +	{ +		try +		{ +			const LLMetaProperty* property = (*iter).second; +			const LLReflective* reflective = property->get(aggregated_data); // Wrong reflective type, should throw exception. + +			// useless op to get rid of compiler warning. +			reflective = NULL; +		} +		catch(...) +		{ +			++exception_count; +		} +	} +	ensure_equals(exception_count, getPropertyCount()); +	 +  } +} diff --git a/indra/llcommon/tests/stringize_test.cpp b/indra/llcommon/tests/stringize_test.cpp new file mode 100644 index 0000000000..dd69787a1c --- /dev/null +++ b/indra/llcommon/tests/stringize_test.cpp @@ -0,0 +1,110 @@ +/** + * @file   stringize_test.cpp + * @author Nat Goodspeed + * @date   2008-09-12 + * @brief  Test of stringize.h + *  + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2008-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$ + */ + +/*==========================================================================*| +#if LL_WINDOWS +#pragma warning (disable : 4675) // "resolved by ADL" -- just as I want! +#endif +|*==========================================================================*/ + +// STL headers +#include <iomanip> + +// Precompiled header +#include "linden_common.h" + +// associated header +#include "../stringize.h" + +// std headers +// external library headers +// other Linden headers +#include "../llsd.h" + +#include "../test/lltut.h" + +namespace tut +{ +    struct stringize_data +    { +        stringize_data(): +            c('c'), +            s(17), +            i(34), +            l(68), +            f(3.14159265358979f), +            d(3.14159265358979), +            // Including a space differentiates this from +            // boost::lexical_cast<std::string>, which doesn't handle embedded +            // spaces so well. +            abc("abc def") +        { +            llsd["i"]   = i; +            llsd["d"]   = d; +            llsd["abc"] = abc; +        } + +        char        c; +        short       s; +        int         i; +        long        l; +        float       f; +        double      d; +        std::string abc; +        LLSD        llsd; +    }; +    typedef test_group<stringize_data> stringize_group; +    typedef stringize_group::object stringize_object; +    tut::stringize_group strzgrp("stringize"); + +    template<> template<> +    void stringize_object::test<1>() +    { +        ensure_equals(stringize(c),    "c"); +        ensure_equals(stringize(s),    "17"); +        ensure_equals(stringize(i),    "34"); +        ensure_equals(stringize(l),    "68"); +        ensure_equals(stringize(f),    "3.14159"); +        ensure_equals(stringize(d),    "3.14159"); +        ensure_equals(stringize(abc),  "abc def"); +        ensure_equals(stringize(llsd), "{'abc':'abc def','d':r3.14159,'i':i34}"); +    } + +    template<> template<> +    void stringize_object::test<2>() +    { +        ensure_equals(STRINGIZE("c is " << c), "c is c"); +        ensure_equals(STRINGIZE(std::setprecision(4) << d), "3.142"); +    } +} // namespace tut | 
