22
33#include " TApplication.h"
44#include " TROOT.h"
5- #include " TBenchmark .h"
5+ #include " TSystem .h"
66
77#include " TCanvas.h"
88#include " TH1.h"
99
10- #include " TPluginManager.h"
1110#include " TError.h"
1211
1312#include " TGComboBox.h"
2726
2827#include " ../src/CommonDefs.h"
2928
30- #ifdef WIN32
31- #include " io.h"
32- #else
33- #include " unistd.h"
34- #endif
29+
30+ TString gTmpfilename ;
3531
3632// Function that compares to doubles up to an error limit
3733int equals (Double_t n1, Double_t n2, double ERRORLIMIT = 1 .E-4 )
@@ -102,10 +98,6 @@ class FitEditorUnitTesting
10298 // Pointer to the current (and only one) TFitEditor opened.
10399 TFitEditor* f;
104100
105- // These two variables are here to redirect the standard output to
106- // a file.
107- int old_stdout;
108- FILE *out;
109101public:
110102
111103 // Exception thrown when any of the pointers managed by the
@@ -121,21 +113,6 @@ class FitEditorUnitTesting
121113
122114 // Constructor: Receives the instance of the TFitEditor
123115 FitEditorUnitTesting () {
124- // Redirect the stdout to a file outputUnitTesting.txt
125- #ifdef WIN32
126- old_stdout = _dup (_fileno (stdout));
127- #else
128- old_stdout = dup (fileno (stdout));
129- #endif
130- auto res = freopen (" outputUnitTesting.txt" , " w" , stdout);
131- if (!res) {
132- throw InvalidPointer (" In FitEditorUnitTesting constructor cannot freopen" );
133- }
134- #ifdef WIN32
135- out = _fdopen (old_stdout, " w" );
136- #else
137- out = fdopen (old_stdout, " w" );
138- #endif
139116
140117 // Execute the initial script
141118 TString scriptLine = TString (" .x " ) + TROOT::GetTutorialDir () + " /math/fit/FittingDemo.C+" ;
@@ -164,73 +141,6 @@ class FitEditorUnitTesting
164141 // then they should comment this method.
165142 ~FitEditorUnitTesting () {
166143 f->DoClose ();
167- gApplication ->Terminate ();
168- }
169-
170- // This is a generic method to make the output of all the tests
171- // consistent. T is a function pointer to one of the tests
172- // function. It has been implemented through templates to permit
173- // more test types than the originally designed.
174- // @ str : Name of the test
175- // @ func : Member function pointer to the real implementation of
176- // the test.
177- template <typename T>
178- int MakeTest (const char * str, T func )
179- {
180- fprintf (stdout, " \n ***** %s *****\n " , str);
181- int status = (this ->*func)();
182-
183- fprintf (stdout, " %s.........." , str);
184- fprintf (out, " %s.........." , str);
185- if ( status == 0 ) {
186- fprintf (stdout, " OK\n " );
187- fprintf (out, " OK\n " );
188- }
189- else {
190- fprintf (stdout, " FAILED\n " );
191- fprintf (out, " FAILED\n " );
192- }
193- return status;
194- }
195-
196- // This is where all the tests are called. If the user wants to add
197- // new tests or avoid executing one of the existing ones, it is
198- // here where they should do it.
199- int UnitTesting () {
200- int result = 0 ;
201-
202- fprintf (out, " \n **STARTING TFitEditor Unit Tests**\n\n " );
203-
204- result += MakeTest (" TestHistogramFit..." , &FitEditorUnitTesting::TestHistogramFit);
205-
206- result += MakeTest (" TestGSLFit........." , &FitEditorUnitTesting::TestGSLFit);
207-
208- result += MakeTest (" TestUpdate........." , &FitEditorUnitTesting::TestUpdate);
209-
210- result += MakeTest (" TestGraph.........." , &FitEditorUnitTesting::TestGraph);
211-
212- result += MakeTest (" TestGraphError....." , &FitEditorUnitTesting::TestGraphError);
213-
214- result += MakeTest (" TestGraph2D........" , &FitEditorUnitTesting::TestGraph2D);
215-
216- result += MakeTest (" TestGraph2DError..." , &FitEditorUnitTesting::TestGraph2DError);
217-
218- result += MakeTest (" TestUpdateTree....." , &FitEditorUnitTesting::TestUpdateTree);
219-
220- // TODO: reenable in batch once stack smashing issue is fixed
221- if (!gROOT ->IsBatch ())
222- result += MakeTest (" TestTree1D........." , &FitEditorUnitTesting::TestTree1D);
223-
224- // TODO: reenable once fit results are fixed
225- // result += MakeTest("TestTree2D.........", &FitEditorUnitTesting::TestTree2D);
226-
227- // TODO: reenable once fit results are fixed
228- // result += MakeTest("TestTreeND.........", &FitEditorUnitTesting::TestTreeND);
229-
230- fprintf (out, " \n Remember to also check outputUnitTesting.txt for "
231- " more detailed information\n\n " );
232-
233- return result;
234144 }
235145
236146 // This is a debuggin method used to print the parameter values
@@ -239,9 +149,9 @@ class FitEditorUnitTesting
239149 void PrintFuncPars ()
240150 {
241151 static int counter = 0 ;
242- fprintf (out , " Printing the Func Pars (%d)\n " , ++counter);
243- for ( unsigned int i = 0 ; i < f->fFuncPars .size (); ++i ) {
244- fprintf (out , " %30.20f %30.20f %30.20f\n " , f->fFuncPars [i][0 ], f->fFuncPars [i][1 ], f->fFuncPars [i][2 ]);
152+ fprintf (stdout , " Printing the Func Pars (%d)\n " , ++counter);
153+ for (unsigned int i = 0 ; i < f->fFuncPars .size (); ++i ) {
154+ fprintf (stdout , " %30.20f %30.20f %30.20f\n " , f->fFuncPars [i][0 ], f->fFuncPars [i][1 ], f->fFuncPars [i][2 ]);
245155 }
246156 }
247157
@@ -256,7 +166,7 @@ class FitEditorUnitTesting
256166 for ( unsigned int j = 0 ; j < 3 ; ++j) {
257167 int internalStatus = equals (pars[i][j], f->fFuncPars [i][j]);
258168 if (internalStatus != 0 ) {
259- fprintf (out , " i: %d, j: %d, e: %d, diff %g\n " , i, j, internalStatus, (pars[i][j] - f->fFuncPars [i][j]));
169+ fprintf (stdout , " i: %d, j: %d, e: %d, diff %g\n " , i, j, internalStatus, (pars[i][j] - f->fFuncPars [i][j]));
260170 }
261171 status += internalStatus;
262172 }
@@ -498,6 +408,73 @@ class FitEditorUnitTesting
498408
499409 return CompareFuncPars (pars);
500410 }
411+
412+ // This is a generic method to make the output of all the tests
413+ // consistent. T is a function pointer to one of the tests
414+ // function. It has been implemented through templates to permit
415+ // more test types than the originally designed.
416+ // @ str : Name of the test
417+ // @ func : Member function pointer to the real implementation of
418+ // the test.
419+ template <typename T>
420+ int MakeTest (const char * str, T func)
421+ {
422+ RedirectHandle_t gRH ;
423+
424+ gSystem ->RedirectOutput (gTmpfilename .Data (), " w" , &gRH );
425+
426+ fprintf (stdout, " \n ***** %s *****\n " , str);
427+
428+ int status = (this ->*func)();
429+
430+ gSystem ->RedirectOutput (0 , 0 , &gRH );
431+
432+ fprintf (stdout, " %s..........%s\n " , str, status == 0 ? " OK" : " FAILED" );
433+
434+ return status;
435+ }
436+
437+ // This is where all the tests are called. If the user wants to add
438+ // new tests or avoid executing one of the existing ones, it is
439+ // here where they should do it.
440+ int UnitTesting ()
441+ {
442+ int result = 0 ;
443+
444+ fprintf (stdout, " \n **STARTING TFitEditor Unit Tests**\n\n " );
445+
446+ result += MakeTest (" TestHistogramFit..." , &FitEditorUnitTesting::TestHistogramFit);
447+
448+ result += MakeTest (" TestGSLFit........." , &FitEditorUnitTesting::TestGSLFit);
449+
450+ result += MakeTest (" TestUpdate........." , &FitEditorUnitTesting::TestUpdate);
451+
452+ result += MakeTest (" TestGraph.........." , &FitEditorUnitTesting::TestGraph);
453+
454+ result += MakeTest (" TestGraphError....." , &FitEditorUnitTesting::TestGraphError);
455+
456+ result += MakeTest (" TestGraph2D........" , &FitEditorUnitTesting::TestGraph2D);
457+
458+ result += MakeTest (" TestGraph2DError..." , &FitEditorUnitTesting::TestGraph2DError);
459+
460+ result += MakeTest (" TestUpdateTree....." , &FitEditorUnitTesting::TestUpdateTree);
461+
462+ // TODO: reenable in batch once stack smashing issue is fixed
463+ if (!gROOT ->IsBatch ())
464+ result += MakeTest (" TestTree1D........." , &FitEditorUnitTesting::TestTree1D);
465+
466+ // TODO: reenable once fit results are fixed
467+ // result += MakeTest("TestTree2D.........", &FitEditorUnitTesting::TestTree2D);
468+
469+ // TODO: reenable once fit results are fixed
470+ // result += MakeTest("TestTreeND.........", &FitEditorUnitTesting::TestTreeND);
471+
472+ fprintf (stdout, " \n Remember to also check outputUnitTesting.txt for "
473+ " more detailed information\n\n " );
474+
475+ return result;
476+ }
477+
501478};
502479
503480// Runs the basic script and pops out the fit panel. Then it will
@@ -507,11 +484,21 @@ int UnitTesting()
507484{
508485 gROOT ->SetWebDisplay (" off" );
509486
487+ gTmpfilename = " UnitTesting.log" ;
488+ auto f = gSystem ->TempFileName (gTmpfilename );
489+ fclose (f);
490+
510491 FitEditorUnitTesting fUT ;
511492
512- return fUT .UnitTesting ();
493+ auto res = fUT .UnitTesting ();
494+
495+ gSystem ->Unlink (gTmpfilename .Data ());
496+
497+ return res;
513498}
514499
500+ #ifndef __ROOTCLING__
501+
515502// The main function. It is VERY important that it is run using the
516503// TApplication.
517504int main (int argc, char ** argv)
@@ -528,3 +515,5 @@ int main(int argc, char** argv)
528515
529516 return ret;
530517}
518+
519+ #endif
0 commit comments