Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2/internal
diff options
context:
space:
mode:
authorBeartama2023-11-14 23:52:15 +0200
committerGitHub2023-11-14 22:52:15 +0100
commit7bf136b501fef3e189b45091e8a4757a5eaef31f (patch)
treefe788efc997f7f4ed26fbe5d564d8d40df83c938 /src/catch2/internal
parent2c68a0d05f4fa8fb79cd43824f69568eb3954d4c (diff)
downloadcatch3-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.cpp115
-rw-r--r--src/catch2/internal/catch_jsonwriter.hpp123
-rw-r--r--src/catch2/internal/catch_reporter_registry.cpp5
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;