diff options
| author | Leitwolf | 2026-10-24 19:03:40 +0300 |
|---|---|---|
| committer | GitHub | 2026-10-24 19:03:40 +0300 |
| commit | 4f1c759cffcb14bd6511e1d7c5fbace682e24f2d (patch) | |
| tree | 415fe5d48a5b48650bba3747beaf245d727c4f61 /tests/Progmasoft/RunnerFixture.cpp | |
| parent | 83c6fc3ac13abe83fa39f7b5f8559ccaf4412233 (diff) | |
| parent | 622188f9c08e4af35941c146979883ed4882410e (diff) | |
| download | catch3-4f1c759cffcb14bd6511e1d7c5fbace682e24f2d.tar.gz | |
Merge pull request #15 from Progmasoft/feature/catch3-runner
Replace Catch2's runner with the Catch3 runner
Diffstat (limited to 'tests/Progmasoft/RunnerFixture.cpp')
| -rw-r--r-- | tests/Progmasoft/RunnerFixture.cpp | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/tests/Progmasoft/RunnerFixture.cpp b/tests/Progmasoft/RunnerFixture.cpp new file mode 100644 index 00000000..fe9fb150 --- /dev/null +++ b/tests/Progmasoft/RunnerFixture.cpp @@ -0,0 +1,190 @@ +// Copyright (c) 2026 Progmasoft. +// SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-1.1 + +// A test binary whose tests misbehave on purpose. The runner's integration +// tests start it and check what the runner made of each misbehaviour. + +#include <Progmasoft/Catch3/Runner.hpp> +#include <catch2/catch_test_macros.hpp> +#include <chrono> +#include <cstdlib> +#include <filesystem> +#include <fstream> +#include <iostream> +#include <optional> +#include <string> +#include <thread> + +namespace +{ + /// The value of the environment variable `name`, if it is set. + std::optional<std::string> + Environment(const char *name) + { +#if defined(_WIN32) + char *value = nullptr; + std::size_t length = 0; + if (_dupenv_s(&value, &length, name) != 0 || value == nullptr) + { + return std::nullopt; + } + std::string result{ value }; + std::free(value); + return result; +#else + const char *value = std::getenv(name); + return value == nullptr ? std::nullopt + : std::optional<std::string>{ value }; +#endif + } + + /// A directory the integration test gives every run of the fixture, to + /// count attempts across worker processes. + std::filesystem::path + StateDirectory() + { + const auto directory = Environment("CATCH3_FIXTURE_STATE"); + return directory ? std::filesystem::path{ *directory } + : std::filesystem::path{}; + } + + /// How often `name` ran before, counted in a file; increments it. + int + CountRun(const std::string &name) + { + const auto file = StateDirectory() / (name + ".count"); + int count = 0; + { + std::ifstream input(file); + input >> count; + } + std::ofstream output(file, std::ios::trunc); + output << count + 1; + return count; + } + + bool polluted = false; +} // namespace + +TEST_CASE("fixture passes", "[fixture][pass]") +{ + REQUIRE(1 + 1 == 2); +} + +TEST_CASE("fixture prints", "[fixture][pass]") +{ + std::cout << "said through std::cout\n"; + std::cerr << "said through std::cerr\n"; + CHECK(true); +} + +TEST_CASE("fixture fails", "[fixture][fail]") +{ + const int expected = 3; + SECTION("in a section") + { + CHECK(1 + 1 == expected); + } +} + +TEST_CASE("fixture throws", "[fixture][fail]") +{ + throw std::runtime_error("broken on purpose"); +} + +TEST_CASE("fixture crashes", "[fixture][crash]") +{ + SECTION("deep down") + { + CHECK(true); + std::abort(); + } +} + +TEST_CASE("fixture hangs", "[fixture][hang][!timeout:1]") +{ + CHECK(true); + std::this_thread::sleep_for(std::chrono::seconds(60)); +} + +TEST_CASE("fixture is flaky", "[fixture][flaky]") +{ + // Fails the first time it runs, passes afterwards. + REQUIRE(CountRun("flaky") > 0); +} + +TEST_CASE("fixture alternates", "[fixture][alternate]") +{ + // Fails on every even run: flaky on every run of the runner. + REQUIRE(CountRun("alternates") % 2 == 1); +} + +TEST_CASE("fixture innocent one", "[fixture][order]") +{ + CHECK(true); +} + +TEST_CASE("fixture polluter", "[fixture][order]") +{ + polluted = true; + CHECK(true); +} + +TEST_CASE("fixture innocent two", "[fixture][order]") +{ + CHECK(true); +} + +TEST_CASE("fixture victim", "[fixture][order]") +{ + REQUIRE_FALSE(polluted); +} + +TEST_CASE("fixture base", "[fixture][deps]") +{ + FAIL("the base is broken"); +} + +TEST_CASE("fixture dependent", "[fixture][deps][!depends:fixture base]") +{ + CHECK(true); +} + +TEST_CASE("fixture temporary directory", "[fixture][temp]") +{ + const auto directory = Progmasoft::Catch3::TestTemporaryDirectory(); + REQUIRE(std::filesystem::exists(directory)); + REQUIRE(std::filesystem::equivalent(std::filesystem::temp_directory_path(), + directory)); + std::ofstream(directory / "scratch.txt") << "kept only on failure"; + CHECK_FALSE(Environment("CATCH3_FIXTURE_FAIL_TEMP").has_value()); +} + +TEST_CASE("fixture slow one", "[fixture][slow]") +{ + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + CHECK(true); +} + +TEST_CASE("fixture slow two", "[fixture][slow]") +{ + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + CHECK(true); +} + +TEST_CASE("fixture slow three", "[fixture][slow]") +{ + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + CHECK(true); +} + +TEST_CASE("fixture slow four", "[fixture][slow]") +{ + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + CHECK(true); +} + +TEST_CASE("fixture skips", "[fixture][skip]") +{ + SKIP("not on this machine"); +} |