diff options
| author | Beartama | 2023-11-14 23:52:15 +0200 |
|---|---|---|
| committer | GitHub | 2023-11-14 22:52:15 +0100 |
| commit | 7bf136b501fef3e189b45091e8a4757a5eaef31f (patch) | |
| tree | fe788efc997f7f4ed26fbe5d564d8d40df83c938 /src/catch2/internal | |
| parent | 2c68a0d05f4fa8fb79cd43824f69568eb3954d4c (diff) | |
| download | catch3-7bf136b501fef3e189b45091e8a4757a5eaef31f.tar.gz | |
Add JSON reporter (#2706)
Co-authored-by: Martin Hořeňovský <martin.horenovsky@gmail.com>
Diffstat (limited to 'src/catch2/internal')
| -rw-r--r-- | src/catch2/internal/catch_jsonwriter.cpp | 115 | ||||
| -rw-r--r-- | src/catch2/internal/catch_jsonwriter.hpp | 123 | ||||
| -rw-r--r-- | src/catch2/internal/catch_reporter_registry.cpp | 5 |
3 files changed, 242 insertions, 1 deletions
diff --git a/src/catch2/internal/catch_jsonwriter.cpp b/src/catch2/internal/catch_jsonwriter.cpp new file mode 100644 index 00000000..f6c279d8 --- /dev/null +++ b/src/catch2/internal/catch_jsonwriter.cpp @@ -0,0 +1,115 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#include <catch2/internal/catch_enforce.hpp> +#include <catch2/internal/catch_jsonwriter.hpp> + +namespace Catch { + void JsonUtils::indent( std::ostream& os, std::uint64_t level ) { + for ( std::uint64_t i = 0; i < level; ++i ) { + os << " "; + } + } + void JsonUtils::appendCommaNewline( std::ostream& os, + bool& should_comma, + std::uint64_t level ) { + if ( should_comma ) { os << ','; } + should_comma = true; + os << '\n'; + indent( os, level ); + } + + JsonObjectWriter::JsonObjectWriter( std::ostream& os ): + JsonObjectWriter{ os, 0 } {} + + JsonObjectWriter::JsonObjectWriter( std::ostream& os, + std::uint64_t indent_level ): + m_os{ os }, m_indent_level{ indent_level } { + m_os << "{"; + } + JsonObjectWriter::JsonObjectWriter( JsonObjectWriter&& source ): + m_os{ source.m_os }, + m_indent_level{ source.m_indent_level }, + m_should_comma{ source.m_should_comma }, + m_active{ source.m_active } { + source.m_active = false; + } + + JsonObjectWriter::~JsonObjectWriter() { + if ( !m_active ) { return; } + + m_os << '\n'; + JsonUtils::indent( m_os, m_indent_level ); + m_os << '}'; + } + + JsonValueWriter JsonObjectWriter::write( std::string const& key ) { + JsonUtils::appendCommaNewline( + m_os, m_should_comma, m_indent_level + 1 ); + + m_os << '"' << key << '"' << ": "; + return JsonValueWriter{ m_os, m_indent_level + 1 }; + } + + JsonArrayWriter::JsonArrayWriter( std::ostream& os ): + JsonArrayWriter{ os, 0 } {} + JsonArrayWriter::JsonArrayWriter( std::ostream& os, + std::uint64_t indent_level ): + m_os{ os }, m_indent_level{ indent_level } { + m_os << "["; + } + JsonArrayWriter::JsonArrayWriter( JsonArrayWriter&& source ): + m_os{ source.m_os }, + m_indent_level{ source.m_indent_level }, + m_should_comma{ source.m_should_comma }, + m_active{ source.m_active } { + source.m_active = false; + } + JsonArrayWriter::~JsonArrayWriter() { + if ( !m_active ) { return; } + + m_os << '\n'; + JsonUtils::indent( m_os, m_indent_level ); + m_os << ']'; + } + + JsonObjectWriter JsonArrayWriter::writeObject() { + JsonUtils::appendCommaNewline( + m_os, m_should_comma, m_indent_level + 1 ); + return JsonObjectWriter{ m_os, m_indent_level + 1 }; + } + + JsonArrayWriter JsonArrayWriter::writeArray() { + JsonUtils::appendCommaNewline( + m_os, m_should_comma, m_indent_level + 1 ); + return JsonArrayWriter{ m_os, m_indent_level + 1 }; + } + + JsonArrayWriter& JsonArrayWriter::write( bool value ) { + return writeImpl( value ); + } + + JsonValueWriter::JsonValueWriter( std::ostream& os ): + JsonValueWriter{ os, 0 } {} + + JsonValueWriter::JsonValueWriter( std::ostream& os, + std::uint64_t indent_level ): + m_os{ os }, m_indent_level{ indent_level } {} + + JsonObjectWriter JsonValueWriter::writeObject() && { + return JsonObjectWriter{ m_os, m_indent_level }; + } + + JsonArrayWriter JsonValueWriter::writeArray() && { + return JsonArrayWriter{ m_os, m_indent_level }; + } + + void JsonValueWriter::write( bool value ) && { + writeImpl( value ? "true" : "false", false ); + } + +} // namespace Catch diff --git a/src/catch2/internal/catch_jsonwriter.hpp b/src/catch2/internal/catch_jsonwriter.hpp new file mode 100644 index 00000000..9cac3de6 --- /dev/null +++ b/src/catch2/internal/catch_jsonwriter.hpp @@ -0,0 +1,123 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_JSONWRITER_HPP_INCLUDED +#define CATCH_JSONWRITER_HPP_INCLUDED + +#include <catch2/internal/catch_reusable_string_stream.hpp> +#include <catch2/internal/catch_stringref.hpp> + +#include <cstdint> +#include <sstream> + +namespace Catch { + class JsonObjectWriter; + class JsonArrayWriter; + + struct JsonUtils { + static void indent( std::ostream& os, std::uint64_t level ); + static void appendCommaNewline( std::ostream& os, + bool& should_comma, + std::uint64_t level ); + }; + + class JsonValueWriter { + public: + JsonValueWriter( std::ostream& os ); + JsonValueWriter( std::ostream& os, std::uint64_t indent_level ); + + JsonObjectWriter writeObject() &&; + JsonArrayWriter writeArray() &&; + + template <typename T> + void write( T const& value ) && { + writeImpl( value, !std::is_arithmetic<T>::value ); + } + + void write( bool value ) &&; + + private: + template <typename T> + void writeImpl( T const& value, bool quote_value ) { + if ( quote_value ) { m_os << '"'; } + m_sstream << value; + while ( true ) { + char c = m_sstream.get(); + + if ( m_sstream.eof() ) { break; } + if ( c == '"' ) { + m_os << '\\' << '"'; + } else { + m_os << c; + } + } + if ( quote_value ) { m_os << '"'; } + } + + std::ostream& m_os; + std::stringstream m_sstream{}; + std::uint64_t m_indent_level; + }; + + class JsonObjectWriter { + public: + JsonObjectWriter( std::ostream& os ); + JsonObjectWriter( std::ostream& os, std::uint64_t indent_level ); + + JsonObjectWriter( JsonObjectWriter&& source ); + JsonObjectWriter& operator=( JsonObjectWriter&& source ) = delete; + + ~JsonObjectWriter(); + + JsonValueWriter write( std::string const& key ); + + private: + std::ostream& m_os; + std::uint64_t m_indent_level; + bool m_should_comma = false; + bool m_active = true; + }; + + class JsonArrayWriter { + public: + JsonArrayWriter( std::ostream& os ); + JsonArrayWriter( std::ostream& os, std::uint64_t indent_level ); + + JsonArrayWriter( JsonArrayWriter&& source ); + JsonArrayWriter& operator=( JsonArrayWriter&& source ) = delete; + + ~JsonArrayWriter(); + + JsonObjectWriter writeObject(); + JsonArrayWriter writeArray(); + + template <typename T> + JsonArrayWriter& write( T const& value ) { + return writeImpl( value ); + } + + JsonArrayWriter& write( bool value ); + + private: + template <typename T> + JsonArrayWriter& writeImpl( T const& value ) { + JsonUtils::appendCommaNewline( + m_os, m_should_comma, m_indent_level + 1 ); + JsonValueWriter{ m_os }.write( value ); + + return *this; + } + + std::ostream& m_os; + std::uint64_t m_indent_level; + bool m_should_comma = false; + bool m_active = true; + }; + +} // namespace Catch + +#endif // CATCH_JSONWRITER_HPP_INCLUDED diff --git a/src/catch2/internal/catch_reporter_registry.cpp b/src/catch2/internal/catch_reporter_registry.cpp index b2b0cd07..cea8c4dc 100644 --- a/src/catch2/internal/catch_reporter_registry.cpp +++ b/src/catch2/internal/catch_reporter_registry.cpp @@ -6,13 +6,14 @@ // SPDX-License-Identifier: BSL-1.0 -#include <catch2/internal/catch_reporter_registry.hpp> #include <catch2/interfaces/catch_interfaces_reporter_factory.hpp> #include <catch2/internal/catch_enforce.hpp> #include <catch2/internal/catch_move_and_forward.hpp> +#include <catch2/internal/catch_reporter_registry.hpp> #include <catch2/reporters/catch_reporter_automake.hpp> #include <catch2/reporters/catch_reporter_compact.hpp> #include <catch2/reporters/catch_reporter_console.hpp> +#include <catch2/reporters/catch_reporter_json.hpp> #include <catch2/reporters/catch_reporter_junit.hpp> #include <catch2/reporters/catch_reporter_registrars.hpp> #include <catch2/reporters/catch_reporter_sonarqube.hpp> @@ -47,6 +48,8 @@ namespace Catch { Detail::make_unique<ReporterFactory<TeamCityReporter>>(); m_impl->factories["XML"] = Detail::make_unique<ReporterFactory<XmlReporter>>(); + m_impl->factories["JSON"] = + Detail::make_unique<ReporterFactory<JsonReporter>>(); } ReporterRegistry::~ReporterRegistry() = default; |