diff --git a/src/catch2/internal/catch_commandline.cpp b/src/catch2/internal/catch_commandline.cpp index fda4b2bd..20bb07f7 100644 --- a/src/catch2/internal/catch_commandline.cpp +++ b/src/catch2/internal/catch_commandline.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -77,23 +78,14 @@ namespace Catch { return ParserResult::ok(ParseResultType::Matched); } - CATCH_TRY { - std::size_t parsedTo = 0; - unsigned long parsedSeed = std::stoul(seed, &parsedTo, 0); - if (parsedTo != seed.size()) { - return ParserResult::runtimeError("Could not parse '" + seed + "' as seed"); - } - - // TODO: Ideally we could parse unsigned int directly, - // but the stdlib doesn't provide helper for that - // type. After this is refactored to use fixed size - // type, we should check the parsed value is in range - // of the underlying type. - config.rngSeed = static_cast(parsedSeed); - return ParserResult::ok(ParseResultType::Matched); - } CATCH_CATCH_ANON(std::exception const&) { - return ParserResult::runtimeError("Could not parse '" + seed + "' as seed"); + // TODO: ideally we should be parsing uint32_t directly + // fix this later when we add new parse overload + auto parsedSeed = parseUInt( seed, 0 ); + if ( !parsedSeed ) { + return ParserResult::runtimeError( "Could not parse '" + seed + "' as seed" ); } + config.rngSeed = *parsedSeed; + return ParserResult::ok( ParseResultType::Matched ); }; auto const setDefaultColourMode = [&]( std::string const& colourMode ) { Optional maybeMode = Catch::Detail::stringToColourMode(toLower( colourMode )); diff --git a/tests/SelfTest/IntrospectiveTests/CmdLine.tests.cpp b/tests/SelfTest/IntrospectiveTests/CmdLine.tests.cpp index e7b0c9c1..cbb0a988 100644 --- a/tests/SelfTest/IntrospectiveTests/CmdLine.tests.cpp +++ b/tests/SelfTest/IntrospectiveTests/CmdLine.tests.cpp @@ -737,3 +737,31 @@ TEST_CASE("Win32 colour implementation is compile-time optional", REQUIRE_FALSE( result ); #endif } + +TEST_CASE( "Parse rng seed in different formats", "[approvals][cli][rng-seed]" ) { + Catch::ConfigData config; + auto cli = Catch::makeCommandLineParser( config ); + + SECTION("well formed cases") { + char const* seed_string; + uint32_t seed_value; + // GCC-5 workaround + using gen_type = std::tuple; + std::tie( seed_string, seed_value ) = GENERATE( table({ + gen_type{ "0xBEEF", 0xBEEF }, + gen_type{ "12345678", 12345678 } + } ) ); + CAPTURE( seed_string ); + + auto result = cli.parse( { "tests", "--rng-seed", seed_string } ); + + REQUIRE( result ); + REQUIRE( config.rngSeed == seed_value ); + } + SECTION( "Error cases" ) { + auto seed_string = + GENERATE( "0xSEED", "999999999999", "08888", "BEEF", "123 456" ); + CAPTURE( seed_string ); + REQUIRE_FALSE( cli.parse( { "tests", "--rng-seed", seed_string } ) ); + } +}