From 1c2a7d6b1d5837f7a58f9294b591bf2cdb7e94e6 Mon Sep 17 00:00:00 2001 From: Pan Block Date: Fri, 15 May 2026 16:34:10 -0700 Subject: [PATCH 1/3] copy mck1117 --- Source/Mock/lhc_mock.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Source/Mock/lhc_mock.cpp b/Source/Mock/lhc_mock.cpp index 73c276ec..c1fb2d7b 100644 --- a/Source/Mock/lhc_mock.cpp +++ b/Source/Mock/lhc_mock.cpp @@ -60,8 +60,8 @@ bool Mock_Internal_HCHttpCallPerformAsync( auto& mocks{ httpSingleton->m_mocks }; HC_MOCK_CALL* mock{ nullptr }; - // Use the most recently added mock that matches (similar to a stack). - for (auto iter = mocks.rbegin(); iter != mocks.rend(); ++iter) + // Use the first mock that matches this call + for (auto iter = mocks.begin(); iter != mocks.end(); ++iter) { if (DoesMockCallMatch(*iter, originalCall)) { @@ -128,6 +128,21 @@ bool Mock_Internal_HCHttpCallPerformAsync( HCHttpCallResponseSetHeader(originalCall, str1, str2); } + // If this is not the only mock that matches, remove it from the list of mocks so that multiple can be used + // in sequence + auto countMatching = std::count_if( + mocks.begin(), + mocks.end(), + [originalCall](auto m) + { + return DoesMockCallMatch(m, originalCall); + }); + + if (countMatching > 1) + { + HCMockRemoveMock(mock); + } + return true; } From 8226e2359d45cc249eae76e76bb08b5af8b4194b Mon Sep 17 00:00:00 2001 From: Pan Block Date: Mon, 18 May 2026 23:04:38 -0700 Subject: [PATCH 2/3] pr --- Source/Global/global.h | 1 + Source/Mock/lhc_mock.cpp | 31 ++++++++++++++++++++++++++----- Source/Mock/mock_publics.cpp | 2 ++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Source/Global/global.h b/Source/Global/global.h index e5cf839a..e35b31ac 100644 --- a/Source/Global/global.h +++ b/Source/Global/global.h @@ -78,6 +78,7 @@ typedef struct http_singleton // Mock state std::recursive_mutex m_mocksLock; http_internal_vector m_mocks; + http_internal_map m_mockCycleIndex; std::recursive_mutex m_sharedPtrsLock; http_internal_unordered_map> m_sharedPtrs; diff --git a/Source/Mock/lhc_mock.cpp b/Source/Mock/lhc_mock.cpp index c1fb2d7b..b7d68aa9 100644 --- a/Source/Mock/lhc_mock.cpp +++ b/Source/Mock/lhc_mock.cpp @@ -60,16 +60,37 @@ bool Mock_Internal_HCHttpCallPerformAsync( auto& mocks{ httpSingleton->m_mocks }; HC_MOCK_CALL* mock{ nullptr }; - // Use the first mock that matches this call - for (auto iter = mocks.begin(); iter != mocks.end(); ++iter) + // Collect all matching mocks in insertion order + http_internal_vector matchingMocks; + for (auto& m : mocks) { - if (DoesMockCallMatch(*iter, originalCall)) + if (DoesMockCallMatch(m, originalCall)) { - mock = *iter; - break; + matchingMocks.push_back(m); } } + if (matchingMocks.empty()) + { + return false; + } + + if (matchingMocks.size() == 1) + { + mock = matchingMocks[0]; + } + else + { + // Build a key from method+url to track cycling position + http_internal_string key{ originalCall->method }; + key += "|"; + key += originalCall->url; + + auto& idx = httpSingleton->m_mockCycleIndex[key]; + mock = matchingMocks[idx % matchingMocks.size()]; + ++idx; + } + if (!mock) { return false; diff --git a/Source/Mock/mock_publics.cpp b/Source/Mock/mock_publics.cpp index fdd7c6c9..e5795f32 100644 --- a/Source/Mock/mock_publics.cpp +++ b/Source/Mock/mock_publics.cpp @@ -115,6 +115,7 @@ try { mocks.erase(iter); HCHttpCallCloseHandle(call); + httpSingleton->m_mockCycleIndex.clear(); return S_OK; } } @@ -139,6 +140,7 @@ try } httpSingleton->m_mocks.clear(); + httpSingleton->m_mockCycleIndex.clear(); return S_OK; } CATCH_RETURN() From fb980d4343d3d0745483b45d7f04189ee1d94d23 Mon Sep 17 00:00:00 2001 From: Pan Block Date: Tue, 19 May 2026 14:19:32 -0700 Subject: [PATCH 3/3] missed change --- Source/Mock/lhc_mock.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/Source/Mock/lhc_mock.cpp b/Source/Mock/lhc_mock.cpp index b7d68aa9..7a73f820 100644 --- a/Source/Mock/lhc_mock.cpp +++ b/Source/Mock/lhc_mock.cpp @@ -149,21 +149,6 @@ bool Mock_Internal_HCHttpCallPerformAsync( HCHttpCallResponseSetHeader(originalCall, str1, str2); } - // If this is not the only mock that matches, remove it from the list of mocks so that multiple can be used - // in sequence - auto countMatching = std::count_if( - mocks.begin(), - mocks.end(), - [originalCall](auto m) - { - return DoesMockCallMatch(m, originalCall); - }); - - if (countMatching > 1) - { - HCMockRemoveMock(mock); - } - return true; }