/* * Created by Phil on 5/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) */ #include "catch_list.h" #include "catch_interfaces_registry_hub.h" #include "catch_interfaces_reporter.h" #include "catch_interfaces_testcase.h" #include "catch_clara.h" // For TextFlow #include "catch_console_colour.hpp" #include "catch_test_spec_parser.hpp" #include #include #include namespace Catch { using namespace clara::TextFlow; std::size_t listTests( Config const& config ) { TestSpec testSpec = config.testSpec(); if( config.testSpec().hasFilters() ) Catch::cout() << "Matching test cases:\n"; else { Catch::cout() << "All available test cases:\n"; testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); } auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( auto const& testCaseInfo : matchedTestCases ) { Colour::Code colour = testCaseInfo.isHidden() ? Colour::SecondaryText : Colour::None; Colour colourGuard( colour ); Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << "\n"; if( config.verbosity() >= Verbosity::High ) { std::string description = testCaseInfo.description.empty() ? std::string( "(NO DESCRIPTION)" ) : testCaseInfo.description; Catch::cout() << " " << testCaseInfo.lineInfo << "\n" << Column( description ).indent( 4 ) << "\n"; } if( !testCaseInfo.tags.empty() ) Catch::cout() << Column( testCaseInfo.tagsAsString ).indent( 6 ) << "\n"; } if( !config.testSpec().hasFilters() ) Catch::cout() << pluralise( matchedTestCases.size(), "test case" ) << '\n' << std::endl; else Catch::cout() << pluralise( matchedTestCases.size(), "matching test case" ) << '\n' << std::endl; return matchedTestCases.size(); } std::size_t listTestsNamesOnly( Config const& config ) { TestSpec testSpec = config.testSpec(); if( !config.testSpec().hasFilters() ) testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); std::size_t matchedTests = 0; std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( auto const& testCaseInfo : matchedTestCases ) { matchedTests++; if( startsWith( testCaseInfo.name, '#' ) ) Catch::cout() << '"' << testCaseInfo.name << '"'; else Catch::cout() << testCaseInfo.name; if ( config.verbosity() >= Verbosity::High ) Catch::cout() << "\t@" << testCaseInfo.lineInfo; Catch::cout() << std::endl; } return matchedTests; } void TagInfo::add( std::string const& spelling ) { ++count; spellings.insert( spelling ); } std::string TagInfo::all() const { std::string out; for( auto const& spelling : spellings ) out += "[" + spelling + "]"; return out; } std::size_t listTags( Config const& config ) { TestSpec testSpec = config.testSpec(); if( config.testSpec().hasFilters() ) Catch::cout() << "Tags for matching test cases:\n"; else { Catch::cout() << "All available tags:\n"; testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); } std::map tagCounts; std::vector matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config ); for( auto const& testCase : matchedTestCases ) { for( auto const& tagName : testCase.getTestCaseInfo().tags ) { std::string lcaseTagName = toLower( tagName ); auto countIt = tagCounts.find( lcaseTagName ); if( countIt == tagCounts.end() ) countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; countIt->second.add( tagName ); } } for( auto const& tagCount : tagCounts ) { std::ostringstream oss; oss << " " << std::setw(2) << tagCount.second.count << " "; auto wrapper = Column( tagCount.second.all() ) .initialIndent( 0 ) .indent( oss.str().size() ) .width( CATCH_CONFIG_CONSOLE_WIDTH-10 ); Catch::cout() << oss.str() << wrapper << '\n'; } Catch::cout() << pluralise( tagCounts.size(), "tag" ) << '\n' << std::endl; return tagCounts.size(); } std::size_t listReporters( Config const& /*config*/ ) { Catch::cout() << "Available reporters:\n"; IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); std::size_t maxNameLen = 0; for( auto const& factoryKvp : getRegistryHub().getReporterRegistry().getFactories() ) maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() ); for( auto const& factoryKvp : getRegistryHub().getReporterRegistry().getFactories() ) { auto wrapper = Column( factoryKvp.second->getDescription() ) .initialIndent( 0 ) .indent( 7+maxNameLen ) .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ); Catch::cout() << " " << factoryKvp.first << ':' << std::string( maxNameLen - factoryKvp.first.size() + 2, ' ' ) << wrapper << '\n'; } Catch::cout() << std::endl; return factories.size(); } Option list( Config const& config ) { Option listedCount; if( config.listTests() ) listedCount = listedCount.valueOr(0) + listTests( config ); if( config.listTestNamesOnly() ) listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); if( config.listTags() ) listedCount = listedCount.valueOr(0) + listTags( config ); if( config.listReporters() ) listedCount = listedCount.valueOr(0) + listReporters( config ); return listedCount; } } // end namespace Catch