mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 12:17:11 +01:00 
			
		
		
		
	Integrated (all) new version of Clara
This commit is contained in:
		| @@ -112,7 +112,7 @@ CheckFileList(TOP_LEVEL_HEADERS ${HEADER_DIR}) | ||||
|  | ||||
| # Please keep these ordered alphabetically | ||||
| set(EXTERNAL_HEADERS | ||||
|         ${HEADER_DIR}/external/clara.h | ||||
|         ${HEADER_DIR}/external/clara.hpp | ||||
|         ${HEADER_DIR}/external/tbc_text_format.h | ||||
|         ) | ||||
| CheckFileList(EXTERNAL_HEADERS ${HEADER_DIR}/external) | ||||
|   | ||||
| @@ -96,17 +96,14 @@ namespace Catch { | ||||
|     } | ||||
|  | ||||
|     class Session : NonCopyable { | ||||
|         static bool alreadyInstantiated; | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; | ||||
|  | ||||
|         Session() | ||||
|         : m_cli( makeCommandLineParser() ) { | ||||
|         Session() { | ||||
|             static bool alreadyInstantiated = false; | ||||
|             if( alreadyInstantiated ) | ||||
|                 CATCH_INTERNAL_ERROR( "Only one instance of Catch::Session can ever be used" ); | ||||
|             alreadyInstantiated = true; | ||||
|             m_cli = makeCommandLineParser( m_configData ); | ||||
|         } | ||||
|         ~Session() { | ||||
|             Catch::cleanUp(); | ||||
| @@ -115,29 +112,27 @@ namespace Catch { | ||||
|         void showHelp( std::string const& processName ) { | ||||
|             Catch::cout() << "\nCatch v" << libraryVersion() << "\n"; | ||||
|  | ||||
|             m_cli.usage( Catch::cout(), processName ); | ||||
|             Catch::cout() << m_cli << std::endl; | ||||
|             Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; | ||||
|         } | ||||
|  | ||||
|         int applyCommandLine( int argc, char const* const* const argv, OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { | ||||
|             try { | ||||
|                 m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); | ||||
|                 m_unusedTokens = m_cli.parseInto( Clara::argsToVector( argc, argv ), m_configData ); | ||||
|                 if( m_configData.showHelp ) | ||||
|                     showHelp( m_configData.processName ); | ||||
|                 m_config.reset(); | ||||
|             } | ||||
|             catch( std::exception& ex ) { | ||||
|         int applyCommandLine( int argc, char* argv[] ) { | ||||
|             auto result = m_cli.parse( clara::Args( argc, argv ) ); | ||||
|             if( !result ) { | ||||
|                 { | ||||
|                     Colour colourGuard( Colour::Red ); | ||||
|                     Catch::cerr() | ||||
|                         << "\nError(s) in input:\n" | ||||
|                         << Text( ex.what(), TextAttributes().setIndent(2) ) | ||||
|                         << Text( result.errorMessage(), TextAttributes().setIndent(2) ) | ||||
|                         << "\n\n"; | ||||
|                 } | ||||
|                 m_cli.usage( Catch::cout(), m_configData.processName ); | ||||
|                 Catch::cerr() << m_cli << std::endl; | ||||
|                 return (std::numeric_limits<int>::max)(); | ||||
|             } | ||||
|  | ||||
|             if( m_configData.showHelp ) | ||||
|                 showHelp( m_configData.processName ); | ||||
|             m_config.reset(); | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
| @@ -146,7 +141,7 @@ namespace Catch { | ||||
|             m_config.reset(); | ||||
|         } | ||||
|  | ||||
|         int run( int argc, char const* const* const argv ) { | ||||
|         int run( int argc, char* argv[] ) { | ||||
|             const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions(); | ||||
|             if ( !exceptions.empty() ) { | ||||
|                 Catch::cerr() << "Errors occured during startup!" << '\n'; | ||||
| @@ -167,7 +162,7 @@ namespace Catch { | ||||
|         } | ||||
|  | ||||
|     #if defined(WIN32) && defined(UNICODE) | ||||
|         int run( int argc, wchar_t const* const* const argv ) { | ||||
|         int run( int argc, wchar_t* const argv[] ) { | ||||
|  | ||||
|             char **utf8Argv = new char *[ argc ]; | ||||
|  | ||||
| @@ -217,11 +212,11 @@ namespace Catch { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Clara::CommandLine<ConfigData> const& cli() const { | ||||
|         clara::Parser const& cli() const { | ||||
|             return m_cli; | ||||
|         } | ||||
|         std::vector<Clara::Parser::Token> const& unusedTokens() const { | ||||
|             return m_unusedTokens; | ||||
|         void cli( clara::Parser const& newParser ) { | ||||
|             m_cli = newParser; | ||||
|         } | ||||
|         ConfigData& configData() { | ||||
|             return m_configData; | ||||
| @@ -232,14 +227,11 @@ namespace Catch { | ||||
|             return *m_config; | ||||
|         } | ||||
|     private: | ||||
|         Clara::CommandLine<ConfigData> m_cli; | ||||
|         std::vector<Clara::Parser::Token> m_unusedTokens; | ||||
|         clara::Parser m_cli; | ||||
|         ConfigData m_configData; | ||||
|         std::shared_ptr<Config> m_config; | ||||
|     }; | ||||
|  | ||||
|     bool Session::alreadyInstantiated = false; | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED | ||||
|   | ||||
							
								
								
									
										1054
									
								
								include/external/clara.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1054
									
								
								include/external/clara.h
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1189
									
								
								include/external/clara.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1189
									
								
								include/external/clara.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -17,10 +17,7 @@ | ||||
| #define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH | ||||
|  | ||||
|  | ||||
| // Declare Clara inside the Catch namespace | ||||
| #define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { | ||||
| #include "../external/clara.h" | ||||
| #undef STITCH_CLARA_OPEN_NAMESPACE | ||||
| #include "../external/clara.hpp" | ||||
|  | ||||
|  | ||||
| // Restore Clara's value for console width, if present | ||||
|   | ||||
| @@ -17,20 +17,90 @@ | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
|     inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } | ||||
|     inline void abortAfterX( ConfigData& config, int x ) { | ||||
|         CATCH_ENFORCE( x >=1, "Value after -x or --abortAfter must be greater than zero" ); | ||||
|         config.abortAfter = x; | ||||
|     } | ||||
|     inline void addTestOrTags( ConfigData& config, std::string const& testSpec ) { config.testsOrTags.push_back( testSpec ); } | ||||
|     inline void addSectionToRun( ConfigData& config, std::string const& sectionName ) { config.sectionsToRun.push_back( sectionName ); } | ||||
|     inline void addReporterName( ConfigData& config, std::string const& reporterName ) { config.reporterNames.push_back( reporterName ); } | ||||
|     inline clara::Parser makeCommandLineParser( ConfigData& config ) { | ||||
|  | ||||
|     inline void addWarning( ConfigData& config, std::string const& warning ) { | ||||
|         CATCH_ENFORCE( warning == "NoAssertions", "Unrecognised warning: '" << warning << "'" ); | ||||
|         config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions ); | ||||
|         auto const loadTestNamesFromFile = [&]( std::string const& filename ) { | ||||
|                 std::ifstream f( filename.c_str() ); | ||||
|                 if( !f.is_open() ) | ||||
|                     return clara::ParserResult::runtimeError( "Unable to load input file: '" + filename + "'" ); | ||||
|  | ||||
|                 std::string line; | ||||
|                 while( std::getline( f, line ) ) { | ||||
|                     line = trim(line); | ||||
|                     if( !line.empty() && !startsWith( line, '#' ) ) { | ||||
|                         if( !startsWith( line, '"' ) ) | ||||
|                             line = '"' + line + '"'; | ||||
|                         config.testsOrTags.push_back( line + ',' ); | ||||
|                     } | ||||
|     inline void setOrder( ConfigData& config, std::string const& order ) { | ||||
|                 } | ||||
|                 return clara::ParserResult::ok( clara::ParseResultType::Matched ); | ||||
|             }; | ||||
|  | ||||
|  | ||||
|         using namespace clara; | ||||
|         auto cli | ||||
|             = ExeName( config.processName ) | ||||
|             + Help( config.showHelp ) | ||||
|             + Opt( config.listTests ) | ||||
|                 ["-l"]["--list-tests"] | ||||
|                 ( "list all/matching test cases" ) | ||||
|             + Opt( config.listTags ) | ||||
|                 ["-t"]["--list-tags"] | ||||
|                 ( "list all/matching tags" ) | ||||
|             + Opt( config.showSuccessfulTests ) | ||||
|                 ["-s"]["--success"] | ||||
|                 ( "include successful tests in output" ) | ||||
|             + Opt( config.shouldDebugBreak ) | ||||
|                 ["-b"]["--break"] | ||||
|                 ( "break into debugger on failure" ) | ||||
|             + Opt( config.noThrow ) | ||||
|                 ["-e"]["--nothrow"] | ||||
|                 ( "skip exception tests" ) | ||||
|             + Opt( config.showInvisibles ) | ||||
|                 ["-i"]["--invisibles"] | ||||
|                 ( "show invisibles (tabs, newlines)" ) | ||||
|             + Opt( config.outputFilename, "filename" ) | ||||
|                 ["-o"]["--out"] | ||||
|                 ( "output filename" ) | ||||
|             + Opt( config.reporterNames, "name" ) | ||||
|                 ["-r"]["--reporter"] | ||||
|                 ( "reporter to use (defaults to console)" ) | ||||
|             + Opt( config.name, "name" ) | ||||
|                 ["-n"]["--name"] | ||||
|                 ( "suite name" ) | ||||
|             + Opt( [&]( bool ){ config.abortAfter = 1; } ) | ||||
|                 ["-a"]["--abort"] | ||||
|                 ( "abort at first failure" ) | ||||
|             + Opt( [&]( int x ){ config.abortAfter = x; }, "no. failures" ) | ||||
|                 ["-x"]["--abortx"] | ||||
|                 ( "abort after x failures" ) | ||||
|             + Opt( [&]( std::string const& warning ) { | ||||
|                         if( warning != "NoAssertions" ) | ||||
|                             return clara::ParserResult::runtimeError( "Unrecognised warning: '" + warning + "'" ); | ||||
|                         config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions ); | ||||
|                         return clara::ParserResult::ok( ParseResultType::Matched ); | ||||
|                     }, "warning name" ) | ||||
|                 ["-w"]["--warn"] | ||||
|                 ( "enable warnings" ) | ||||
|             + Opt( [&]( bool ) { config.showDurations = ShowDurations::Always; } ) | ||||
|                 ["-d"]["--durations"] | ||||
|                 ( "show test durations" ) | ||||
|             + Opt( loadTestNamesFromFile, "filename" ) | ||||
|                 ["-f"]["--input-file"] | ||||
|                 ( "load test names to run from a file" ) | ||||
|             + Opt( config.filenamesAsTags ) | ||||
|                 ["-#"]["--filenames-as-tags"] | ||||
|                 ( "adds a tag for the filename" ) | ||||
|             + Opt( config.sectionsToRun, "section name" ) | ||||
|                 ["-c"]["--section"] | ||||
|                 ( "specify section to run" ) | ||||
|             + Opt( config.listTestNamesOnly ) | ||||
|                 ["--list-test-names-only"] | ||||
|                 ( "list all/matching test cases names only" ) | ||||
|             + Opt( config.listReporters ) | ||||
|                 ["--list-reporters"] | ||||
|                 ( "list all reporters" ) | ||||
|             + Opt( [&]( std::string const& order ) { | ||||
|                         if( startsWith( "declared", order ) ) | ||||
|                             config.runOrder = RunTests::InDeclarationOrder; | ||||
|                         else if( startsWith( "lexical", order ) ) | ||||
| @@ -38,30 +108,21 @@ namespace Catch { | ||||
|                         else if( startsWith( "random", order ) ) | ||||
|                             config.runOrder = RunTests::InRandomOrder; | ||||
|                         else | ||||
|             CATCH_ENFORCE( false, "Unrecognised ordering: '" << order << '\'' ); | ||||
|     } | ||||
|     inline void setRngSeed( ConfigData& config, std::string const& seed ) { | ||||
|         if( seed == "time" ) { | ||||
|                             return clara::ParserResult::runtimeError( "Unrecognised ordering: '" + order + "'" ); | ||||
|                         return clara::ParserResult::ok( ParseResultType::Matched ); | ||||
|                     }, "decl|lex|rand" ) | ||||
|                 ["--order"] | ||||
|                 ( "test case order (defaults to decl)" ) | ||||
|             + Opt( [&]( std::string const& seed ) { | ||||
|                         if( seed != "time" ) | ||||
|                             return clara::detail::convertInto( seed, config.rngSeed ); | ||||
|                         config.rngSeed = static_cast<unsigned int>( std::time(0) ); | ||||
|         } | ||||
|         else { | ||||
|             std::stringstream ss; | ||||
|             ss << seed; | ||||
|             ss >> config.rngSeed; | ||||
|             CATCH_ENFORCE( !ss.fail(), "Argument to --rng-seed should be the word 'time' or a number" ); | ||||
|         } | ||||
|     } | ||||
|     inline void setVerbosity( ConfigData& config, int level ) { | ||||
|         // !TBD: accept strings? | ||||
|         config.verbosity = static_cast<Verbosity::Level>( level ); | ||||
|     } | ||||
|     inline void setShowDurations( ConfigData& config, bool _showDurations ) { | ||||
|         config.showDurations = _showDurations | ||||
|             ? ShowDurations::Always | ||||
|             : ShowDurations::Never; | ||||
|     } | ||||
|     inline void setUseColour( ConfigData& config, std::string const& value ) { | ||||
|         std::string mode = toLower( value ); | ||||
|                         return clara::ParserResult::ok( ParseResultType::Matched ); | ||||
|                     }, "'time'|number" ) | ||||
|                 ["--rng-seed"] | ||||
|                 ( "set a specific seed for random numbers" ) | ||||
|             + Opt( [&]( std::string const& useColour ) { | ||||
|                             auto mode = toLower( useColour ); | ||||
|  | ||||
|                             if( mode == "yes" ) | ||||
|                                 config.useColour = UseColour::Yes; | ||||
| @@ -70,137 +131,14 @@ namespace Catch { | ||||
|                             else if( mode == "auto" ) | ||||
|                                 config.useColour = UseColour::Auto; | ||||
|                             else | ||||
|             CATCH_ENFORCE( false, "colour mode must be one of: auto, yes or no" ); | ||||
|     } | ||||
|     inline void forceColour( ConfigData& config ) { | ||||
|         config.useColour = UseColour::Yes; | ||||
|     } | ||||
|     inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { | ||||
|         std::ifstream f( _filename.c_str() ); | ||||
|         CATCH_ENFORCE( f.is_open(), "Unable to load input file: '" << _filename << "'" ); | ||||
|                                 return clara::ParserResult::runtimeError( "colour mode must be one of: auto, yes or no. '" + useColour + "' not recognised" ); | ||||
|                         return clara::ParserResult::ok( ParseResultType::Matched ); | ||||
|                     }, "yes|no" ) | ||||
|                 ["--use-colour"] | ||||
|                 ( "should output be colourised" ) | ||||
|  | ||||
|         std::string line; | ||||
|         while( std::getline( f, line ) ) { | ||||
|             line = trim(line); | ||||
|             if( !line.empty() && !startsWith( line, '#' ) ) { | ||||
|                 if( !startsWith( line, '"' ) ) | ||||
|                     line = '"' + line + '"'; | ||||
|                 addTestOrTags( config, line + ',' ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     inline Clara::CommandLine<ConfigData> makeCommandLineParser() { | ||||
|  | ||||
|         using namespace Clara; | ||||
|         CommandLine<ConfigData> cli; | ||||
|  | ||||
|         cli.bindProcessName( &ConfigData::processName ); | ||||
|  | ||||
|         cli["-?"]["-h"]["--help"] | ||||
|             .describe( "display usage information" ) | ||||
|             .bind( &ConfigData::showHelp ); | ||||
|  | ||||
|         cli["-l"]["--list-tests"] | ||||
|             .describe( "list all/matching test cases" ) | ||||
|             .bind( &ConfigData::listTests ); | ||||
|  | ||||
|         cli["-t"]["--list-tags"] | ||||
|             .describe( "list all/matching tags" ) | ||||
|             .bind( &ConfigData::listTags ); | ||||
|  | ||||
|         cli["-s"]["--success"] | ||||
|             .describe( "include successful tests in output" ) | ||||
|             .bind( &ConfigData::showSuccessfulTests ); | ||||
|  | ||||
|         cli["-b"]["--break"] | ||||
|             .describe( "break into debugger on failure" ) | ||||
|             .bind( &ConfigData::shouldDebugBreak ); | ||||
|  | ||||
|         cli["-e"]["--nothrow"] | ||||
|             .describe( "skip exception tests" ) | ||||
|             .bind( &ConfigData::noThrow ); | ||||
|  | ||||
|         cli["-i"]["--invisibles"] | ||||
|             .describe( "show invisibles (tabs, newlines)" ) | ||||
|             .bind( &ConfigData::showInvisibles ); | ||||
|  | ||||
|         cli["-o"]["--out"] | ||||
|             .describe( "output filename" ) | ||||
|             .bind( &ConfigData::outputFilename, "filename" ); | ||||
|  | ||||
|         cli["-r"]["--reporter"] | ||||
| //            .placeholder( "name[:filename]" ) | ||||
|             .describe( "reporter to use (defaults to console)" ) | ||||
|             .bind( &addReporterName, "name" ); | ||||
|  | ||||
|         cli["-n"]["--name"] | ||||
|             .describe( "suite name" ) | ||||
|             .bind( &ConfigData::name, "name" ); | ||||
|  | ||||
|         cli["-a"]["--abort"] | ||||
|             .describe( "abort at first failure" ) | ||||
|             .bind( &abortAfterFirst ); | ||||
|  | ||||
|         cli["-x"]["--abortx"] | ||||
|             .describe( "abort after x failures" ) | ||||
|             .bind( &abortAfterX, "no. failures" ); | ||||
|  | ||||
|         cli["-w"]["--warn"] | ||||
|             .describe( "enable warnings" ) | ||||
|             .bind( &addWarning, "warning name" ); | ||||
|  | ||||
| // - needs updating if reinstated | ||||
| //        cli.into( &setVerbosity ) | ||||
| //            .describe( "level of verbosity (0=no output)" ) | ||||
| //            .shortOpt( "v") | ||||
| //            .longOpt( "verbosity" ) | ||||
| //            .placeholder( "level" ); | ||||
|  | ||||
|         cli[_] | ||||
|             .describe( "which test or tests to use" ) | ||||
|             .bind( &addTestOrTags, "test name, pattern or tags" ); | ||||
|  | ||||
|         cli["-d"]["--durations"] | ||||
|             .describe( "show test durations" ) | ||||
|             .bind( &setShowDurations, "yes|no" ); | ||||
|  | ||||
|         cli["-f"]["--input-file"] | ||||
|             .describe( "load test names to run from a file" ) | ||||
|             .bind( &loadTestNamesFromFile, "filename" ); | ||||
|  | ||||
|         cli["-#"]["--filenames-as-tags"] | ||||
|             .describe( "adds a tag for the filename" ) | ||||
|             .bind( &ConfigData::filenamesAsTags ); | ||||
|  | ||||
|         cli["-c"]["--section"] | ||||
|                 .describe( "specify section to run" ) | ||||
|                 .bind( &addSectionToRun, "section name" ); | ||||
|  | ||||
|         // Less common commands which don't have a short form | ||||
|         cli["--list-test-names-only"] | ||||
|             .describe( "list all/matching test cases names only" ) | ||||
|             .bind( &ConfigData::listTestNamesOnly ); | ||||
|  | ||||
|         cli["--list-reporters"] | ||||
|             .describe( "list all reporters" ) | ||||
|             .bind( &ConfigData::listReporters ); | ||||
|  | ||||
|         cli["--order"] | ||||
|             .describe( "test case order (defaults to decl)" ) | ||||
|             .bind( &setOrder, "decl|lex|rand" ); | ||||
|  | ||||
|         cli["--rng-seed"] | ||||
|             .describe( "set a specific seed for random numbers" ) | ||||
|             .bind( &setRngSeed, "'time'|number" ); | ||||
|  | ||||
|         cli["--force-colour"] | ||||
|             .describe( "force colourised output (deprecated)" ) | ||||
|             .bind( &forceColour ); | ||||
|  | ||||
|         cli["--use-colour"] | ||||
|             .describe( "should output be colourised" ) | ||||
|             .bind( &setUseColour, "yes|no" ); | ||||
|             + Arg( config.testsOrTags, "test name|pattern|tags" ) | ||||
|                 ( "which test or tests to use" ); | ||||
|  | ||||
|         return cli; | ||||
|     } | ||||
|   | ||||
| @@ -25,24 +25,24 @@ CATCH_REGISTER_TAG_ALIAS( "[@tricky]", "[tricky]~[.]" ) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| template<size_t size> | ||||
| void parseIntoConfig( const char * (&argv)[size], Catch::ConfigData& config ) { | ||||
|     Catch::Clara::CommandLine<Catch::ConfigData> parser = Catch::makeCommandLineParser(); | ||||
|     parser.parseInto( Catch::Clara::argsToVector( size, argv ), config ); | ||||
| } | ||||
|  | ||||
| template<size_t size> | ||||
| std::string parseIntoConfigAndReturnError( const char * (&argv)[size], Catch::ConfigData& config ) { | ||||
|     try { | ||||
|         parseIntoConfig( argv, config ); | ||||
|         FAIL( "expected exception" ); | ||||
|     } | ||||
|     catch( std::exception& ex ) { | ||||
|         return ex.what(); | ||||
|     } | ||||
|     return ""; | ||||
| } | ||||
|  | ||||
| //template<size_t size> | ||||
| //void parseIntoConfig( const char * (&argv)[size], Catch::ConfigData& config ) { | ||||
| //    auto parser = Catch::makeCommandLineParser(); | ||||
| //    parser.parseInto( Catch::Clara::argsToVector( size, argv ), config ); | ||||
| //} | ||||
| // | ||||
| //template<size_t size> | ||||
| //std::string parseIntoConfigAndReturnError( const char * (&argv)[size], Catch::ConfigData& config ) { | ||||
| //    try { | ||||
| //        parseIntoConfig( argv, config ); | ||||
| //        FAIL( "expected exception" ); | ||||
| //    } | ||||
| //    catch( std::exception& ex ) { | ||||
| //        return ex.what(); | ||||
| //    } | ||||
| //    return ""; | ||||
| //} | ||||
| // | ||||
| inline Catch::TestCase fakeTestCase( const char* name, const char* desc = "" ){ return Catch::makeTestCase( nullptr, "", name, desc, CATCH_INTERNAL_LINEINFO ); } | ||||
|  | ||||
| TEST_CASE( "Process can be configured on command line", "[config][command-line]" ) { | ||||
| @@ -50,197 +50,182 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]" | ||||
|     using namespace Catch::Matchers; | ||||
|  | ||||
|     Catch::ConfigData config; | ||||
|     auto cli = Catch::makeCommandLineParser(config); | ||||
|  | ||||
|     SECTION( "empty args don't cause a crash" ) { | ||||
|         Catch::Clara::CommandLine<Catch::ConfigData> parser = Catch::makeCommandLineParser(); | ||||
|         CHECK_NOTHROW( parser.parseInto( std::vector<std::string>(), config ) ); | ||||
|  | ||||
|         CHECK( config.processName == "" ); | ||||
|     SECTION("empty args don't cause a crash") { | ||||
|         auto result = cli.parse({""}); | ||||
|         CHECK(result); | ||||
|         CHECK(config.processName == ""); | ||||
|     } | ||||
|  | ||||
|     SECTION( "default - no arguments", "" ) { | ||||
|         const char* argv[] = { "test" }; | ||||
|         CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|  | ||||
|         CHECK( config.processName == "test" ); | ||||
|         CHECK( config.shouldDebugBreak == false ); | ||||
|         CHECK( config.abortAfter == -1 ); | ||||
|         CHECK( config.noThrow == false ); | ||||
|         CHECK( config.reporterNames.empty() ); | ||||
|     SECTION("default - no arguments") { | ||||
|         auto result = cli.parse({"test"}); | ||||
|         CHECK(result); | ||||
|         CHECK(config.processName == "test"); | ||||
|         CHECK(config.shouldDebugBreak == false); | ||||
|         CHECK(config.abortAfter == -1); | ||||
|         CHECK(config.noThrow == false); | ||||
|         CHECK(config.reporterNames.empty()); | ||||
|     } | ||||
|  | ||||
|     SECTION( "test lists", "" ) { | ||||
|         SECTION( "1 test", "Specify one test case using" ) { | ||||
|             const char* argv[] = { "test", "test1" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|     SECTION("test lists") { | ||||
|         SECTION("1 test", "Specify one test case using") { | ||||
|             auto result = cli.parse({"test", "test1"}); | ||||
|             CHECK(result); | ||||
|  | ||||
|             Catch::Config cfg( config ); | ||||
|             REQUIRE( cfg.testSpec().matches( fakeTestCase( "notIncluded" ) ) == false ); | ||||
|             REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) ); | ||||
|             Catch::Config cfg(config); | ||||
|             REQUIRE(cfg.testSpec().matches(fakeTestCase("notIncluded")) == false); | ||||
|             REQUIRE(cfg.testSpec().matches(fakeTestCase("test1"))); | ||||
|         } | ||||
|         SECTION( "Specify one test case exclusion using exclude:", "" ) { | ||||
|             const char* argv[] = { "test", "exclude:test1" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION("Specify one test case exclusion using exclude:") { | ||||
|             auto result = cli.parse({"test", "exclude:test1"}); | ||||
|             CHECK(result); | ||||
|  | ||||
|             Catch::Config cfg( config ); | ||||
|             REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ); | ||||
|             REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ); | ||||
|             Catch::Config cfg(config); | ||||
|             REQUIRE(cfg.testSpec().matches(fakeTestCase("test1")) == false); | ||||
|             REQUIRE(cfg.testSpec().matches(fakeTestCase("alwaysIncluded"))); | ||||
|         } | ||||
|  | ||||
|         SECTION( "Specify one test case exclusion using ~", "" ) { | ||||
|             const char* argv[] = { "test", "~test1" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION("Specify one test case exclusion using ~") { | ||||
|             auto result = cli.parse({"test", "~test1"}); | ||||
|             CHECK(result); | ||||
|  | ||||
|             Catch::Config cfg( config ); | ||||
|             REQUIRE( cfg.testSpec().matches( fakeTestCase( "test1" ) ) == false ); | ||||
|             REQUIRE( cfg.testSpec().matches( fakeTestCase( "alwaysIncluded" ) ) ); | ||||
|             Catch::Config cfg(config); | ||||
|             REQUIRE(cfg.testSpec().matches(fakeTestCase("test1")) == false); | ||||
|             REQUIRE(cfg.testSpec().matches(fakeTestCase("alwaysIncluded"))); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     SECTION( "reporter", "" ) { | ||||
|         SECTION( "-r/console", "" ) { | ||||
|             const char* argv[] = { "test", "-r", "console" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|     SECTION("reporter") { | ||||
|         SECTION("-r/console") { | ||||
|             CHECK(cli.parse({"test", "-r", "console"})); | ||||
|  | ||||
|             REQUIRE( config.reporterNames[0] == "console" ); | ||||
|             REQUIRE(config.reporterNames[0] == "console"); | ||||
|         } | ||||
|         SECTION( "-r/xml", "" ) { | ||||
|             const char* argv[] = { "test", "-r", "xml" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION("-r/xml") { | ||||
|             CHECK(cli.parse({"test", "-r", "xml"})); | ||||
|  | ||||
|             REQUIRE( config.reporterNames[0] == "xml" ); | ||||
|             REQUIRE(config.reporterNames[0] == "xml"); | ||||
|         } | ||||
|         SECTION( "-r xml and junit", "" ) { | ||||
|             const char* argv[] = { "test", "-r", "xml", "-r", "junit" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION("-r xml and junit") { | ||||
|             CHECK(cli.parse({"test", "-r", "xml", "-r", "junit"})); | ||||
|  | ||||
|             REQUIRE( config.reporterNames.size() == 2 ); | ||||
|             REQUIRE( config.reporterNames[0] == "xml" ); | ||||
|             REQUIRE( config.reporterNames[1] == "junit" ); | ||||
|             REQUIRE(config.reporterNames.size() == 2); | ||||
|             REQUIRE(config.reporterNames[0] == "xml"); | ||||
|             REQUIRE(config.reporterNames[1] == "junit"); | ||||
|         } | ||||
|         SECTION( "--reporter/junit", "" ) { | ||||
|             const char* argv[] = { "test", "--reporter", "junit" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION("--reporter/junit") { | ||||
|             CHECK(cli.parse({"test", "--reporter", "junit"})); | ||||
|  | ||||
|             REQUIRE( config.reporterNames[0] == "junit" ); | ||||
|             REQUIRE(config.reporterNames[0] == "junit"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     SECTION( "debugger", "" ) { | ||||
|         SECTION( "-b", "" ) { | ||||
|             const char* argv[] = { "test", "-b" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|  | ||||
|             REQUIRE( config.shouldDebugBreak == true ); | ||||
|     SECTION("debugger") { | ||||
|         SECTION("-b") { | ||||
|             CHECK(cli.parse({"test", "-b"})); | ||||
|  | ||||
|             REQUIRE(config.shouldDebugBreak == true); | ||||
|         } | ||||
|         SECTION( "--break", "" ) { | ||||
|             const char* argv[] = { "test", "--break" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION("--break") { | ||||
|             CHECK(cli.parse({"test", "--break"})); | ||||
|  | ||||
|             REQUIRE( config.shouldDebugBreak ); | ||||
|             REQUIRE(config.shouldDebugBreak); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     SECTION( "abort", "" ) { | ||||
|         SECTION( "-a aborts after first failure", "" ) { | ||||
|             const char* argv[] = { "test", "-a" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|  | ||||
|             REQUIRE( config.abortAfter == 1 ); | ||||
|         } | ||||
|         SECTION( "-x 2 aborts after two failures", "" ) { | ||||
|             const char* argv[] = { "test", "-x", "2" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|     SECTION("abort") { | ||||
|         SECTION("-a aborts after first failure") { | ||||
|             CHECK(cli.parse({"test", "-a"})); | ||||
|  | ||||
|             REQUIRE( config.abortAfter == 2 ); | ||||
|             REQUIRE(config.abortAfter == 1); | ||||
|         } | ||||
|         SECTION( "-x must be greater than zero", "" ) { | ||||
|             const char* argv[] = { "test", "-x", "0" }; | ||||
|             REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "greater than zero" ) ); | ||||
|         SECTION("-x 2 aborts after two failures") { | ||||
|             CHECK(cli.parse({"test", "-x", "2"})); | ||||
|  | ||||
|             REQUIRE(config.abortAfter == 2); | ||||
|         } | ||||
|         SECTION( "-x must be numeric", "" ) { | ||||
|             const char* argv[] = { "test", "-x", "oops" }; | ||||
|             REQUIRE_THAT( parseIntoConfigAndReturnError( argv, config ), Contains( "-x" ) ); | ||||
|         SECTION("-x must be numeric") { | ||||
|             auto result = cli.parse({"test", "-x", "oops"}); | ||||
|             CHECK(!result); | ||||
|  | ||||
|             REQUIRE_THAT(result.errorMessage(), Contains("convert") && Contains("oops")); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     SECTION( "nothrow", "" ) { | ||||
|         SECTION( "-e", "" ) { | ||||
|             const char* argv[] = { "test", "-e" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|     SECTION("nothrow") { | ||||
|         SECTION("-e") { | ||||
|             CHECK(cli.parse({"test", "-e"})); | ||||
|  | ||||
|             REQUIRE( config.noThrow == true ); | ||||
|             REQUIRE(config.noThrow); | ||||
|         } | ||||
|         SECTION( "--nothrow", "" ) { | ||||
|             const char* argv[] = { "test", "--nothrow" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION("--nothrow") { | ||||
|             CHECK(cli.parse({"test", "--nothrow"})); | ||||
|  | ||||
|             REQUIRE( config.noThrow == true ); | ||||
|             REQUIRE(config.noThrow); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     SECTION( "output filename", "" ) { | ||||
|         SECTION( "-o filename", "" ) { | ||||
|             const char* argv[] = { "test", "-o", "filename.ext" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|     SECTION("output filename") { | ||||
|         SECTION("-o filename") { | ||||
|             CHECK(cli.parse({"test", "-o", "filename.ext"})); | ||||
|  | ||||
|             REQUIRE( config.outputFilename == "filename.ext" ); | ||||
|             REQUIRE(config.outputFilename == "filename.ext"); | ||||
|         } | ||||
|         SECTION( "--out", "" ) { | ||||
|             const char* argv[] = { "test", "--out", "filename.ext" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION("--out") { | ||||
|             CHECK(cli.parse({"test", "--out", "filename.ext"})); | ||||
|  | ||||
|             REQUIRE( config.outputFilename == "filename.ext" ); | ||||
|             REQUIRE(config.outputFilename == "filename.ext"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     SECTION( "combinations", "" ) { | ||||
|         SECTION( "Single character flags can be combined", "" ) { | ||||
|             const char* argv[] = { "test", "-abe" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|     SECTION("combinations") { | ||||
|         SECTION("Single character flags can be combined") { | ||||
|             CHECK(cli.parse({"test", "-abe"})); | ||||
|  | ||||
|             CHECK( config.abortAfter == 1 ); | ||||
|             CHECK( config.shouldDebugBreak ); | ||||
|             CHECK( config.noThrow == true ); | ||||
|             CHECK(config.abortAfter == 1); | ||||
|             CHECK(config.shouldDebugBreak); | ||||
|             CHECK(config.noThrow == true); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     SECTION( "use-colour", "") { | ||||
|  | ||||
|     SECTION( "use-colour") { | ||||
|  | ||||
|         using Catch::UseColour; | ||||
|  | ||||
|         SECTION( "without option", "" ) { | ||||
|             const char* argv[] = { "test" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION( "without option" ) { | ||||
|             CHECK(cli.parse({"test"})); | ||||
|  | ||||
|             REQUIRE( config.useColour == UseColour::Auto ); | ||||
|         } | ||||
|  | ||||
|         SECTION( "auto", "" ) { | ||||
|             const char* argv[] = { "test", "--use-colour", "auto" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION( "auto" ) { | ||||
|             CHECK(cli.parse({"test", "--use-colour", "auto"})); | ||||
|  | ||||
|             REQUIRE( config.useColour == UseColour::Auto ); | ||||
|         } | ||||
|  | ||||
|         SECTION( "yes", "" ) { | ||||
|             const char* argv[] = { "test", "--use-colour", "yes" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION( "yes" ) { | ||||
|             CHECK(cli.parse({"test", "--use-colour", "yes"})); | ||||
|  | ||||
|             REQUIRE( config.useColour == UseColour::Yes ); | ||||
|         } | ||||
|  | ||||
|         SECTION( "no", "" ) { | ||||
|             const char* argv[] = { "test", "--use-colour", "no" }; | ||||
|             CHECK_NOTHROW( parseIntoConfig( argv, config ) ); | ||||
|         SECTION( "no" ) { | ||||
|             CHECK(cli.parse({"test", "--use-colour", "no"})); | ||||
|  | ||||
|             REQUIRE( config.useColour == UseColour::No ); | ||||
|         } | ||||
|  | ||||
|         SECTION( "error", "" ) { | ||||
|             const char* argv[] = { "test", "--use-colour", "wrong" }; | ||||
|             REQUIRE_THROWS_WITH( parseIntoConfig( argv, config ), Contains( "colour mode must be one of" ) ); | ||||
|         SECTION( "error" ) { | ||||
|             auto result = cli.parse({"test", "--use-colour", "wrong"}); | ||||
|             CHECK( !result ); | ||||
|             CHECK_THAT( result.errorMessage(), Contains( "colour mode must be one of" ) ); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -249,31 +234,31 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]" | ||||
| TEST_CASE( "Long strings can be wrapped", "[wrap]" ) { | ||||
|  | ||||
|     using namespace Catch; | ||||
|     SECTION( "plain string", "" ) { | ||||
|     SECTION( "plain string" ) { | ||||
|         // guide:                 123456789012345678 | ||||
|         std::string testString = "one two three four"; | ||||
|  | ||||
|         SECTION( "No wrapping", "" ) { | ||||
|         SECTION( "No wrapping" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString ); | ||||
|         } | ||||
|         SECTION( "Wrapped once", "" ) { | ||||
|         SECTION( "Wrapped once" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 17 ) ).toString() == "one two three\nfour" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 16 ) ).toString() == "one two three\nfour" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 14 ) ).toString() == "one two three\nfour" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 13 ) ).toString() == "one two three\nfour" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 12 ) ).toString() == "one two\nthree four" ); | ||||
|         } | ||||
|         SECTION( "Wrapped twice", "" ) { | ||||
|         SECTION( "Wrapped twice" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" ); | ||||
|         } | ||||
|         SECTION( "Wrapped three times", "" ) { | ||||
|         SECTION( "Wrapped three times" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one\ntwo\nthree\nfour" ); | ||||
|         } | ||||
|         SECTION( "Short wrap", "" ) { | ||||
|         SECTION( "Short wrap" ) { | ||||
|             CHECK( Text( "abcdef", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef" ); | ||||
|             CHECK( Text( "abcdefg", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndefg" ); | ||||
|             CHECK( Text( "abcdefgh", TextAttributes().setWidth( 4 ) ).toString() == "abc-\ndef-\ngh" ); | ||||
| @@ -281,7 +266,7 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one\ntwo\nthr-\nee\nfour" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 3 ) ).toString() == "one\ntwo\nth-\nree\nfo-\nur" ); | ||||
|         } | ||||
|         SECTION( "As container", "" ) { | ||||
|         SECTION( "As container" ) { | ||||
|             Text text( testString, TextAttributes().setWidth( 6 ) ); | ||||
|             REQUIRE( text.size() == 4 ); | ||||
|             CHECK( text[0] == "one" ); | ||||
| @@ -289,7 +274,7 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) { | ||||
|             CHECK( text[2] == "three" ); | ||||
|             CHECK( text[3] == "four" ); | ||||
|         } | ||||
|         SECTION( "Indent first line differently", "" ) { | ||||
|         SECTION( "Indent first line differently" ) { | ||||
|             Text text( testString, TextAttributes() | ||||
|                                         .setWidth( 10 ) | ||||
|                                         .setIndent( 4 ) | ||||
| @@ -299,43 +284,43 @@ TEST_CASE( "Long strings can be wrapped", "[wrap]" ) { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     SECTION( "With newlines", "" ) { | ||||
|     SECTION( "With newlines" ) { | ||||
|  | ||||
|         // guide:                 1234567890123456789 | ||||
|         std::string testString = "one two\nthree four"; | ||||
|  | ||||
|         SECTION( "No wrapping" , "" ) { | ||||
|         SECTION( "No wrapping" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 18 ) ).toString() == testString ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 10 ) ).toString() == testString ); | ||||
|         } | ||||
|         SECTION( "Trailing newline" , "" ) { | ||||
|         SECTION( "Trailing newline" ) { | ||||
|             CHECK( Text( "abcdef\n", TextAttributes().setWidth( 10 ) ).toString() == "abcdef" ); | ||||
|             CHECK( Text( "abcdef", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" ); | ||||
|             CHECK( Text( "abcdef\n", TextAttributes().setWidth( 6 ) ).toString() == "abcdef" ); | ||||
|             CHECK( Text( "abcdef\n", TextAttributes().setWidth( 5 ) ).toString() == "abcd-\nef" ); | ||||
|         } | ||||
|         SECTION( "Wrapped once", "" ) { | ||||
|         SECTION( "Wrapped once" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 9 ) ).toString() == "one two\nthree\nfour" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 8 ) ).toString() == "one two\nthree\nfour" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 7 ) ).toString() == "one two\nthree\nfour" ); | ||||
|         } | ||||
|         SECTION( "Wrapped twice", "" ) { | ||||
|         SECTION( "Wrapped twice" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one\ntwo\nthree\nfour" ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     SECTION( "With wrap-before/ after characters", "" ) { | ||||
|     SECTION( "With wrap-before/ after characters" ) { | ||||
|         std::string testString = "one,two(three) <here>"; | ||||
|  | ||||
|         SECTION( "No wrapping", "" ) { | ||||
|         SECTION( "No wrapping" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 80 ) ).toString() == testString ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 24 ) ).toString() == testString ); | ||||
|         } | ||||
|         SECTION( "Wrap before", "" ) { | ||||
|         SECTION( "Wrap before" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 11 ) ).toString() == "one,two\n(three)\n<here>" ); | ||||
|         } | ||||
|         SECTION( "Wrap after", "" ) { | ||||
|         SECTION( "Wrap after" ) { | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 6 ) ).toString() == "one,\ntwo\n(thre-\ne)\n<here>" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 5 ) ).toString() == "one,\ntwo\n(thr-\nee)\n<her-\ne>" ); | ||||
|             CHECK( Text( testString, TextAttributes().setWidth( 4 ) ).toString() == "one,\ntwo\n(th-\nree)\n<he-\nre>" ); | ||||
| @@ -416,7 +401,7 @@ private: | ||||
|     std::vector<ColourIndex> colours; | ||||
| }; | ||||
|  | ||||
| TEST_CASE( "replaceInPlace", "" ) { | ||||
| TEST_CASE( "replaceInPlace" ) { | ||||
|     std::string letters = "abcdefcg"; | ||||
|     SECTION( "replace single char" ) { | ||||
|         CHECK( replaceInPlace( letters, "b", "z" ) ); | ||||
| @@ -469,7 +454,7 @@ TEST_CASE( "Strings can be rendered with colour", "[.colour]" ) { | ||||
|  | ||||
| } | ||||
|  | ||||
| TEST_CASE( "Text can be formatted using the Text class", "" ) { | ||||
| TEST_CASE( "Text can be formatted using the Text class" ) { | ||||
|  | ||||
|     CHECK( Text( "hi there" ).toString() == "hi there" ); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash