Skip to content

Commit 5eaf984

Browse files
committed
Modernize fitpanel UnitTesting.cxx
Do not automatically terminate application Use gSystem->RedirectOutput
1 parent a52bcd2 commit 5eaf984

1 file changed

Lines changed: 87 additions & 98 deletions

File tree

gui/fitpanel/test/UnitTesting.cxx

Lines changed: 87 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
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"
@@ -27,11 +26,8 @@
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
3733
int 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;
109101
public:
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, "\nRemember 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, "\nRemember 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.
517504
int 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

Comments
 (0)