]> git.stg.codes - stg.git/blob - tests/tut/tut_main.hpp
Portable count.
[stg.git] / tests / tut / tut_main.hpp
1 #ifndef TUT_MAIN_H
2 #define TUT_MAIN_H
3
4 #include <tut/tut.hpp>
5 #include <tut/tut_console_reporter.hpp>
6 #include <tut/tut_cppunit_reporter.hpp>
7 #include <iostream>
8 #include <cstring>
9
10 namespace tut
11 {
12
13 /** Helper function to make test binaries simpler.
14  *
15  * Example of basic usage follows.
16  *
17  * @code
18  *  namespace tut { test_runner_singleton runner; }
19  *
20  *  int main(int argc, char **argv)
21  *  {
22  *      if( tut_main(argc, argv) )
23  *          return 0;
24  *      else
25  *          return -1;
26  *  }
27  * @endcode
28  *
29  * It is also possible to do some generic initialization before
30  * running any tests and cleanup before exiting application.
31  * Note that tut_main can throw tut::no_such_group or tut::no_such_test.
32  *
33  * @code
34  *  namespace tut { test_runner_singleton runner; }
35  *
36  *  int main(int argc, char **argv)
37  *  {
38  *      tut::xml_reporter reporter;
39  *      tut::runner.get().insert_callback(&reporter);
40  *
41  *      MyInit();
42  *      try
43  *      {
44  *          tut_main(argc, argv);
45  *      }
46  *      catch(const tut::tut_error &ex)
47  *      {
48  *          std::cerr << "TUT error: " << ex.what() << std::endl;
49  *      }
50  *      MyCleanup();
51  *  }
52  * @endcode
53  */
54 inline bool tut_main(int argc, const char * const * const argv, std::ostream &os = std::cerr)
55 {
56     std::stringstream usage;
57     usage << "Usage: " << argv[0] << " [group] [testcase]" << std::endl;
58     groupnames gr = runner.get().list_groups();
59     usage << "Available test groups:" << std::endl;
60     for(groupnames::const_iterator i = gr.begin(); i != gr.end(); ++i)
61     {
62         usage << "    " << *i << std::endl;
63     }
64
65     if(argc>1)
66     {
67         if(std::string(argv[1]) == "-h" ||
68            std::string(argv[1]) == "--help" ||
69            std::string(argv[1]) == "/?" ||
70            argc > 3)
71         {
72             os << usage.rdbuf();
73             return false;
74         }
75     }
76
77     // Check command line options.
78     switch(argc)
79     {
80         case 1:
81             runner.get().run_tests();
82         break;
83
84         case 2:
85             runner.get().run_tests(argv[1]);
86         break;
87
88         case 3:
89         {
90             char *end;
91             int t = strtol(argv[2], &end, 10);
92             if(end != argv[2] + strlen(argv[2]))
93             {
94                 throw no_such_test("`" + std::string(argv[2]) + "` should be a number");
95             }
96
97             test_result tr;
98             if(!runner.get().run_test(argv[1], t, tr) || tr.result == test_result::dummy)
99             {
100                 throw no_such_test("No testcase `" + std::string(argv[2]) + "` in group `" + argv[1] + "`");
101             }
102         }
103         break;
104     }
105
106     return true;
107 } // tut_main()
108
109 }
110
111 #endif