summaryrefslogtreecommitdiff
path: root/indra/test/llevents_tut.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/test/llevents_tut.cpp')
-rw-r--r--indra/test/llevents_tut.cpp646
1 files changed, 323 insertions, 323 deletions
diff --git a/indra/test/llevents_tut.cpp b/indra/test/llevents_tut.cpp
index a38de71e48..875ca9ad89 100644
--- a/indra/test/llevents_tut.cpp
+++ b/indra/test/llevents_tut.cpp
@@ -3,25 +3,25 @@
* @author Nat Goodspeed
* @date 2008-09-12
* @brief Test of llevents.h
- *
+ *
* $LicenseInfo:firstyear=2008&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$
*/
@@ -57,7 +57,7 @@ using boost::assign::list_of;
template<typename T>
T make(const T& value)
{
- return value;
+ return value;
}
/*****************************************************************************
@@ -67,21 +67,21 @@ namespace tut
{
struct events_data
{
- events_data() :
- pumps(LLEventPumps::instance()),
- listener0("first"),
- listener1("second")
- {
- }
- LLEventPumps& pumps;
- Listener listener0;
- Listener listener1;
+ events_data() :
+ pumps(LLEventPumps::instance()),
+ listener0("first"),
+ listener1("second")
+ {
+ }
+ LLEventPumps& pumps;
+ Listener listener0;
+ Listener listener1;
- void check_listener(const std::string& desc, const Listener& listener, LLSD::Integer got)
- {
- ensure_equals(STRINGIZE(listener << ' ' << desc),
- listener.getLastEvent().asInteger(), got);
- }
+ void check_listener(const std::string& desc, const Listener& listener, LLSD::Integer got)
+ {
+ ensure_equals(STRINGIZE(listener << ' ' << desc),
+ listener.getLastEvent().asInteger(), got);
+ }
};
typedef test_group<events_data> events_group;
typedef events_group::object events_object;
@@ -90,367 +90,367 @@ tut::events_group evgr("events");
template<> template<>
void events_object::test<1>()
{
- set_test_name("basic operations");
- // Having to modify this to track the statically-
- // constructed pumps in other TUT modules in this giant monolithic test
- // executable isn't such a hot idea.
- // ensure_equals("initial pump", pumps.mPumpMap.size(), 1);
- size_t initial_pumps(pumps.mPumpMap.size());
- LLEventPump& per_frame(pumps.obtain("per-frame"));
- ensure_equals("first explicit pump", pumps.mPumpMap.size(), initial_pumps + 1);
- // Verify that per_frame was instantiated as an LLEventStream.
- ensure("LLEventStream leaf class", dynamic_cast<LLEventStream*> (&per_frame));
- ensure("enabled", per_frame.enabled());
- // Trivial test, but posting an event to an EventPump with no
- // listeners should not blow up. The test is relevant because defining
- // a boost::signal with a non-void return signature, using the default
- // combiner, blows up if there are no listeners. This is because the
- // default combiner is defined to return the value returned by the
- // last listener, which is meaningless if there were no listeners.
- per_frame.post(0);
- LLBoundListener connection = listener0.listenTo(per_frame);
- ensure("connected", connection.connected());
- ensure("not blocked", !connection.blocked());
- per_frame.post(1);
- check_listener("received", listener0, 1);
- { // block the connection
- LLEventPump::Blocker block(connection);
- ensure("blocked", connection.blocked());
- per_frame.post(2);
- check_listener("not updated", listener0, 1);
- } // unblock
- ensure("unblocked", !connection.blocked());
- per_frame.post(3);
- check_listener("unblocked", listener0, 3);
- LLBoundListener sameConnection = per_frame.getListener(listener0.getName());
- ensure("still connected", sameConnection.connected());
- ensure("still not blocked", !sameConnection.blocked());
- { // block it again
- LLEventPump::Blocker block(sameConnection);
- ensure("re-blocked", sameConnection.blocked());
- per_frame.post(4);
- check_listener("re-blocked", listener0, 3);
- } // unblock
- std::string threw = catch_what<LLEventPump::DupListenerName>(
- [&per_frame, this](){
- // NOTE: boost::bind() saves its arguments by VALUE! If you pass
- // an object instance rather than a pointer, you'll end up binding
- // to an internal copy of that instance! Use boost::ref() to
- // capture a reference instead.
- per_frame.listen(listener0.getName(), // note bug, dup name
- boost::bind(&Listener::call, boost::ref(listener1), _1));
- });
- ensure_equals(threw,
- std::string("DupListenerName: "
- "Attempt to register duplicate listener name '") +
- listener0.getName() + "' on " + typeid(per_frame).name() +
- " '" + per_frame.getName() + "'");
- // do it right this time
- listener1.listenTo(per_frame);
- per_frame.post(5);
- check_listener("got", listener0, 5);
- check_listener("got", listener1, 5);
- per_frame.enable(false);
- per_frame.post(6);
- check_listener("didn't get", listener0, 5);
- check_listener("didn't get", listener1, 5);
- per_frame.enable();
- per_frame.post(7);
- check_listener("got", listener0, 7);
- check_listener("got", listener1, 7);
- per_frame.stopListening(listener0.getName());
- ensure("disconnected 0", ! connection.connected());
- ensure("disconnected 1", ! sameConnection.connected());
- per_frame.post(8);
- check_listener("disconnected", listener0, 7);
- check_listener("still connected", listener1, 8);
- per_frame.stopListening(listener1.getName());
- per_frame.post(9);
- check_listener("disconnected", listener1, 8);
+ set_test_name("basic operations");
+ // Having to modify this to track the statically-
+ // constructed pumps in other TUT modules in this giant monolithic test
+ // executable isn't such a hot idea.
+ // ensure_equals("initial pump", pumps.mPumpMap.size(), 1);
+ size_t initial_pumps(pumps.mPumpMap.size());
+ LLEventPump& per_frame(pumps.obtain("per-frame"));
+ ensure_equals("first explicit pump", pumps.mPumpMap.size(), initial_pumps + 1);
+ // Verify that per_frame was instantiated as an LLEventStream.
+ ensure("LLEventStream leaf class", dynamic_cast<LLEventStream*> (&per_frame));
+ ensure("enabled", per_frame.enabled());
+ // Trivial test, but posting an event to an EventPump with no
+ // listeners should not blow up. The test is relevant because defining
+ // a boost::signal with a non-void return signature, using the default
+ // combiner, blows up if there are no listeners. This is because the
+ // default combiner is defined to return the value returned by the
+ // last listener, which is meaningless if there were no listeners.
+ per_frame.post(0);
+ LLBoundListener connection = listener0.listenTo(per_frame);
+ ensure("connected", connection.connected());
+ ensure("not blocked", !connection.blocked());
+ per_frame.post(1);
+ check_listener("received", listener0, 1);
+ { // block the connection
+ LLEventPump::Blocker block(connection);
+ ensure("blocked", connection.blocked());
+ per_frame.post(2);
+ check_listener("not updated", listener0, 1);
+ } // unblock
+ ensure("unblocked", !connection.blocked());
+ per_frame.post(3);
+ check_listener("unblocked", listener0, 3);
+ LLBoundListener sameConnection = per_frame.getListener(listener0.getName());
+ ensure("still connected", sameConnection.connected());
+ ensure("still not blocked", !sameConnection.blocked());
+ { // block it again
+ LLEventPump::Blocker block(sameConnection);
+ ensure("re-blocked", sameConnection.blocked());
+ per_frame.post(4);
+ check_listener("re-blocked", listener0, 3);
+ } // unblock
+ std::string threw = catch_what<LLEventPump::DupListenerName>(
+ [&per_frame, this](){
+ // NOTE: boost::bind() saves its arguments by VALUE! If you pass
+ // an object instance rather than a pointer, you'll end up binding
+ // to an internal copy of that instance! Use boost::ref() to
+ // capture a reference instead.
+ per_frame.listen(listener0.getName(), // note bug, dup name
+ boost::bind(&Listener::call, boost::ref(listener1), _1));
+ });
+ ensure_equals(threw,
+ std::string("DupListenerName: "
+ "Attempt to register duplicate listener name '") +
+ listener0.getName() + "' on " + typeid(per_frame).name() +
+ " '" + per_frame.getName() + "'");
+ // do it right this time
+ listener1.listenTo(per_frame);
+ per_frame.post(5);
+ check_listener("got", listener0, 5);
+ check_listener("got", listener1, 5);
+ per_frame.enable(false);
+ per_frame.post(6);
+ check_listener("didn't get", listener0, 5);
+ check_listener("didn't get", listener1, 5);
+ per_frame.enable();
+ per_frame.post(7);
+ check_listener("got", listener0, 7);
+ check_listener("got", listener1, 7);
+ per_frame.stopListening(listener0.getName());
+ ensure("disconnected 0", ! connection.connected());
+ ensure("disconnected 1", ! sameConnection.connected());
+ per_frame.post(8);
+ check_listener("disconnected", listener0, 7);
+ check_listener("still connected", listener1, 8);
+ per_frame.stopListening(listener1.getName());
+ per_frame.post(9);
+ check_listener("disconnected", listener1, 8);
}
template<> template<>
void events_object::test<2>()
{
- set_test_name("callstop() returning true");
- LLEventPump& per_frame(pumps.obtain("per-frame"));
- listener0.reset(0);
- listener1.reset(0);
- LLBoundListener bound0 = listener0.listenTo(per_frame, &Listener::callstop);
- LLBoundListener bound1 = listener1.listenTo(per_frame, &Listener::call,
- // after listener0
- make<LLEventPump::NameList>(list_of(listener0.getName())));
- ensure("enabled", per_frame.enabled());
- ensure("connected 0", bound0.connected());
- ensure("unblocked 0", !bound0.blocked());
- ensure("connected 1", bound1.connected());
- ensure("unblocked 1", !bound1.blocked());
- per_frame.post(1);
- check_listener("got", listener0, 1);
- // Because listener0.callstop() returns true, control never reaches listener1.call().
- check_listener("got", listener1, 0);
+ set_test_name("callstop() returning true");
+ LLEventPump& per_frame(pumps.obtain("per-frame"));
+ listener0.reset(0);
+ listener1.reset(0);
+ LLBoundListener bound0 = listener0.listenTo(per_frame, &Listener::callstop);
+ LLBoundListener bound1 = listener1.listenTo(per_frame, &Listener::call,
+ // after listener0
+ make<LLEventPump::NameList>(list_of(listener0.getName())));
+ ensure("enabled", per_frame.enabled());
+ ensure("connected 0", bound0.connected());
+ ensure("unblocked 0", !bound0.blocked());
+ ensure("connected 1", bound1.connected());
+ ensure("unblocked 1", !bound1.blocked());
+ per_frame.post(1);
+ check_listener("got", listener0, 1);
+ // Because listener0.callstop() returns true, control never reaches listener1.call().
+ check_listener("got", listener1, 0);
}
bool chainEvents(Listener& someListener, const LLSD& event)
{
- // Make this call so we can watch for side effects for test purposes.
- someListener.call(event);
- // This function represents a recursive event chain -- or some other
- // scenario in which an event handler raises additional events.
- int value = event.asInteger();
- if (value)
- {
- LLEventPumps::instance().obtain("login").post(value - 1);
- }
- return false;
+ // Make this call so we can watch for side effects for test purposes.
+ someListener.call(event);
+ // This function represents a recursive event chain -- or some other
+ // scenario in which an event handler raises additional events.
+ int value = event.asInteger();
+ if (value)
+ {
+ LLEventPumps::instance().obtain("login").post(value - 1);
+ }
+ return false;
}
template<> template<>
void events_object::test<3>()
{
- set_test_name("explicitly-instantiated LLEventStream");
- // Explicitly instantiate an LLEventStream, and verify that it
- // self-registers with LLEventPumps
- size_t registered = pumps.mPumpMap.size();
- size_t owned = pumps.mOurPumps.size();
- LLEventPump* localInstance;
- {
- LLEventStream myEventStream("stream");
- localInstance = &myEventStream;
- LLEventPump& stream(pumps.obtain("stream"));
- ensure("found named LLEventStream instance", &stream == localInstance);
- ensure_equals("registered new instance", pumps.mPumpMap.size(), registered + 1);
- ensure_equals("explicit instance not owned", pumps.mOurPumps.size(), owned);
- } // destroy myEventStream -- should unregister
- ensure_equals("destroyed instance unregistered", pumps.mPumpMap.size(), registered);
- ensure_equals("destroyed instance not owned", pumps.mOurPumps.size(), owned);
- LLEventPump& stream(pumps.obtain("stream"));
- ensure("new LLEventStream instance", &stream != localInstance);
- ensure_equals("obtain()ed instance registered", pumps.mPumpMap.size(), registered + 1);
- ensure_equals("obtain()ed instance owned", pumps.mOurPumps.size(), owned + 1);
+ set_test_name("explicitly-instantiated LLEventStream");
+ // Explicitly instantiate an LLEventStream, and verify that it
+ // self-registers with LLEventPumps
+ size_t registered = pumps.mPumpMap.size();
+ size_t owned = pumps.mOurPumps.size();
+ LLEventPump* localInstance;
+ {
+ LLEventStream myEventStream("stream");
+ localInstance = &myEventStream;
+ LLEventPump& stream(pumps.obtain("stream"));
+ ensure("found named LLEventStream instance", &stream == localInstance);
+ ensure_equals("registered new instance", pumps.mPumpMap.size(), registered + 1);
+ ensure_equals("explicit instance not owned", pumps.mOurPumps.size(), owned);
+ } // destroy myEventStream -- should unregister
+ ensure_equals("destroyed instance unregistered", pumps.mPumpMap.size(), registered);
+ ensure_equals("destroyed instance not owned", pumps.mOurPumps.size(), owned);
+ LLEventPump& stream(pumps.obtain("stream"));
+ ensure("new LLEventStream instance", &stream != localInstance);
+ ensure_equals("obtain()ed instance registered", pumps.mPumpMap.size(), registered + 1);
+ ensure_equals("obtain()ed instance owned", pumps.mOurPumps.size(), owned + 1);
}
template<> template<>
void events_object::test<4>()
{
- set_test_name("stopListening()");
- LLEventPump& login(pumps.obtain("login"));
- listener0.listenTo(login);
- login.stopListening(listener0.getName());
- // should not throw because stopListening() should have removed name
- listener0.listenTo(login, &Listener::callstop);
- LLBoundListener wrong = login.getListener("bogus");
- ensure("bogus connection disconnected", !wrong.connected());
- ensure("bogus connection blocked", wrong.blocked());
+ set_test_name("stopListening()");
+ LLEventPump& login(pumps.obtain("login"));
+ listener0.listenTo(login);
+ login.stopListening(listener0.getName());
+ // should not throw because stopListening() should have removed name
+ listener0.listenTo(login, &Listener::callstop);
+ LLBoundListener wrong = login.getListener("bogus");
+ ensure("bogus connection disconnected", !wrong.connected());
+ ensure("bogus connection blocked", wrong.blocked());
}
template<> template<>
void events_object::test<5>()
{
- set_test_name("chaining LLEventPump instances");
- LLEventPump& upstream(pumps.obtain("upstream"));
- // One potentially-useful construct is to chain LLEventPumps together.
- // Among other things, this allows you to turn subsets of listeners on
- // and off in groups.
- LLEventPump& filter0(pumps.obtain("filter0"));
- LLEventPump& filter1(pumps.obtain("filter1"));
- upstream.listen(filter0.getName(), boost::bind(&LLEventPump::post, boost::ref(filter0), _1));
- upstream.listen(filter1.getName(), boost::bind(&LLEventPump::post, boost::ref(filter1), _1));
- listener0.listenTo(filter0);
- listener1.listenTo(filter1);
- listener0.reset(0);
- listener1.reset(0);
- upstream.post(1);
- check_listener("got unfiltered", listener0, 1);
- check_listener("got unfiltered", listener1, 1);
- filter0.enable(false);
- upstream.post(2);
- check_listener("didn't get filtered", listener0, 1);
- check_listener("got filtered", listener1, 2);
+ set_test_name("chaining LLEventPump instances");
+ LLEventPump& upstream(pumps.obtain("upstream"));
+ // One potentially-useful construct is to chain LLEventPumps together.
+ // Among other things, this allows you to turn subsets of listeners on
+ // and off in groups.
+ LLEventPump& filter0(pumps.obtain("filter0"));
+ LLEventPump& filter1(pumps.obtain("filter1"));
+ upstream.listen(filter0.getName(), boost::bind(&LLEventPump::post, boost::ref(filter0), _1));
+ upstream.listen(filter1.getName(), boost::bind(&LLEventPump::post, boost::ref(filter1), _1));
+ listener0.listenTo(filter0);
+ listener1.listenTo(filter1);
+ listener0.reset(0);
+ listener1.reset(0);
+ upstream.post(1);
+ check_listener("got unfiltered", listener0, 1);
+ check_listener("got unfiltered", listener1, 1);
+ filter0.enable(false);
+ upstream.post(2);
+ check_listener("didn't get filtered", listener0, 1);
+ check_listener("got filtered", listener1, 2);
}
template<> template<>
void events_object::test<6>()
{
- set_test_name("listener dependency order");
- typedef LLEventPump::NameList NameList;
- LLEventPump& button(pumps.obtain("button"));
- Collect collector;
- button.listen("Mary",
- boost::bind(&Collect::add, boost::ref(collector), "Mary", _1),
- // state that "Mary" must come after "checked"
- make<NameList> (list_of("checked")));
- button.listen("checked",
- boost::bind(&Collect::add, boost::ref(collector), "checked", _1),
- // "checked" must come after "spot"
- make<NameList> (list_of("spot")));
- button.listen("spot",
- boost::bind(&Collect::add, boost::ref(collector), "spot", _1));
- button.post(1);
- ensure_equals(collector.result, make<StringVec>(list_of("spot")("checked")("Mary")));
- collector.clear();
- button.stopListening("Mary");
- button.listen("Mary",
- boost::bind(&Collect::add, boost::ref(collector), "Mary", _1),
- LLEventPump::empty, // no after dependencies
- // now "Mary" must come before "spot"
- make<NameList>(list_of("spot")));
- button.post(2);
- ensure_equals(collector.result, make<StringVec>(list_of("Mary")("spot")("checked")));
- collector.clear();
- button.stopListening("spot");
- std::string threw = catch_what<LLEventPump::Cycle>(
- [&button, &collector](){
- button.listen("spot",
- boost::bind(&Collect::add, boost::ref(collector), "spot", _1),
- // after "Mary" and "checked" -- whoops!
- make<NameList>(list_of("Mary")("checked")));
- });
- // Obviously the specific wording of the exception text can
- // change; go ahead and change the test to match.
- // Establish that it contains:
- // - the name and runtime type of the LLEventPump
- ensure_contains("LLEventPump type", threw, typeid(button).name());
- ensure_contains("LLEventPump name", threw, "'button'");
- // - the name of the new listener that caused the problem
- ensure_contains("new listener name", threw, "'spot'");
- // - a synopsis of the problematic dependencies.
- ensure_contains("cyclic dependencies", threw,
- "\"Mary\" -> before (\"spot\")");
- ensure_contains("cyclic dependencies", threw,
- "after (\"spot\") -> \"checked\"");
- ensure_contains("cyclic dependencies", threw,
- "after (\"Mary\", \"checked\") -> \"spot\"");
- button.listen("yellow",
- boost::bind(&Collect::add, boost::ref(collector), "yellow", _1),
- make<NameList>(list_of("checked")));
- button.listen("shoelaces",
- boost::bind(&Collect::add, boost::ref(collector), "shoelaces", _1),
- make<NameList>(list_of("checked")));
- button.post(3);
- ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces")));
- collector.clear();
- threw = catch_what<LLEventPump::OrderChange>(
- [&button, &collector](){
- button.listen("of",
- boost::bind(&Collect::add, boost::ref(collector), "of", _1),
- make<NameList>(list_of("shoelaces")),
- make<NameList>(list_of("yellow")));
- });
- // Same remarks about the specific wording of the exception. Just
- // ensure that it contains enough information to clarify the
- // problem and what must be done to resolve it.
- ensure_contains("LLEventPump type", threw, typeid(button).name());
- ensure_contains("LLEventPump name", threw, "'button'");
- ensure_contains("new listener name", threw, "'of'");
- ensure_contains("prev listener name", threw, "'yellow'");
- // std::cout << "Thrown Exception: " << threw << std::endl;
- ensure_contains("old order", threw, "was: Mary, checked, yellow, shoelaces");
- ensure_contains("new order", threw, "now: Mary, checked, shoelaces, of, yellow");
- button.post(4);
- ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces")));
+ set_test_name("listener dependency order");
+ typedef LLEventPump::NameList NameList;
+ LLEventPump& button(pumps.obtain("button"));
+ Collect collector;
+ button.listen("Mary",
+ boost::bind(&Collect::add, boost::ref(collector), "Mary", _1),
+ // state that "Mary" must come after "checked"
+ make<NameList> (list_of("checked")));
+ button.listen("checked",
+ boost::bind(&Collect::add, boost::ref(collector), "checked", _1),
+ // "checked" must come after "spot"
+ make<NameList> (list_of("spot")));
+ button.listen("spot",
+ boost::bind(&Collect::add, boost::ref(collector), "spot", _1));
+ button.post(1);
+ ensure_equals(collector.result, make<StringVec>(list_of("spot")("checked")("Mary")));
+ collector.clear();
+ button.stopListening("Mary");
+ button.listen("Mary",
+ boost::bind(&Collect::add, boost::ref(collector), "Mary", _1),
+ LLEventPump::empty, // no after dependencies
+ // now "Mary" must come before "spot"
+ make<NameList>(list_of("spot")));
+ button.post(2);
+ ensure_equals(collector.result, make<StringVec>(list_of("Mary")("spot")("checked")));
+ collector.clear();
+ button.stopListening("spot");
+ std::string threw = catch_what<LLEventPump::Cycle>(
+ [&button, &collector](){
+ button.listen("spot",
+ boost::bind(&Collect::add, boost::ref(collector), "spot", _1),
+ // after "Mary" and "checked" -- whoops!
+ make<NameList>(list_of("Mary")("checked")));
+ });
+ // Obviously the specific wording of the exception text can
+ // change; go ahead and change the test to match.
+ // Establish that it contains:
+ // - the name and runtime type of the LLEventPump
+ ensure_contains("LLEventPump type", threw, typeid(button).name());
+ ensure_contains("LLEventPump name", threw, "'button'");
+ // - the name of the new listener that caused the problem
+ ensure_contains("new listener name", threw, "'spot'");
+ // - a synopsis of the problematic dependencies.
+ ensure_contains("cyclic dependencies", threw,
+ "\"Mary\" -> before (\"spot\")");
+ ensure_contains("cyclic dependencies", threw,
+ "after (\"spot\") -> \"checked\"");
+ ensure_contains("cyclic dependencies", threw,
+ "after (\"Mary\", \"checked\") -> \"spot\"");
+ button.listen("yellow",
+ boost::bind(&Collect::add, boost::ref(collector), "yellow", _1),
+ make<NameList>(list_of("checked")));
+ button.listen("shoelaces",
+ boost::bind(&Collect::add, boost::ref(collector), "shoelaces", _1),
+ make<NameList>(list_of("checked")));
+ button.post(3);
+ ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces")));
+ collector.clear();
+ threw = catch_what<LLEventPump::OrderChange>(
+ [&button, &collector](){
+ button.listen("of",
+ boost::bind(&Collect::add, boost::ref(collector), "of", _1),
+ make<NameList>(list_of("shoelaces")),
+ make<NameList>(list_of("yellow")));
+ });
+ // Same remarks about the specific wording of the exception. Just
+ // ensure that it contains enough information to clarify the
+ // problem and what must be done to resolve it.
+ ensure_contains("LLEventPump type", threw, typeid(button).name());
+ ensure_contains("LLEventPump name", threw, "'button'");
+ ensure_contains("new listener name", threw, "'of'");
+ ensure_contains("prev listener name", threw, "'yellow'");
+ // std::cout << "Thrown Exception: " << threw << std::endl;
+ ensure_contains("old order", threw, "was: Mary, checked, yellow, shoelaces");
+ ensure_contains("new order", threw, "now: Mary, checked, shoelaces, of, yellow");
+ button.post(4);
+ ensure_equals(collector.result, make<StringVec>(list_of("Mary")("checked")("yellow")("shoelaces")));
}
template<> template<>
void events_object::test<7>()
{
- set_test_name("tweaked and untweaked LLEventPump instance names");
- { // nested scope
- // Hand-instantiate an LLEventStream...
- LLEventStream bob("bob");
- std::string threw = catch_what<LLEventPump::DupPumpName>(
- [](){
- // then another with a duplicate name.
- LLEventStream bob2("bob");
- });
- ensure("Caught DupPumpName", !threw.empty());
- } // delete first 'bob'
- LLEventStream bob("bob"); // should work, previous one unregistered
- LLEventStream bob1("bob", true);// allowed to tweak name
- ensure_equals("tweaked LLEventStream name", bob1.getName(), "bob1");
- std::vector<std::shared_ptr<LLEventStream> > streams;
- for (int i = 2; i <= 10; ++i)
- {
- streams.push_back(std::shared_ptr<LLEventStream>(new LLEventStream("bob", true)));
- }
- ensure_equals("last tweaked LLEventStream name", streams.back()->getName(), "bob10");
+ set_test_name("tweaked and untweaked LLEventPump instance names");
+ { // nested scope
+ // Hand-instantiate an LLEventStream...
+ LLEventStream bob("bob");
+ std::string threw = catch_what<LLEventPump::DupPumpName>(
+ [](){
+ // then another with a duplicate name.
+ LLEventStream bob2("bob");
+ });
+ ensure("Caught DupPumpName", !threw.empty());
+ } // delete first 'bob'
+ LLEventStream bob("bob"); // should work, previous one unregistered
+ LLEventStream bob1("bob", true);// allowed to tweak name
+ ensure_equals("tweaked LLEventStream name", bob1.getName(), "bob1");
+ std::vector<std::shared_ptr<LLEventStream> > streams;
+ for (int i = 2; i <= 10; ++i)
+ {
+ streams.push_back(std::shared_ptr<LLEventStream>(new LLEventStream("bob", true)));
+ }
+ ensure_equals("last tweaked LLEventStream name", streams.back()->getName(), "bob10");
}
// Define a function that accepts an LLListenerOrPumpName
void eventSource(const LLListenerOrPumpName& listener)
{
- // Pretend that some time has elapsed. Call listener immediately.
- listener(17);
+ // Pretend that some time has elapsed. Call listener immediately.
+ listener(17);
}
template<> template<>
void events_object::test<8>()
{
- set_test_name("LLListenerOrPumpName");
- // Passing a boost::bind() expression to LLListenerOrPumpName
- listener0.reset(0);
- eventSource(boost::bind(&Listener::call, boost::ref(listener0), _1));
- check_listener("got by listener", listener0, 17);
- // Passing a string LLEventPump name to LLListenerOrPumpName
- listener0.reset(0);
- LLEventStream random("random");
- listener0.listenTo(random);
- eventSource("random");
- check_listener("got by pump name", listener0, 17);
- std::string threw = catch_what<LLListenerOrPumpName::Empty>(
- [](){
- LLListenerOrPumpName empty;
- empty(17);
- });
+ set_test_name("LLListenerOrPumpName");
+ // Passing a boost::bind() expression to LLListenerOrPumpName
+ listener0.reset(0);
+ eventSource(boost::bind(&Listener::call, boost::ref(listener0), _1));
+ check_listener("got by listener", listener0, 17);
+ // Passing a string LLEventPump name to LLListenerOrPumpName
+ listener0.reset(0);
+ LLEventStream random("random");
+ listener0.listenTo(random);
+ eventSource("random");
+ check_listener("got by pump name", listener0, 17);
+ std::string threw = catch_what<LLListenerOrPumpName::Empty>(
+ [](){
+ LLListenerOrPumpName empty;
+ empty(17);
+ });
- ensure("threw Empty", !threw.empty());
+ ensure("threw Empty", !threw.empty());
}
class TempListener: public Listener
{
public:
- TempListener(const std::string& name, bool& liveFlag) :
- Listener(name), mLiveFlag(liveFlag)
- {
- mLiveFlag = true;
- }
+ TempListener(const std::string& name, bool& liveFlag) :
+ Listener(name), mLiveFlag(liveFlag)
+ {
+ mLiveFlag = true;
+ }
- virtual ~TempListener()
- {
- mLiveFlag = false;
- }
+ virtual ~TempListener()
+ {
+ mLiveFlag = false;
+ }
private:
- bool& mLiveFlag;
+ bool& mLiveFlag;
};
template<> template<>
void events_object::test<9>()
{
- set_test_name("listen(boost::bind(...TempListener...))");
- // listen() can't do anything about a plain TempListener instance:
- // it's not managed with shared_ptr, nor is it an LLEventTrackable subclass
- bool live = false;
- LLEventPump& heaptest(pumps.obtain("heaptest"));
- LLBoundListener connection;
- {
- TempListener tempListener("temp", live);
- ensure("TempListener constructed", live);
- connection = heaptest.listen(tempListener.getName(),
- boost::bind(&Listener::call,
- boost::ref(tempListener),
- _1));
- heaptest.post(1);
- check_listener("received", tempListener, 1);
- } // presumably this will make newListener go away?
- // verify that
- ensure("TempListener destroyed", !live);
- // This is the case against which we can't defend. Don't even try to
- // post to heaptest -- that would engage Undefined Behavior.
- // Cautiously inspect connection...
- ensure("misleadingly connected", connection.connected());
- // then disconnect by hand.
- heaptest.stopListening("temp");
+ set_test_name("listen(boost::bind(...TempListener...))");
+ // listen() can't do anything about a plain TempListener instance:
+ // it's not managed with shared_ptr, nor is it an LLEventTrackable subclass
+ bool live = false;
+ LLEventPump& heaptest(pumps.obtain("heaptest"));
+ LLBoundListener connection;
+ {
+ TempListener tempListener("temp", live);
+ ensure("TempListener constructed", live);
+ connection = heaptest.listen(tempListener.getName(),
+ boost::bind(&Listener::call,
+ boost::ref(tempListener),
+ _1));
+ heaptest.post(1);
+ check_listener("received", tempListener, 1);
+ } // presumably this will make newListener go away?
+ // verify that
+ ensure("TempListener destroyed", !live);
+ // This is the case against which we can't defend. Don't even try to
+ // post to heaptest -- that would engage Undefined Behavior.
+ // Cautiously inspect connection...
+ ensure("misleadingly connected", connection.connected());
+ // then disconnect by hand.
+ heaptest.stopListening("temp");
}
class TempTrackableListener: public TempListener, public LLEventTrackable