catch_list.cpp
1 2 // Copyright Catch2 Authors 3 // Distributed under the Boost Software License, Version 1.0. 4 // (See accompanying file LICENSE.txt or copy at 5 // https://www.boost.org/LICENSE_1_0.txt) 6 7 // SPDX-License-Identifier: BSL-1.0 8 #include <catch2/internal/catch_list.hpp> 9 10 #include <catch2/interfaces/catch_interfaces_registry_hub.hpp> 11 #include <catch2/interfaces/catch_interfaces_reporter.hpp> 12 #include <catch2/interfaces/catch_interfaces_reporter_factory.hpp> 13 #include <catch2/internal/catch_test_case_registry_impl.hpp> 14 #include <catch2/internal/catch_reporter_registry.hpp> 15 #include <catch2/internal/catch_move_and_forward.hpp> 16 #include <catch2/internal/catch_case_insensitive_comparisons.hpp> 17 18 #include <catch2/internal/catch_context.hpp> 19 #include <catch2/catch_config.hpp> 20 #include <catch2/catch_test_spec.hpp> 21 #include <catch2/catch_test_case_info.hpp> 22 23 namespace Catch { 24 namespace { 25 26 void listTests(IEventListener& reporter, IConfig const& config) { 27 auto const& testSpec = config.testSpec(); 28 auto matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config); 29 reporter.listTests(matchedTestCases); 30 } 31 32 void listTags(IEventListener& reporter, IConfig const& config) { 33 auto const& testSpec = config.testSpec(); 34 std::vector<TestCaseHandle> matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config); 35 36 std::map<StringRef, TagInfo, Detail::CaseInsensitiveLess> tagCounts; 37 for (auto const& testCase : matchedTestCases) { 38 for (auto const& tagName : testCase.getTestCaseInfo().tags) { 39 auto it = tagCounts.find(tagName.original); 40 if (it == tagCounts.end()) 41 it = tagCounts.insert(std::make_pair(tagName.original, TagInfo())).first; 42 it->second.add(tagName.original); 43 } 44 } 45 46 std::vector<TagInfo> infos; infos.reserve(tagCounts.size()); 47 for (auto& tagc : tagCounts) { 48 infos.push_back(CATCH_MOVE(tagc.second)); 49 } 50 51 reporter.listTags(infos); 52 } 53 54 void listReporters(IEventListener& reporter) { 55 std::vector<ReporterDescription> descriptions; 56 57 auto const& factories = getRegistryHub().getReporterRegistry().getFactories(); 58 descriptions.reserve(factories.size()); 59 for (auto const& fac : factories) { 60 descriptions.push_back({ fac.first, fac.second->getDescription() }); 61 } 62 63 reporter.listReporters(descriptions); 64 } 65 66 void listListeners(IEventListener& reporter) { 67 std::vector<ListenerDescription> descriptions; 68 69 auto const& factories = 70 getRegistryHub().getReporterRegistry().getListeners(); 71 descriptions.reserve( factories.size() ); 72 for ( auto const& fac : factories ) { 73 descriptions.push_back( { fac->getName(), fac->getDescription() } ); 74 } 75 76 reporter.listListeners( descriptions ); 77 } 78 79 } // end anonymous namespace 80 81 void TagInfo::add( StringRef spelling ) { 82 ++count; 83 spellings.insert( spelling ); 84 } 85 86 std::string TagInfo::all() const { 87 // 2 per tag for brackets '[' and ']' 88 size_t size = spellings.size() * 2; 89 for (auto const& spelling : spellings) { 90 size += spelling.size(); 91 } 92 93 std::string out; out.reserve(size); 94 for (auto const& spelling : spellings) { 95 out += '['; 96 out += spelling; 97 out += ']'; 98 } 99 return out; 100 } 101 102 bool list( IEventListener& reporter, Config const& config ) { 103 bool listed = false; 104 if (config.listTests()) { 105 listed = true; 106 listTests(reporter, config); 107 } 108 if (config.listTags()) { 109 listed = true; 110 listTags(reporter, config); 111 } 112 if (config.listReporters()) { 113 listed = true; 114 listReporters(reporter); 115 } 116 if ( config.listListeners() ) { 117 listed = true; 118 listListeners( reporter ); 119 } 120 return listed; 121 } 122 123 } // end namespace Catch