/indra/llcommon/tests/lllazy_test.cpp
C++ | 244 lines | 146 code | 24 blank | 74 comment | 0 complexity | fac681168003855bccbdc940c8bfd091 MD5 | raw file
Possible License(s): LGPL-2.1
- /**
- * @file lllazy_test.cpp
- * @author Nat Goodspeed
- * @date 2009-01-28
- * @brief Tests of lllazy.h.
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
- // Precompiled header
- #include "linden_common.h"
- // associated header
- #include "lllazy.h"
- // STL headers
- #include <iostream>
- // std headers
- // external library headers
- #include <boost/lambda/construct.hpp>
- #include <boost/lambda/bind.hpp>
- // other Linden headers
- #include "../test/lltut.h"
- namespace bll = boost::lambda;
- /*****************************************************************************
- * Test classes
- *****************************************************************************/
- // Let's say that because of its many external dependencies, YuckyFoo is very
- // hard to instantiate in a test harness.
- class YuckyFoo
- {
- public:
- virtual ~YuckyFoo() {}
- virtual std::string whoami() const { return "YuckyFoo"; }
- };
- // Let's further suppose that YuckyBar is another hard-to-instantiate class.
- class YuckyBar
- {
- public:
- YuckyBar(const std::string& which):
- mWhich(which)
- {}
- virtual ~YuckyBar() {}
- virtual std::string identity() const { return std::string("YuckyBar(") + mWhich + ")"; }
- private:
- const std::string mWhich;
- };
- // Pretend that this class would be tough to test because, up until we started
- // trying to test it, it contained instances of both YuckyFoo and YuckyBar.
- // Now we've refactored so it contains LLLazy<YuckyFoo> and LLLazy<YuckyBar>.
- // More than that, it contains them by virtue of deriving from
- // LLLazyBase<YuckyFoo> and LLLazyBase<YuckyBar>.
- // We postulate two different LLLazyBases because, with only one, you need not
- // specify *which* get()/set() method you're talking about. That's a simpler
- // case.
- class NeedsTesting: public LLLazyBase<YuckyFoo>, public LLLazyBase<YuckyBar>
- {
- public:
- NeedsTesting():
- // mYuckyBar("RealYuckyBar")
- LLLazyBase<YuckyBar>(bll::bind(bll::new_ptr<YuckyBar>(), "RealYuckyBar"))
- {}
- virtual ~NeedsTesting() {}
- virtual std::string describe() const
- {
- return std::string("NeedsTesting(") + getLazy<YuckyFoo>(this).whoami() + ", " +
- getLazy<YuckyBar>(this).identity() + ")";
- }
- private:
- // These instance members were moved to LLLazyBases:
- // YuckyFoo mYuckyFoo;
- // YuckyBar mYuckyBar;
- };
- // Fake up a test YuckyFoo class
- class TestFoo: public YuckyFoo
- {
- public:
- virtual std::string whoami() const { return "TestFoo"; }
- };
- // and a test YuckyBar
- class TestBar: public YuckyBar
- {
- public:
- TestBar(const std::string& which): YuckyBar(which) {}
- virtual std::string identity() const
- {
- return std::string("TestBar(") + YuckyBar::identity() + ")";
- }
- };
- // So here's a test subclass of NeedsTesting that uses TestFoo and TestBar
- // instead of YuckyFoo and YuckyBar.
- class TestNeedsTesting: public NeedsTesting
- {
- public:
- TestNeedsTesting()
- {
- // Exercise setLazy(T*)
- setLazy<YuckyFoo>(this, new TestFoo());
- // Exercise setLazy(Factory)
- setLazy<YuckyBar>(this, bll::bind(bll::new_ptr<TestBar>(), "TestYuckyBar"));
- }
- virtual std::string describe() const
- {
- return std::string("TestNeedsTesting(") + NeedsTesting::describe() + ")";
- }
- void toolate()
- {
- setLazy<YuckyFoo>(this, new TestFoo());
- }
- };
- // This class tests having an explicit LLLazy<T> instance as a named member,
- // rather than deriving from LLLazyBase<T>.
- class LazyMember
- {
- public:
- YuckyFoo& getYuckyFoo() { return *mYuckyFoo; }
- std::string whoisit() const { return mYuckyFoo->whoami(); }
- protected:
- LLLazy<YuckyFoo> mYuckyFoo;
- };
- // This is a test subclass of the above, dynamically replacing the
- // LLLazy<YuckyFoo> member.
- class TestLazyMember: public LazyMember
- {
- public:
- // use factory setter
- TestLazyMember()
- {
- mYuckyFoo.set(bll::new_ptr<TestFoo>());
- }
- // use instance setter
- TestLazyMember(YuckyFoo* instance)
- {
- mYuckyFoo.set(instance);
- }
- };
- /*****************************************************************************
- * TUT
- *****************************************************************************/
- namespace tut
- {
- struct lllazy_data
- {
- };
- typedef test_group<lllazy_data> lllazy_group;
- typedef lllazy_group::object lllazy_object;
- lllazy_group lllazygrp("lllazy");
- template<> template<>
- void lllazy_object::test<1>()
- {
- // Instantiate an official one, just because we can
- NeedsTesting nt;
- // and a test one
- TestNeedsTesting tnt;
- // std::cout << nt.describe() << '\n';
- ensure_equals(nt.describe(), "NeedsTesting(YuckyFoo, YuckyBar(RealYuckyBar))");
- // std::cout << tnt.describe() << '\n';
- ensure_equals(tnt.describe(),
- "TestNeedsTesting(NeedsTesting(TestFoo, TestBar(YuckyBar(TestYuckyBar))))");
- }
- template<> template<>
- void lllazy_object::test<2>()
- {
- TestNeedsTesting tnt;
- std::string threw;
- try
- {
- tnt.toolate();
- }
- catch (const LLLazyCommon::InstanceChange& e)
- {
- threw = e.what();
- }
- ensure_contains("InstanceChange exception", threw, "replace LLLazy instance");
- }
- template<> template<>
- void lllazy_object::test<3>()
- {
- {
- LazyMember lm;
- // operator*() on-demand instantiation
- ensure_equals(lm.getYuckyFoo().whoami(), "YuckyFoo");
- }
- {
- LazyMember lm;
- // operator->() on-demand instantiation
- ensure_equals(lm.whoisit(), "YuckyFoo");
- }
- }
- template<> template<>
- void lllazy_object::test<4>()
- {
- {
- // factory setter
- TestLazyMember tlm;
- ensure_equals(tlm.whoisit(), "TestFoo");
- }
- {
- // instance setter
- TestLazyMember tlm(new TestFoo());
- ensure_equals(tlm.whoisit(), "TestFoo");
- }
- }
- } // namespace tut