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

summaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
authorLeitwolf112026-11-01 20:05:56 +0300
committerLeitwolf112026-11-01 20:05:56 +0300
commit8603d31fd8c1a72e30cb444f278d7a0592383ba7 (patch)
tree496d26ff659e92cdf4e6fe27a4aa47bf52818052 /tests
parent2aea9dafd283d69bec459ea0d495c25d1f6a0f94 (diff)
downloadcatch3-feature/mocking.tar.gz
Answer the review of the mocksfeature/mocking
A report no longer throws, so a noexcept mock survives an aborting run. A call that has nothing to return still leaves the test case, which ends the process in a noexcept function; the documentation says so. RunContext clears the result capture when it goes, so a mock of static lifetime finds none and writes to standard error. Decision owns its source line, since Verify can free the expectation while a call is on its way. Moving a result out takes the lock. Vector matchers refer to their vector, so they are rejected at compile time like composed ones. A null text expectation accepts only null, and integers compare by value, so 256 no longer accepts an unsigned char.
Diffstat (limited to 'tests')
-rw-r--r--tests/Progmasoft/Mock.tests.cpp75
-rw-r--r--tests/Progmasoft/RunnerFixture.cpp9
2 files changed, 84 insertions, 0 deletions
diff --git a/tests/Progmasoft/Mock.tests.cpp b/tests/Progmasoft/Mock.tests.cpp
index 0329bc41..a5213e51 100644
--- a/tests/Progmasoft/Mock.tests.cpp
+++ b/tests/Progmasoft/Mock.tests.cpp
@@ -5,6 +5,7 @@
#include <Progmasoft/Catch3/Matchers/String.hpp>
#include <Progmasoft/Catch3/Mock.hpp>
#include <Progmasoft/Catch3/TestMacros.hpp>
+#include <atomic>
#include <functional>
#include <map>
#include <memory>
@@ -242,6 +243,80 @@ TEST_CASE("Strings match by value, whatever their type", "[progmasoft][mock]")
size(3);
}
+TEST_CASE("A null text expectation accepts only null", "[progmasoft][mock]")
+{
+ const char *const missing = nullptr;
+ CATCH3_MOCK_FUNCTION(pointer, int(const char *));
+ CATCH3_MOCK_FUNCTION(text, int(const std::string &));
+ CATCH3_EXPECT_CALL(pointer)(missing).Returns(1);
+ CATCH3_EXPECT_CALL(pointer)("text").Returns(2);
+ CATCH3_EXPECT_CALL(text)(missing).AnyTimes().Returns(1);
+ CATCH3_EXPECT_CALL(text)(Any).Returns(2);
+
+ CHECK(pointer(nullptr) == 1);
+ CHECK(pointer("text") == 2);
+ CHECK(text("") == 2);
+}
+
+TEST_CASE("Integers match by value, whatever their types", "[progmasoft][mock]")
+{
+ CATCH3_MOCK_FUNCTION(narrow, int(unsigned char));
+ CATCH3_MOCK_FUNCTION(unsignedOne, int(unsigned));
+ CATCH3_MOCK_FUNCTION(signedOne, int(int));
+ CATCH3_MOCK_FUNCTION(flag, int(bool));
+ CATCH3_EXPECT_CALL(narrow)(256).AnyTimes().Returns(1);
+ CATCH3_EXPECT_CALL(narrow)(Any).Returns(2);
+ CATCH3_EXPECT_CALL(unsignedOne)(-1).AnyTimes().Returns(1);
+ CATCH3_EXPECT_CALL(unsignedOne)(7).Returns(2);
+ CATCH3_EXPECT_CALL(unsignedOne)(Any).Returns(3);
+ CATCH3_EXPECT_CALL(signedOne)(4294967295U).AnyTimes().Returns(1);
+ CATCH3_EXPECT_CALL(signedOne)(Any).Returns(2);
+ CATCH3_EXPECT_CALL(flag)(true).Returns(1);
+
+ CHECK(narrow(0) == 2);
+ CHECK(unsignedOne(7U) == 2);
+ CHECK(unsignedOne(4294967295U) == 3);
+ CHECK(signedOne(-1) == 2);
+ CHECK(flag(true) == 1);
+}
+
+TEST_CASE("Calls from other threads share a result that can only move",
+ "[progmasoft][mock]")
+{
+ CATCH3_MOCK_FUNCTION(take, std::unique_ptr<int>());
+ CATCH3_EXPECT_CALL(take)().Times(400).Returns(std::make_unique<int>(1));
+ std::atomic<int> taken{ 0 };
+ std::vector<std::thread> threads;
+ for (int thread = 0; thread < 4; ++thread)
+ {
+ threads.emplace_back([&take, &taken] {
+ for (int call = 0; call < 100; ++call)
+ {
+ if (take() != nullptr)
+ {
+ ++taken;
+ }
+ }
+ });
+ }
+ for (auto &thread : threads)
+ {
+ thread.join();
+ }
+ CHECK(taken == 1);
+}
+
+TEST_CASE("A mock can outlive the run", "[progmasoft][mock]")
+{
+ const Scratch scratch;
+ const auto run
+ = RunFixture(scratch, { "--no-history", "[mock-exit]", "--jobs=1" });
+ INFO(run.output);
+ CHECK(ExitCode(run) == 0);
+ CHECK(run.Test("fixture mock outlives the run")["outcome"].AsString()
+ == "passed");
+}
+
TEST_CASE("Calls from other threads are counted", "[progmasoft][mock]")
{
CATCH3_MOCK_FUNCTION(tick, int());
diff --git a/tests/Progmasoft/RunnerFixture.cpp b/tests/Progmasoft/RunnerFixture.cpp
index 2796912f..3a61d05c 100644
--- a/tests/Progmasoft/RunnerFixture.cpp
+++ b/tests/Progmasoft/RunnerFixture.cpp
@@ -251,6 +251,15 @@ TEST_CASE("fixture mock left by a failure", "[fixture][mock]")
FAIL("the test's own failure");
}
+TEST_CASE("fixture mock outlives the run", "[fixture][mock-exit]")
+{
+ static auto *mock = new Progmasoft::Catch3::MockFunction<void()>{ "late" };
+ CATCH3_EXPECT_CALL (*mock)();
+ std::atexit([] {
+ delete mock;
+ });
+}
+
TEST_CASE("fixture skips", "[fixture][skip]")
{
SKIP("not on this machine");