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

Next cpp setup #4

Draft
wants to merge 26 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
adb3d2e
Test possibilities of Catch2 reporter
hobovsky Jan 22, 2024
a422cfd
CW preprocessor for solution and preloaded snippets
hobovsky Jan 22, 2024
30eac8c
Setup using preprocessed snippets
hobovsky Jan 22, 2024
53a7517
Dockerfile - initial attempt
hobovsky Jan 22, 2024
766d0d9
Organization of snippets
hobovsky Jan 22, 2024
5321634
make scripts runnable in my docker
hobovsky Jan 22, 2024
0ae9f21
Organize examples of migrated kata
hobovsky Jan 22, 2024
eccb2d8
Update locations of files in the original example to my proposed solu…
hobovsky Jan 22, 2024
602b6b3
Add example "Cafeteria"
hobovsky Jan 22, 2024
3f6333a
Remove preprocessor from the Docker image, copy processed files into …
hobovsky Jan 24, 2024
f5d1a4d
Add missing newlines around `<DESCRIBE::>`
hobovsky Jan 24, 2024
18e7a0b
Example with parametrized tests
hobovsky Jan 25, 2024
709f7bb
Example with exceptions
hobovsky Jan 25, 2024
2cea213
Example with crashes
hobovsky Jan 25, 2024
c730982
Add/fix missing includes and macros
hobovsky Jan 25, 2024
3b3cd17
Showcase of assertions and matchers most useful in context of CW
hobovsky Jan 25, 2024
2a1c45a
Update README.md
hobovsky Jan 25, 2024
e022dce
Presentation of results for various kinds of test fixtures
hobovsky Jan 25, 2024
95f6b5c
Remove test_Case_name from test titles
hobovsky Jan 25, 2024
2d17807
Presentation of results for various kinds of test fixtures
hobovsky Jan 25, 2024
9cf36c3
Move preprocessor out of the GTest folder
hobovsky Jan 25, 2024
701a234
Docker image for Catch2
hobovsky Jan 25, 2024
cbfd1df
Reporter - initial version, all events
hobovsky Jan 25, 2024
9c1962f
Examples for organization of tests
hobovsky Jan 25, 2024
273c4c8
Update codewars_reporter.cpp
hobovsky Jan 25, 2024
d6f314d
Fix markers
kazk Nov 8, 2024
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
27 changes: 27 additions & 0 deletions catch2/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
FROM alpine:latest

RUN apk update \
&& apk upgrade \
&& apk add --no-cache \
clang \
clang-dev \
alpine-sdk \
dpkg \
cmake \
ccache \
ninja

RUN ln -sf /usr/bin/clang /usr/bin/cc \
&& ln -sf /usr/bin/clang++ /usr/bin/c++ \
&& update-alternatives --install /usr/bin/cc cc /usr/bin/clang 10\
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 10\
&& update-alternatives --auto cc \
&& update-alternatives --auto c++ \
&& update-alternatives --display cc \
&& update-alternatives --display c++ \
&& ls -l /usr/bin/cc /usr/bin/c++ \
&& cc --version \
&& c++ --version

WORKDIR /code
COPY docker_image .
27 changes: 23 additions & 4 deletions catch2/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# Catch2
# GoogleTest

## Scripts for local Docker

Locally I use Windows, that's why my scripts are batch files.
- `build-image.bat` builds an image to run C++ kata,
- `run-image.bat` runs code of a kata in a container. Use `run-image KATA-CODE` to run, whenre `KATA-CODE` is a name of one of subdirectories in `kata_code` directory.

## Docker image

> `CodewarsReporter` is unfinished.

Expand All @@ -9,10 +17,21 @@ cmake --build build && ./build/tests/tests --reporter=codewars

Use `./configure.sh` and `./run-tests.sh`.


We'll configure and build an example project while building the container image so each submission will only build the submitted code.

---

I haven't figured out the timings of the test events used in the custom reporter yet.
The tests can be written more naturally, but it might be difficult to get the output we want.

The `snippets` directory contains snippets of example kata as they are submitted, before preprocessing.

The `kata_code` directory contains source file of a kata as produced by the CW preprocessor. The files are cp-ed into a container.

## Example kata

- `ExampleExceptions` - a set of test cases to evaluate output of the reporter in case of expected and unexpected exceptions.
- `ExampleFailureMessages` - showcase of assertions and matchers most useful for CW authors.
- `ExampleOrganization` - a set of test fixtures instantiated in various ways evaluate output of the reporter (especially grouping of tests).
- `ExampleParametrized` - a set of parametrized/generated tests to evaluate output of the reporter.
- `OriginalExample` - the original example of Google Test tests prepared by kazk. It uses no CW preprocessor markers, and only `preloaded.h` and `solution.cpp` are relevant. `preloaded.cpp` and `solution.h` are also saved, but are irrelevant, and cause no problems when buiding and testing the kata.
- `UniqueInOrder` - a kata which requires separate cpp file and header file for solution, because it requires users to implement two functions: one is a template, and one is a "normal" function. It uses CW preprocessor markers to split submitted solution snippet into two files.
- `Cafeteria` - a kata with no preprocessing markers, with a complex preloaded, where both solution and preloaded are treated as headers, and the cpp part of both gets (apparently) ignored. It also defines custom `operator <<` for the preloaded types, which is used by GTest to present instances in failure messages. To be honest, I am not sure why this example works because I expected it to fail with linker errors caused by standalone definitions of `operator<<`. I need to take a better look.
1 change: 1 addition & 0 deletions catch2/build_image.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
docker build --tag cw-catch2-cpp .
1 change: 1 addition & 0 deletions catch2/docker_image/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
File renamed without changes.
2 changes: 1 addition & 1 deletion catch2/configure.sh → catch2/docker_image/configure.sh
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/bash
#!/bin/sh
cmake -S . -B build -G Ninja
3 changes: 3 additions & 0 deletions catch2/docker_image/run-kata.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

./configure.sh && ./run-tests.sh
2 changes: 1 addition & 1 deletion catch2/run-tests.sh → catch2/docker_image/run-tests.sh
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/bash
#!/bin/sh

cmake --build build && ./build/tests/tests --reporter=codewars
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(CMAKE_MESSAGE_LOG_LEVEL WARNING)
set(CMAKE_RULE_MESSAGES OFF)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

FetchContent_Declare(
fmt
Expand All @@ -9,10 +10,10 @@ FetchContent_Declare(
)
FetchContent_MakeAvailable(fmt)

find_package(Threads REQUIRED)

add_library(challenge solution.cpp)
add_library(challenge preloaded.cpp solution.cpp)
target_include_directories(challenge PUBLIC ../include)
target_compile_features(challenge PUBLIC cxx_std_20)
target_compile_options(challenge PUBLIC -Wall -Wextra -O2)
target_link_libraries(challenge PUBLIC m crypto dl sqlite3 tbb fmt Threads::Threads)
# target_link_libraries(challenge PUBLIC m crypto dl sqlite3 tbb fmt Threads::Threads)
target_link_libraries(challenge PUBLIC m dl fmt Threads::Threads)
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ add_executable(tests codewars_reporter.cpp test_solution.cpp)
target_compile_features(tests PRIVATE cxx_std_20)
target_compile_options(tests PRIVATE -Wall -Wextra -O2)
# target_link_libraries(tests PRIVATE challenge Catch2::Catch2 m crypto dl sqlite3 tbb fmt Threads::Threads)
target_link_libraries(tests PRIVATE challenge Catch2::Catch2WithMain m crypto dl sqlite3 tbb fmt Threads::Threads)
target_link_libraries(tests PRIVATE challenge Catch2::Catch2WithMain m dl fmt Threads::Threads)

# Not really necessary for CR, but allows running tests through CMake
add_test(NAME tests COMMAND tests)
86 changes: 86 additions & 0 deletions catch2/docker_image/tests/codewars_reporter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include <catch2/reporters/catch_reporter_helpers.hpp>
#include <catch2/reporters/catch_reporter_streaming_base.hpp>
#include <catch2/catch_test_case_info.hpp>
#include <catch2/reporters/catch_reporter_registrars.hpp>
#include <catch2/catch_timer.hpp>

#include <iostream>
#include <string>

// TODO Complete custom reporter
// - https://github.com/catchorg/Catch2/blob/devel/docs/reporters.md
// - https://github.com/catchorg/Catch2/blob/devel/docs/reporter-events.md
// - https://github.com/catchorg/Catch2/blob/devel/docs/test-cases-and-sections.md
class CodewarsReporter : public Catch::StreamingReporterBase {

private:
unsigned nestedSections = 0;

public:
using StreamingReporterBase::StreamingReporterBase;

CodewarsReporter( Catch::ReporterConfig&& config ):
StreamingReporterBase( CATCH_MOVE(config) ) {
// This is necessary to emit <COMPLETEDIN::> to syntetic, per-assertion IT's
m_preferences.shouldReportAllAssertions = true;
}

static std::string getDescription() {
return "Reporter for Codewars";
}

// Emitted before the first test case is executed.
void testRunStarting(Catch::TestRunInfo const& testRunInfo) override {
std::cout << "\ntestRunStarting " << testRunInfo.name << '\n';
}

// Emitted after all the test cases have been executed.
void testRunEnded(__attribute__((unused)) Catch::TestRunStats const& testRunStats) override {
std::cout << "\ntestRunEnded\n";
}

void sectionStarting(Catch::SectionInfo const& sectionInfo) override {
// Do not emit groups for implicit sections, put results in
// the related test case (or test case partial)
if(nestedSections++ <= 0)
return;
std::cout << "\n<DESCRIBE::>[S]" << sectionInfo.name << '\n';
}

void sectionEnded(__attribute__((unused)) Catch::SectionStats const& sectionStats) override {
if(--nestedSections <= 0)
return;
std::cout << "\n<COMPLETEDIN::>\n";
}

void testCaseStarting(Catch::TestCaseInfo const& testInfo) override {
std::cout << "\n<DESCRIBE::>[TC]" << testInfo.name << '\n';
}

void testCaseEnded(__attribute__((unused)) Catch::TestCaseStats const& testCaseStats) override {
std::cout << "\n<COMPLETEDIN::>\n";
}

void testCasePartialStarting(Catch::TestCaseInfo const& testInfo, uint64_t partNumber) override {
std::cout << "\n<DESCRIBE::>[TCP]" << testInfo.name << '#' << partNumber << '\n';
}

void testCasePartialEnded(__attribute__((unused)) Catch::TestCaseStats const& testCaseStats, __attribute__((unused)) uint64_t partNumber) override {
std::cout << "\n<COMPLETEDIN::>\n";
}

void assertionStarting(__attribute__((unused)) Catch::AssertionInfo const& assertionInfo ) override {
std::cout << "\n<IT::>Assertion: " << assertionInfo.macroName << "(" << assertionInfo.capturedExpression << ")\n";
}
void assertionEnded(Catch::AssertionStats const& assertionStats ) override {
const Catch::AssertionResult& result = assertionStats.assertionResult;
std::string resultTag = result.succeeded() ? "PASSED" : "FAILED";
std::string message = result.hasMessage() ? static_cast<std::string>(result.getMessage()) : (result.succeeded() ? "Test passed" : "Test failed");
std::cout << "\n<" << resultTag << "::>" << message << "\n";
std::cout << "\n<COMPLETEDIN::>\n";
}

};


CATCH_REGISTER_REPORTER("codewars", CodewarsReporter)
Empty file.
Empty file.
Empty file.
Empty file.
143 changes: 143 additions & 0 deletions catch2/kata_code/ExampleOrganization/tests/test_solution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include <vector>

#include <preloaded.h>
#include <catch2/catch_test_macros.hpp>


TEST_CASE( "TestCase1" ) {

REQUIRE( 5 == 5 );
REQUIRE( 12 >= 5 );

SECTION( "Outermost section 1" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "MidLevel section 11" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "Innermost section 111" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
SECTION( "Innermost section 112" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
}
SECTION( "MidLevel section 21" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "Innermost section 121" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
SECTION( "Innermost section 221" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
}
}
SECTION( "Outermost section 2" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "MidLevel section 12" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "Innermost section 112" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
SECTION( "Innermost section 212" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
}
SECTION( "MidLevel section 22" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "Innermost section 122" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
SECTION( "Innermost section 122" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
}
}
}

TEST_CASE( "TestCase2" ) {

REQUIRE( 5 == 5 );
REQUIRE( 12 >= 5 );

SECTION( "Outermost section 1" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "MidLevel section 11" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "Innermost section 111" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
SECTION( "Innermost section 112" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
}
SECTION( "MidLevel section 21" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "Innermost section 121" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
SECTION( "Innermost section 221" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
}
}
SECTION( "Outermost section 2" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "MidLevel section 12" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "Innermost section 112" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
SECTION( "Innermost section 212" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
}
SECTION( "MidLevel section 22" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );

SECTION( "Innermost section 122" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
SECTION( "Innermost section 122" ) {
REQUIRE( 10 == 10 );
REQUIRE( 15 >= 10 );
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ class Counter {
int Increment();
// Returns the current counter value, and decrements it.
int Decrement();
};
};
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include <challenge.h>
#include <preloaded.h>

// Returns the current counter value, and increments it.
int Counter::Increment() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <vector>

#include <challenge.h>
#include <preloaded.h>
#include <catch2/catch_test_macros.hpp>


Expand Down Expand Up @@ -47,4 +47,4 @@ TEST_CASE("Counter") {
REQUIRE(c.Increment() == 2);
REQUIRE(c.Decrement() == 3);
}
}
}
8 changes: 8 additions & 0 deletions catch2/run_image.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
set KATA=%1
set IMAGE=cw-catch2-cpp
set WORKDIR=/code/
set CREATE_CMD=docker container create --rm -w %WORKDIR% %IMAGE% ./run-kata.sh

FOR /F %%i IN ('%CREATE_CMD%') DO set CONTAINER=%%i
docker cp ./kata_code/%KATA%/. %CONTAINER%:%WORKDIR%
docker start --attach -i %CONTAINER%
Loading