summaryrefslogtreecommitdiff
path: root/indra/test
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2009-05-11 20:05:46 +0000
committerNat Goodspeed <nat@lindenlab.com>2009-05-11 20:05:46 +0000
commitdc934629919bdcaea72c78e5291263914fb958ec (patch)
tree0ac81213f607d9a3a133481758fa2274fe986aa3 /indra/test
parent3800c0df910c83e987184d541b868168fc2b5bec (diff)
svn merge -r113003:119136 svn+ssh://svn.lindenlab.com/svn/linden/branches/login-api/login-api-2 svn+ssh://svn.lindenlab.com/svn/linden/branches/login-api/login-api-3
Diffstat (limited to 'indra/test')
-rw-r--r--indra/test/llevents_tut.cpp133
-rw-r--r--indra/test/llsdutil_tut.cpp180
-rw-r--r--indra/test/lltut.cpp12
-rw-r--r--indra/test/lltut.h3
-rw-r--r--indra/test/test.cpp19
5 files changed, 217 insertions, 130 deletions
diff --git a/indra/test/llevents_tut.cpp b/indra/test/llevents_tut.cpp
index e401f89b22..31130c3c79 100644
--- a/indra/test/llevents_tut.cpp
+++ b/indra/test/llevents_tut.cpp
@@ -32,96 +32,10 @@
// other Linden headers
#include "lltut.h"
#include "stringize.h"
+#include "tests/listener.h"
using boost::assign::list_of;
-/*****************************************************************************
-* test listener class
-*****************************************************************************/
-class Listener;
-std::ostream& operator<<(std::ostream&, const Listener&);
-
-class Listener
-{
-public:
- Listener(const std::string& name):
- mName(name)
- {
-// std::cout << *this << ": ctor\n";
- }
- Listener(const Listener& that):
- mName(that.mName),
- mLastEvent(that.mLastEvent)
- {
-// std::cout << *this << ": copy\n";
- }
- virtual ~Listener()
- {
-// std::cout << *this << ": dtor\n";
- }
- std::string getName() const { return mName; }
- bool call(const LLSD& event)
- {
-// std::cout << *this << "::call(" << event << ")\n";
- mLastEvent = event;
- return false;
- }
- bool callstop(const LLSD& event)
- {
-// std::cout << *this << "::callstop(" << event << ")\n";
- mLastEvent = event;
- return true;
- }
- LLSD getLastEvent() const
- {
-// std::cout << *this << "::getLastEvent() -> " << mLastEvent << "\n";
- return mLastEvent;
- }
- void reset(const LLSD& to = LLSD())
- {
-// std::cout << *this << "::reset(" << to << ")\n";
- mLastEvent = to;
- }
-
-private:
- std::string mName;
- LLSD mLastEvent;
-};
-
-std::ostream& operator<<(std::ostream& out, const Listener& listener)
-{
- out << "Listener(" << listener.getName() /* << "@" << &listener */ << ')';
- return out;
-}
-
-struct Collect
-{
- bool add(const std::string& bound, const LLSD& event)
- {
- result.push_back(bound);
- return false;
- }
- void clear() { result.clear(); }
- typedef std::vector<std::string> StringList;
- StringList result;
-};
-
-std::ostream& operator<<(std::ostream& out, const Collect::StringList& strings)
-{
- out << '(';
- Collect::StringList::const_iterator begin(strings.begin()), end(strings.end());
- if (begin != end)
- {
- out << '"' << *begin << '"';
- while (++begin != end)
- {
- out << ", \"" << *begin << '"';
- }
- }
- out << ')';
- return out;
-}
-
template<typename T>
T make(const T& value) { return value; }
@@ -174,14 +88,7 @@ namespace tut
// 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);
- // 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.
- LLBoundListener connection = per_frame.listen(listener0.getName(),
- boost::bind(&Listener::call,
- boost::ref(listener0),
- _1));
+ LLBoundListener connection = listener0.listenTo(per_frame);
ensure("connected", connection.connected());
ensure("not blocked", ! connection.blocked());
per_frame.post(1);
@@ -207,6 +114,10 @@ namespace tut
bool threw = false;
try
{
+ // 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));
}
@@ -221,8 +132,7 @@ namespace tut
}
ensure("threw DupListenerName", threw);
// do it right this time
- per_frame.listen(listener1.getName(),
- boost::bind(&Listener::call, boost::ref(listener1), _1));
+ listener1.listenTo(per_frame);
per_frame.post(5);
check_listener("got", listener0, 5);
check_listener("got", listener1, 5);
@@ -252,16 +162,10 @@ namespace tut
LLEventPump& per_frame(pumps.obtain("per-frame"));
listener0.reset(0);
listener1.reset(0);
- LLBoundListener bound0 = per_frame.listen(listener0.getName(),
- boost::bind(&Listener::callstop,
- boost::ref(listener0),
- _1));
- LLBoundListener bound1 = per_frame.listen(listener1.getName(),
- boost::bind(&Listener::call,
- boost::ref(listener1),
- _1),
- // after listener0
- make<LLEventPump::NameList>(list_of(listener0.getName())));
+ 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());
@@ -301,7 +205,7 @@ namespace tut
// LLEventQueue.
LLEventPump& mainloop(pumps.obtain("mainloop"));
ensure("LLEventQueue leaf class", dynamic_cast<LLEventQueue*>(&login));
- login.listen(listener0.getName(), boost::bind(&Listener::call, boost::ref(listener0), _1));
+ listener0.listenTo(login);
listener0.reset(0);
login.post(1);
check_listener("waiting for queued event", listener0, 0);
@@ -354,11 +258,10 @@ namespace tut
{
set_test_name("stopListening()");
LLEventPump& login(pumps.obtain("login"));
- login.listen(listener0.getName(), boost::bind(&Listener::call, boost::ref(listener0), _1));
+ listener0.listenTo(login);
login.stopListening(listener0.getName());
// should not throw because stopListening() should have removed name
- login.listen(listener0.getName(),
- boost::bind(&Listener::callstop, boost::ref(listener0), _1));
+ listener0.listenTo(login, &Listener::callstop);
LLBoundListener wrong = login.getListener("bogus");
ensure("bogus connection disconnected", ! wrong.connected());
ensure("bogus connection blocked", wrong.blocked());
@@ -378,10 +281,8 @@ namespace tut
boost::bind(&LLEventPump::post, boost::ref(filter0), _1));
upstream.listen(filter1.getName(),
boost::bind(&LLEventPump::post, boost::ref(filter1), _1));
- filter0.listen(listener0.getName(),
- boost::bind(&Listener::call, boost::ref(listener0), _1));
- filter1.listen(listener1.getName(),
- boost::bind(&Listener::call, boost::ref(listener1), _1));
+ listener0.listenTo(filter0);
+ listener1.listenTo(filter1);
listener0.reset(0);
listener1.reset(0);
upstream.post(1);
@@ -536,7 +437,7 @@ namespace tut
// Passing a string LLEventPump name to LLListenerOrPumpName
listener0.reset(0);
LLEventStream random("random");
- random.listen(listener0.getName(), boost::bind(&Listener::call, boost::ref(listener0), _1));
+ listener0.listenTo(random);
eventSource("random");
check_listener("got by pump name", listener0, 17);
bool threw = false;
diff --git a/indra/test/llsdutil_tut.cpp b/indra/test/llsdutil_tut.cpp
index 0c4bbc2e62..093a29652c 100644
--- a/indra/test/llsdutil_tut.cpp
+++ b/indra/test/llsdutil_tut.cpp
@@ -44,12 +44,40 @@
#include "v4math.h"
#include "llquaternion.h"
#include "llsdutil.h"
-
+#include <set>
+#include <boost/range.hpp>
namespace tut
{
struct llsdutil_data
{
+ void test_matches(const std::string& proto_key, const LLSD& possibles,
+ const char** begin, const char** end)
+ {
+ std::set<std::string> succeed(begin, end);
+ LLSD prototype(possibles[proto_key]);
+ for (LLSD::map_const_iterator pi(possibles.beginMap()), pend(possibles.endMap());
+ pi != pend; ++pi)
+ {
+ std::string match(llsd_matches(prototype, pi->second));
+ std::set<std::string>::const_iterator found = succeed.find(pi->first);
+ if (found != succeed.end())
+ {
+ // This test is supposed to succeed. Comparing to the
+ // empty string ensures that if the test fails, it will
+ // display the string received so we can tell what failed.
+ ensure_equals("match", match, "");
+ }
+ else
+ {
+ // This test is supposed to fail. If we get a false match,
+ // the string 'match' will be empty, which doesn't tell us
+ // much about which case went awry. So construct a more
+ // detailed description string.
+ ensure(proto_key + " shouldn't match " + pi->first, ! match.empty());
+ }
+ }
+ }
};
typedef test_group<llsdutil_data> llsdutil_test;;
typedef llsdutil_test::object llsdutil_object;
@@ -159,4 +187,154 @@ namespace tut
LLSD sd1 = ll_sd_from_color4(c1);
ensure_equals("sd -> LLColor4 -> sd", sd, sd1);
}
+
+ template<> template<>
+ void llsdutil_object::test<9>()
+ {
+ set_test_name("llsd_matches");
+
+ // for this test, construct a map of all possible LLSD types
+ LLSD map;
+ map.insert("empty", LLSD());
+ map.insert("Boolean", LLSD::Boolean());
+ map.insert("Integer", LLSD::Integer(0));
+ map.insert("Real", LLSD::Real(0.0));
+ map.insert("String", LLSD::String("bah"));
+ map.insert("NumString", LLSD::String("1"));
+ map.insert("UUID", LLSD::UUID());
+ map.insert("Date", LLSD::Date());
+ map.insert("URI", LLSD::URI());
+ map.insert("Binary", LLSD::Binary());
+ map.insert("Map", LLSD().insert("foo", LLSD()));
+ // array can't be constructed on the fly
+ LLSD array;
+ array.append(LLSD());
+ map.insert("Array", array);
+
+ // These iterators are declared outside our various for loops to avoid
+ // fatal MSVC warning: "I used to be broken, but I'm all better now!"
+ LLSD::map_const_iterator mi(map.beginMap()), mend(map.endMap());
+
+ // empty prototype matches anything
+ for (mi = map.beginMap(); mi != mend; ++mi)
+ {
+ ensure_equals(std::string("empty matches ") + mi->first, llsd_matches(LLSD(), mi->second), "");
+ }
+
+ LLSD proto_array, data_array;
+ for (int i = 0; i < 3; ++i)
+ {
+ proto_array.append(LLSD());
+ data_array.append(LLSD());
+ }
+
+ // prototype array matches only array
+ for (mi = map.beginMap(); mi != mend; ++mi)
+ {
+ ensure(std::string("array doesn't match ") + mi->first,
+ ! llsd_matches(proto_array, mi->second).empty());
+ }
+
+ // data array must be at least as long as prototype array
+ proto_array.append(LLSD());
+ ensure_equals("data array too short", llsd_matches(proto_array, data_array),
+ "Array size 4 required instead of Array size 3");
+ data_array.append(LLSD());
+ ensure_equals("data array just right", llsd_matches(proto_array, data_array), "");
+ data_array.append(LLSD());
+ ensure_equals("data array longer", llsd_matches(proto_array, data_array), "");
+
+ // array element matching
+ data_array[0] = LLSD::String();
+ ensure_equals("undefined prototype array entry", llsd_matches(proto_array, data_array), "");
+ proto_array[0] = LLSD::Binary();
+ ensure_equals("scalar prototype array entry", llsd_matches(proto_array, data_array),
+ "[0]: Binary required instead of String");
+ data_array[0] = LLSD::Binary();
+ ensure_equals("matching prototype array entry", llsd_matches(proto_array, data_array), "");
+
+ // build a coupla maps
+ LLSD proto_map, data_map;
+ data_map["got"] = LLSD();
+ data_map["found"] = LLSD();
+ for (LLSD::map_const_iterator dmi(data_map.beginMap()), dmend(data_map.endMap());
+ dmi != dmend; ++dmi)
+ {
+ proto_map[dmi->first] = dmi->second;
+ }
+ proto_map["foo"] = LLSD();
+ proto_map["bar"] = LLSD();
+
+ // prototype map matches only map
+ for (mi = map.beginMap(); mi != mend; ++mi)
+ {
+ ensure(std::string("map doesn't match ") + mi->first,
+ ! llsd_matches(proto_map, mi->second).empty());
+ }
+
+ // data map must contain all keys in prototype map
+ std::string error(llsd_matches(proto_map, data_map));
+ ensure_contains("missing keys", error, "missing keys");
+ ensure_contains("missing foo", error, "foo");
+ ensure_contains("missing bar", error, "bar");
+ ensure_does_not_contain("found found", error, "found");
+ ensure_does_not_contain("got got", error, "got");
+ data_map["bar"] = LLSD();
+ error = llsd_matches(proto_map, data_map);
+ ensure_contains("missing foo", error, "foo");
+ ensure_does_not_contain("got bar", error, "bar");
+ data_map["foo"] = LLSD();
+ ensure_equals("data map just right", llsd_matches(proto_map, data_map), "");
+ data_map["extra"] = LLSD();
+ ensure_equals("data map with extra", llsd_matches(proto_map, data_map), "");
+
+ // map element matching
+ data_map["foo"] = LLSD::String();
+ ensure_equals("undefined prototype map entry", llsd_matches(proto_map, data_map), "");
+ proto_map["foo"] = LLSD::Binary();
+ ensure_equals("scalar prototype map entry", llsd_matches(proto_map, data_map),
+ "['foo']: Binary required instead of String");
+ data_map["foo"] = LLSD::Binary();
+ ensure_equals("matching prototype map entry", llsd_matches(proto_map, data_map), "");
+
+ // String
+ {
+ static const char* matches[] = { "String", "NumString", "Boolean", "Integer",
+ "Real", "UUID", "Date", "URI" };
+ test_matches("String", map, boost::begin(matches), boost::end(matches));
+ }
+
+ // Boolean, Integer, Real
+ static const char* numerics[] = { "Boolean", "Integer", "Real" };
+ for (const char **ni = boost::begin(numerics), **nend = boost::end(numerics);
+ ni != nend; ++ni)
+ {
+ static const char* matches[] = { "Boolean", "Integer", "Real", "String", "NumString" };
+ test_matches(*ni, map, boost::begin(matches), boost::end(matches));
+ }
+
+ // UUID
+ {
+ static const char* matches[] = { "UUID", "String", "NumString" };
+ test_matches("UUID", map, boost::begin(matches), boost::end(matches));
+ }
+
+ // Date
+ {
+ static const char* matches[] = { "Date", "String", "NumString" };
+ test_matches("Date", map, boost::begin(matches), boost::end(matches));
+ }
+
+ // URI
+ {
+ static const char* matches[] = { "URI", "String", "NumString" };
+ test_matches("URI", map, boost::begin(matches), boost::end(matches));
+ }
+
+ // Binary
+ {
+ static const char* matches[] = { "Binary" };
+ test_matches("Binary", map, boost::begin(matches), boost::end(matches));
+ }
+ }
}
diff --git a/indra/test/lltut.cpp b/indra/test/lltut.cpp
index 201e174f9c..e4e0de1ff1 100644
--- a/indra/test/lltut.cpp
+++ b/indra/test/lltut.cpp
@@ -76,9 +76,13 @@ namespace tut
void ensure_equals(const char* m, const LLSD& actual,
const LLSD& expected)
+ {
+ ensure_equals(std::string(m), actual, expected);
+ }
+
+ void ensure_equals(const std::string& msg, const LLSD& actual,
+ const LLSD& expected)
{
- const std::string& msg = m ? m : "";
-
ensure_equals(msg + " type", actual.type(), expected.type());
switch (actual.type())
{
@@ -128,7 +132,7 @@ namespace tut
{
ensure_equals(msg + " map keys",
actual_iter->first, expected_iter->first);
- ensure_equals((msg + "[" + actual_iter->first + "]").c_str(),
+ ensure_equals(msg + "[" + actual_iter->first + "]",
actual_iter->second, expected_iter->second);
++actual_iter;
++expected_iter;
@@ -141,7 +145,7 @@ namespace tut
for(int i = 0; i < actual.size(); ++i)
{
- ensure_equals((msg + llformat("[%d]", i)).c_str(),
+ ensure_equals(msg + llformat("[%d]", i),
actual[i], expected[i]);
}
return;
diff --git a/indra/test/lltut.h b/indra/test/lltut.h
index 47ea9d3f9e..ba3791cbd4 100644
--- a/indra/test/lltut.h
+++ b/indra/test/lltut.h
@@ -121,6 +121,9 @@ namespace tut
void ensure_equals(const char* msg,
const LLSD& actual, const LLSD& expected);
+
+ void ensure_equals(const std::string& msg,
+ const LLSD& actual, const LLSD& expected);
void ensure_starts_with(const std::string& msg,
const std::string& actual, const std::string& expectedStart);
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index ba81c6e49e..0ba5758e15 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -64,13 +64,14 @@ namespace tut
class LLTestCallback : public tut::callback
{
public:
- LLTestCallback(bool verbose_mode, std::ostream *stream) :
+ LLTestCallback(bool verbose_mode, std::ostream *stream, bool wait) :
mVerboseMode(verbose_mode),
mTotalTests(0),
mPassedTests(0),
mFailedTests(0),
mSkippedTests(0),
- mStream(stream)
+ mStream(stream),
+ mWaitAtExit(wait)
{
}
@@ -137,6 +138,11 @@ public:
}
run_completed_(std::cout);
+ if(mWaitAtExit) {
+ std::cerr << "Waiting for input before exiting..." << std::endl;
+ std::cin.get();
+ }
+
if (mFailedTests > 0)
{
exit(1);
@@ -176,6 +182,7 @@ protected:
int mFailedTests;
int mSkippedTests;
std::ostream *mStream;
+ bool mWaitAtExit;
};
static const apr_getopt_option_t TEST_CL_OPTIONS[] =
@@ -328,7 +335,7 @@ int main(int argc, char **argv)
}
// run the tests
- LLTestCallback callback(verbose_mode, output);
+ LLTestCallback callback(verbose_mode, output, wait_at_exit);
tut::runner.get().set_callback(&callback);
if(test_group.empty())
@@ -339,12 +346,6 @@ int main(int argc, char **argv)
{
tut::runner.get().run_tests(test_group);
}
-
- if (wait_at_exit)
- {
- std::cerr << "Waiting for input before exiting..." << std::endl;
- std::cin.get();
- }
if (output)
{