lleventfilter_test.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:12k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /**
  2.  * @file   lleventfilter_test.cpp
  3.  * @author Nat Goodspeed
  4.  * @date   2009-03-06
  5.  * @brief  Test for lleventfilter.
  6.  * 
  7.  * $LicenseInfo:firstyear=2009&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2009-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. // Precompiled header
  35. #include "linden_common.h"
  36. // associated header
  37. #include "lleventfilter.h"
  38. // STL headers
  39. // std headers
  40. // external library headers
  41. // other Linden headers
  42. #include "../test/lltut.h"
  43. #include "stringize.h"
  44. #include "listener.h"
  45. #include "tests/wrapllerrs.h"
  46. /*****************************************************************************
  47. *   Test classes
  48. *****************************************************************************/
  49. // Strictly speaking, we're testing LLEventTimeoutBase rather than the
  50. // production LLEventTimeout (using LLTimer) because we don't want every test
  51. // run to pause for some number of seconds until we reach a real timeout. But
  52. // as we've carefully put all functionality except actual LLTimer calls into
  53. // LLEventTimeoutBase, that should suffice. We're not not not trying to test
  54. // LLTimer here.
  55. class TestEventTimeout: public LLEventTimeoutBase
  56. {
  57. public:
  58.     TestEventTimeout():
  59.         mElapsed(true)
  60.     {}
  61.     TestEventTimeout(LLEventPump& source):
  62.         LLEventTimeoutBase(source),
  63.         mElapsed(true)
  64.     {}
  65.     // test hook
  66.     void forceTimeout(bool timeout=true) { mElapsed = timeout; }
  67. protected:
  68.     virtual void setCountdown(F32 seconds) { mElapsed = false; }
  69.     virtual bool countdownElapsed() const { return mElapsed; }
  70. private:
  71.     bool mElapsed;
  72. };
  73. /*****************************************************************************
  74. *   TUT
  75. *****************************************************************************/
  76. namespace tut
  77. {
  78.     struct filter_data
  79.     {
  80.         // The resemblance between this test data and that in llevents_tut.cpp
  81.         // is not coincidental.
  82.         filter_data():
  83.             pumps(LLEventPumps::instance()),
  84.             mainloop(pumps.obtain("mainloop")),
  85.             listener0("first"),
  86.             listener1("second")
  87.         {}
  88.         LLEventPumps& pumps;
  89.         LLEventPump& mainloop;
  90.         Listener listener0;
  91.         Listener listener1;
  92.         void check_listener(const std::string& desc, const Listener& listener, const LLSD& got)
  93.         {
  94.             ensure_equals(STRINGIZE(listener << ' ' << desc),
  95.                           listener.getLastEvent(), got);
  96.         }
  97.     };
  98.     typedef test_group<filter_data> filter_group;
  99.     typedef filter_group::object filter_object;
  100.     filter_group filtergrp("lleventfilter");
  101.     template<> template<>
  102.     void filter_object::test<1>()
  103.     {
  104.         set_test_name("LLEventMatching");
  105.         LLEventPump& driver(pumps.obtain("driver"));
  106.         listener0.reset(0);
  107.         // Listener isn't derived from LLEventTrackable specifically to test
  108.         // various connection-management mechanisms. But that means we have a
  109.         // couple of transient Listener objects, one of which is listening to
  110.         // a persistent LLEventPump. Capture those connections in local
  111.         // LLTempBoundListener instances so they'll disconnect
  112.         // on destruction.
  113.         LLTempBoundListener temp1(
  114.             listener0.listenTo(driver));
  115.         // Construct a pattern LLSD: desired Event must have a key "foo"
  116.         // containing string "bar"
  117.         LLEventMatching filter(driver, LLSD().insert("foo", "bar"));
  118.         listener1.reset(0);
  119.         LLTempBoundListener temp2(
  120.             listener1.listenTo(filter));
  121.         driver.post(1);
  122.         check_listener("direct", listener0, LLSD(1));
  123.         check_listener("filtered", listener1, LLSD(0));
  124.         // Okay, construct an LLSD map matching the pattern
  125.         LLSD data;
  126.         data["foo"] = "bar";
  127.         data["random"] = 17;
  128.         driver.post(data);
  129.         check_listener("direct", listener0, data);
  130.         check_listener("filtered", listener1, data);
  131.     }
  132.     template<> template<>
  133.     void filter_object::test<2>()
  134.     {
  135.         set_test_name("LLEventTimeout::actionAfter()");
  136.         LLEventPump& driver(pumps.obtain("driver"));
  137.         TestEventTimeout filter(driver);
  138.         listener0.reset(0);
  139.         LLTempBoundListener temp1(
  140.             listener0.listenTo(filter));
  141.         // Use listener1.call() as the Action for actionAfter(), since it
  142.         // already provides a way to sense the call
  143.         listener1.reset(0);
  144.         // driver --> filter --> listener0
  145.         filter.actionAfter(20,
  146.                            boost::bind(&Listener::call, boost::ref(listener1), LLSD("timeout")));
  147.         // Okay, (fake) timer is ticking. 'filter' can only sense the timer
  148.         // when we pump mainloop. Do that right now to take the logic path
  149.         // before either the anticipated event arrives or the timer expires.
  150.         mainloop.post(17);
  151.         check_listener("no timeout 1", listener1, LLSD(0));
  152.         // Expected event arrives...
  153.         driver.post(1);
  154.         check_listener("event passed thru", listener0, LLSD(1));
  155.         // Should have canceled the timer. Verify that by asserting that the
  156.         // time has expired, then pumping mainloop again.
  157.         filter.forceTimeout();
  158.         mainloop.post(17);
  159.         check_listener("no timeout 2", listener1, LLSD(0));
  160.         // Verify chained actionAfter() calls, that is, that a second
  161.         // actionAfter() resets the timer established by the first
  162.         // actionAfter().
  163.         filter.actionAfter(20,
  164.                            boost::bind(&Listener::call, boost::ref(listener1), LLSD("timeout")));
  165.         // Since our TestEventTimeout class isn't actually manipulating time
  166.         // (quantities of seconds), only a bool "elapsed" flag, sense that by
  167.         // forcing the flag between actionAfter() calls.
  168.         filter.forceTimeout();
  169.         // Pumping mainloop here would result in a timeout (as we'll verify
  170.         // below). This state simulates a ticking timer that has not yet timed
  171.         // out. But now, before a mainloop event lets 'filter' recognize
  172.         // timeout on the previous actionAfter() call, pretend we're pushing
  173.         // that timeout farther into the future.
  174.         filter.actionAfter(20,
  175.                            boost::bind(&Listener::call, boost::ref(listener1), LLSD("timeout")));
  176.         // Look ma, no timeout!
  177.         mainloop.post(17);
  178.         check_listener("no timeout 3", listener1, LLSD(0));
  179.         // Now let the updated actionAfter() timer expire.
  180.         filter.forceTimeout();
  181.         // Notice the timeout.
  182.         mainloop.post(17);
  183.         check_listener("timeout", listener1, LLSD("timeout"));
  184.         // Timing out cancels the timer. Verify that.
  185.         listener1.reset(0);
  186.         filter.forceTimeout();
  187.         mainloop.post(17);
  188.         check_listener("no timeout 4", listener1, LLSD(0));
  189.         // Reset the timer and then cancel() it.
  190.         filter.actionAfter(20,
  191.                            boost::bind(&Listener::call, boost::ref(listener1), LLSD("timeout")));
  192.         // neither expired nor satisified
  193.         mainloop.post(17);
  194.         check_listener("no timeout 5", listener1, LLSD(0));
  195.         // cancel
  196.         filter.cancel();
  197.         // timeout!
  198.         filter.forceTimeout();
  199.         mainloop.post(17);
  200.         check_listener("no timeout 6", listener1, LLSD(0));
  201.     }
  202.     template<> template<>
  203.     void filter_object::test<3>()
  204.     {
  205.         set_test_name("LLEventTimeout::eventAfter()");
  206.         LLEventPump& driver(pumps.obtain("driver"));
  207.         TestEventTimeout filter(driver);
  208.         listener0.reset(0);
  209.         LLTempBoundListener temp1(
  210.             listener0.listenTo(filter));
  211.         filter.eventAfter(20, LLSD("timeout"));
  212.         // Okay, (fake) timer is ticking. 'filter' can only sense the timer
  213.         // when we pump mainloop. Do that right now to take the logic path
  214.         // before either the anticipated event arrives or the timer expires.
  215.         mainloop.post(17);
  216.         check_listener("no timeout 1", listener0, LLSD(0));
  217.         // Expected event arrives...
  218.         driver.post(1);
  219.         check_listener("event passed thru", listener0, LLSD(1));
  220.         // Should have canceled the timer. Verify that by asserting that the
  221.         // time has expired, then pumping mainloop again.
  222.         filter.forceTimeout();
  223.         mainloop.post(17);
  224.         check_listener("no timeout 2", listener0, LLSD(1));
  225.         // Set timer again.
  226.         filter.eventAfter(20, LLSD("timeout"));
  227.         // Now let the timer expire.
  228.         filter.forceTimeout();
  229.         // Notice the timeout.
  230.         mainloop.post(17);
  231.         check_listener("timeout", listener0, LLSD("timeout"));
  232.         // Timing out cancels the timer. Verify that.
  233.         listener0.reset(0);
  234.         filter.forceTimeout();
  235.         mainloop.post(17);
  236.         check_listener("no timeout 3", listener0, LLSD(0));
  237.     }
  238.     template<> template<>
  239.     void filter_object::test<4>()
  240.     {
  241.         set_test_name("LLEventTimeout::errorAfter()");
  242.         WrapLL_ERRS capture;
  243.         LLEventPump& driver(pumps.obtain("driver"));
  244.         TestEventTimeout filter(driver);
  245.         listener0.reset(0);
  246.         LLTempBoundListener temp1(
  247.             listener0.listenTo(filter));
  248.         filter.errorAfter(20, "timeout");
  249.         // Okay, (fake) timer is ticking. 'filter' can only sense the timer
  250.         // when we pump mainloop. Do that right now to take the logic path
  251.         // before either the anticipated event arrives or the timer expires.
  252.         mainloop.post(17);
  253.         check_listener("no timeout 1", listener0, LLSD(0));
  254.         // Expected event arrives...
  255.         driver.post(1);
  256.         check_listener("event passed thru", listener0, LLSD(1));
  257.         // Should have canceled the timer. Verify that by asserting that the
  258.         // time has expired, then pumping mainloop again.
  259.         filter.forceTimeout();
  260.         mainloop.post(17);
  261.         check_listener("no timeout 2", listener0, LLSD(1));
  262.         // Set timer again.
  263.         filter.errorAfter(20, "timeout");
  264.         // Now let the timer expire.
  265.         filter.forceTimeout();
  266.         // Notice the timeout.
  267.         std::string threw;
  268.         try
  269.         {
  270.             mainloop.post(17);
  271.         }
  272.         catch (const WrapLL_ERRS::FatalException& e)
  273.         {
  274.             threw = e.what();
  275.         }
  276.         ensure_contains("errorAfter() timeout exception", threw, "timeout");
  277.         // Timing out cancels the timer. Verify that.
  278.         listener0.reset(0);
  279.         filter.forceTimeout();
  280.         mainloop.post(17);
  281.         check_listener("no timeout 3", listener0, LLSD(0));
  282.     }
  283. } // namespace tut
  284. /*****************************************************************************
  285. *   Link dependencies
  286. *****************************************************************************/
  287. #include "llsdutil.cpp"