GammaLib 2.2.0.dev
Loading...
Searching...
No Matches
GTestSuite.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * GTestSuite.cpp - Abstract test suite base class *
3 * ----------------------------------------------------------------------- *
4 * copyright (C) 2012-2026 by Jean-Baptiste Cayrou *
5 * ----------------------------------------------------------------------- *
6 * *
7 * This program is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 * *
20 ***************************************************************************/
21/**
22 * @file GTestSuite.cpp
23 * @brief Abstract test suite base class implementation
24 * @author Jean-Baptiste Cayrou
25 */
26
27/* __ Includes ___________________________________________________________ */
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31#include <typeinfo>
32#include "GTestSuite.hpp"
33#include "GTools.hpp"
34#include "GLog.hpp"
35
36/* __ OpenMP section _____________________________________________________ */
37#ifdef _OPENMP
38#include <omp.h>
39#ifdef HAVE_OPENMP_DARWIN_KLUGE
40#include <pthread.h>
41pthread_attr_t gomp_thread_attr;
42#endif
43#endif
44
45/* __ Method name definitions ____________________________________________ */
46#define G_OP_ACCESS "GTestSuite::operator[](int&)"
47#define G_TRY_SUCCESS "GTestSuite::test_try_success()"
48#define G_TRY_FAILURE1 "GTestSuite::test_try_failure(std::string&,"\
49 " std::string&)"
50#define G_TRY_FAILURE2 "GTestSuite::test_try_failure(std::exception&)"
51
52/* __ Macros _____________________________________________________________ */
53
54/* __ Coding definitions _________________________________________________ */
55
56/* __ Debug definitions __________________________________________________ */
57
58
59/*==========================================================================
60 = =
61 = Constructors/destructors =
62 = =
63 ==========================================================================*/
64
65/***********************************************************************//**
66 * @brief Void constructor
67 ***************************************************************************/
69{
70 // Initialise members
72
73 //Return
74 return;
75}
76
77
78/***********************************************************************//**
79 * @brief Copy constructor
80 *
81 * @param[in] suite Test Suite.
82 ***************************************************************************/
84{
85 // Initialise members
87
88 // Copy members
89 copy_members(suite);
90
91 //Return
92 return;
93}
94
95
96/***********************************************************************//**
97 * @brief Name constructor
98 *
99 * @param[in] name Test suite name.
100 ***************************************************************************/
101GTestSuite::GTestSuite(const std::string& name)
102{
103 // Initialise members
104 init_members();
105
106 // Set name
107 m_name = name;
108
109 //Return
110 return;
111}
112
113
114/***********************************************************************//**
115 * @brief Destructor
116 ***************************************************************************/
118{
119 // Free members
120 free_members();
121
122 // Return
123 return;
124}
125
126
127/*==========================================================================
128 = =
129 = Operators =
130 = =
131 ==========================================================================*/
132
133/***********************************************************************//**
134 * @brief Assignment operator
135 *
136 * @param[in] suite Test suite.
137 * @return Test suite.
138 ***************************************************************************/
140{
141 // Execute only if object is not identical
142 if (this != &suite) {
143
144 // Free members
145 free_members();
146
147 // Initialise members
148 init_members();
149
150 // Copy members
151 copy_members(suite);
152
153 } // endif: object was not identical
154
155 // Return
156 return *this;
157}
158
159
160/***********************************************************************//**
161 * @brief Returns reference to test case
162 *
163 * @param[in] index Test case index [0,...,size()-1].
164 * @return Reference to test case.
165 *
166 * @exception GException::out_of_range
167 * Test case index is out of range.
168 ***************************************************************************/
170{
171 // Compile option: raise exception if index is out of range
172 #if defined(G_RANGE_CHECK)
173 if (index < 0 || index >= size()) {
174 throw GException::out_of_range(G_OP_ACCESS, "Test case index", index, size());
175 }
176 #endif
177
178 // Return reference
179 return (m_tests[index]);
180}
181
182
183/***********************************************************************//**
184 * @brief Returns const reference to test case
185 *
186 * @param[in] index Test case index [0,...,size()-1].
187 * @return Const reference to test case.
188 *
189 * @exception GException::out_of_range
190 * Test case index is out of range.
191 ***************************************************************************/
192const GTestCase& GTestSuite::operator[](const int& index) const
193{
194 // Compile option: raise exception if index is out of range
195 #if defined(G_RANGE_CHECK)
196 if (index < 0 || index >= size()) {
197 throw GException::out_of_range(G_OP_ACCESS, "Test case index", index, size());
198 }
199 #endif
200
201 // Return reference
202 return (m_tests[index]);
203}
204
205
206/*==========================================================================
207 = =
208 = Public methods =
209 = =
210 ==========================================================================*/
211
212/***********************************************************************//**
213 * @brief Clear test suite
214 ***************************************************************************/
216{
217 // Free members
218 free_members();
219
220 // Initialise members
221 init_members();
222
223 // Return
224 return;
225}
226
227
228/***********************************************************************//**
229 * @brief Append test functions to test suite
230 *
231 * @param[in] function Test function pointer.
232 * @param[in] name Test name.
233 *
234 * This method adds test functions to the test suite. The test functions will
235 * be executed when the run method is called.
236 ***************************************************************************/
237void GTestSuite::append(const pfunction function, const std::string& name)
238{
239 // Add test function pointer and name to suite
240 m_functions.push_back(function);
241 m_names.push_back(name);
242
243 // Return
244 return;
245}
246
247
248/***********************************************************************//**
249 * @brief Run all tests in test suite
250 *
251 * @return True if all tests were successful, false otherwise.
252 *
253 * Executes all test functions that have been appended to the test suite.
254 * For each test function a test case is added to the test suite.
255 ***************************************************************************/
257{
258 // Setup the test functions. This is a pure virtual function that needs
259 // to be implemented in the derived class. It sets the function
260 // pointers and function names for all test functions that should be
261 // executed.
262 set();
263
264 // Initialise success flag
265 bool success = true;
266
267 // Loop over all functions in suite
268 for (m_index = 0; m_index < m_functions.size(); ++m_index) {
269
270 // Continue only if function is valid
271 if (m_functions[m_index] != NULL) {
272
273 // Save the number of errors and failures before test
274 // execution. We use this after the test to see if
275 // any failures occured.
276 int old_errors = errors();
277 int old_failures = failures();
278
279 // Log the name of the test
280 std::cout << m_names[m_index] << ": ";
281
282 // Create a test of error type for function testing
284
285 // Set start time
286 #ifdef _OPENMP
287 double t_start = omp_get_wtime();
288 #else
289 clock_t t_start = clock();
290 #endif
291
292 // Execute test function
293 try {
294 (this->*(m_functions[m_index]))();
295 }
296 catch (std::exception& e) {
297
298 // Signal that test did not succeed
299 test.has_passed(false);
300
301 // Set test message to exception message
302 test.message(e.what());
303
304 // Set type as class name
305 test.type(typeid(e).name());
306
307 }
308 catch (...)
309 {
310 // For other exceptions
311 test.has_passed(false);
312 test.message("Non-standard C++ exception thrown");
313 }
314
315 // Compute elapsed time
316 #ifdef _OPENMP
317 double t_elapse = omp_get_wtime()-t_start;
318 #else
319 double t_elapse = (double)(clock() - t_start) / (double)CLOCKS_PER_SEC;
320 #endif
321
322 // Set test duration
323 test.duration(t_elapse);
324
325 // Increment number of errors if the test did not pass
326 if (!test.has_passed()) {
327 m_errors++;
328 }
329
330 // Log the result (".","F" or, "E")
331 std::cout << test.print();
332
333 // Log if there are errors or failures
334 if ((m_errors == old_errors && m_failures == old_failures)) {
335 std::cout << " ok" << std::endl;
336 }
337 else {
338 std::cout << " NOK" << std::endl;
339 success = false;
340 }
341
342 // Add function testing test case to test suite
343 m_tests.push_back(test);
344
345 } // endif: test case has a function pointer
346
347 } // endfor: looped over tests on the stack
348
349 // Reset index
350 m_index = 0;
351
352 // Return success flag
353 return success;
354}
355
356
357/***********************************************************************//**
358 * @brief Test an assert
359 *
360 * @param[in] assert Assert (true/false).
361 * @param[in] name Test case name.
362 * @param[in] message Test case name (defaults to "").
363 *
364 * Tests if a condition is true or false. This method adds a test case of
365 * type "failure" to the test suite.
366 *
367 * Examples:
368 * test_assert(x>3, "Test if x > 3");
369 * test_assert(x>3 && x<10, "Test if 3 < x < 10 ");
370 ***************************************************************************/
371void GTestSuite::test_assert(const bool& assert,
372 const std::string& name,
373 const std::string& message)
374{
375 // Create a test case of failure type
377
378 // If assert is false then signal that the test is not passed and
379 // increment the number of failures in this test suite
380 if (!assert) {
381 testcase.has_passed(false);
382 m_failures++;
383 }
384
385 // Set message
386 testcase.message(message);
387
388 // Log the result (".","F" or, "E")
389 std::cout << testcase.print();
390
391 // Add test case to test suite
392 m_tests.push_back(testcase);
393
394 // Return
395 return;
396}
397
398
399/***********************************************************************//**
400 * @brief Test an integer value
401 *
402 * @param[in] value Integer value to test.
403 * @param[in] expected Expected integer value.
404 * @param[in] name Test case name.
405 * @param[in] message Test case message.
406 *
407 * Test if integer @p value is the @p expected value.
408 ***************************************************************************/
409void GTestSuite::test_value(const int& value,
410 const int& expected,
411 const std::string& name,
412 const std::string& message)
413{
414 // Set test case name. If no name is specify then build the name from
415 // the actual test parameters.
416 std::string formated_name;
417 if (name != "") {
418 formated_name = format_name(name);
419 }
420 else {
421 formated_name = format_name("Test if "+gammalib::str(value)+" is "+
422 gammalib::str(expected));
423 }
424
425 // Create a test case of failure type
426 GTestCase testcase(GTestCase::FAIL_TEST, formated_name);
427
428 // If value is not the expected one then signal test as failed and
429 // increment the number of failures
430 if (value != expected) {
431 testcase.has_passed(false);
432 m_failures++;
433 }
434
435 // If no message is specified then build message from test result
436 std::string formated_message;
437 if (message != "") {
438 formated_message = message;
439 }
440 else {
441 formated_message = "Value "+gammalib::str(value)+" equals not the "+
442 "expected value of "+gammalib::str(expected)+".";
443 }
444
445 // Set message
446 testcase.message(formated_message);
447
448 // Log the result (".","F" or, "E")
449 std::cout << testcase.print();
450
451 // Add test case to test suite
452 m_tests.push_back(testcase);
453
454 // Return
455 return;
456}
457
458
459/***********************************************************************//**
460 * @brief Test a double precision value
461 *
462 * @param[in] value Double precision value to test.
463 * @param[in] expected Expected double precision value.
464 * @param[in] name Test case name.
465 * @param[in] message Test case message.
466 *
467 * Test if the @p value is equal to the @p expected value within a relative
468 * precision of 1.0e-7.
469 ***************************************************************************/
470void GTestSuite::test_value(const double& value,
471 const double& expected,
472 const std::string& name,
473 const std::string& message)
474{
475 // Compute precision
476 double eps = (expected != 0.0) ? 1.0e-7 * std::abs(expected) : 1.0e-7;
477
478 // Test double precision value
479 test_value(value, expected, eps, name, message);
480
481 // Return
482 return;
483}
484
485
486/***********************************************************************//**
487 * @brief Test a double precision value
488 *
489 * @param[in] value Double precision value to test.
490 * @param[in] expected Expected double precision value.
491 * @param[in] eps Precision of the test.
492 * @param[in] name Test case name.
493 * @param[in] message Test case message.
494 *
495 * Test if the value is comprised in the interval
496 * [expected-eps, expected+eps].
497 ***************************************************************************/
498void GTestSuite::test_value(const double& value,
499 const double& expected,
500 const double& eps,
501 const std::string& name,
502 const std::string& message)
503{
504 // Set test case name. If no name is specify then build the name from
505 // the actual test parameters.
506 std::string formated_name;
507 if (name != "") {
508 formated_name = format_name(name);
509 }
510 else {
511 formated_name = format_name("Test if "+gammalib::str(value)+
512 " is comprised within "+
513 gammalib::str(expected)+" +/- "+
514 gammalib::str(eps));
515 }
516
517 // Create a test case of failure type
518 GTestCase testcase(GTestCase::FAIL_TEST, formated_name);
519
520 // If value is not between in interval [expected-eps, expected+eps]
521 // then signal test as failed and increment the number of failures
522 if (value > expected + eps || value < expected - eps) {
523 testcase.has_passed(false);
524 m_failures++;
525 }
526
527 // If no message is specified then build message from test result
528 std::string formated_message;
529 if (message != "") {
530 formated_message = message;
531 }
532 else {
533 formated_message = "Value "+gammalib::str(value)+" not within "+
534 gammalib::str(expected)+" +/- "+gammalib::str(eps)+
535 " (value-expected = "+gammalib::str(value-expected)+
536 ").";
537 }
538
539 // Set message
540 testcase.message(formated_message);
541
542 // Log the result (".","F" or, "E")
543 std::cout << testcase.print();
544
545 // Add test case to test suite
546 m_tests.push_back(testcase);
547
548 // Return
549 return;
550}
551
552
553/***********************************************************************//**
554 * @brief Test a complex value
555 *
556 * @param[in] value Complex value to test.
557 * @param[in] expected Expected complex value.
558 * @param[in] name Test case name.
559 * @param[in] message Test case message.
560 *
561 * Test if the @p value is equal to the @p expected value within a relative
562 * precision of 1.0e-7.
563 ***************************************************************************/
564void GTestSuite::test_value(const std::complex<double>& value,
565 const std::complex<double>& expected,
566 const std::string& name,
567 const std::string& message)
568{
569 // Compute precision
570 double eps = (expected != 0.0) ? 1.0e-7 * std::abs(expected) : 1.0e-7;
571
572 // Test double precision value
573 test_value(value, expected, eps, name, message);
574
575 // Return
576 return;
577}
578
579
580/***********************************************************************//**
581 * @brief Test a complex value
582 *
583 * @param[in] value Complex value to test.
584 * @param[in] expected Expected complex value.
585 * @param[in] eps Precision of the test.
586 * @param[in] name Test case name.
587 * @param[in] message Test case message.
588 *
589 * Test if the value is comprised in the interval
590 * [expected-eps, expected+eps].
591 ***************************************************************************/
592void GTestSuite::test_value(const std::complex<double>& value,
593 const std::complex<double>& expected,
594 const double& eps,
595 const std::string& name,
596 const std::string& message)
597{
598 // Set test case name. If no name is specify then build the name from
599 // the actual test parameters.
600 std::string formated_name;
601 if (name != "") {
602 formated_name = format_name(name);
603 }
604 else {
605 formated_name = format_name("Test if "+gammalib::str(value)+
606 " is comprised within "+
607 gammalib::str(expected)+" +/- "+
608 gammalib::str(eps));
609 }
610
611 // Create a test case of failure type
612 GTestCase testcase(GTestCase::FAIL_TEST, formated_name);
613
614 // If value is not between in interval [expected-eps, expected+eps]
615 // then signal test as failed and increment the number of failures
616 if ((value.real() > expected.real() + eps) ||
617 (value.real() < expected.real() - eps) ||
618 (value.imag() > expected.imag() + eps) ||
619 (value.imag() < expected.imag() - eps)) {
620 testcase.has_passed(false);
621 m_failures++;
622 }
623
624 // If no message is specified then build message from test result
625 std::string formated_message;
626 if (message != "") {
627 formated_message = message;
628 }
629 else {
630 formated_message = "Value "+gammalib::str(value)+" not within "+
631 gammalib::str(expected)+" +/- "+gammalib::str(eps)+
632 " (value-expected = "+gammalib::str(value-expected)+
633 ").";
634 }
635
636 // Set message
637 testcase.message(formated_message);
638
639 // Log the result (".","F" or, "E")
640 std::cout << testcase.print();
641
642 // Add test case to test suite
643 m_tests.push_back(testcase);
644
645 // Return
646 return;
647}
648
649
650/***********************************************************************//**
651 * @brief Test a string value
652 *
653 * @param[in] value String value to test.
654 * @param[in] expected Expected string value.
655 * @param[in] name Test case name (defaults to "").
656 * @param[in] message Test case message (defaults to "").
657 *
658 * Test if the string @p value corresponds to the @p expected value.
659 ***************************************************************************/
660void GTestSuite::test_value(const std::string& value,
661 const std::string& expected,
662 const std::string& name,
663 const std::string& message)
664{
665 // Set test case name. If no name is specify then build the name from
666 // the actual test parameters.
667 std::string formated_name;
668 if (name != "") {
669 formated_name = format_name(name);
670 }
671 else {
672 formated_name = format_name("Test if \""+value+"\" is \""+expected+"\"");
673 }
674
675 // Create a test case of failure type
676 GTestCase testcase(GTestCase::FAIL_TEST, formated_name);
677
678 // If value is not the expected one then signal test as failed and
679 // increment the number of failures
680 if (value != expected) {
681 testcase.has_passed(false);
682 m_failures++;
683 }
684
685 // If no message is specified then build message from test result
686 std::string formated_message;
687 if (message != "") {
688 formated_message = message;
689 }
690 else {
691 formated_message = "String \""+value+"\" is not equal to the "+
692 "expected string \""+expected+"\".";
693 }
694
695 // Set message
696 testcase.message(formated_message);
697
698 // Log the result (".","F" or, "E")
699 std::cout << testcase.print();
700
701 // Add test case to test suite
702 m_tests.push_back(testcase);
703
704 // Return
705 return;
706}
707
708
709/***********************************************************************//**
710 * @brief Test an try block
711 *
712 * @param[in] name Test case name (defaults to "").
713 *
714 * @see test_try_sucess()
715 * @see test_try_failure(const std::string& message,const std::string& type)
716 * @see test_try_failure(const std::exception& e)
717 *
718 * Call before testing a try/catch block.
719 *
720 * Example:
721 * test_try("Test a try block");
722 * try {
723 * ... //someting to test
724 * test_try_success();
725 * }
726 * catch(...) {
727 * test_try_failure();
728 * }
729 ***************************************************************************/
730void GTestSuite::test_try(const std::string& name)
731{
732 // Create a test case of error type
734
735 // Add test case to try stack of test suite
736 m_stack_try.push_back(testcase);
737
738 // Return
739 return;
740}
741
742
743/***********************************************************************//**
744 * @brief Notice when a try block succeeded
745 *
746 * @exception GException::test_nested_try_error
747 * Test case index is out of range.
748 *
749 * @see test_try(const std::string& name)
750 * @see test_try_failure(const std::string& message, const std::string& type)
751 * @see test_try_failure(const std::exception& e)
752 *
753 * Call this method at the last line of a try
754 *
755 * Example:
756 * test_try("Test a try block");
757 * try {
758 * ... //someting to test
759 * test_try_success();
760 * }
761 * catch(...) {
762 * test_try_failure();
763 * }
764 ***************************************************************************/
766{
767 // If the stack is empty
768 if (m_stack_try.empty()) {
770 "Called \"G_TRY_SUCCESS\" without a previous call to test_try()");
771 }
772
773 // Add test case to test suite
774 m_tests.push_back(m_stack_try.back());
775
776 // Delete the test case from the try stack
777 m_stack_try.pop_back();
778
779 // Log the result (".","F" or, "E")
780 std::cout << m_tests.back().print();
781
782 // Return
783 return;
784}
785
786
787/***********************************************************************//**
788 * @brief Notice when a try block failed
789 *
790 * @param[in] message Message to explain why test failed (defaults to "").
791 * @param[in] type Type of message (defaults to "").
792 *
793 * @exception GException::test_nested_try_error
794 * Test case index is out of range.
795 *
796 * @see test_try_sucess()
797 * @see test_try(const std::string& name)
798 * @see test_try_failure(const std::exception& e)
799 *
800 * Call this method in the catch block.
801 *
802 * Example:
803 * test_try("Test a try block");
804 * try {
805 * ... //someting to test
806 * test_try_success();
807 * }
808 * catch(...) {
809 * test_try_failure();
810 * }
811 ***************************************************************************/
812void GTestSuite::test_try_failure(const std::string& message,
813 const std::string& type)
814{
815 // If the stack is empty then create an eception test case
816 if (m_stack_try.empty()) {
817 GTestCase testcase(GTestCase::ERROR_TEST, "Exception test");
818 m_stack_try.push_back(testcase);
819 }
820
821 // Signal that test is not ok
822 m_stack_try.back().has_passed(false);
823
824 // Increment the number of errors
825 m_errors++;
826
827 // Set test type
829
830 // Set message
831 m_stack_try.back().message(message);
832
833 // Set type of message
834 m_stack_try.back().type(type);
835
836 // Add test case to test suite
837 m_tests.push_back(m_stack_try.back());
838
839 // Delete the test case from the stack
840 m_stack_try.pop_back();
841
842 // Log the result ( ".","F" or, "E")
843 std::cout << m_tests.back().print();
844
845 //Return
846 return;
847}
848
849
850/***********************************************************************//**
851 * @brief Notice when a try block failed
852 *
853 * @param[in] e Exception.
854 *
855 * @exception GException::test_nested_try_error
856 * Test case index is out of range.
857 *
858 * @see test_try_sucess()
859 * @see test_try(const std::string& name)
860 * @see test_try_failure(const std::string& message, const std::string& type)
861 *
862 * Call this method in a catch block.
863 *
864 * Example:
865 * test_try("Test a try block");
866 * try {
867 * ... //someting to test
868 * test_try_success();
869 * }
870 * catch(exception& e) {
871 * test_try_failure(e);
872 * }
873 ***************************************************************************/
874void GTestSuite::test_try_failure(const std::exception& e)
875{
876 // Extract message of exception and class name
877 test_try_failure(e.what(), typeid(e).name());
878
879 // Return
880 return;
881}
882
883
884/***********************************************************************//**
885 * @brief Return a failure exception
886 *
887 * @param[in] message Message.
888 *
889 * @see test_try()
890 * @see test_error(const std::string& message)
891 *
892 * It can be use in a try test
893 *
894 * Example:
895 * test_try("Test a try block");
896 * try {
897 * throw exception_failure("a failure");
898 * test_try_success();
899 * }
900 * catch(exception& e) {
901 * test_try_failure(e);
902 * }
903 ***************************************************************************/
905{
906 // Return exception
907 return *(new GException::test_failure(m_stack_try.back().name(), message));
908}
909
910
911/***********************************************************************//**
912 * @brief Return an error exception
913 *
914 * @param[in] message Message.
915 *
916 * @see test_try()
917 * @see test_failure(const std::string& message)
918 *
919 * It can be use in a try test
920 *
921 * Example:
922 * test_try("Test a try block");
923 * try {
924 * throw exception_error("an error");
925 * test_try_success();
926 * }
927 * catch(exception& e) {
928 * test_try_failure(e);
929 * }
930 ***************************************************************************/
932{
933 // Return exception
934 return *(new GException::test_error(m_stack_try.back().name(),message));
935}
936
937
938/***********************************************************************//**
939 * @brief Return the number of successful tests
940 ***************************************************************************/
941int GTestSuite::success(void) const
942{
943 // Return successes
944 return size()-(m_errors+m_failures);
945}
946
947
948/***********************************************************************//**
949 * @brief Return the total duration of all tests
950 *
951 * This method sums up all test durations and returns the result.
952 ***************************************************************************/
953double GTestSuite::duration(void) const
954{
955 // Initialise duration
956 double duration = 0.0;
957
958 // Add up the durations of all tests
959 for (int i = 0; i < m_tests.size(); ++i) {
960 duration += m_tests[i].duration();
961 }
962
963 // Return duration
964 return duration;
965}
966
967
968/***********************************************************************//**
969 * @brief Print test suite information
970 *
971 * @param[in] chatter Chattiness (defaults to NORMAL).
972 * @return String containing test suite information.
973 ***************************************************************************/
974std::string GTestSuite::print(const GChatter& chatter) const
975{
976 // Initialise result string
977 std::string result;
978
979 // Continue only if chatter is not silent
980 if (chatter != SILENT) {
981
982 // Append header
983 result.append("=== GTestSuite ===");
984
985 // Append information
986 result.append("\n"+gammalib::parformat("Name")+m_name);
987 result.append("\n"+gammalib::parformat("Number of functions"));
988 result.append(gammalib::str(m_names.size()));
989 result.append("\n"+gammalib::parformat("Number of executed tests"));
990 result.append(gammalib::str(size()));
991 result.append("\n"+gammalib::parformat("Number of errors"));
992 result.append(gammalib::str(errors()));
993 result.append("\n"+gammalib::parformat("Number of failures"));
994 result.append(gammalib::str(failures()));
995
996 } // endif: chatter was not silent
997
998 // Return result
999 return result;
1000}
1001
1002
1003/*==========================================================================
1004 = =
1005 = Private methods =
1006 = =
1007 ==========================================================================*/
1008
1009/***********************************************************************//**
1010 * @brief Initialise class members
1011 ***************************************************************************/
1013{
1014 // Initialise members
1015 m_name = "Unnamed Test Suite";
1016 m_names.clear();
1017 m_functions.clear();
1018 m_tests.clear();
1019 m_stack_try.clear();
1020 m_index = 0;
1021 m_failures = 0;
1022 m_errors = 0;
1023 m_log.clear();
1024 m_timestamp = time(NULL);
1025
1026 // Set logger parameters
1027 cout(true);
1028 m_log.buffer_size(1);
1029
1030 // Return
1031 return;
1032}
1033
1034/***********************************************************************//**
1035 * @brief Copy class members
1036 *
1037 * @param[in] suite Test suite.
1038 ***************************************************************************/
1040{
1041 // Copy members
1042 m_name = suite.m_name;
1043 m_names = suite.m_names;
1044 m_functions = suite.m_functions;
1045 m_tests = suite.m_tests;
1046 m_stack_try = suite.m_stack_try;
1047 m_index = suite.m_index;
1048 m_failures = suite.m_failures;
1049 m_errors = suite.m_errors;
1050 m_log = suite.m_log;
1051 m_timestamp = suite.m_timestamp;
1052
1053 // Return
1054 return;
1055}
1056
1057
1058/***********************************************************************//**
1059 * @brief Delete class members
1060 ***************************************************************************/
1062{
1063 // Close logger
1064 m_log.close();
1065
1066 // Return
1067 return;
1068}
1069
1070
1071/***********************************************************************//**
1072 * @brief Format Name
1073 *
1074 * Return a string with the format
1075 * "TestFunctionName:TestTryname1:TestTryName2: name"
1076 ***************************************************************************/
1077std::string GTestSuite::format_name(const std::string& name)
1078{
1079 // Initialise format name
1080 std::string format_name;
1081
1082 // Set name of the try blocks
1083 if (!m_stack_try.empty()) {
1084 format_name = m_stack_try.back().name();
1085 }
1086 else {
1087 // Set name of the test
1089 }
1090
1091 // Append test suite name
1092 format_name += ": " + name;
1093
1094 // Return format
1095 return format_name;
1096}
Information logger class definition.
#define G_OP_ACCESS
Definition GPhotons.cpp:36
#define G_TRY_SUCCESS
Abstract test suite base class definition.
void(GTestSuite::* pfunction)(void)
Gammalib tools definition.
GChatter
Definition GTypemaps.hpp:33
@ SILENT
Definition GTypemaps.hpp:34
void buffer_size(const int &size)
Set the buffer size.
Definition GLog.hpp:327
void close(void)
Close log file.
Definition GLog.cpp:538
void clear(void)
Clear object.
Definition GLog.cpp:456
Test class.
Definition GTestCase.hpp:47
const double & duration(void) const
Return test case duration.
const bool & has_passed(void) const
Return whether the test passed.
std::string print(const GChatter &chatter=NORMAL) const
Print test case result.
const std::string & type(void) const
Return test case type.
const std::string & message(void) const
Return test case message.
Abstract test suite class for unit testing on GammaLib fixtures.
void test_try_failure(const std::string &message="", const std::string &type="")
Notice when a try block failed.
bool run(void)
Run all tests in test suite.
void test_try_success(void)
Notice when a try block succeeded.
void clear(void)
Clear test suite.
GException::test_failure & exception_failure(const std::string &message)
Return a failure exception.
std::vector< GTestCase > m_tests
List of test results.
int m_errors
Number of errors.
const int & failures(void) const
Return the number of failures.
void test_value(const int &value, const int &expected, const std::string &name="", const std::string &message="")
Test an integer value.
void copy_members(const GTestSuite &testsuite)
Copy class members.
std::vector< pfunction > m_functions
Test functions of this suite.
void test_assert(const bool &result, const std::string &name, const std::string &message="")
Test an assert.
int m_failures
Number of failures.
void init_members(void)
Initialise class members.
void free_members(void)
Delete class members.
void append(pfunction function, const std::string &name)
Append test functions to test suite.
GTestCase & operator[](const int &index)
Returns reference to test case.
virtual void set(void)=0
time_t m_timestamp
Timestamp.
int size(void) const
Return number of tests in test suite.
std::string print(const GChatter &chatter=NORMAL) const
Print test suite information.
GTestSuite(void)
Void constructor.
GTestSuite & operator=(const GTestSuite &testsuite)
Assignment operator.
const int & errors(void) const
Return the number of errors.
std::string m_name
Name of the test suite.
void cout(const bool &flag)
Enables/disables logging into standard output stream.
virtual ~GTestSuite(void)
Destructor.
GException::test_error & exception_error(const std::string &message)
Return an error exception.
void test_try(const std::string &name)
Test an try block.
int success(void) const
Return the number of successful tests.
GLog m_log
Log.
int m_index
Index of actual test function.
std::string format_name(const std::string &name)
Format Name.
const std::string & name(void) const
Return test suite name.
std::vector< GTestCase > m_stack_try
Stack for nested try blocks.
double duration(void) const
Return the total duration of all tests.
std::vector< std::string > m_names
Names of test functions.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
Definition GTools.cpp:1136
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:508