Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JSON reporter #2706

Merged
merged 41 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
2acb192
Add initial class for JsonWriter
uyha Jun 18, 2023
85c8fdc
Add full implementation for JsonWriter and tests for it
uyha Jun 25, 2023
3bccecf
Make JsonWriter accept more arithmetic types
uyha Jun 25, 2023
aabaced
Make JsonValueWriter accept even more types
uyha Jun 25, 2023
e499b9c
Make constructor with indent level public, remove useless JsonWriter,…
uyha Jun 25, 2023
af8d480
Handle moved from Json{Object,Array}Writer
uyha Jun 25, 2023
8450e1f
Fix quoting bug
uyha Jun 25, 2023
50818bb
Add test for Custom class for JsonValueWriter
uyha Jun 25, 2023
7645901
Handle quote and add test for it
uyha Jun 25, 2023
51daec3
Add barebone JsonReporter which only reports test cases
uyha Jun 25, 2023
3466ae2
Remove unnecessary functions
uyha Jun 25, 2023
5de01e6
Change function names to {start,end}{Object,Array}, add section infor…
uyha Jun 26, 2023
bca353b
Escape quotes for JSON report passing regular expression
uyha Jun 26, 2023
875a266
Fix PR according to comments
uyha Jul 29, 2023
8311231
Add missing endline in test case
uyha Jul 29, 2023
aef7fb0
Add "version" and "metadata" field
uyha Jul 29, 2023
6552d85
Implement listing
uyha Jul 29, 2023
0231352
Remove unnecessary startObject
uyha Jul 29, 2023
17d5ac1
Change how writeSourceInfo and writeCounts are implemented
uyha Jul 30, 2023
1a77b58
Fix "totals" attribute
uyha Jul 30, 2023
27d765e
Change "test-cases" to "test-resulst", use `writeSourceInfo` instead …
uyha Jul 30, 2023
cf58e93
Unify source-location, show properties as a list
uyha Jul 30, 2023
755800a
Adjust section statistics to comments
uyha Jul 30, 2023
23cfd79
Have `startArray` and `startObject` return the writer
uyha Aug 12, 2023
c83f25f
Make the code compilable for C++ 14
uyha Oct 7, 2023
f836897
put sections in `sections` property, still need to make them nested
uyha Oct 7, 2023
0737f88
switch to using `CumulativeReporterBase` instead of `StreamingReporte…
uyha Oct 7, 2023
2e422fe
JSON reporter: clean up the listings a bit
horenmar Oct 10, 2023
d3747f5
JSON reporter asks for stdout redirect
horenmar Oct 10, 2023
88ef5d6
Cleanout superfluous variable assignments
horenmar Oct 10, 2023
151f344
Stub of streaming json reporter
horenmar Nov 13, 2023
121ffa6
Fix size_t -> uint64_t confusion
horenmar Nov 13, 2023
d4f6649
Fix test
horenmar Nov 13, 2023
87b31a0
Actually commit updated approval tests
horenmar Nov 14, 2023
1f5542b
Meson build fix
horenmar Nov 14, 2023
1c41509
Fix license header
horenmar Nov 14, 2023
ff586de
Try fix for old GCC versions
horenmar Nov 14, 2023
d2dcbe7
Fix raw string literal compilation for older compiler
horenmar Nov 14, 2023
9b0c7b3
.
horenmar Nov 14, 2023
934c4ef
meson
horenmar Nov 14, 2023
f372cec
Fix missing include
horenmar Nov 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ set(IMPL_HEADERS
${SOURCES_DIR}/internal/catch_floating_point_helpers.hpp
${SOURCES_DIR}/internal/catch_getenv.hpp
${SOURCES_DIR}/internal/catch_istream.hpp
${SOURCES_DIR}/internal/catch_jsonwriter.hpp
${SOURCES_DIR}/internal/catch_is_permutation.hpp
${SOURCES_DIR}/internal/catch_lazy_expr.hpp
${SOURCES_DIR}/internal/catch_leak_detector.hpp
Expand Down Expand Up @@ -177,6 +178,7 @@ set(IMPL_SOURCES
${SOURCES_DIR}/internal/catch_floating_point_helpers.cpp
${SOURCES_DIR}/internal/catch_getenv.cpp
${SOURCES_DIR}/internal/catch_istream.cpp
${SOURCES_DIR}/internal/catch_jsonwriter.cpp
${SOURCES_DIR}/internal/catch_lazy_expr.cpp
${SOURCES_DIR}/internal/catch_leak_detector.cpp
${SOURCES_DIR}/internal/catch_list.cpp
Expand Down Expand Up @@ -289,6 +291,7 @@ set(REPORTER_HEADERS
${SOURCES_DIR}/reporters/catch_reporter_cumulative_base.hpp
${SOURCES_DIR}/reporters/catch_reporter_event_listener.hpp
${SOURCES_DIR}/reporters/catch_reporter_helpers.hpp
${SOURCES_DIR}/reporters/catch_reporter_json.hpp
${SOURCES_DIR}/reporters/catch_reporter_junit.hpp
${SOURCES_DIR}/reporters/catch_reporter_multi.hpp
${SOURCES_DIR}/reporters/catch_reporter_registrars.hpp
Expand All @@ -307,6 +310,7 @@ set(REPORTER_SOURCES
${SOURCES_DIR}/reporters/catch_reporter_cumulative_base.cpp
${SOURCES_DIR}/reporters/catch_reporter_event_listener.cpp
${SOURCES_DIR}/reporters/catch_reporter_helpers.cpp
${SOURCES_DIR}/reporters/catch_reporter_json.cpp
${SOURCES_DIR}/reporters/catch_reporter_junit.cpp
${SOURCES_DIR}/reporters/catch_reporter_multi.cpp
${SOURCES_DIR}/reporters/catch_reporter_registrars.cpp
Expand Down
1 change: 1 addition & 0 deletions src/catch2/catch_all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
#include <catch2/internal/catch_getenv.hpp>
#include <catch2/internal/catch_is_permutation.hpp>
#include <catch2/internal/catch_istream.hpp>
#include <catch2/internal/catch_jsonwriter.hpp>
#include <catch2/internal/catch_lazy_expr.hpp>
#include <catch2/internal/catch_leak_detector.hpp>
#include <catch2/internal/catch_list.hpp>
Expand Down
115 changes: 115 additions & 0 deletions src/catch2/internal/catch_jsonwriter.cpp
Original file line number Diff line number Diff line change
@@ -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
122 changes: 122 additions & 0 deletions src/catch2/internal/catch_jsonwriter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@

// 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 <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
5 changes: 4 additions & 1 deletion src/catch2/internal/catch_reporter_registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down
Loading
Loading