| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  catch_commandline.hpp | 
					
						
							|  |  |  |  *  Catch | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Created by Phil on 02/11/2010. | 
					
						
							|  |  |  |  *  Copyright 2010 Two Blue Cubes Ltd. All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Distributed under the Boost Software License, Version 1.0. (See accompanying | 
					
						
							|  |  |  |  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
 | 
					
						
							|  |  |  | #define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-01 00:29:58 +00:00
										 |  |  | #include "catch_config.hpp"
 | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  | #include "catch_runner_impl.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Catch | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-12-31 16:12:48 +00:00
										 |  |  |     // !TBD: This could be refactored to be more "declarative"
 | 
					
						
							|  |  |  |     //       have a table up front that relates the mode, option strings, # arguments, names of arguments
 | 
					
						
							|  |  |  |     //       - may not be worth it at this scale
 | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2010-12-30 18:24:22 +00:00
										 |  |  |     // -l, --list tests [xml] lists available tests (optionally in xml)
 | 
					
						
							| 
									
										
										
										
											2010-12-30 18:51:02 +00:00
										 |  |  |     // -l, --list reporters [xml] lists available reports (optionally in xml)
 | 
					
						
							| 
									
										
										
										
											2010-12-30 18:24:22 +00:00
										 |  |  |     // -l, --list all [xml] lists available tests and reports (optionally in xml)
 | 
					
						
							|  |  |  |     // -t, --test "testspec" ["testspec", ...]
 | 
					
						
							| 
									
										
										
										
											2010-12-30 18:51:02 +00:00
										 |  |  |     // -r, --reporter <type>
 | 
					
						
							| 
									
										
										
										
											2010-12-30 18:24:22 +00:00
										 |  |  |     // -o, --out filename to write to
 | 
					
						
							|  |  |  |     // -s, --success report successful cases too
 | 
					
						
							|  |  |  |     // -b, --break breaks into debugger on test failure
 | 
					
						
							| 
									
										
										
										
											2011-04-12 08:07:39 +01:00
										 |  |  |     // -n, --name specifies an optional name for the test run
 | 
					
						
							| 
									
										
										
										
											2010-11-12 19:32:13 +00:00
										 |  |  | 	class ArgParser : NonCopyable | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         enum Mode | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             modeNone, | 
					
						
							|  |  |  |             modeList, | 
					
						
							|  |  |  |             modeTest, | 
					
						
							|  |  |  |             modeReport, | 
					
						
							|  |  |  |             modeOutput, | 
					
						
							|  |  |  |             modeSuccess, | 
					
						
							| 
									
										
										
										
											2010-12-27 20:49:19 +00:00
										 |  |  |             modeBreak, | 
					
						
							| 
									
										
										
										
											2011-04-12 08:07:39 +01:00
										 |  |  |             modeName, | 
					
						
							| 
									
										
										
										
											2010-12-30 18:51:02 +00:00
										 |  |  |             modeHelp, | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             modeError | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     public: | 
					
						
							| 
									
										
										
										
											2011-02-03 20:00:46 +00:00
										 |  |  |         ///////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  |         ArgParser | 
					
						
							|  |  |  |         ( | 
					
						
							|  |  |  |             int argc,  | 
					
						
							|  |  |  |             char * const argv[],  | 
					
						
							|  |  |  |             Config& config | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |         :   m_mode( modeNone ), | 
					
						
							|  |  |  |             m_config( config ) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2010-11-11 20:56:38 +00:00
										 |  |  |             for( int i=1; i < argc; ++i ) | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                 if( argv[i][0] == '-' ) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     std::string cmd = ( argv[i] ); | 
					
						
							|  |  |  |                     if( cmd == "-l" || cmd == "--list" ) | 
					
						
							|  |  |  |                         changeMode( cmd, modeList ); | 
					
						
							|  |  |  |                     else if( cmd == "-t" || cmd == "--test" ) | 
					
						
							|  |  |  |                         changeMode( cmd, modeTest ); | 
					
						
							| 
									
										
										
										
											2010-12-30 18:51:02 +00:00
										 |  |  |                     else if( cmd == "-r" || cmd == "--reporter" ) | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                         changeMode( cmd, modeReport ); | 
					
						
							| 
									
										
										
										
											2010-12-30 18:24:22 +00:00
										 |  |  |                     else if( cmd == "-o" || cmd == "--out" ) | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                         changeMode( cmd, modeOutput ); | 
					
						
							|  |  |  |                     else if( cmd == "-s" || cmd == "--success" ) | 
					
						
							|  |  |  |                         changeMode( cmd, modeSuccess ); | 
					
						
							| 
									
										
										
										
											2010-12-27 20:49:19 +00:00
										 |  |  |                     else if( cmd == "-b" || cmd == "--break" ) | 
					
						
							|  |  |  |                         changeMode( cmd, modeBreak ); | 
					
						
							| 
									
										
										
										
											2011-04-12 08:07:39 +01:00
										 |  |  |                     else if( cmd == "-n" || cmd == "--name" ) | 
					
						
							|  |  |  |                         changeMode( cmd, modeName ); | 
					
						
							| 
									
										
										
										
											2010-12-30 18:51:02 +00:00
										 |  |  |                     else if( cmd == "-h" || cmd == "-?" || cmd == "--help" ) | 
					
						
							|  |  |  |                         changeMode( cmd, modeHelp ); | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     m_args.push_back( argv[i] ); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if( m_mode == modeError ) | 
					
						
							|  |  |  |                     return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             changeMode( "", modeNone );             | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     private: | 
					
						
							| 
									
										
										
										
											2011-02-03 20:00:46 +00:00
										 |  |  |         ///////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  |         std::string argsAsString | 
					
						
							|  |  |  |         () | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             std::ostringstream oss; | 
					
						
							|  |  |  |             std::vector<std::string>::const_iterator it = m_args.begin(); | 
					
						
							|  |  |  |             std::vector<std::string>::const_iterator itEnd = m_args.end(); | 
					
						
							|  |  |  |             for( bool first = true; it != itEnd; ++it, first = false ) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if( !first ) | 
					
						
							|  |  |  |                     oss << " "; | 
					
						
							|  |  |  |                 oss << *it; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return oss.str(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2011-02-03 20:00:46 +00:00
										 |  |  |         ///////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  |         void changeMode | 
					
						
							|  |  |  |         ( | 
					
						
							|  |  |  |             const std::string& cmd,  | 
					
						
							|  |  |  |             Mode mode | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             m_command = cmd; | 
					
						
							|  |  |  |             switch( m_mode ) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 case modeNone: | 
					
						
							|  |  |  |                     if( m_args.size() > 0 ) | 
					
						
							|  |  |  |                         return setErrorMode( "Unexpected arguments before " + m_command + ": " + argsAsString() ); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case modeList: | 
					
						
							|  |  |  |                     if( m_args.size() > 2 ) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         return setErrorMode( m_command + " expected upto 2 arguments but recieved: " + argsAsString() ); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                     { | 
					
						
							| 
									
										
										
										
											2011-01-01 00:37:49 +00:00
										 |  |  |                         Config::List::What listSpec = Config::List::All; | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                         if( m_args.size() >= 1 ) | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             if( m_args[0] == "tests" ) | 
					
						
							| 
									
										
										
										
											2011-01-01 00:37:49 +00:00
										 |  |  |                                 listSpec = Config::List::Tests; | 
					
						
							| 
									
										
										
										
											2010-12-30 18:28:56 +00:00
										 |  |  |                             else if( m_args[0] == "reporters" ) | 
					
						
							| 
									
										
										
										
											2011-01-01 00:37:49 +00:00
										 |  |  |                                 listSpec = Config::List::Reports; | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                             else | 
					
						
							| 
									
										
										
										
											2010-12-30 18:28:56 +00:00
										 |  |  |                                 return setErrorMode( m_command + " expected [tests] or [reporters] but recieved: [" + m_args[0] + "]" );                         | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                         } | 
					
						
							|  |  |  |                         if( m_args.size() >= 2 ) | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             if( m_args[1] == "xml" ) | 
					
						
							| 
									
										
										
										
											2011-01-31 10:10:20 +00:00
										 |  |  |                                 listSpec = static_cast<Config::List::What>( listSpec | Config::List::AsXml ); | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                             else if( m_args[1] == "text" ) | 
					
						
							| 
									
										
										
										
											2011-01-31 10:10:20 +00:00
										 |  |  |                                 listSpec = static_cast<Config::List::What>( listSpec | Config::List::AsText ); | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                             else | 
					
						
							|  |  |  |                                 return setErrorMode( m_command + " expected [xml] or [text] but recieved: [" + m_args[1] + "]" );                         | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2011-01-31 10:10:20 +00:00
										 |  |  |                         m_config.setListSpec( static_cast<Config::List::What>( m_config.getListSpec() | listSpec ) ); | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case modeTest: | 
					
						
							|  |  |  |                     if( m_args.size() == 0 )                         | 
					
						
							|  |  |  |                         return setErrorMode( m_command + " expected at least 1 argument but recieved none" ); | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         std::vector<std::string>::const_iterator it = m_args.begin(); | 
					
						
							|  |  |  |                         std::vector<std::string>::const_iterator itEnd = m_args.end(); | 
					
						
							|  |  |  |                         for(; it != itEnd; ++it ) | 
					
						
							|  |  |  |                             m_config.addTestSpec( *it ); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case modeReport: | 
					
						
							|  |  |  |                     if( m_args.size() != 1 ) | 
					
						
							|  |  |  |                         return setErrorMode( m_command + " expected one argument, recieved: " +  argsAsString() ); | 
					
						
							| 
									
										
										
										
											2011-01-05 21:07:20 +00:00
										 |  |  |                     m_config.setReporter( m_args[0] ); | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case modeOutput: | 
					
						
							|  |  |  |                     if( m_args.size() == 0 ) | 
					
						
							|  |  |  |                         return setErrorMode( m_command + " expected filename" ); | 
					
						
							| 
									
										
										
										
											2011-01-18 09:20:06 +00:00
										 |  |  |                     if( m_args[0][0] == '%' ) | 
					
						
							|  |  |  |                         m_config.useStream( m_args[0].substr( 1 ) ); | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                         m_config.setFilename( m_args[0] ); | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case modeSuccess: | 
					
						
							|  |  |  |                     if( m_args.size() != 0 ) | 
					
						
							|  |  |  |                         return setErrorMode( m_command + " does not accept arguments" ); | 
					
						
							| 
									
										
										
										
											2011-01-01 00:20:14 +00:00
										 |  |  |                     m_config.setIncludeWhat( Config::Include::SuccessfulResults ); | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |                     break; | 
					
						
							| 
									
										
										
										
											2010-12-27 20:49:19 +00:00
										 |  |  |                 case modeBreak: | 
					
						
							|  |  |  |                     if( m_args.size() != 0 ) | 
					
						
							|  |  |  |                         return setErrorMode( m_command + " does not accept arguments" ); | 
					
						
							|  |  |  |                     m_config.setShouldDebugBreak( true ); | 
					
						
							| 
									
										
										
										
											2011-04-26 19:00:25 +01:00
										 |  |  |                     break; | 
					
						
							| 
									
										
										
										
											2011-04-12 08:07:39 +01:00
										 |  |  |                 case modeName: | 
					
						
							|  |  |  |                     if( m_args.size() != 1 ) | 
					
						
							|  |  |  |                         return setErrorMode( m_command + " requires exactly one argument (a name)" ); | 
					
						
							|  |  |  |                     m_config.setName( m_args[0] ); | 
					
						
							| 
									
										
										
										
											2010-12-27 20:49:19 +00:00
										 |  |  |                     break; | 
					
						
							| 
									
										
										
										
											2010-12-30 18:51:02 +00:00
										 |  |  |                 case modeHelp: | 
					
						
							|  |  |  |                     if( m_args.size() != 0 ) | 
					
						
							|  |  |  |                         return setErrorMode( m_command + " does not accept arguments" ); | 
					
						
							|  |  |  |                     m_config.setShowHelp( true ); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 default: | 
					
						
							| 
									
										
										
										
											2010-12-28 15:42:46 +01:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             m_args.clear(); | 
					
						
							|  |  |  |             m_mode = mode; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							| 
									
										
										
										
											2011-02-03 20:00:46 +00:00
										 |  |  |         ///////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  |         void setErrorMode | 
					
						
							|  |  |  |         ( | 
					
						
							|  |  |  |             const std::string& errorMessage | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             m_mode = modeError; | 
					
						
							|  |  |  |             m_command = ""; | 
					
						
							|  |  |  |             m_config.setError( errorMessage ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         Mode m_mode; | 
					
						
							|  |  |  |         std::string m_command; | 
					
						
							|  |  |  |         std::vector<std::string> m_args; | 
					
						
							| 
									
										
										
										
											2011-01-01 00:20:14 +00:00
										 |  |  |         Config& m_config; | 
					
						
							| 
									
										
										
										
											2010-11-09 23:24:00 +00:00
										 |  |  |     }; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  | } // end namespace Catch
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-28 15:42:46 +01:00
										 |  |  | #endif // TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED
 |