Silence errors when assigning random values to test data
[gssweb.git] / json_gssapi / test / test_with_options.cpp
1 #ifndef _1_cppunit_cpp_
2 #define _1_cppunit_cpp_
3
4 /*
5  * Copyright (c) 2008, Robert Emerson
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in the
14  *       documentation and/or other materials provided with the distribution.
15  *     * Neither the name of Robert Emerson nor the
16  *       names of its contributors may be used to endorse or promote products
17  *       derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY ROBERT EMERSON ''AS IS'' AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL ROBERT EMERSON BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <unistd.h>
32
33 #include <iostream>
34 #include <exception>
35 #include <memory>
36 #include <string>
37 #include <map>
38
39 #include <cppunit/CompilerOutputter.h>
40 #include <cppunit/TextOutputter.h>
41 #include <cppunit/XmlOutputter.h>
42 #include <cppunit/extensions/TestFactoryRegistry.h>
43 #include <cppunit/TestResult.h>
44 #include <cppunit/TestResultCollector.h>
45 #include <cppunit/TestRunner.h>
46 #include <cppunit/TextTestProgressListener.h>
47 #include <cppunit/BriefTestProgressListener.h>
48 #include <cppunit/TestSuccessListener.h>
49 #include <cppunit/Portability.h>
50
51 using namespace CPPUNIT_NS;
52
53 using std::cerr;
54 using std::cout;
55 using std::endl;
56 using std::exception;
57 using std::auto_ptr;
58 using std::string;
59 using std::map;
60 using std::make_pair;
61
62 static const int RET_OK = 0;
63 static const int RET_USAGE = -1;
64 static const int RET_BAD_OUTPUTTER = -2;
65 static const int RET_BAD_LISTENER = -3;
66 static const int RET_BAD_TEST = -4;
67
68 typedef map<string, Outputter *> OutputterMap;
69 typedef map<string, TestListener *> ListenerMap;
70
71 void usage(const char *image, 
72            const char *defaultTest,
73            const OutputterMap &outputters,
74            const ListenerMap &listeners)
75 {
76   cout << endl;
77   cout << "Usage: " << basename(image) 
78        << " (-o outputter) (-p progress) (-t test) (-r count)" << endl;
79   cout << "       " << basename(image) 
80        << " [ -l | -h ]" << endl;
81   cout << endl;
82   cout << "A CppUnit command line test execution tool. " << endl;
83   cout << endl;
84   cout << "Built against cppunit version: " << CPPUNIT_VERSION << endl;
85   cout << endl;
86   cout << "Options:" << endl;
87   cout << endl;
88   cout << "    -o Output style. Choices: ";
89   
90   {
91     OutputterMap::const_iterator it = outputters.begin();
92     
93     while (it != outputters.end()) { 
94       cout << it->first << " "; 
95       ++it;
96     }
97   }
98
99   cout << "Default: compiler" << endl;
100   cout << "    -p Progress style. Choices: ";
101   {
102     ListenerMap::const_iterator it = listeners.begin();
103
104     while (it != listeners.end()) { 
105       cout << it->first << " "; 
106       ++it;
107     }
108   }
109
110   cout << "Default: dots";
111   cout << endl;
112   cout << "    -t Runs given the test only. Default: \"" << defaultTest << "\"" << endl;
113   cout << "    -r Repeat count. Default: 1" << endl;
114   cout << endl;
115   cout << "    -l List all available tests." << endl;
116   cout << "    -h Print this usage message." << endl;
117   cout << endl;
118   cout << "Returns 0 on success, negative for usage errors, positive errors plus failures." << endl;
119   cout << endl;
120   cout << "If the image name is a valid test name, then this is the default test executed." << endl;
121   cout << endl;
122
123   return;
124 }
125
126 // Recursive dumps the given Test heirarchy to cout
127 void dump(Test *test)
128 {
129   if (0 == test) return;
130
131   cout << test->getName() << endl;
132
133   if (0 == test->getChildTestCount()) return;
134
135   for (int i = 0; i < test->getChildTestCount(); i++) {
136     dump(test->getChildTestAt(i));
137   }
138
139   return;
140 }
141
142 // Recursively seeks the Test matching the given name, returns 0 otherwise.
143 Test *find(Test *test, const string &name)
144 {
145   if (0 == test) return 0;
146   if (name == test->getName()) return test;
147   if (0 == test->getChildTestCount()) return 0;
148
149   for (int i = 0; i < test->getChildTestCount(); i++) {
150     Test *found = find(test->getChildTestAt(i), name);
151     if (found) return found;
152   }
153
154   return 0;
155 }
156
157 int main(int argc, char **argv)
158 {
159   TestResult result;
160   TestResultCollector collector;
161   result.addListener(&collector);
162   
163   OutputterMap allOutputters;
164   {
165     allOutputters.insert(make_pair("compiler", 
166                                    new CompilerOutputter(&collector, cout)));
167     allOutputters.insert(make_pair("text", 
168                                    new TextOutputter(&collector, cout)));
169     allOutputters.insert(make_pair("xml", 
170                                    new XmlOutputter(&collector, cout)));
171     allOutputters.insert(make_pair("none", static_cast<Outputter *>(0)));
172   }
173   Outputter *outputter = allOutputters.find("compiler")->second;
174  
175   ListenerMap allListeners;
176   {
177     allListeners.insert(make_pair("dots", new TextTestProgressListener()));
178     allListeners.insert(make_pair("brief", new BriefTestProgressListener()));
179     allListeners.insert(make_pair("none", static_cast<TestListener *>(0)));
180   }
181   TestListener *listener = allListeners.find("dots")->second;
182
183   string runTest = basename(argv[0]);
184
185   if (!find(TestFactoryRegistry::getRegistry().makeTest(), runTest)) {
186       runTest = "All Tests";
187   }
188
189   int repeat = 1;
190   char flag = 0;
191   while ((flag = getopt(argc, argv, "r:t:o:p:lh")) != -1) {
192
193     switch(flag) {
194
195     case 'r':
196       repeat = atoi(optarg);
197       break;
198
199     case 'o':
200       {
201         OutputterMap::const_iterator it = allOutputters.find(optarg);
202         if (it == allOutputters.end()) {
203           cerr << "Unknown outputter: " << optarg << endl;
204           return RET_BAD_OUTPUTTER;
205         }
206         outputter = it->second;
207       }
208       break;
209
210     case 'p':
211       {
212         string progress(optarg);
213         ListenerMap::const_iterator it = allListeners.find(optarg);
214         if (it == allListeners.end()) {
215           cerr << "Unknown listener: " << optarg << endl;
216           return RET_BAD_LISTENER;
217         }
218         listener = it->second;
219       }
220       break;
221
222     case 'l':
223       {
224         Test *all = TestFactoryRegistry::getRegistry().makeTest();
225         dump(all);
226         return RET_OK;
227       }
228       break; // not reached
229
230     case 't':
231       {
232         runTest = optarg;
233       }
234       break;
235
236     case 'h':
237     default:
238       usage(argv[0], runTest.c_str(), allOutputters, allListeners);
239       return RET_USAGE;
240       break; // not reached
241     }
242   }
243   if (listener != 0) result.addListener(listener);
244
245   Test *run = find(TestFactoryRegistry::getRegistry().makeTest(), runTest);
246   if (run == 0) {
247     cerr << "Unknown test case: " << runTest << endl;
248     return RET_BAD_TEST;
249   }
250   
251   TestRunner runner;
252   runner.addTest(run);
253   
254   for (int i = 0; i < repeat; i++) {
255     runner.run(result);
256   }
257
258   if (outputter) outputter->write();
259
260   return collector.testErrors() + collector.testFailures();
261
262 }
263
264 #endif // _1_cppunit_cpp_