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

summaryrefslogtreecommitdiffhomepage
path: root/tests/Progmasoft
diff options
context:
space:
mode:
authorLeitwolf2026-10-31 17:18:21 +0300
committerGitHub2026-10-31 17:18:21 +0300
commit326ea0c0213aeecb6b984bba3dabb0ebad97679e (patch)
tree5cec698f0bc0b8a60f45e866fb40f2fd8a358bd1 /tests/Progmasoft
parent6a42cdf6461b2577106ef094d6f98025554b6077 (diff)
parentafe91797e9d50cd4712d3694a2e5fedfc0b966b1 (diff)
downloadcatch3-326ea0c0213aeecb6b984bba3dabb0ebad97679e.tar.gz
Merge pull request #22 from Progmasoft/build/cpp17
Build Catch3 as C++17
Diffstat (limited to 'tests/Progmasoft')
-rw-r--r--tests/Progmasoft/BUILD.bazel8
-rw-r--r--tests/Progmasoft/Generators.tests.cpp76
-rw-r--r--tests/Progmasoft/Property.tests.cpp66
-rw-r--r--tests/Progmasoft/Results.tests.cpp2
-rw-r--r--tests/Progmasoft/Snapshot.tests.cpp77
-rw-r--r--tests/Progmasoft/Strategy.tests.cpp34
6 files changed, 182 insertions, 81 deletions
diff --git a/tests/Progmasoft/BUILD.bazel b/tests/Progmasoft/BUILD.bazel
index 9627f65d..de7f124d 100644
--- a/tests/Progmasoft/BUILD.bazel
+++ b/tests/Progmasoft/BUILD.bazel
@@ -24,8 +24,8 @@ cc_test(
"Strategy.tests.cpp",
],
copts = select({
- "@platforms//os:windows": ["/std:c++20"],
- "//conditions:default": ["-std=c++20"],
+ "@platforms//os:windows": ["/std:c++17"],
+ "//conditions:default": ["-std=c++17"],
}),
args = ["--no-history"],
data = [":runner_fixture"],
@@ -41,8 +41,8 @@ cc_binary(
name = "runner_fixture",
srcs = ["RunnerFixture.cpp"],
copts = select({
- "@platforms//os:windows": ["/std:c++20"],
- "//conditions:default": ["-std=c++20"],
+ "@platforms//os:windows": ["/std:c++17"],
+ "//conditions:default": ["-std=c++17"],
}),
deps = [
"//:catch3",
diff --git a/tests/Progmasoft/Generators.tests.cpp b/tests/Progmasoft/Generators.tests.cpp
index 553a8962..b59bab4a 100644
--- a/tests/Progmasoft/Generators.tests.cpp
+++ b/tests/Progmasoft/Generators.tests.cpp
@@ -96,11 +96,16 @@ TEST_CASE( "Vector shrinking offers a bounded number of candidates",
TEST_CASE( "Vector properties shrink to a small counterexample",
"[progmasoft][property][vector]" ) {
const auto result = CheckProperty(
- Vector( Integer<int>( 0, 100 ), 0, 20 ),
- []( const std::vector<int>& values ) {
+ Vector(Integer<int>(0, 100), 0, 20),
+ [](const std::vector<int> &values) {
return std::accumulate( values.begin(), values.end(), 0 ) < 10;
},
- PropertyOptions{ .Trials = 200, .Seed = 0xF00D } );
+ [&] {
+ PropertyOptions made;
+ made.Trials = 200;
+ made.Seed = 0xF00D;
+ return made;
+ }());
REQUIRE( result.Status == PropertyStatus::kFailed );
REQUIRE( result.Failure.has_value() );
@@ -113,10 +118,15 @@ TEST_CASE( "Vector<bool> values generate, shrink and print",
const auto generator = Vector( Progmasoft::Catch3::Boolean(), 0, 8 );
const auto result = CheckProperty(
generator,
- []( const std::vector<bool>& flags ) {
+ [](const std::vector<bool> &flags) {
return std::count( flags.begin(), flags.end(), true ) < 2;
},
- PropertyOptions{ .Trials = 300, .Seed = 0xB001 } );
+ [&] {
+ PropertyOptions made;
+ made.Trials = 300;
+ made.Seed = 0xB001;
+ return made;
+ }());
REQUIRE( result.Status == PropertyStatus::kFailed );
REQUIRE( result.Failure.has_value() );
CHECK( result.Failure->Counterexample == "{ true, true }" );
@@ -167,11 +177,16 @@ TEST_CASE( "Tuple shrinking changes one component at a time, first to last",
TEST_CASE( "Tuple properties minimize every component",
"[progmasoft][property][tuple]" ) {
const auto result = CheckProperty(
- Tuple( Integer<int>( 0, 1000 ), Integer<int>( 0, 1000 ) ),
- []( const std::tuple<int, int>& value ) {
+ Tuple(Integer<int>(0, 1000), Integer<int>(0, 1000)),
+ [](const std::tuple<int, int> &value) {
return std::get<0>( value ) < 50 || std::get<1>( value ) < 50;
},
- PropertyOptions{ .Trials = 500, .Seed = 0x7007 } );
+ [&] {
+ PropertyOptions made;
+ made.Trials = 500;
+ made.Seed = 0x7007;
+ return made;
+ }());
REQUIRE( result.Status == PropertyStatus::kFailed );
REQUIRE( result.Failure.has_value() );
@@ -234,11 +249,16 @@ TEST_CASE( "Text generators stay inside their alphabet and length range",
TEST_CASE( "Text properties shrink to the shortest simplest string",
"[progmasoft][property][text]" ) {
const auto result = CheckProperty(
- Text( "abcxyz", 0, 24 ),
- []( const std::string& value ) {
+ Text("abcxyz", 0, 24),
+ [](const std::string &value) {
return value.find( 'x' ) == std::string::npos;
},
- PropertyOptions{ .Trials = 300, .Seed = 0x7E47 } );
+ [&] {
+ PropertyOptions made;
+ made.Trials = 300;
+ made.Seed = 0x7E47;
+ return made;
+ }());
REQUIRE( result.Status == PropertyStatus::kFailed );
REQUIRE( result.Failure.has_value() );
@@ -260,8 +280,12 @@ TEST_CASE( "A reported replay seed reproduces exactly that trial",
std::get<1>( value ).size() < 2;
};
- const auto original = CheckProperty(
- generator, predicate, PropertyOptions{ .Trials = 500, .Seed = 0x5EED } );
+ const auto original = CheckProperty(generator, predicate, [&] {
+ PropertyOptions made;
+ made.Trials = 500;
+ made.Seed = 0x5EED;
+ return made;
+ }());
REQUIRE( original.Status == PropertyStatus::kFailed );
REQUIRE( original.Failure.has_value() );
// The failure was not on the first trial, so replay skips real work.
@@ -273,12 +297,13 @@ TEST_CASE( "A reported replay seed reproduces exactly that trial",
// A different root seed and trial count prove that only the replay seed
// decides what runs.
- const auto replayed = CheckProperty(
- generator,
- predicate,
- PropertyOptions{ .Trials = 3,
- .Seed = 1,
- .ReplayTrialSeed = original.Failure->TrialSeed } );
+ const auto replayed = CheckProperty(generator, predicate, [&] {
+ PropertyOptions made;
+ made.Trials = 3;
+ made.Seed = 1;
+ made.ReplayTrialSeed = original.Failure->TrialSeed;
+ return made;
+ }());
REQUIRE( replayed.Status == PropertyStatus::kFailed );
REQUIRE( replayed.Failure.has_value() );
CHECK( replayed.TrialsRun == 1 );
@@ -290,9 +315,16 @@ TEST_CASE( "A reported replay seed reproduces exactly that trial",
// Replaying a seed whose trial passes reports one passing trial.
const auto passing = CheckProperty(
- Integer<int>( 0, 10 ),
- []( int value ) { return value <= 10; },
- PropertyOptions{ .Trials = 50, .ReplayTrialSeed = 12345 } );
+ Integer<int>(0, 10),
+ [](int value) {
+ return value <= 10;
+ },
+ [&] {
+ PropertyOptions made;
+ made.Trials = 50;
+ made.ReplayTrialSeed = 12345;
+ return made;
+ }());
CHECK( passing.Succeeded() );
CHECK( passing.TrialsRun == 1 );
}
diff --git a/tests/Progmasoft/Property.tests.cpp b/tests/Progmasoft/Property.tests.cpp
index 5cec3979..9c4c95fb 100644
--- a/tests/Progmasoft/Property.tests.cpp
+++ b/tests/Progmasoft/Property.tests.cpp
@@ -63,11 +63,13 @@ TEST_CASE( "Integer generators preserve bounds and useful shrink order",
Integer<int>( -100, 100 ).Shrink( 6 );
REQUIRE( !positiveShrinks.empty() );
CHECK( positiveShrinks.front() == 0 );
- CHECK( std::ranges::find( positiveShrinks, 5 ) != positiveShrinks.end() );
+ CHECK(std::find(positiveShrinks.begin(), positiveShrinks.end(), 5)
+ != positiveShrinks.end());
const std::vector<int> negativeShrinks = generator.Shrink( -6 );
CHECK( negativeShrinks.front() == 0 );
- CHECK( std::ranges::find( negativeShrinks, -5 ) != negativeShrinks.end() );
+ CHECK(std::find(negativeShrinks.begin(), negativeShrinks.end(), -5)
+ != negativeShrinks.end());
CHECK_THROWS_AS( Integer<int>( 5, -5 ), std::invalid_argument );
}
@@ -93,8 +95,13 @@ TEST_CASE( "Properties count trials and reproduce their seed",
using Progmasoft::Catch3::PropertyOptions;
int checks = 0;
- const PropertyOptions options{
- .Trials = 64, .Seed = 0xC0FFEE, .MaxShrinkSteps = 100 };
+ const PropertyOptions options = [&] {
+ PropertyOptions made;
+ made.Trials = 64;
+ made.Seed = 0xC0FFEE;
+ made.MaxShrinkSteps = 100;
+ return made;
+ }();
const auto property = [&]( int value ) {
++checks;
return value >= -100 && value <= 100;
@@ -137,8 +144,16 @@ TEST_CASE( "Property failures shrink to and report a replayable counterexample",
const auto result = CheckProperty(
generator,
- []( int value ) { return value >= 0; },
- PropertyOptions{ .Trials = 4, .Seed = 0xFACE, .MaxShrinkSteps = 20 } );
+ [](int value) {
+ return value >= 0;
+ },
+ [&] {
+ PropertyOptions made;
+ made.Trials = 4;
+ made.Seed = 0xFACE;
+ made.MaxShrinkSteps = 20;
+ return made;
+ }());
CHECK_FALSE( result.Succeeded() );
CHECK( result.Status == Progmasoft::Catch3::PropertyStatus::kFailed );
@@ -166,8 +181,16 @@ TEST_CASE( "Property shrink work is bounded", "[progmasoft][property]" ) {
} );
const auto result = CheckProperty(
generator,
- []( int ) { return false; },
- PropertyOptions{ .Trials = 1, .Seed = 4, .MaxShrinkSteps = 3 } );
+ [](int) {
+ return false;
+ },
+ [&] {
+ PropertyOptions made;
+ made.Trials = 1;
+ made.Seed = 4;
+ made.MaxShrinkSteps = 3;
+ return made;
+ }());
REQUIRE( result.Failure.has_value() );
CHECK( result.Failure->ShrinkSteps == 3 );
@@ -198,8 +221,16 @@ TEST_CASE(
[]( const int& ) { return std::vector<int>{}; } );
const auto invalidOptions = CheckProperty(
constantGenerator,
- []( int ) { return true; },
- PropertyOptions{ .Trials = 0, .Seed = 1, .MaxShrinkSteps = 1 } );
+ [](int) {
+ return true;
+ },
+ [&] {
+ PropertyOptions made;
+ made.Trials = 0;
+ made.Seed = 1;
+ made.MaxShrinkSteps = 1;
+ return made;
+ }());
CHECK( invalidOptions.Status == PropertyStatus::kInvalidConfiguration );
}
@@ -226,8 +257,15 @@ TEST_CASE( "Predicate exceptions are ordinary reproducible property failures",
TEST_CASE( "Catch3 property assertions report successful runs",
"[progmasoft][property]" ) {
CATCH3_CHECK_PROPERTY(
- Progmasoft::Catch3::Integer<int>( 1, 100 ),
- []( int value ) { return value > 0; },
- Progmasoft::Catch3::PropertyOptions{
- .Trials = 25, .Seed = 42, .MaxShrinkSteps = 10 } );
+ Progmasoft::Catch3::Integer<int>(1, 100),
+ [](int value) {
+ return value > 0;
+ },
+ [&] {
+ Progmasoft::Catch3::PropertyOptions made;
+ made.Trials = 25;
+ made.Seed = 42;
+ made.MaxShrinkSteps = 10;
+ return made;
+ }());
}
diff --git a/tests/Progmasoft/Results.tests.cpp b/tests/Progmasoft/Results.tests.cpp
index ad52d311..a05a601d 100644
--- a/tests/Progmasoft/Results.tests.cpp
+++ b/tests/Progmasoft/Results.tests.cpp
@@ -207,7 +207,7 @@ TEST_CASE("JUnit XML keeps every attempt and marks flaky tests",
CHECK(xml.find("<property name=\"random-seed\" value=\"42\" />") !=
std::string::npos);
CHECK(xml.find("time=\"0.263500\"") != std::string::npos);
- CHECK(xml.ends_with("</testsuites>\n"));
+ CHECK(xml.rfind("</testsuites>\n") == xml.size() - 14U);
}
TEST_CASE("JUnit XML replaces malformed UTF-8 and forbidden XML controls",
diff --git a/tests/Progmasoft/Snapshot.tests.cpp b/tests/Progmasoft/Snapshot.tests.cpp
index 65ee732e..c29cb143 100644
--- a/tests/Progmasoft/Snapshot.tests.cpp
+++ b/tests/Progmasoft/Snapshot.tests.cpp
@@ -42,10 +42,11 @@ TEST_CASE( "Snapshot comparison does not write during ordinary runs",
using Progmasoft::Catch3::SnapshotStatus;
const TemporarySnapshotDirectory directory;
- const auto result =
- CompareSnapshot( "greeting",
- "hello\nworld\n",
- SnapshotOptions{ .Directory = directory.Path } );
+ const auto result = CompareSnapshot("greeting", "hello\nworld\n", [&] {
+ SnapshotOptions made;
+ made.Directory = directory.Path;
+ return made;
+ }());
CHECK( result.Status == SnapshotStatus::kMismatched );
CHECK_FALSE( result.Succeeded() );
@@ -62,10 +63,12 @@ TEST_CASE( "Snapshots normalize line endings and report precise differences",
using Progmasoft::Catch3::SnapshotUpdateMode;
const TemporarySnapshotDirectory directory;
- const SnapshotOptions createOptions{
- .Directory = directory.Path,
- .UpdateMode = SnapshotUpdateMode::kCreateMissing,
- };
+ const SnapshotOptions createOptions = [&] {
+ SnapshotOptions made;
+ made.Directory = directory.Path;
+ made.UpdateMode = SnapshotUpdateMode::kCreateMissing;
+ return made;
+ }();
const auto created =
CompareSnapshot( "multiline", "one\ntwo\n", createOptions );
REQUIRE( created.Status == SnapshotStatus::kCreated );
@@ -76,10 +79,11 @@ TEST_CASE( "Snapshots normalize line endings and report precise differences",
CHECK( normalized.Status == SnapshotStatus::kMatched );
CHECK( normalized.Expected == "one\ntwo\n" );
- const auto mismatch =
- CompareSnapshot( "multiline",
- "one\ntoo\n",
- SnapshotOptions{ .Directory = directory.Path } );
+ const auto mismatch = CompareSnapshot("multiline", "one\ntoo\n", [&] {
+ SnapshotOptions made;
+ made.Directory = directory.Path;
+ return made;
+ }());
CHECK( mismatch.Status == SnapshotStatus::kMismatched );
CHECK( mismatch.DifferenceLine == 2 );
CHECK( mismatch.DifferenceColumn == 2 );
@@ -94,10 +98,12 @@ TEST_CASE( "Snapshot creation and replacement require explicit update modes",
using Progmasoft::Catch3::SnapshotUpdateMode;
const TemporarySnapshotDirectory directory;
- const SnapshotOptions createMissing{
- .Directory = directory.Path,
- .UpdateMode = SnapshotUpdateMode::kCreateMissing,
- };
+ const SnapshotOptions createMissing = [&] {
+ SnapshotOptions made;
+ made.Directory = directory.Path;
+ made.UpdateMode = SnapshotUpdateMode::kCreateMissing;
+ return made;
+ }();
REQUIRE( CompareSnapshot( "answer", "first", createMissing ).Succeeded() );
const auto protectedMismatch =
@@ -105,10 +111,12 @@ TEST_CASE( "Snapshot creation and replacement require explicit update modes",
CHECK( protectedMismatch.Status == SnapshotStatus::kMismatched );
CHECK( protectedMismatch.Expected == "first" );
- const SnapshotOptions updateEverything{
- .Directory = directory.Path,
- .UpdateMode = SnapshotUpdateMode::kAlways,
- };
+ const SnapshotOptions updateEverything = [&] {
+ SnapshotOptions made;
+ made.Directory = directory.Path;
+ made.UpdateMode = SnapshotUpdateMode::kAlways;
+ return made;
+ }();
const auto updated =
CompareSnapshot( "answer", "second", updateEverything );
REQUIRE( updated.Status == SnapshotStatus::kUpdated );
@@ -125,7 +133,11 @@ TEST_CASE( "Snapshot names and I/O failures are returned as structured errors",
using Progmasoft::Catch3::SnapshotUpdateMode;
const TemporarySnapshotDirectory directory;
- const SnapshotOptions options{ .Directory = directory.Path };
+ const SnapshotOptions options = [&] {
+ SnapshotOptions made;
+ made.Directory = directory.Path;
+ return made;
+ }();
CHECK( CompareSnapshot( "../outside", "text", options ).Status ==
SnapshotStatus::kInvalidName );
CHECK( CompareSnapshot( "nested/name", "text", options ).Status ==
@@ -141,11 +153,12 @@ TEST_CASE( "Snapshot names and I/O failures are returned as structured errors",
REQUIRE( output.good() );
output << "file";
}
- const auto ioFailure = CompareSnapshot(
- "snapshot",
- "text",
- SnapshotOptions{ .Directory = blockingFile,
- .UpdateMode = SnapshotUpdateMode::kCreateMissing } );
+ const auto ioFailure = CompareSnapshot("snapshot", "text", [&] {
+ SnapshotOptions made;
+ made.Directory = blockingFile;
+ made.UpdateMode = SnapshotUpdateMode::kCreateMissing;
+ return made;
+ }());
CHECK( ioFailure.Status == SnapshotStatus::kIoError );
CHECK_FALSE( ioFailure.Message.empty() );
}
@@ -156,9 +169,11 @@ TEST_CASE( "Snapshot assertion macro reports successful explicit updates",
CATCH3_CHECK_SNAPSHOT(
"macro",
"stable value",
- ( Progmasoft::Catch3::SnapshotOptions{
- .Directory = directory.Path,
- .UpdateMode =
- Progmasoft::Catch3::SnapshotUpdateMode::kCreateMissing,
- } ) );
+ ([&] {
+ Progmasoft::Catch3::SnapshotOptions made;
+ made.Directory = directory.Path;
+ made.UpdateMode
+ = Progmasoft::Catch3::SnapshotUpdateMode::kCreateMissing;
+ return made;
+ }()));
}
diff --git a/tests/Progmasoft/Strategy.tests.cpp b/tests/Progmasoft/Strategy.tests.cpp
index 5a1d5a2a..2bd49105 100644
--- a/tests/Progmasoft/Strategy.tests.cpp
+++ b/tests/Progmasoft/Strategy.tests.cpp
@@ -116,15 +116,23 @@ TEST_CASE( "Integer strategies respect every kind of range",
TEST_CASE( "Float strategies stay finite and in range unless allowed",
"[progmasoft][strategy]" ) {
using Progmasoft::Catch3::FloatOptions;
- const auto bounded = Gen::Floats<double>(
- FloatOptions{ .Minimum = -2.5, .Maximum = 1000.0 } );
+ const auto bounded = Gen::Floats<double>([&] {
+ FloatOptions made;
+ made.Minimum = -2.5;
+ made.Maximum = 1000.0;
+ return made;
+ }());
for ( double value : Sample( bounded, 3000, 6 ) ) {
CHECK( std::isfinite( value ) );
CHECK( value >= -2.5 );
CHECK( value <= 1000.0 );
}
- const auto everything = Gen::Floats<double>(
- FloatOptions{ .AllowNaN = true, .AllowInfinity = true } );
+ const auto everything = Gen::Floats<double>([&] {
+ FloatOptions made;
+ made.AllowNaN = true;
+ made.AllowInfinity = true;
+ return made;
+ }());
const auto values = Sample( everything, 3000, 7 );
CHECK( std::any_of( values.begin(), values.end(), []( double value ) {
return std::isnan( value );
@@ -132,14 +140,22 @@ TEST_CASE( "Float strategies stay finite and in range unless allowed",
CHECK( std::any_of( values.begin(), values.end(), []( double value ) {
return std::isinf( value );
} ) );
- const auto positive = Gen::Floats<float>(
- FloatOptions{ .Minimum = 1.0, .Maximum = 2.0 } );
+ const auto positive = Gen::Floats<float>([&] {
+ FloatOptions made;
+ made.Minimum = 1.0;
+ made.Maximum = 2.0;
+ return made;
+ }());
const std::vector<std::uint64_t> zeros;
ChoiceSource simplest( zeros, 0 );
CHECK( positive.Draw( simplest ) == 1.0F );
- CHECK_THROWS_AS( Gen::Floats<double>( FloatOptions{ .Minimum = 2.0,
- .Maximum = 1.0 } ),
- std::invalid_argument );
+ CHECK_THROWS_AS(Gen::Floats<double>([&] {
+ FloatOptions made;
+ made.Minimum = 2.0;
+ made.Maximum = 1.0;
+ return made;
+ }()),
+ std::invalid_argument);
}
TEST_CASE( "Collection strategies respect their size ranges",