From: Ron F. <ro...@us...> - 2006-12-20 12:35:47
|
Update of /cvsroot/nsclspectcl/SpecTcl/contrib/calibratedparams In directory sc8-pr-cvs7.sourceforge.net:/tmp/cvs-serv16335 Modified Files: Tag: SpecTcl-3-0_developmentreally MySpecTclApp.cpp Added Files: Tag: SpecTcl-3-0_developmentreally Asserts.h CalibManagerTest.cpp CalibParamTest.cpp CommandTest.cpp CreatorTest.cpp FactoryTest.cpp FitTest.cpp TestRunner.cpp TestSuite.cpp all.tcl Log Message: Add tests to top level dir of calibparams contrib --- NEW FILE: TestSuite.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" class Testname : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(Testname); CPPUNIT_TEST(aTest); CPPUNIT_TEST_SUITE_END(); private: public: void setUp() { } void tearDown() { } protected: void aTest(); }; CPPUNIT_TEST_SUITE_REGISTRATION(Testname); void Testname::aTest() { } --- NEW FILE: FitTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" #include <iostream> #include <DesignByContract.h> #include <CFit.h> #include <CLinearFit.h> #include <math.h> class FitTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(FitTest); CPPUNIT_TEST(Construction); CPPUNIT_TEST(AddPoints); CPPUNIT_TEST(Fit); CPPUNIT_TEST_SUITE_END(); private: CLinearFit* m_pFit; public: void setUp() { m_pFit = new CLinearFit; } void tearDown() { delete m_pFit; } protected: void Construction(); void AddPoints(); void Fit(); }; CPPUNIT_TEST_SUITE_REGISTRATION(FitTest); /* Construction: Ensure initial state is correct 1. Get state 2. Get number of points in fit data. 3. Evaluate the fit 4. Perform the Fit 5. Get the fit parameters. */ void FitTest::Construction() { cerr << "FitTest\n"; EQMSG("Fit state: ", CFit::Accepting, m_pFit->GetState()); EQMSG("# points: ", (size_t)0, m_pFit->size()); /* EXCEPTION(m_pFit->Perform(), DesignByContract::DesignByContractException&); */ bool ok = false; try { m_pFit->Perform(); } catch (DesignByContract::DesignByContractException&) { ok = true; } catch(...) { cerr << "Caught something!!\n"; ok = true; } ASSERT(ok); CFit::FitParameterList params; EXCEPTION(params = m_pFit->GetParameters(), DesignByContract::DesignByContractException&); } static CFit::Point dummypoints[] = { {1, 2}, {2, 3}, {3, 4}, {10, 42} }; static const int numdummypoints = sizeof(dummypoints)/sizeof(CFit::Point); /* Test Name AddPoints Test Objective Ensure points can be added correctly. Test Description 1. Add points to the fit. 2. Check the final number of points. 3. Iterate through the points. Expected Results 1. After each point the size() member should give the number of points added. 2. After all points are added, the total number of points should match the number added. 3. Iterating through the points should retrieve the same set of points inserted, in the order inserted. */ void FitTest::AddPoints() { for(int i =0; i < numdummypoints; i++) { m_pFit->AddPoint(dummypoints[i]); EQMSG("size in loop", (size_t)(i+1), m_pFit->size()); } EQMSG("size after loop", (size_t)numdummypoints, m_pFit->size()); // int i = 0; CFit::PointIterator p = m_pFit->begin(); while(p != m_pFit->end()) { EQMSG("Xcompare: ", dummypoints[i].x, p->x); EQMSG("Ycompare: ", dummypoints[i].y, p->y); p++; i++; } } /* Test Name FitTest Test Objective Ensure that linear fits work, that parameters can be retrieved and points evaluated. Test Description 1. Insert 10 points that randomly vary along the line y=1.5x+7.3 2. Perform the fit 3. Get the fit state. 4. Get the parameters of the fit 5. Evaluate the 10 data points. Expected Results 3 The fit state should be Performed. 4. The parameters should be within 10% of the actual (that's probably generous). 5. The 10 points should evaluate as described by the fit parameters. */ static const double testSlope = 1.5; static const double testIntercept = 7.3; static const int dataPoints = 10; static const double tolerance = 0.1; // fraction of value. static const double jitter = 0.01; // jitter on data points. void CheckLinearFit(CFit* pFit) { CFit::Point pt; for(int i = 0; i < dataPoints; i++) { double x = (double)i; double y = x*testSlope + testIntercept; // exact value. y += (drand48() - 0.5)*jitter*y; // random +/- jitter. pt.x = x; pt.y = y; pFit->AddPoint(pt); } // Peform the fit> pFit->Perform(); EQMSG("state",CFit::Performed, pFit->GetState()); CFit::FitParameterList params = pFit->GetParameters(); // there are three parameters named: slope, offset, chisquare. // We are only interested in slope and offset. EQ((size_t)3, params.size()); CFit::FitParameterIterator p = params.begin(); double slope; double intercept; int found = 0; while(p != params.end()) { if(p->first == string("slope")) { slope = p->second; found++; } if(p->first == string("offset")) { intercept = p->second; found++; } p++; } EQMSG("Not all params found", 2, found); // Check the fit quality. ASSERT(fabs(testSlope-slope) < tolerance*testSlope); ASSERT(fabs(testIntercept - intercept) < tolerance*testIntercept); // evaluate the fit: for(int i = 15; i < 25; i++) { // extrapolate past data... double x = (double)i; double y = (*pFit)(x); EQMSG("Point check: ", x*slope+intercept, y); } } void FitTest::Fit() { CheckLinearFit(m_pFit); } --- NEW FILE: CalibManagerTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" #include <CCalibratedParameter.h> #include <CCalibratedParameterManager.h> #include <CLinearFit.h> #include <Event.h> #include <Analyzer.h> #include <BufferDecoder.h> #include <stdio.h> class CalibManager : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(CalibManager); CPPUNIT_TEST(AddTest); CPPUNIT_TEST(DeleteTest); CPPUNIT_TEST(STLJacketTest); CPPUNIT_TEST(EvalTest); CPPUNIT_TEST_SUITE_END(); private: public: void setUp() { } void tearDown() { // empty out the manager: while (CCalibratedParameterManager::size()) { CCalibratedParameterManager::CalibratedParameterIterator i = CCalibratedParameterManager::begin(); string name = i->first; CCalibratedParameter* pParam = CCalibratedParameterManager::DeleteParameter(name); delete pParam; } } protected: void AddTest(); void DeleteTest(); void STLJacketTest(); void EvalTest(); }; CPPUNIT_TEST_SUITE_REGISTRATION(CalibManager); /* Test Name AddTest Test Objective Test ability to add calibrated parameters to the manager. Test Description 1. Create a pair of calibrated parameters 2. Check size of manager. 3. Add a parameter 4. Check size of manager 5. Find added parameter 6. Add second parameter 7. find first parameter 8. find second parameter 9. check size of manager. Expected Results 1. NA 2. SB 0 3. NA 4. SB 1 5. Should not be end and iterator.second should point to first parameter 6. NA 7. Should not be end and iterator.second should point to first parameter. 8. Should not be end and iterator.second should point to second parameter. 9. Should be 2. */ void CalibManager::AddTest() { // 1. Make the pair of parameters CLinearFit line1; CLinearFit::Point pt; pt.x = 0.0; pt.y = 0.1; line1.AddPoint(pt); pt.x = 1.0; pt.y = 2.2; line1.AddPoint(pt); line1.Perform(); CCalibratedParameter param1(1, 0, "line1", &line1); CLinearFit line2; pt.x = 0.0; pt.y = -1.0; line2.AddPoint(pt); pt.x = 5.0; pt.y = 15.0; line2.AddPoint(pt); line2.Perform(); CCalibratedParameter param2(2,4, "line2", &line2); // 2. Check size of manager: EQMSG("Initial size", (size_t)0, CCalibratedParameterManager::size()); // 3. Add the first parametrs: CCalibratedParameterManager::AddParameter("The First", new CCalibratedParameter(param1)); // 4. Check size: EQMSG("After first add", (size_t)1, CCalibratedParameterManager::size()); // 5. Check find: CCalibratedParameterManager::CalibratedParameterIterator i = CCalibratedParameterManager::FindParameter("The First"); ASSERT(i != CCalibratedParameterManager::end()); ASSERT(param1 == *(i->second)); // 6. Add second parameter: CCalibratedParameterManager::AddParameter("second one", new CCalibratedParameter(param2)); // 7. Re-find 1. i = CCalibratedParameterManager::FindParameter("The First"); ASSERT(i != CCalibratedParameterManager::end()); ASSERT(param1 == *(i->second)); // 8. Find 2: i = CCalibratedParameterManager::FindParameter("second one"); ASSERT(i != CCalibratedParameterManager::end()); ASSERT(param2 == *(i->second)); // Size sb. 2: EQMSG("Size = 2",(size_t)2, CCalibratedParameterManager::size()); } /*! Test Name DeleteTest Test Objective Test ability to delete a parameter. Test Description 1. Add 2 parameters as for prior test. 2. Check size. 3. Delete first parameter. 4. Check size 5. Find First 6. Find second. Expected Results 1. NA 2. 2 3. NA 4. 1 5. end() 6. not end, and *(i->second) == second parameter. */ void CalibManager::DeleteTest() { // 1. Make the pair of parameters and add them. CLinearFit line1; CLinearFit::Point pt; pt.x = 0.0; pt.y = 0.1; line1.AddPoint(pt); pt.x = 1.0; pt.y = 2.2; line1.AddPoint(pt); line1.Perform(); CCalibratedParameter param1(1, 0, "line1", &line1); CLinearFit line2; pt.x = 0.0; pt.y = -1.0; line2.AddPoint(pt); pt.x = 5.0; pt.y = 15.0; line2.AddPoint(pt); line2.Perform(); CCalibratedParameter param2(2,4, "line2", &line2); CCalibratedParameterManager::AddParameter("1", new CCalibratedParameter(param1)); CCalibratedParameterManager::AddParameter("2", new CCalibratedParameter(param2)); //2. Check size: EQMSG("Sizecheck2: ", (size_t)2, CCalibratedParameterManager::size()); // 3. delete first. CCalibratedParameter* p = CCalibratedParameterManager::DeleteParameter("1"); delete p; // 4. Size check: EQMSG("Sizecheck1: ", (size_t)1, CCalibratedParameterManager::size()); // 5. Find deleted: CCalibratedParameterManager::CalibratedParameterIterator i; i = CCalibratedParameterManager::FindParameter("1"); ASSERT(i == CCalibratedParameterManager::end()); // 6. Locate second one: i = CCalibratedParameterManager::FindParameter("2"); ASSERT(i != CCalibratedParameterManager::end()); ASSERT(param2 == *(i->second)); } /*! Test Name STLJacketTest - Test Objective Test STL Jackets esp. for begin() end() itertion. Test Description 1. Create a pair of parameters, and add them. 2. Iterate through the manager. Expected Results Both parameters should appear in the iteration exactly once.and the number of iterations should be 2. */ void CalibManager::STLJacketTest() { // 1. Make the pair of parameters and add them. CLinearFit line1; CLinearFit::Point pt; pt.x = 0.0; pt.y = 0.1; line1.AddPoint(pt); pt.x = 1.0; pt.y = 2.2; line1.AddPoint(pt); line1.Perform(); CCalibratedParameter param1(1, 0, "line1", &line1); CLinearFit line2; pt.x = 0.0; pt.y = -1.0; line2.AddPoint(pt); pt.x = 5.0; pt.y = 15.0; line2.AddPoint(pt); line2.Perform(); CCalibratedParameter param2(2,4, "line2", &line2); CCalibratedParameterManager::AddParameter("1", new CCalibratedParameter(param1)); CCalibratedParameterManager::AddParameter("2", new CCalibratedParameter(param2)); // The structure below is used to keep track of iteration: struct { CCalibratedParameter* pParam; int nVisits; } parameters[2] = { {¶m1, 0}, {¶m2, 0} }; // Iterate and scoreboard. int iterations(0); CCalibratedParameterManager::CalibratedParameterIterator i = CCalibratedParameterManager::begin(); while(i != CCalibratedParameterManager::end()) { CCalibratedParameter* p = i->second; for(int j= 0; j < 2; j++) { if(*(parameters[j].pParam) == *p) { parameters[j].nVisits++; } } i++; iterations++; } // Check it out: EQMSG("Iteration count", 2, iterations); for(int j = 0; j < 2; j++) { char msg[100]; sprintf(msg, "Checking param %d", j); EQMSG(msg, 1,parameters[j].nVisits); } } /* Test Name EvalTest Test Objective Test ability to evaluate parameters. Test Description 1. Create and insert 2 calibrated parameters with known fits. 2. Evaluate for several events.Note we will be dirty about the analyzer and the buffer decoder references since those are not used by the software. Expected Results Resulting calibrated parameters should match . */ void CalibManager::EvalTest() { CCalibratedParameterManager manager; // need an object now. // 1. Make the pair of parameters and add them. CLinearFit line1; CLinearFit::Point pt; pt.x = 0.0; pt.y = 0.0; line1.AddPoint(pt); pt.x = 1.0; pt.y = 2.0; line1.AddPoint(pt); line1.Perform(); // y = 2x CCalibratedParameter param1(1, 0, "line1", &line1); CLinearFit line2; pt.x = 0.0; pt.y = 5.0; line2.AddPoint(pt); pt.x = 1.0; pt.y = 7; // y = 2x+5 line2.AddPoint(pt); line2.Perform(); CCalibratedParameter param2(2,0, "line2", &line2); CCalibratedParameterManager::AddParameter("1", new CCalibratedParameter(param1)); CCalibratedParameterManager::AddParameter("2", new CCalibratedParameter(param2)); // Here's where it gets a bit dirty: CBufferDecoder* pDecoder(0); CAnalyzer* pAnalyzer(0); // Fortunately these get passed around by reference. CEvent anEvent; for(int i= 0; i < 100; i++) { anEvent.clear(); // Clear the event's validity flags. anEvent[0] = (float)i; manager((Address_t)NULL, // Don't use anEvent, // Do use *pAnalyzer, // Don't use. *pDecoder); // Don't use. // rEvent[1,2] should be valid: ASSERT(anEvent[1].isValid()); ASSERT(anEvent[2].isValid()); // and the elements should have correct values: float y = (float)i*2.0; float actual = anEvent[1]; EQMSG("Element 1: ", y, actual); y = (float)i*2.0 + 5.0; actual = anEvent[2]; EQMSG("Element2: ", y, actual); } } --- NEW FILE: FactoryTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" #include <CLinearFitCreator.h> #include <CFitFactory.h> #include <iostream> extern void CheckLinearFit(CFit* pFit); class FactoryTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(FactoryTest); CPPUNIT_TEST(CreatorList); CPPUNIT_TEST(FitCreation); CPPUNIT_TEST(FitManipulation); CPPUNIT_TEST_SUITE_END(); private: public: void setUp() { } void tearDown() { } protected: void CreatorList(); void FitCreation(); void FitManipulation(); }; CPPUNIT_TEST_SUITE_REGISTRATION(FactoryTest); /* Test Name CreatorList Test Objective Ensure that functions on the creator list operate correctly. Test Description 1. Check number of fit creators. (sizecreators). 2. Add a CLinearFitCreator to the factory. 3. Check # fit creators4. iterate through the fit creators. 5. Find the CLinearFitCreator. Test Conditions Expected Results 1. 0 2. N/A 3. 1 4. Should see the linear fit creator we added. 5. Should be able to find it. */ void FactoryTest::CreatorList() { cerr << "Factory test\n"; CLinearFitCreator* pCreator = new CLinearFitCreator(); EQ(0, CFitFactory::sizeCreators()); CFitFactory::AddFitType("linear", pCreator); EQ(1, CFitFactory::sizeCreators()); CFitFactory::FitCreatorIterator c = CFitFactory::FindFitCreator("linear"); ASSERT(c != CFitFactory::endCreators()); EQMSG("pointer compare", (CFitCreator*)pCreator, c->second); } /* Test Name FitCreation Test Objective Ensure a named fit can be created. Test Description 1. Check number of fits. 2. Create a linear fit. 3. check # of fits. 4. iterate fits 5. Find the fit. 6. Delete the fit 7. number of fits? Expected Results 1. 0 2. N/A 3. 1 4. Should have exactly the fit I created. 5. Should find the fit I created. 6. N/A 7. 0. */ void FactoryTest::FitCreation() { CFit* pFit = CFitFactory::Create("linear", "testfit"); ASSERT(pFit); EQMSG("1 fit", 1, CFitFactory::size()); CFitFactory::FitIterator f = CFitFactory::begin(); ASSERT(f != CFitFactory::end()); EQMSG("fit in factory map", pFit, f->second); f++; ASSERT( f == CFitFactory::end()); f = CFitFactory::FindFit("testfit"); ASSERT(f != CFitFactory::end()); EQMSG("Fit found is mine", pFit, f->second); ASSERT(CFitFactory::Delete("testfit")); EQMSG("Fit factory empty", 0, CFitFactory::size()); } /* Test Name/# FitManipulation Test Objective Ensure a created fit can be manipulated. Test Description 1. Create a linear fit. 2. Add points to it 3. Perform the fit 4. Get the fit parameters 5. Evaluate the fit at some points Test Conditions Expected Results 1. N/A2. true 3. true 4. Fit parameters are good to 10% of the line I'm putting in. 5. Fit evaulates as it should according to its parameters. Note the tests are identical to those done by FitTest::Fit so the actual test is factored out into CheckLinearFit. */ void FactoryTest::FitManipulation() { CFit* pFit = CFitFactory::Create("linear", "testfit"); CheckLinearFit(pFit); CFitFactory::Delete("testfit"); } Index: MySpecTclApp.cpp =================================================================== RCS file: /cvsroot/nsclspectcl/SpecTcl/contrib/calibratedparams/MySpecTclApp.cpp,v retrieving revision 5.1.4.1 retrieving revision 5.1.4.2 diff -C2 -d -r5.1.4.1 -r5.1.4.2 *** MySpecTclApp.cpp 15 Dec 2004 17:29:22 -0000 5.1.4.1 --- MySpecTclApp.cpp 20 Dec 2006 12:35:42 -0000 5.1.4.2 *************** *** 281,286 **** ////////////////////////// FILE_NAME.cpp ///////////////////////////////////////////////////// - - #include <config.h> #include "MySpecTclApp.h" #include "EventProcessor.h" --- 281,284 ---- *************** *** 296,306 **** #include <CalibrationDistribution.h> - #include <CScriptableUnpacker.h> - - #ifdef HAVE_STD_NAMESPACE - using namespace std; - #endif - - // Local Class definitions: --- 294,297 ---- *************** *** 490,505 **** #endif ! RegisterEventProcessor(*(new CScriptableUnpacker)); ! ! // Below is a trick to get the scaler stuff defined too. ! // ! ! CScriptableUnpacker* pUnpacker = new CScriptableUnpacker("scaler", ! "scalerbank"); ! pUnpacker->OnAttach(rAnalyzer); // Register the commands. ! ! // Register to do cablibratedparameters: ! ! RegisterEventProcessor(*(new CCalibratedParameterManager)); --- 481,486 ---- #endif ! RegisterEventProcessor(Stage1); ! RegisterEventProcessor(*(new CCalibratedParameterManager)); *************** *** 640,643 **** --- 621,645 ---- CTclGrammerApp::SetupTestDataSource(); + CMultiTestSource* pSource = getTestDataSource(); + + // starting with the default test source, add another test source + // that produces multiple evenly spaced narrow peaks. + // + + + CTestFile *pmyTestFile = new CTestFile(*(pSource->getDefaultTestSource())); + // Calibration distributions construct with + // First peak position, number of peaks, peak spacing + // and peak widths. This will produce a spectrrum that looks like + // a pulsr was run across the spectrum at regular intervals.. good for my testing. + // + CCalibrationDistribution* pCalibrationParameter = + new CCalibrationDistribution(50.0, 10, 100.0, 5.0, 1024.0); + pmyTestFile->AddDistribution(*pCalibrationParameter); + pSource->addTestSource("calibrationSource", pmyTestFile); + + // Select it. + + pSource->useTestSource("calibrationSource"); } --- NEW FILE: CommandTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" #include <iostream> #include <tcl.h> #include <TCLInterpreter.h> #include <TCLList.h> #include <TCLResult.h> #include <CFitCommand.h> #include <CFitFactory.h> #include <CFit.h> #include <vector> // STL Vector. #include <string> // STL STring. #include <string.h> // C runtime string. #include <stdio.h> #include <math.h> void* gpTCLApplication; // Expected by TCL lib. class CommandTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(CommandTest); CPPUNIT_TEST(CreateTest); CPPUNIT_TEST(DeleteTest); CPPUNIT_TEST(ListTest); CPPUNIT_TEST(AddPoints); CPPUNIT_TEST(Perform); CPPUNIT_TEST(Evaluate); CPPUNIT_TEST_SUITE_END(); // Must define the function for each test. protected: void CreateTest(); void DeleteTest(); void ListTest(); void AddPoints(); void Perform(); void Evaluate(); int PerformUtility(char* pName); private: // These are created and torn down for each test. Tcl_Interp* m_pInterpreter; CTCLInterpreter* m_pInterp; CTCLResult* m_pResult; CFitCommand* m_pFitCommand; public: CommandTest() : m_pInterpreter(0), m_pInterp(0), m_pResult(0), m_pFitCommand(0) { } ~CommandTest() { tearDown(); // In case destroyed before teardown. } void setUp() { // Create the interpreter, bind it to an object and m_pInterpreter = Tcl_CreateInterp(); Tcl_Init(m_pInterpreter); m_pInterp = new CTCLInterpreter(m_pInterpreter); // Create and register the fit command: m_pFitCommand = new CFitCommand(m_pInterp); // defines "fit". // Create a result object bound to the interp: m_pResult = new CTCLResult(m_pInterp); } void tearDown() { // Destroy the fit command (unregisters it): delete m_pFitCommand; // Delete the interpreter object and the interp: delete m_pResult; delete m_pInterp; // Tcl_DeleteInterp(m_pInterpreter); m_pFitCommand = (CFitCommand*)NULL; m_pInterp = (CTCLInterpreter*)NULL; m_pInterpreter= (Tcl_Interp*)NULL; m_pResult = (CTCLResult*)NULL; } }; CPPUNIT_TEST_SUITE_REGISTRATION(CommandTest); /* Test Name CreateTest Test Objective Check ability to create a fit via command parse Test Description 1. Create TCL interpreter/object (setup) 2. Create CFitCommand object registered on interp (setup) 3. Invoke Create_parse with new fit name. 4. Search for fit directly from factory. 5. Create a duplicate fit. 6. Delete fit from factory 7. Destroy CFitCommand (teardown) 8. Destroy TCL Interpreter/object) (teardown). Expected Results 1. NA 2. N/A 3. TCL_OK returned. 4. Found a fit with that name. 5. TCL_ERROR returned. 6. N/A 7. N/A 8. N/A */ static char* create_args[] = {"linear", "testfit" }; static const int create_count = sizeof(create_args)/sizeof(char*); void CommandTest::CreateTest() { cerr << "Command test\n"; int status = m_pFitCommand->Create_parse(*m_pInterp, *m_pResult, create_count, create_args); EQMSG("Create_parse return", TCL_OK, status); CFitFactory::FitIterator i = CFitFactory::FindFit("testfit"); ASSERT(i != CFitFactory::end()); // Now go for a duplicate fit: status = m_pFitCommand->Create_parse(*m_pInterp, *m_pResult, create_count, create_args); EQMSG("Duplicate create", TCL_ERROR, status); // should have failed. CFitFactory::Delete("testfit"); // This cleanup is not done in teardown. } /* Test Name DeleteTest Test Objective Check command parsing for delete Test Description 1. See setup above 2. Create a linear fit with known name. 3. Delete it via Delete_parse 4. Search for fit directly in factory 5. Delete it again via Delete_parse 6. See teardown above. Expected Results 1. N/A 2. N/A 3. Return is TCL_OK 4. end() returned 5. TCL_ERROR is returned 6. N/A. */ static char* delete_args[] = { "testfit" }; static const int delete_count = sizeof(delete_args)/sizeof(char*); void CommandTest::DeleteTest() { int status = m_pFitCommand->Create_parse(*m_pInterp, *m_pResult, create_count, create_args); EQMSG("Create_parse return", TCL_OK, status); status = m_pFitCommand->Delete_parse(*m_pInterp, *m_pResult, delete_count, delete_args); EQMSG("Delete_parse return", TCL_OK, status); ASSERT(CFitFactory::FindFit("testfit") == CFitFactory::end()); status = m_pFitCommand->Delete_parse(*m_pInterp, *m_pResult, delete_count, delete_args); EQMSG("Delete_parse second return", TCL_ERROR, status); } /* Test Name/# ListTest Test Objective Test commands to list fits. Test Description 1. Set Setup above 2. Create linear fits: fit1 fit2 george. 3. List for all 4. Create TCLList of results and query size. 5. List for fit* 6. Create TCLList of results and query size 7. list for george 8. Create TCLList of results and split 9. Delete the fits. 10. Tear down as above Expected Results 1. NA 2. na 3. TCL_OK returned. 4. 3 elements 5. NA 6. 2 elements 7. NA 8. Following: a. list size is 1 b. Element 0 is "george" c. Element 1 is "accepting" d. Element 2 is empty e. Element 3 is empty 9. Na 10. NA */ char fitname[1000] = ""; static char* listpattern_args[] = { fitname }; static const int listpattern_count = sizeof(listpattern_args)/sizeof(char*); void CommandTest::ListTest() { // Create the fits: CFitFactory::Create("linear", "fit1"); CFitFactory::Create("linear", "fit2"); CFitFactory::Create("linear", "george"); // List all fits: int status = m_pFitCommand->List_parse(*m_pInterp, *m_pResult, 0, (char**)NULL); // Default pattern is *. EQMSG("list *", TCL_OK, status); CTCLList listall(m_pInterp, (const char*)(*m_pResult)); StringArray elements; EQMSG("list * split status", TCL_OK, listall.Split(elements)); EQMSG("list * size", (size_t)3, elements.size()); elements.erase(elements.begin(), elements.end()); // List the fits that match fit* strcpy(fitname, "fit*"); status = m_pFitCommand->List_parse(*m_pInterp, *m_pResult, listpattern_count, listpattern_args); EQMSG("list fit*", TCL_OK, status); CTCLList listfitstar(m_pInterp, (const char*)(*m_pResult)); EQMSG("list fit* split status", TCL_OK, listfitstar.Split(elements)); EQMSG("list fit* size", (size_t)2, elements.size()); elements.erase(elements.begin(), elements.end()); // List only george: strcpy(fitname, "george"); status = m_pFitCommand->List_parse(*m_pInterp, *m_pResult, listpattern_count, listpattern_args); EQMSG("list fit*", TCL_OK, status); CTCLList listgeorge(m_pInterp, (const char*)(*m_pResult)); EQMSG("list george split status", TCL_OK, listgeorge.Split(elements)); EQMSG("list george size", (size_t)1, elements.size()); CTCLList george(m_pInterp, elements[0]); // George's desription list StringArray georgelist; EQMSG("element list status", TCL_OK, george.Split(georgelist)); EQMSG("element list size", (size_t)5, georgelist.size()); EQMSG("name", string("george"), georgelist[0]); EQMSG("linear", string("linear"), georgelist[1]); EQMSG("state", string("accepting"), georgelist[2]); EQMSG("points", string(""), georgelist[3]); EQMSG("params", string(""), georgelist[4]); // Delete the fits: CFitFactory::Delete("fit1"); CFitFactory::Delete("fit2"); CFitFactory::Delete("george"); } /* Test Name/# AddPoints Test Objective Test commands to add points. Test Description 1. Setup as above. 2. Create a fit. 3. Add a point to it. 4. Add a second point to it. 5. Find the fit in the fit factory. 6. Ask it how many fits it has 7. Iterate the fit points 8. Destroy the fit 9. tear down as above. Expected Results 1. NA 2. NA 3. TCL_OK Returned 4. TCL_OK returned 5. NA 6. 2 7. Find both the points I inserted in the fit. 8. NA 9. NA */ static CFit::Point testPoints[] = { {1.0, 2.5}, {3.5, 7.25} }; static int ntestPoints = sizeof(testPoints)/sizeof(CFit::Point); void CommandTest::AddPoints() { CFit* pFit = CFitFactory::Create("linear", "test"); // easiest way. // Create the command string, we'll later split it: string command("test"); for(int i =0; i < ntestPoints; i++) { char apoint[100]; sprintf(apoint, " {%f %f}", testPoints[i].x, testPoints[i].y); command += apoint; } // Turn command into an arg/argv list. CTCLList lCommand(m_pInterp, command); int argc; char **argv; lCommand.Split(argc, &argv); // Now add the points: int status = m_pFitCommand->AddPoints_parse(*m_pInterp, *m_pResult, argc, argv); // Check that all is well. EQMSG("add status", TCL_OK, status); EQMSG("fit point count", (size_t)2, pFit->size()); CFit::PointIterator pPoint = pFit->begin(); int pt = 0; while(pPoint != pFit->end()) { EQMSG("x: ", testPoints[pt].x, pPoint->x); EQMSG("y: ", testPoints[pt].y, pPoint->y); pPoint++; pt++; } CFitFactory::Delete("test"); } /* Test Name/# Perform Test Objective Test command to perform a fit. Test Description 1. Setup as above. 2. create a fit 3. Add the points to it near the line y = 2.5x - 7 4. Request the perform. 5. Result -> TCLList 6. size of list? 7. Break apart list. a. decode slope b. decode offset 8. Teardown as above (note fit remains for next test). Expected Results 1. Na 2. NA 3. NA 4. TCL_OK returned 5. NA 6. 3 7. slope and offset are within 10% of actual. 8. NA */ static double m = 2.5; static double b = -7; static double jitter = 0.01; static double tolerance = 0.1; int CommandTest::PerformUtility(char* name) { CFitFactory::FitIterator p = CFitFactory::FindFit(name); CFit* pFit = p->second; for(int i =0; i < 10; i++) { // We'll use 10 points. CFit::Point pt; pt.x = (double)i; pt.y = m*pt.x + b; // This is the unjitter y. pt.y += jitter * (drand48() - 0.5); // jitter it. pFit->AddPoint(pt); } // Now do the fit: int status = m_pFitCommand->Perform_parse(*m_pInterp, *m_pResult, 1, &name); return status; } void CommandTest::Perform() { char* name = "test"; CFit* pFit = CFitFactory::Create("linear", name); int status = PerformUtility(name); EQMSG("status: ", TCL_OK, status); // There should be 3 elements in the result list: CTCLList params(m_pInterp, (const char*)(*m_pResult)); vector<string> parameters; params.Split(parameters); EQMSG("num params:", (size_t)3, parameters.size()); // Pick them apart and require the slope and offset be in tolerance of m, b int found(0); for(int i=0; i < parameters.size(); i++) { CTCLList aparam(m_pInterp, parameters[i]); vector<string> oneparam; aparam.Split(oneparam); EQMSG("one param size", (size_t)2, oneparam.size()); if(oneparam[0] == string("slope")) { double slope; sscanf(oneparam[1].c_str(), "%lf", &slope); ASSERT((fabs(m - slope) < fabs(tolerance*m)) && (copysign(1.0, slope) == copysign(1.0, m))); found++; } if(oneparam[0] == string("offset")) { double offset; sscanf(oneparam[1].c_str(), "%lf", &offset); ASSERT((fabs(b - offset)*copysign(1.0, b) < fabs(tolerance*b)) && (copysign(1.0, offset) == copysign(1.0, b))); found++; } } EQMSG("All params", 2, found); CFitFactory::Delete(name); } /* Test Name/# Evaluate Test Objective Test evaluate command. Test Description 1. Setup as above and perform the fit as for Peform(). 2. Locate fit in factory (ensure its there) 3. Check state 4. For a set of point Evaluate 5. Check result value against raw eval of fit. 6. teardown. Test Conditions Expected Results 1. NA 2. found 3. performed 4. TCL_OK for each point. 5. match 6. NA */ void CommandTest::Evaluate() { char* name = "test"; CFit* pFit = CFitFactory::Create("linear", "test"); PerformUtility(name); // Now evaluate 10 points starting at x = 7.8 and stepping by // approximately pi. double x = 7.8; for(int i=0; i < 10; i++) { char pBuffer[100]; // command -> here then split.. sprintf(pBuffer, "%s %g", name, x); CTCLList command(m_pInterp, pBuffer); int argc; char** argv; command.Split(argc, &argv); int status = m_pFitCommand->Evaluate_parse(*m_pInterp, *m_pResult, argc, argv); EQMSG("Eval status: ", TCL_OK, status); string result((const char*)*m_pResult); double value; sscanf(result.c_str(), "%lf", &value); double actual = (*pFit)(x); ASSERT(fabs(actual - value) < (double)0.001); Tcl_Free((char*)argv); x += 3.14159265359; // increment of pi. } } --- NEW FILE: CalibParamTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" #include <CCalibratedParameter.h> #include <Event.h> #include <CLinearFit.h> // Test for the calibrated parameter class. class CalibratedParameterTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(CalibratedParameterTest); CPPUNIT_TEST(ConstructTest); CPPUNIT_TEST(FunctionCall); CPPUNIT_TEST(FitChange); CPPUNIT_TEST_SUITE_END(); private: public: void setUp() { } void tearDown() { } protected: void ConstructTest(); void FunctionCall(); void FitChange(); }; CPPUNIT_TEST_SUITE_REGISTRATION(CalibratedParameterTest); /* Test Name/# Construction Test Objective Test the constructors and canonical operations of the class (Note this will also test the selectors. Test Description 1. Construct a Calibrated parameter 2. Inspect with selectors. 3. Do copy construction of the calibrated parameter 4. Test for equality 5. Test fits for equality. 6. Create another calibrated parameter (different parameters etc). 7. Compare for equality 8. Compare for inequality. Expected Results 1. N/A 2. Selectors should reflect constructor parameters. 3. NA 4. The two Calibrated parameters should compare equal. 5. The two fits contained by the parameters should compare equal 6. NA 7. Should not get equality 8. Should get inequality. */ void CalibratedParameterTest::ConstructTest() { // 1. Construct the initial calibrated parameter. CLinearFit line; // The fit I'm using. CFit::Point pt; pt.x = 0.0; pt.y = 0.0; line.AddPoint(pt); pt.x = 1.0; pt.y = 2.0; line.AddPoint(pt); // y = 2*x. line.Perform(); CCalibratedParameter p1(1, 0, "TestFit", &line); // 2. Check the results of the construction. EQMSG("Target id", 1, p1.getTargetId()); EQMSG("Raw id", 0, p1.getRawId()); EQMSG("Fitname", string("TestFit"), p1.getFitName()); const CFit* pFit = p1.getFit(); if(line != *(const CLinearFit*)pFit) { FAIL("Fits not equal"); } // 3. Copy construct parameter. CCalibratedParameter p2(p1); // 4. Calibrated parameters must be equal ASSERT(p1 == p2); // Parameters must compare equal // 5. And their fits must be equal: const CFit* pFit2 = p2.getFit(); ASSERT(*pFit == *pFit2); // 6. Create a different calibrated parameter. CCalibratedParameter p3(5, 7, "Testing", &line); // 7. SHould not be equal: if(p1 == p3) { FAIL("Unequal are equal"); } // 8. Should be unequal. ASSERT(p1 != p3); // This is not the same test as above. } /* Test Name function call Test Objective Test the function call operator of CCalibratedParameter Test Description 1. Construct a fit and perform it such that it will yield y = 2*x+1 2. Construct a calibrated parameter with this fit. 3. Run several concocted events through the parameter checking that they all compute to y= 2*x+1. Expected Results 1. NA 2. NA 3. All calibrated parameters evaluate to 2*x+1. */ void CalibratedParameterTest::FunctionCall() { CLinearFit line; CFit::Point pt; pt.x = 0.0; pt.y = 1.0; line.AddPoint(pt); pt.x = 1.0; pt.y = 3.0; line.AddPoint(pt); line.Perform(); CCalibratedParameter Param(1, 0, "test", &line); CEvent event; for(int i =0; i < 10; i++) { event.clear(); // Reset the event. event[0] = i; // Raw parameter. Param(event); // Compute the calibrated param. ASSERT(event[1].isValid()); // Should have been set. float result = (double)i*2.0 + 1.0; float calibrated = event[1]; EQMSG("comparison", result, calibrated); } } /* Test Name FitChange Test Objective Test ability to change from one fit to the other. Test Description 1. Construct a calibrated parameter. 2. Replace its fit. 3. Check returned fit for equality with initial fit. 4. Evaluate parameter for several data points with new fit. Expected Results 4. Initial fit should be equal to replaced fit. 5. Parameter should evaluate using new fit. */ void CalibratedParameterTest::FitChange() { // 1. create initial parameter. CLinearFit line; CFit::Point pt; pt.x = 0.0; pt.y = 1.0; line.AddPoint(pt); pt.x = 1.0; pt.y = 3.0; line.AddPoint(pt); line.Perform(); CCalibratedParameter Param(1, 0, "test", &line); // Make a secod fit and repalce the parameter's fit. CLinearFit line2; // This will be y = 3x-5. pt.x = 0.0; pt.y = -5.0; line2.AddPoint(pt); pt.x = 1.0; pt.y = -2.0; line2.AddPoint(pt); line2.Perform(); CFit* pOldFit = Param.ReplaceFit(line2); // 4 - check against old fit. if(line != *(CLinearFit*)pOldFit) { FAIL("Replaced fit != line"); } delete pOldFit; // 5 Evaluate. CEvent event; for(int i =0; i < 100; i ++) { event.clear(); event[0] = i; Param(event); float result = ((float)i)*3.0 - 5.0; float calib = event[1]; EQMSG("Comparison", result, calib); } } --- NEW FILE: TestRunner.cpp --- #include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/ui/text/TestRunner.h> #include <string> 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 // 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); \ } #endif --- NEW FILE: CreatorTest.cpp --- // Template for a test suite. #include <cppunit/extensions/HelperMacros.h> #include <cppunit/Asserter.h> #include "Asserts.h" #include <CLinearFitCreator.h> #include <CFit.h> #include <iostream> class CreatorTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(CreatorTest); CPPUNIT_TEST(Create); CPPUNIT_TEST_SUITE_END(); private: public: void setUp() { } void tearDown() { } protected: void Create(); }; CPPUNIT_TEST_SUITE_REGISTRATION(CreatorTest); /* Test Name Creation Test Objective Ensure I can create a linear fit. Test Description 1. Create a CLinearFitCreator 2. Ask it to create a fit. 3. Check the state of the fit. Expected Results 3. Fit state should be accepting. */ void CreatorTest::Create() { cerr << "CreatorTest\n"; CLinearFitCreator creator; CFit* pFit = creator(); EQ(CFit::Accepting, pFit->GetState()); } --- NEW FILE: all.tcl --- lappend auto_path ..; # Satisfy packages from up one level. # Load the TCL Test packages. if {[lsearch [namespace children] ::tcltest] == -1 } { package require tcltest namespace import ::tcltest::* } # Run all tests in this directory: set ::tcltest::testSingleFile false set ::tcltest::testsDirectory [file dir [info script]] # Run the tests (.test files). foreach file [::tcltest::getMatchingFiles] { if {[catch {source $file} msg]} { puts stdout $msg } } ::tcltest::cleanupTests 1 return |