From: Ron F. <ro...@us...> - 2007-05-01 15:41:16
|
Update of /cvsroot/nsclspectcl/SpecTcl/Sorter In directory sc8-pr-cvs16:/tmp/cvs-serv8546/Sorter Modified Files: Dictionary.h Makefile.am Added Files: Asserts.h TestDictObservers.cpp TestRunner.cpp Log Message: Added tests for dictionary observers --- NEW FILE: TestDictObservers.cpp --- // Template for a test suite. #include <config.h> #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" #include <string> #include "Dictionary.h" using namespace std; static int counter = 0; static int addItem(-1); static int removeItem(-1); static string addName; static string removeName; class MyObserver : public DictionaryObserver<int> { virtual void onAdd(const STD(string)& name, const int& item) { counter++; addItem = item; addName = name; } virtual void onRemove(const STD(string)& name, const int& item) { counter--; removeItem = item; removeName = name; } }; class TestDictObserver : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestDictObserver); // // Tests of the observer manager: // CPPUNIT_TEST(testEmptyManager); CPPUNIT_TEST(testManagerWith1); CPPUNIT_TEST(testRemove); CPPUNIT_TEST(testABunch); CPPUNIT_TEST(testParams); // // Full tests of the dictionary. // CPPUNIT_TEST(testDictionaryNoObs); CPPUNIT_TEST(testDictionaryWithObs); CPPUNIT_TEST_SUITE_END(); private: public: void setUp() { counter = 0; addItem = -1; removeItem = -1; addName = ""; removeName = ""; } void tearDown() { } protected: void testEmptyManager(); void testManagerWith1(); void testRemove(); void testABunch(); void testParams(); void testDictionaryNoObs(); void testDictionaryWithObs(); }; CPPUNIT_TEST_SUITE_REGISTRATION(TestDictObserver); void TestDictObserver::testEmptyManager() { CDictionaryObserverManager<int> manager; string name("a"); int i(0); manager.invokeAdd(name, i); EQMSG("Invoke add on empty manager", 0, counter); manager.invokeRemove(name, i); EQMSG("Invoke remove on empty manager", 0, counter); } void TestDictObserver::testManagerWith1() { CDictionaryObserverManager<int> manager; MyObserver observer; string name("a"); int i(0); manager.addObserver(&observer); manager.invokeAdd(name, i); EQMSG("Add with one observer", 1, counter); manager.invokeRemove(name, i); EQMSG("Remove with one observer", 0, counter); } void TestDictObserver::testRemove() { CDictionaryObserverManager<int> manager; MyObserver observer; string name("a"); int i(0); manager.addObserver(&observer); manager.invokeAdd(name, i); EQMSG("Add with one observer (before remove)", 1, counter); manager.removeObserver(&observer); manager.invokeRemove(name, i); EQMSG("Remove after observers removed", 1, counter); manager.invokeAdd(name, i); EQMSG("Add after observers removed", 1, counter); } void TestDictObserver::testABunch() { CDictionaryObserverManager<int> manager; MyObserver obs1, obs2, obs3; string name("a"); int i(0); manager.addObserver(&obs1); manager.addObserver(&obs2); manager.addObserver(&obs3); manager.invokeAdd(name, i); EQMSG("Add with 3 observers: ", 3, counter); manager.removeObserver(&obs2); manager.invokeRemove(name, i); EQMSG("Remove with 2 observers: ", 1, counter); } void TestDictObserver::testParams() { CDictionaryObserverManager<int> manager; string name("a"); int i(123); MyObserver obs; manager.addObserver(&obs); manager.invokeAdd(name, i); manager.invokeRemove(name, i); EQMSG("addItem", i, addItem); EQMSG("addName", name, addName); EQMSG("removeItem", i , removeItem); EQMSG("removeName", name, removeName); } void TestDictObserver::testDictionaryNoObs() { CDictionary<int> dict; string key("a"); int item(0); dict.Enter(key, item); EQMSG("add no observers", 0, counter); dict.Remove(key); EQMSG("remove no observers", 0, counter); } void TestDictObserver::testDictionaryWithObs() { CDictionary<int> dict; MyObserver obs; string key("a"); int item(1234); dict.addObserver(&obs); dict.Enter(key, item); EQMSG("add with obs", 1, counter); EQMSG("AddItem", item, addItem); EQMSG("addName", key, addName); dict.Remove(key); EQMSG("remove with obs", 0, counter); EQMSG("removeItem", item, removeItem); EQMSG("removeName", key, removeName); } Index: Makefile.am =================================================================== RCS file: /cvsroot/nsclspectcl/SpecTcl/Sorter/Makefile.am,v retrieving revision 5.10 retrieving revision 5.11 diff -C2 -d -r5.10 -r5.11 *** Makefile.am 23 Feb 2007 20:38:18 -0000 5.10 --- Makefile.am 1 May 2007 15:41:13 -0000 5.11 *************** *** 1,6 **** INCLUDES = -I. -I../Utility -I../NSCLException -I../Xamine -I../Gates \ -I../Events -I../Display @TCL_FLAGS@ -I.. -I@top_srcdir@/Fits ! LDADD = -lSorting -lXplus -lGates -lAnalysis -lEventSource -ltclPlus \ ! -lException -lXamine -lXt -lX11 # AM_LDFLAGS = -L. @TCL_LDFLAGS@ @XTLIBSW@ @XLIBSW@ --- 1,12 ---- INCLUDES = -I. -I../Utility -I../NSCLException -I../Xamine -I../Gates \ -I../Events -I../Display @TCL_FLAGS@ -I.. -I@top_srcdir@/Fits ! libSorting_la_LIBADD = @top_srcdir@/Xamine/libXplus.la \ ! @top_srcdir@/Gates/libGates.la \ ! @top_srcdir@/Events/libAnalysis.la \ ! @top_srcdir@/EventSource/libEventSource.la \ ! @top_srcdir@/TCL/libtclPlus.la \ ! @top_srcdir@/NSCLException/libException.la \ ! @top_srcdir@/Display/libXamine.la ! # AM_LDFLAGS = -L. @TCL_LDFLAGS@ @XTLIBSW@ @XLIBSW@ *************** *** 34,35 **** --- 40,57 ---- EXTRA_DIST = Sorter.WC Sorter.omt + + + if CPPUNIT + noinst_PROGRAMS=TestRunner + + TestRunner_SOURCES=TestRunner.cpp TestDictObservers.cpp + + TestRunner_CXXFLAGS=$(CPPUNIT_INCLUDES) + + TestRunner_LDADD = $(CPPUNIT_LDFLAGS) + + noinst_HEADERS = Asserts.h + + TESTS=./TestRunner + + endif \ No newline at end of file --- NEW FILE: TestRunner.cpp --- #include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/ui/text/TestRunner.h> #include <string> #include <iostream> using namespace std; int main(int argc, char** argv) { CppUnit::TextUi::TestRunner runner; // Control tests. CppUnit::TestFactoryRegistry& registry(CppUnit::TestFactoryRegistry::getRegistry()); runner.addTest(registry.makeTest()); bool wasSucessful; try { wasSucessful = runner.run("",false); } catch(string& rFailure) { cerr << "Caught a string exception from test suites.: \n"; cerr << rFailure << endl; wasSucessful = false; } return !wasSucessful; } --- NEW FILE: Asserts.h --- #ifndef __ASSERTS_H #define __ASSERTS_H #include <iostream> #include <string> // Abbreviations for assertions in cppunit. #define EQMSG(msg, a, b) CPPUNIT_ASSERT_EQUAL_MESSAGE(msg,a,b) #define EQ(a,b) CPPUNIT_ASSERT_EQUAL(a,b) #define ASSERT(expr) CPPUNIT_ASSERT(expr) #define FAIL(msg) CPPUNIT_FAIL(msg) // Macro to test for exceptions: #define EXCEPTION(operation, type) \ { \ bool ok = false; \ try { \ operation; \ } \ catch (type e) { \ ok = true; \ } \ ASSERT(ok); \ } class Warning { public: Warning(std::string message) { std::cerr << message << std::endl; } }; #endif Index: Dictionary.h =================================================================== RCS file: /cvsroot/nsclspectcl/SpecTcl/Sorter/Dictionary.h,v retrieving revision 5.2 retrieving revision 5.3 diff -C2 -d -r5.2 -r5.3 *** Dictionary.h 3 Jun 2005 15:19:22 -0000 5.2 --- Dictionary.h 1 May 2007 15:41:13 -0000 5.3 *************** *** 1,282 **** - /* - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your - freedom to share and change it. By contrast, the GNU General Public - License is intended to guarantee your freedom to share and change free - software--to make sure the software is free for all its users. This - General Public License applies to most of the Free Software - Foundation's software and to any other program whose authors commit to - using it. (Some other Free Software Foundation software is covered by - the GNU Library General Public License instead.) You can apply it to - your programs, too. - - When we speak of free software, we are referring to freedom, not - price. Our General Public Licenses are designed to make sure that you - have the freedom to distribute copies of free software (and charge for - this service if you wish), that you receive source code or can get it - if you want it, that you can change the software or use pieces of it - in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid - anyone to deny you these rights or to ask you to surrender the rights. - These restrictions translate to certain responsibilities for you if you - distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether - gratis or for a fee, you must give the recipients all the rights that - you have. You must make sure that they, too, receive or can get the - source code. And you must show them these terms so they know their - rights. - - We protect your rights with two steps: (1) copyright the software, and - (2) offer you this license which gives you legal permission to copy, - distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain - that everyone understands that there is no warranty for this free - software. If the software is modified by someone else and passed on, we - want its recipients to know that what they have is not the original, so - that any problems introduced by others will not reflect on the original - authors' reputations. - - Finally, any free program is threatened constantly by software - patents. We wish to avoid the danger that redistributors of a free - program will individually obtain patent licenses, in effect making the - program proprietary. To prevent this, we have made it clear that any - patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and - modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains - a notice placed by the copyright holder saying it may be distributed - under the terms of this General Public License. The "Program", below, - refers to any such program or work, and a "work based on the Program" - means either the Program or any derivative work under copyright law: - that is to say, a work containing the Program or a portion of it, - either verbatim or with modifications and/or translated into another - language. (Hereinafter, translation is included without limitation in - the term "modification".) Each licensee is addressed as "you". - - Activities other than copying, distribution and modification are not - covered by this License; they are outside its scope. The act of - running the Program is not restricted, and the output from the Program - is covered only if its contents constitute a work based on the - Program (independent of having been made by running the Program). - Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's - source code as you receive it, in any medium, provided that you - conspicuously and appropriately publish on each copy an appropriate - copyright notice and disclaimer of warranty; keep intact all the - notices that refer to this License and to the absence of any warranty; - and give any other recipients of the Program a copy of this License - along with the Program. - - You may charge a fee for the physical act of transferring a copy, and - you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion - of it, thus forming a work based on the Program, and copy and - distribute such modifications or work under the terms of Section 1 - above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - - These requirements apply to the modified work as a whole. If - identifiable sections of that work are not derived from the Program, - and can be reasonably considered independent and separate works in - themselves, then this License, and its terms, do not apply to those - sections when you distribute them as separate works. But when you - distribute the same sections as part of a whole which is a work based - on the Program, the distribution of the whole must be on the terms of - this License, whose permissions for other licensees extend to the - entire whole, and thus to each and every part regardless of who wrote it. - - Thus, it is not the intent of this section to claim rights or contest - your rights to work written entirely by you; rather, the intent is to - exercise the right to control the distribution of derivative or - collective works based on the Program. - - In addition, mere aggregation of another work not based on the Program - with the Program (or with a work based on the Program) on a volume of - a storage or distribution medium does not bring the other work under - the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, - under Section 2) in object code or executable form under the terms of - Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - - The source code for a work means the preferred form of the work for - making modifications to it. For an executable work, complete source - code means all the source code for all modules it contains, plus any - associated interface definition files, plus the scripts used to - control compilation and installation of the executable. However, as a - special exception, the source code distributed need not include - anything that is normally distributed (in either source or binary - form) with the major components (compiler, kernel, and so on) of the - operating system on which the executable runs, unless that component - itself accompanies the executable. - - If distribution of executable or object code is made by offering - access to copy from a designated place, then offering equivalent - access to copy the source code from the same place counts as - distribution of the source code, even though third parties are not - compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program - except as expressly provided under this License. Any attempt - otherwise to copy, modify, sublicense or distribute the Program is - void, and will automatically terminate your rights under this License. - However, parties who have received copies, or rights, from you under - this License will not have their licenses terminated so long as such - parties remain in full compliance. - - 5. You are not required to accept this License, since you have not - signed it. However, nothing else grants you permission to modify or - distribute the Program or its derivative works. These actions are - prohibited by law if you do not accept this License. Therefore, by - modifying or distributing the Program (or any work based on the - Program), you indicate your acceptance of this License to do so, and - all its terms and conditions for copying, distributing or modifying - the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the - Program), the recipient automatically receives a license from the - original licensor to copy, distribute or modify the Program subject to - these terms and conditions. You may not impose any further - restrictions on the recipients' exercise of the rights granted herein. - You are not responsible for enforcing compliance by third parties to - this License. - - 7. If, as a consequence of a court judgment or allegation of patent - infringement or for any other reason (not limited to patent issues), - conditions are imposed on you (whether by court order, agreement or - otherwise) that contradict the conditions of this License, they do not - excuse you from the conditions of this License. If you cannot - distribute so as to satisfy simultaneously your obligations under this - License and any other pertinent obligations, then as a consequence you - may not distribute the Program at all. For example, if a patent - license would not permit royalty-free redistribution of the Program by - all those who receive copies directly or indirectly through you, then - the only way you could satisfy both it and this License would be to - refrain entirely from distribution of the Program. - - If any portion of this section is held invalid or unenforceable under - any particular circumstance, the balance of the section is intended to - apply and the section as a whole is intended to apply in other - circumstances. - - It is not the purpose of this section to induce you to infringe any - patents or other property right claims or to contest validity of any - such claims; this section has the sole purpose of protecting the - integrity of the free software distribution system, which is - implemented by public license practices. Many people have made - generous contributions to the wide range of software distributed - through that system in reliance on consistent application of that - system; it is up to the author/donor to decide if he or she is willing - to distribute software through any other system and a licensee cannot - impose that choice. - - This section is intended to make thoroughly clear what is believed to - be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in - certain countries either by patents or by copyrighted interfaces, the - original copyright holder who places the Program under this License - may add an explicit geographical distribution limitation excluding - those countries, so that distribution is permitted only in or among - countries not thus excluded. In such case, this License incorporates - the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions of - the General Public License from time to time. Such new versions will be - similar in spirit to the present version, but may differ in detail to address - new problems or concerns. - - Each version is given a distinguishing version number. If the Program - specifies a version number of this License which applies to it and "any - later version", you have the option of following the terms and conditions - either of that version or of any later version published by the Free Software - Foundation. If the Program does not specify a version number of this License, - you may choose any version ever published by the Free Software Foundation. - - 10. If you wish to incorporate parts of the Program into other free - programs whose distribution conditions are different, write to the author to - ask for permission. For software which is copyrighted by the Free Software - Foundation, write to the Free Software Foundation; we sometimes make - exceptions for this. Our decision will be guided by the two goals of - preserving the free status of all derivatives of our free software and of - promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR - THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN - OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE - THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND - PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, - YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING - WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR - REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, - INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING - OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO - LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR - THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), - EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - DAMAGES. - - END OF TERMS AND CONDITIONS ' - */ // // CDictionary.h: --- 1,2 ---- *************** *** 305,308 **** --- 25,35 ---- #endif + #ifndef __STL_LIST + #include <list> + #ifndef __STL_LIST + #define __STL_LIST + #endif + #endif + #ifndef __STL_ALGORITHM #include <algorithm> *************** *** 324,331 **** --- 51,118 ---- #endif + // Template class for observers of dictionaries: + + template <class T> + class DictionaryObserver + { + public: + virtual void onAdd(const STD(string)& name, const T& item) {} + virtual void onRemove(const STD(string)& name, const T& item) {} + + }; + + // Template class for managing observer lists for Dictionaries. + // + // + template <class T> + class CDictionaryObserverManager + { + // Need to do a bit of dirty work in due to + // stl and C++'s template limitations: + + typedef STD(list)<void*> ObserverList; + typedef ObserverList::iterator ObserverIterator; + + ObserverList m_observers; + + public: + void addObserver(DictionaryObserver<T>* observer) { + m_observers.push_back(observer); + } + void removeObserver(DictionaryObserver<T>* observer) { + ObserverIterator i = m_observers.begin(); + while(i != m_observers.end()) { + if (*i == (void*)observer) { + m_observers.erase(i); + return; + } + i++; + } + } + void invokeAdd(const STD(string)& name, const T& item) { + ObserverIterator i = m_observers.begin(); + while (i != m_observers.end()) { + DictionaryObserver<T>* obs = static_cast<DictionaryObserver<T>*>(*i); + obs->onAdd(name, item); + i++; + } + } + void invokeRemove(const STD(string)& name, const T& item) { + ObserverIterator i = m_observers.begin(); + while (i != m_observers.end()) { + DictionaryObserver<T>* obs = static_cast<DictionaryObserver<T>*>(*i); + obs->onRemove(name, item); + i++; + } + } + + + }; + // Note this is a template class which maintains a dictionary of named // objects. Objects must have copy constructors, and assignment operators. // The dictionary provides a simplified adaptor interface to the STL MAP // container, as well as searching mechanisms. + // template <class T> class CDictionary *************** *** 337,340 **** --- 124,128 ---- private: Dictionary m_Map; + CDictionaryObserverManager<T> m_observers; public: *************** *** 370,373 **** --- 158,162 ---- void Enter(const STD(string)& sName, const T& Item) { m_Map[sName] = Item; + m_observers.invokeAdd(sName, Item); } *************** *** 375,378 **** --- 164,168 ---- DictionaryIterator i = m_Map.find(rsName); if(i != m_Map.end()) + m_observers.invokeRemove(rsName, i->second); m_Map.erase(i); // m_Map.erase(rsName); // Erase by name kills my g++ compiler!!! *************** *** 390,393 **** --- 180,189 ---- return m_Map.size(); } + void addObserver(DictionaryObserver<T>* observer) { + m_observers.addObserver(observer); + } + void removeObserver(DictionaryObserver<T>* observer) { + m_observers.removeObserver(observer); + } }; |