GammaLib 2.0.0
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-2016 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 *
165 * @exception GException::out_of_range
166 * Test case index is out of range.
167 ***************************************************************************/
169{
170 // Compile option: raise exception if index is out of range
171 #if defined(G_RANGE_CHECK)
172 if (index < 0 || index >= size()) {
173 throw GException::out_of_range(G_OP_ACCESS, "Test case index", index, size());
174 }
175 #endif
176
177 // Return reference
178 return *(m_tests[index]);
179}
180
181/***********************************************************************//**
182 * @brief Returns reference to test case
183 *
184 * @param[in] index Test case index [0,...,size()-1].
185 *
186 * @exception GException::out_of_range
187 * Test case index is out of range.
188 ***************************************************************************/
189const GTestCase& GTestSuite::operator[](const int& index) const
190{
191 // Compile option: raise exception if index is out of range
192 #if defined(G_RANGE_CHECK)
193 if (index < 0 || index >= size()) {
194 throw GException::out_of_range(G_OP_ACCESS, "Test case index", index, size());
195 }
196 #endif
197
198 // Return reference
199 return *(m_tests[index]);
200}
201
202
203/*==========================================================================
204 = =
205 = Public methods =
206 = =
207 ==========================================================================*/
208
209/***********************************************************************//**
210 * @brief Clear test suite
211 ***************************************************************************/
213{
214 // Free members
215 free_members();
216
217 // Initialise members
218 init_members();
219
220 // Return
221 return;
222}
223
224
225/***********************************************************************//**
226 * @brief Append test functions to test suite
227 *
228 * @param[in] function Test function pointer.
229 * @param[in] name Test name.
230 *
231 * This method adds test functions to the test suite. The test functions will
232 * be executed when the run method is called.
233 ***************************************************************************/
234void GTestSuite::append(const pfunction function, const std::string& name)
235{
236 // Add test function pointer and name to suite
237 m_functions.push_back(function);
238 m_names.push_back(name);
239
240 // Return
241 return;
242}
243
244
245/***********************************************************************//**
246 * @brief Run all tests in test suite
247 *
248 * @return True if all tests were successful, false otherwise.
249 *
250 * Executes all test functions that have been appended to the test suite.
251 * For each test function a test case is added to the test suite.
252 ***************************************************************************/
254{
255 // Setup the test functions. This is a pure virtual function that needs
256 // to be implemented in the derived class. It sets the function
257 // pointers and function names for all test functions that should be
258 // executed.
259 set();
260
261 // Initialise success flag
262 bool success = true;
263
264 // Loop over all functions in suite
265 for (m_index = 0; m_index < m_functions.size(); ++m_index) {
266
267 // Continue only if function is valid
268 if (m_functions[m_index] != NULL) {
269
270 // Save the number of errors and failures before test
271 // execution. We use this after the test to see if
272 // any failures occured.
273 int old_errors = errors();
274 int old_failures = failures();
275
276 // Log the name of the test
277 std::cout << m_names[m_index] << ": ";
278
279 // Create a test of error type for function testing
281
282 // Add test case to test suite
283 m_tests.push_back(test);
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 } // endif: test case has a function pointer
343
344 } // endfor: looped over tests on the stack
345
346 // Reset index
347 m_index = 0;
348
349 // Return success flag
350 return success;
351}
352
353
354/***********************************************************************//**
355 * @brief Test an assert
356 *
357 * @param[in] assert Assert (true/false).
358 * @param[in] name Test case name.
359 * @param[in] message Test case name (defaults to "").
360 *
361 * Tests if a condition is true or false. This method adds a test case of
362 * type "failure" to the test suite.
363 *
364 * Examples:
365 * test_assert(x>3, "Test if x > 3");
366 * test_assert(x>3 && x<10, "Test if 3 < x < 10 ");
367 ***************************************************************************/
368void GTestSuite::test_assert(const bool& assert,
369 const std::string& name,
370 const std::string& message)
371{
372 // Create a test case of failure type
374
375 // If assert is false then signal that the test is not passed and
376 // increment the number of failures in this test suite
377 if (!assert) {
378 testcase->has_passed(false);
379 m_failures++;
380 }
381
382 // Set message
383 testcase->message(message);
384
385 // Log the result (".","F" or, "E")
386 std::cout << testcase->print();
387
388 // Add test case to test suite
389 m_tests.push_back(testcase);
390
391 // Return
392 return;
393}
394
395
396/***********************************************************************//**
397 * @brief Test an integer value
398 *
399 * @param[in] value Integer value to test.
400 * @param[in] expected Expected integer value.
401 * @param[in] name Test case name.
402 * @param[in] message Test case message.
403 *
404 * Test if integer @p value is the @p expected value.
405 ***************************************************************************/
406void GTestSuite::test_value(const int& value,
407 const int& expected,
408 const std::string& name,
409 const std::string& message)
410{
411 // Set test case name. If no name is specify then build the name from
412 // the actual test parameters.
413 std::string formated_name;
414 if (name != "") {
415 formated_name = format_name(name);
416 }
417 else {
418 formated_name = format_name("Test if "+gammalib::str(value)+" is "+
419 gammalib::str(expected));
420 }
421
422 // Create a test case of failure type
423 GTestCase* testcase = new GTestCase(GTestCase::FAIL_TEST, formated_name);
424
425 // If value is not the expected one then signal test as failed and
426 // increment the number of failures
427 if (value != expected) {
428 testcase->has_passed(false);
429 m_failures++;
430 }
431
432 // If no message is specified then build message from test result
433 std::string formated_message;
434 if (message != "") {
435 formated_message = message;
436 }
437 else {
438 formated_message = "Value "+gammalib::str(value)+" equals not the "+
439 "expected value of "+gammalib::str(expected)+".";
440 }
441
442 // Set message
443 testcase->message(formated_message);
444
445 // Log the result (".","F" or, "E")
446 std::cout << testcase->print();
447
448 // Add test case to test suite
449 m_tests.push_back(testcase);
450
451 // Return
452 return;
453}
454
455
456/***********************************************************************//**
457 * @brief Test a double precision value
458 *
459 * @param[in] value Double precision value to test.
460 * @param[in] expected Expected double precision value.
461 * @param[in] name Test case name.
462 * @param[in] message Test case message.
463 *
464 * Test if the @p value is equal to the @p expected value within a relative
465 * precision of 1.0e-7.
466 ***************************************************************************/
467void GTestSuite::test_value(const double& value,
468 const double& expected,
469 const std::string& name,
470 const std::string& message)
471{
472 // Compute precision
473 double eps = (expected != 0.0) ? 1.0e-7 * std::abs(expected) : 1.0e-7;
474
475 // Test double precision value
476 test_value(value, expected, eps, name, message);
477
478 // Return
479 return;
480}
481
482
483/***********************************************************************//**
484 * @brief Test a double precision value
485 *
486 * @param[in] value Double precision value to test.
487 * @param[in] expected Expected double precision value.
488 * @param[in] eps Precision of the test.
489 * @param[in] name Test case name.
490 * @param[in] message Test case message.
491 *
492 * Test if the value is comprised in the interval
493 * [expected-eps, expected+eps].
494 ***************************************************************************/
495void GTestSuite::test_value(const double& value,
496 const double& expected,
497 const double& eps,
498 const std::string& name,
499 const std::string& message)
500{
501 // Set test case name. If no name is specify then build the name from
502 // the actual test parameters.
503 std::string formated_name;
504 if (name != "") {
505 formated_name = format_name(name);
506 }
507 else {
508 formated_name = format_name("Test if "+gammalib::str(value)+
509 " is comprised within "+
510 gammalib::str(expected)+" +/- "+
511 gammalib::str(eps));
512 }
513
514 // Create a test case of failure type
515 GTestCase* testcase = new GTestCase(GTestCase::FAIL_TEST, formated_name);
516
517 // If value is not between in interval [expected-eps, expected+eps]
518 // then signal test as failed and increment the number of failures
519 if (value > expected + eps || value < expected - eps) {
520 testcase->has_passed(false);
521 m_failures++;
522 }
523
524 // If no message is specified then build message from test result
525 std::string formated_message;
526 if (message != "") {
527 formated_message = message;
528 }
529 else {
530 formated_message = "Value "+gammalib::str(value)+" not within "+
531 gammalib::str(expected)+" +/- "+gammalib::str(eps)+
532 " (value-expected = "+gammalib::str(value-expected)+
533 ").";
534 }
535
536 // Set message
537 testcase->message(formated_message);
538
539 // Log the result (".","F" or, "E")
540 std::cout << testcase->print();
541
542 // Add test case to test suite
543 m_tests.push_back(testcase);
544
545 // Return
546 return;
547}
548
549
550/***********************************************************************//**
551 * @brief Test a complex value
552 *
553 * @param[in] value Complex value to test.
554 * @param[in] expected Expected complex value.
555 * @param[in] name Test case name.
556 * @param[in] message Test case message.
557 *
558 * Test if the @p value is equal to the @p expected value within a relative
559 * precision of 1.0e-7.
560 ***************************************************************************/
561void GTestSuite::test_value(const std::complex<double>& value,
562 const std::complex<double>& expected,
563 const std::string& name,
564 const std::string& message)
565{
566 // Compute precision
567 double eps = (expected != 0.0) ? 1.0e-7 * std::abs(expected) : 1.0e-7;
568
569 // Test double precision value
570 test_value(value, expected, eps, name, message);
571
572 // Return
573 return;
574}
575
576
577/***********************************************************************//**
578 * @brief Test a complex value
579 *
580 * @param[in] value Complex value to test.
581 * @param[in] expected Expected complex value.
582 * @param[in] eps Precision of the test.
583 * @param[in] name Test case name.
584 * @param[in] message Test case message.
585 *
586 * Test if the value is comprised in the interval
587 * [expected-eps, expected+eps].
588 ***************************************************************************/
589void GTestSuite::test_value(const std::complex<double>& value,
590 const std::complex<double>& expected,
591 const double& eps,
592 const std::string& name,
593 const std::string& message)
594{
595 // Set test case name. If no name is specify then build the name from
596 // the actual test parameters.
597 std::string formated_name;
598 if (name != "") {
599 formated_name = format_name(name);
600 }
601 else {
602 formated_name = format_name("Test if "+gammalib::str(value)+
603 " is comprised within "+
604 gammalib::str(expected)+" +/- "+
605 gammalib::str(eps));
606 }
607
608 // Create a test case of failure type
609 GTestCase* testcase = new GTestCase(GTestCase::FAIL_TEST, formated_name);
610
611 // If value is not between in interval [expected-eps, expected+eps]
612 // then signal test as failed and increment the number of failures
613 if ((value.real() > expected.real() + eps) ||
614 (value.real() < expected.real() - eps) ||
615 (value.imag() > expected.imag() + eps) ||
616 (value.imag() < expected.imag() - eps)) {
617 testcase->has_passed(false);
618 m_failures++;
619 }
620
621 // If no message is specified then build message from test result
622 std::string formated_message;
623 if (message != "") {
624 formated_message = message;
625 }
626 else {
627 formated_message = "Value "+gammalib::str(value)+" not within "+
628 gammalib::str(expected)+" +/- "+gammalib::str(eps)+
629 " (value-expected = "+gammalib::str(value-expected)+
630 ").";
631 }
632
633 // Set message
634 testcase->message(formated_message);
635
636 // Log the result (".","F" or, "E")
637 std::cout << testcase->print();
638
639 // Add test case to test suite
640 m_tests.push_back(testcase);
641
642 // Return
643 return;
644}
645
646
647/***********************************************************************//**
648 * @brief Test a string value
649 *
650 * @param[in] value String value to test.
651 * @param[in] expected Expected string value.
652 * @param[in] name Test case name (defaults to "").
653 * @param[in] message Test case message (defaults to "").
654 *
655 * Test if the string @p value corresponds to the @p expected value.
656 ***************************************************************************/
657void GTestSuite::test_value(const std::string& value,
658 const std::string& expected,
659 const std::string& name,
660 const std::string& message)
661{
662 // Set test case name. If no name is specify then build the name from
663 // the actual test parameters.
664 std::string formated_name;
665 if (name != "") {
666 formated_name = format_name(name);
667 }
668 else {
669 formated_name = format_name("Test if \""+value+"\" is \""+expected+"\"");
670 }
671
672 // Create a test case of failure type
673 GTestCase* testcase = new GTestCase(GTestCase::FAIL_TEST, formated_name);
674
675 // If value is not the expected one then signal test as failed and
676 // increment the number of failures
677 if (value != expected) {
678 testcase->has_passed(false);
679 m_failures++;
680 }
681
682 // If no message is specified then build message from test result
683 std::string formated_message;
684 if (message != "") {
685 formated_message = message;
686 }
687 else {
688 formated_message = "String \""+value+"\" is not equal to the "+
689 "expected string \""+expected+"\".";
690 }
691
692 // Set message
693 testcase->message(formated_message);
694
695 // Log the result (".","F" or, "E")
696 std::cout << testcase->print();
697
698 // Add test case to test suite
699 m_tests.push_back(testcase);
700
701 // Return
702 return;
703}
704
705
706/***********************************************************************//**
707 * @brief Test an try block
708 *
709 * @param[in] name Test case name (defaults to "").
710 *
711 * @see test_try_sucess()
712 * @see test_try_failure(const std::string& message,const std::string& type)
713 * @see test_try_failure(const std::exception& e)
714 *
715 * Call before testing a try/catch block.
716 *
717 * Example:
718 * test_try("Test a try block");
719 * try {
720 * ... //someting to test
721 * test_try_success();
722 * }
723 * catch(...) {
724 * test_try_failure();
725 * }
726 ***************************************************************************/
727void GTestSuite::test_try(const std::string& name)
728{
729 // Create a test case of error type
731
732 // Add test case to try stack of test suite
733 m_stack_try.push_back(testcase);
734
735 // Return
736 return;
737}
738
739
740/***********************************************************************//**
741 * @brief Notice when a try block succeeded
742 *
743 * @exception GException::test_nested_try_error
744 * Test case index is out of range.
745 *
746 * @see test_try(const std::string& name)
747 * @see test_try_failure(const std::string& message, const std::string& type)
748 * @see test_try_failure(const std::exception& e)
749 *
750 * Call this method at the last line of a try
751 *
752 * Example:
753 * test_try("Test a try block");
754 * try {
755 * ... //someting to test
756 * test_try_success();
757 * }
758 * catch(...) {
759 * test_try_failure();
760 * }
761 ***************************************************************************/
763{
764 // If the stack is empty
765 if (m_stack_try.empty()) {
767 "Called \"G_TRY_SUCCESS\" without a previous call to test_try()");
768 }
769
770 // Add test case to test suite
771 m_tests.push_back(m_stack_try.back());
772
773 // Delete the test case from the try stack
774 m_stack_try.pop_back();
775
776 // Log the result (".","F" or, "E")
777 std::cout << m_tests.back()->print();
778
779 // Return
780 return;
781}
782
783
784/***********************************************************************//**
785 * @brief Notice when a try block failed
786 *
787 * @param[in] message Message to explain why test failed (defaults to "").
788 * @param[in] type Type of message (defaults to "").
789 *
790 * @exception GException::test_nested_try_error
791 * Test case index is out of range.
792 *
793 * @see test_try_sucess()
794 * @see test_try(const std::string& name)
795 * @see test_try_failure(const std::exception& e)
796 *
797 * Call this method in the catch block.
798 *
799 * Example:
800 * test_try("Test a try block");
801 * try {
802 * ... //someting to test
803 * test_try_success();
804 * }
805 * catch(...) {
806 * test_try_failure();
807 * }
808 ***************************************************************************/
809void GTestSuite::test_try_failure(const std::string& message,
810 const std::string& type)
811{
812 // If the stack is empty then create an eception test case
813 if (m_stack_try.empty()) {
814 GTestCase* testcase = new GTestCase(GTestCase::ERROR_TEST, "Exception test");
815 m_stack_try.push_back(testcase);
816 }
817
818 // Signal that test is not ok
819 m_stack_try.back()->has_passed(false);
820
821 // Increment the number of errors
822 m_errors++;
823
824 // Set test type
826
827 // Set message
828 m_stack_try.back()->message(message);
829
830 // Set type of message
831 m_stack_try.back()->type(type);
832
833 // Add test case to test suite
834 m_tests.push_back(m_stack_try.back());
835
836 // Delete the test case from the stack
837 m_stack_try.pop_back();
838
839 // Log the result ( ".","F" or, "E")
840 std::cout << m_tests.back()->print();
841
842 //Return
843 return;
844}
845
846
847/***********************************************************************//**
848 * @brief Notice when a try block failed
849 *
850 * @param[in] e Exception.
851 *
852 * @exception GException::test_nested_try_error
853 * Test case index is out of range.
854 *
855 * @see test_try_sucess()
856 * @see test_try(const std::string& name)
857 * @see test_try_failure(const std::string& message, const std::string& type)
858 *
859 * Call this method in a catch block.
860 *
861 * Example:
862 * test_try("Test a try block");
863 * try {
864 * ... //someting to test
865 * test_try_success();
866 * }
867 * catch(exception& e) {
868 * test_try_failure(e);
869 * }
870 ***************************************************************************/
871void GTestSuite::test_try_failure(const std::exception& e)
872{
873 // Extract message of exception and class name
874 test_try_failure(e.what(), typeid(e).name());
875
876 // Return
877 return;
878}
879
880
881/***********************************************************************//**
882 * @brief Return a failure exception
883 *
884 * @param[in] message Message.
885 *
886 * @see test_try()
887 * @see test_error(const std::string& message)
888 *
889 * It can be use in a try test
890 *
891 * Example:
892 * test_try("Test a try block");
893 * try {
894 * throw exception_failure("a failure");
895 * test_try_success();
896 * }
897 * catch(exception& e) {
898 * test_try_failure(e);
899 * }
900 ***************************************************************************/
902{
903 // Return exception
904 return *(new GException::test_failure(m_stack_try.back()->name(), message));
905}
906
907
908/***********************************************************************//**
909 * @brief Return an error exception
910 *
911 * @param[in] message Message.
912 *
913 * @see test_try()
914 * @see test_failure(const std::string& message)
915 *
916 * It can be use in a try test
917 *
918 * Example:
919 * test_try("Test a try block");
920 * try {
921 * throw exception_error("an error");
922 * test_try_success();
923 * }
924 * catch(exception& e) {
925 * test_try_failure(e);
926 * }
927 ***************************************************************************/
929{
930 // Return exception
931 return *(new GException::test_error(m_stack_try.back()->name(),message));
932}
933
934
935/***********************************************************************//**
936 * @brief Return the number of successful tests
937 ***************************************************************************/
938int GTestSuite::success(void) const
939{
940 // Return successes
941 return size()-(m_errors+m_failures);
942}
943
944
945/***********************************************************************//**
946 * @brief Return the total duration of all tests
947 *
948 * This method sums up all test durations and returns the result.
949 ***************************************************************************/
950double GTestSuite::duration(void) const
951{
952 // Initialise duration
953 double duration = 0.0;
954
955 // Add up the durations of all tests
956 for (int i = 0; i < m_tests.size(); ++i) {
957 duration += m_tests[i]->duration();
958 }
959
960 // Return duration
961 return duration;
962}
963
964
965/***********************************************************************//**
966 * @brief Print test suite information
967 *
968 * @param[in] chatter Chattiness (defaults to NORMAL).
969 * @return String containing test suite information.
970 ***************************************************************************/
971std::string GTestSuite::print(const GChatter& chatter) const
972{
973 // Initialise result string
974 std::string result;
975
976 // Continue only if chatter is not silent
977 if (chatter != SILENT) {
978
979 // Append header
980 result.append("=== GTestSuite ===");
981
982 // Append information
983 result.append("\n"+gammalib::parformat("Name")+m_name);
984 result.append("\n"+gammalib::parformat("Number of functions"));
985 result.append(gammalib::str(m_names.size()));
986 result.append("\n"+gammalib::parformat("Number of executed tests"));
987 result.append(gammalib::str(size()));
988 result.append("\n"+gammalib::parformat("Number of errors"));
989 result.append(gammalib::str(errors()));
990 result.append("\n"+gammalib::parformat("Number of failures"));
991 result.append(gammalib::str(failures()));
992
993 } // endif: chatter was not silent
994
995 // Return result
996 return result;
997}
998
999
1000/*==========================================================================
1001 = =
1002 = Private methods =
1003 = =
1004 ==========================================================================*/
1005
1006/***********************************************************************//**
1007 * @brief Initialise class members
1008 ***************************************************************************/
1010{
1011 // Initialise members
1012 m_name = "Unnamed Test Suite";
1013 m_names.clear();
1014 m_functions.clear();
1015 m_tests.clear();
1016 m_stack_try.clear();
1017 m_index = 0;
1018 m_failures = 0;
1019 m_errors = 0;
1020 m_log.clear();
1021 m_timestamp = time(NULL);
1022
1023 // Set logger parameters
1024 cout(true);
1025 m_log.buffer_size(1);
1026
1027 // Return
1028 return;
1029}
1030
1031/***********************************************************************//**
1032 * @brief Copy class members
1033 *
1034 * @param[in] suite Test suite.
1035 *
1036 * This method just clone the container not the test case.
1037 ***************************************************************************/
1039{
1040 // Copy members
1041 m_name = suite.m_name;
1042 m_names = suite.m_names;
1043 m_functions = suite.m_functions;
1044 m_index = suite.m_index;
1045 m_failures = suite.m_failures;
1046 m_errors = suite.m_errors;
1047 m_log = suite.m_log;
1048 m_timestamp = suite.m_timestamp;
1049
1050 // Clone test cases
1051 for (int i = 0; i < suite.m_tests.size(); ++i) {
1052 m_tests[i] = suite.m_tests[i]->clone();
1053 }
1054
1055 // Clone try stack
1056 for (int i = 0; i < suite.m_stack_try.size(); ++i) {
1057 m_stack_try[i] = suite.m_stack_try[i]->clone();
1058 }
1059
1060 // Return
1061 return;
1062}
1063
1064
1065/***********************************************************************//**
1066 * @brief Delete class members
1067 ***************************************************************************/
1069{
1070 // Delete test cases
1071 for (int i = 0; i < m_tests.size(); ++i) {
1072 delete m_tests[i];
1073 m_tests[i] = NULL;
1074 }
1075
1076 // Delete try stack
1077 for (int i = 0; i < m_stack_try.size(); ++i) {
1078 delete m_stack_try[i];
1079 m_stack_try[i] = NULL;
1080 }
1081
1082 // Close logger
1083 m_log.close();
1084
1085 // Return
1086 return;
1087}
1088
1089
1090/***********************************************************************//**
1091 * @brief Format Name
1092 *
1093 * Return a string with the format
1094 * "TestFunctionName:TestTryname1:TestTryName2: name"
1095 ***************************************************************************/
1096std::string GTestSuite::format_name(const std::string& name)
1097{
1098 // Initialise format name
1099 std::string format_name;
1100
1101 // Set name of the try blocks
1102 if (!m_stack_try.empty()) {
1103 format_name = m_stack_try.back()->name();
1104 }
1105 else {
1106 // Set name of the test
1108 }
1109
1110 // Append test suite name
1111 format_name += ": " + name;
1112
1113 // Return format
1114 return format_name;
1115}
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.
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< GTestCase * > m_tests
List of test results.
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.
std::vector< GTestCase * > m_stack_try
Stack for nested try blocks.
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.
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:1143
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.
Definition GTools.cpp:489