catch_config.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // Copyright Catch2 Authors
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // https://www.boost.org/LICENSE_1_0.txt)
  5. // SPDX-License-Identifier: BSL-1.0
  6. #include <catch2/catch_config.hpp>
  7. #include <catch2/catch_user_config.hpp>
  8. #include <catch2/internal/catch_enforce.hpp>
  9. #include <catch2/internal/catch_platform.hpp>
  10. #include <catch2/internal/catch_stringref.hpp>
  11. #include <catch2/internal/catch_string_manip.hpp>
  12. #include <catch2/internal/catch_test_spec_parser.hpp>
  13. #include <catch2/interfaces/catch_interfaces_tag_alias_registry.hpp>
  14. namespace {
  15. bool provideBazelReporterOutput() {
  16. #if defined(CATCH_CONFIG_BAZEL_SUPPORT)
  17. return true;
  18. #elif defined(CATCH_PLATFORM_WINDOWS_UWP)
  19. // UWP does not support environment variables
  20. return false;
  21. #else
  22. # if defined( _MSC_VER )
  23. // On Windows getenv throws a warning as there is no input validation,
  24. // since the switch is hardcoded, this should not be an issue.
  25. # pragma warning( push )
  26. # pragma warning( disable : 4996 )
  27. # endif
  28. return std::getenv( "BAZEL_TEST" ) != nullptr;
  29. # if defined( _MSC_VER )
  30. # pragma warning( pop )
  31. # endif
  32. #endif
  33. }
  34. }
  35. namespace Catch {
  36. bool operator==( ProcessedReporterSpec const& lhs,
  37. ProcessedReporterSpec const& rhs ) {
  38. return lhs.name == rhs.name &&
  39. lhs.outputFilename == rhs.outputFilename &&
  40. lhs.colourMode == rhs.colourMode &&
  41. lhs.customOptions == rhs.customOptions;
  42. }
  43. Config::Config( ConfigData const& data ):
  44. m_data( data ) {
  45. // We need to trim filter specs to avoid trouble with superfluous
  46. // whitespace (esp. important for bdd macros, as those are manually
  47. // aligned with whitespace).
  48. for (auto& elem : m_data.testsOrTags) {
  49. elem = trim(elem);
  50. }
  51. for (auto& elem : m_data.sectionsToRun) {
  52. elem = trim(elem);
  53. }
  54. TestSpecParser parser(ITagAliasRegistry::get());
  55. if (!m_data.testsOrTags.empty()) {
  56. m_hasTestFilters = true;
  57. for (auto const& testOrTags : m_data.testsOrTags) {
  58. parser.parse(testOrTags);
  59. }
  60. }
  61. m_testSpec = parser.testSpec();
  62. // Insert the default reporter if user hasn't asked for a specfic one
  63. if ( m_data.reporterSpecifications.empty() ) {
  64. m_data.reporterSpecifications.push_back( {
  65. #if defined( CATCH_CONFIG_DEFAULT_REPORTER )
  66. CATCH_CONFIG_DEFAULT_REPORTER,
  67. #else
  68. "console",
  69. #endif
  70. {}, {}, {}
  71. } );
  72. }
  73. #if !defined(CATCH_PLATFORM_WINDOWS_UWP)
  74. if(provideBazelReporterOutput()){
  75. // Register a JUnit reporter for Bazel. Bazel sets an environment
  76. // variable with the path to XML output. If this file is written to
  77. // during test, Bazel will not generate a default XML output.
  78. // This allows the XML output file to contain higher level of detail
  79. // than what is possible otherwise.
  80. # if defined( _MSC_VER )
  81. // On Windows getenv throws a warning as there is no input validation,
  82. // since the key is hardcoded, this should not be an issue.
  83. # pragma warning( push )
  84. # pragma warning( disable : 4996 )
  85. # endif
  86. const auto bazelOutputFilePtr = std::getenv( "XML_OUTPUT_FILE" );
  87. # if defined( _MSC_VER )
  88. # pragma warning( pop )
  89. # endif
  90. if ( bazelOutputFilePtr != nullptr ) {
  91. m_data.reporterSpecifications.push_back(
  92. { "junit", std::string( bazelOutputFilePtr ), {}, {} } );
  93. }
  94. }
  95. #endif
  96. // We now fixup the reporter specs to handle default output spec,
  97. // default colour spec, etc
  98. bool defaultOutputUsed = false;
  99. for ( auto const& reporterSpec : m_data.reporterSpecifications ) {
  100. // We do the default-output check separately, while always
  101. // using the default output below to make the code simpler
  102. // and avoid superfluous copies.
  103. if ( reporterSpec.outputFile().none() ) {
  104. CATCH_ENFORCE( !defaultOutputUsed,
  105. "Internal error: cannot use default output for "
  106. "multiple reporters" );
  107. defaultOutputUsed = true;
  108. }
  109. m_processedReporterSpecs.push_back( ProcessedReporterSpec{
  110. reporterSpec.name(),
  111. reporterSpec.outputFile() ? *reporterSpec.outputFile()
  112. : data.defaultOutputFilename,
  113. reporterSpec.colourMode().valueOr( data.defaultColourMode ),
  114. reporterSpec.customOptions() } );
  115. }
  116. }
  117. Config::~Config() = default;
  118. bool Config::listTests() const { return m_data.listTests; }
  119. bool Config::listTags() const { return m_data.listTags; }
  120. bool Config::listReporters() const { return m_data.listReporters; }
  121. bool Config::listListeners() const { return m_data.listListeners; }
  122. std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }
  123. std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }
  124. std::vector<ReporterSpec> const& Config::getReporterSpecs() const {
  125. return m_data.reporterSpecifications;
  126. }
  127. std::vector<ProcessedReporterSpec> const&
  128. Config::getProcessedReporterSpecs() const {
  129. return m_processedReporterSpecs;
  130. }
  131. TestSpec const& Config::testSpec() const { return m_testSpec; }
  132. bool Config::hasTestFilters() const { return m_hasTestFilters; }
  133. bool Config::showHelp() const { return m_data.showHelp; }
  134. // IConfig interface
  135. bool Config::allowThrows() const { return !m_data.noThrow; }
  136. StringRef Config::name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
  137. bool Config::includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
  138. bool Config::warnAboutMissingAssertions() const {
  139. return !!( m_data.warnings & WarnAbout::NoAssertions );
  140. }
  141. bool Config::warnAboutUnmatchedTestSpecs() const {
  142. return !!( m_data.warnings & WarnAbout::UnmatchedTestSpec );
  143. }
  144. bool Config::zeroTestsCountAsSuccess() const { return m_data.allowZeroTests; }
  145. ShowDurations Config::showDurations() const { return m_data.showDurations; }
  146. double Config::minDuration() const { return m_data.minDuration; }
  147. TestRunOrder Config::runOrder() const { return m_data.runOrder; }
  148. uint32_t Config::rngSeed() const { return m_data.rngSeed; }
  149. unsigned int Config::shardCount() const { return m_data.shardCount; }
  150. unsigned int Config::shardIndex() const { return m_data.shardIndex; }
  151. ColourMode Config::defaultColourMode() const { return m_data.defaultColourMode; }
  152. bool Config::shouldDebugBreak() const { return m_data.shouldDebugBreak; }
  153. int Config::abortAfter() const { return m_data.abortAfter; }
  154. bool Config::showInvisibles() const { return m_data.showInvisibles; }
  155. Verbosity Config::verbosity() const { return m_data.verbosity; }
  156. bool Config::skipBenchmarks() const { return m_data.skipBenchmarks; }
  157. bool Config::benchmarkNoAnalysis() const { return m_data.benchmarkNoAnalysis; }
  158. unsigned int Config::benchmarkSamples() const { return m_data.benchmarkSamples; }
  159. double Config::benchmarkConfidenceInterval() const { return m_data.benchmarkConfidenceInterval; }
  160. unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; }
  161. std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }
  162. } // end namespace Catch