replace mocked awaitable with std future (#2258)

This commit is contained in:
Tian L. 2024-11-28 18:57:08 +08:00 committed by GitHub
parent bb540e6d80
commit 9d637ccef1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 43 additions and 37 deletions

View file

@ -127,22 +127,25 @@ namespace
namespace CalculatorApp::ViewModel::DataLoaders
{
bool CurrencyHttpClient::ForceWebFailure = false;
void CurrencyHttpClient::Initialize(Platform::String ^ sourceCurrencyCode, Platform::String ^ responseLanguage)
{
m_sourceCurrencyCode = sourceCurrencyCode;
m_responseLanguage = responseLanguage;
}
MockAwaitable<Platform::String ^> CurrencyHttpClient::GetCurrencyMetadataAsync() const
std::future<Platform::String ^> CurrencyHttpClient::GetCurrencyMetadataAsync() const
{
(void)m_responseLanguage; // to be used in production.
return MockAwaitable<Platform::String ^>{ ref new Platform::String(MockCurrencyStaticData) };
std::promise<Platform::String ^> mockedTask;
mockedTask.set_value(ref new Platform::String(MockCurrencyStaticData));
return mockedTask.get_future();
}
MockAwaitable<Platform::String ^> CurrencyHttpClient::GetCurrencyRatiosAsync() const
std::future<Platform::String ^> CurrencyHttpClient::GetCurrencyRatiosAsync() const
{
(void)m_sourceCurrencyCode; // to be used in production.
return MockAwaitable<Platform::String ^>{ ref new Platform::String(MockCurrencyConverterData) };
std::promise<Platform::String ^> mockedTask;
mockedTask.set_value(ref new Platform::String(MockCurrencyConverterData));
return mockedTask.get_future();
}
} // namespace CalculatorApp::ViewModel::DataLoaders

View file

@ -3,38 +3,20 @@
#pragma once
#include <cassert>
#include <future>
namespace CalculatorApp::ViewModel::DataLoaders
{
template <class T>
struct MockAwaitable
{
T Value;
bool await_ready() const noexcept
{
return true;
}
void await_suspend(std::experimental::coroutine_handle<>) const noexcept
{
assert(false && "not implemented.");
}
T await_resume() noexcept
{
return std::move(Value);
}
};
class CurrencyHttpClient
{
public:
#ifdef VIEWMODEL_FOR_UT
static bool ForceWebFailure;
#endif
void Initialize(Platform::String ^ sourceCurrencyCode, Platform::String ^ responseLanguage);
MockAwaitable<Platform::String ^> GetCurrencyMetadataAsync() const;
MockAwaitable<Platform::String ^> GetCurrencyRatiosAsync() const;
std::future<Platform::String ^> GetCurrencyMetadataAsync() const;
std::future<Platform::String ^> GetCurrencyRatiosAsync() const;
private:
Platform::String ^ m_sourceCurrencyCode;

View file

@ -136,6 +136,7 @@
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -156,6 +157,7 @@
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -176,6 +178,7 @@
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -196,6 +199,7 @@
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -216,6 +220,7 @@
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -236,6 +241,7 @@
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -256,6 +262,7 @@
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -276,6 +283,7 @@
<AdditionalOptions>/bigobj /await /std:c++17 /utf-8 %(AdditionalOptions)</AdditionalOptions>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

View file

@ -21,23 +21,28 @@ namespace CalculatorApp::ViewModel::DataLoaders
m_responseLanguage = responseLanguage;
}
MockAwaitable<Platform::String ^> CurrencyHttpClient::GetCurrencyMetadataAsync() const
std::future<Platform::String ^> CurrencyHttpClient::GetCurrencyMetadataAsync() const
{
if (ForceWebFailure)
{
throw ref new Platform::Exception(E_FAIL, L"Mocked Network Failure: failed to load currency metadata");
}
(void)m_responseLanguage; // to be used in production.
return MockAwaitable<Platform::String ^>{ ref new Platform::String(MockCurrencyStaticData) };
std::promise<Platform::String ^> mockedTask;
mockedTask.set_value(ref new Platform::String(MockCurrencyStaticData));
return mockedTask.get_future();
}
MockAwaitable<Platform::String ^> CurrencyHttpClient::GetCurrencyRatiosAsync() const
std::future<Platform::String ^> CurrencyHttpClient::GetCurrencyRatiosAsync() const
{
if (ForceWebFailure)
{
throw ref new Platform::Exception(E_FAIL, L"Mocked Network Failure: failed to load currency metadata");
}
(void)m_sourceCurrencyCode; // to be used in production.
return MockAwaitable<Platform::String ^>{ ref new Platform::String(MockCurrencyConverterData) };
std::promise<Platform::String ^> mockedTask;
mockedTask.set_value(ref new Platform::String(MockCurrencyConverterData));
return mockedTask.get_future();
}
} // namespace CalculatorApp::ViewModel::DataLoaders

View file

@ -135,6 +135,7 @@
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
@ -145,6 +146,7 @@
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<ControlFlowGuard>Guard</ControlFlowGuard>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
@ -154,6 +156,7 @@
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
@ -164,6 +167,7 @@
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<ControlFlowGuard>Guard</ControlFlowGuard>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -173,6 +177,7 @@
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -183,6 +188,7 @@
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<ControlFlowGuard>Guard</ControlFlowGuard>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -192,6 +198,7 @@
<AdditionalIncludeDirectories>$(SolutionDir);$(SolutionDir)CalcManager;$(SolutionDir)CalcViewModel;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -202,6 +209,7 @@
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<ControlFlowGuard>Guard</ControlFlowGuard>
<PreprocessorDefinitions>VIEWMODEL_FOR_UT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>

View file

@ -160,8 +160,8 @@ namespace CalculatorUnitTests
VERIFY_IS_TRUE(DeleteCurrencyCacheFiles());
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient{}.GetCurrencyMetadataAsync().Value));
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename, CurrencyHttpClient{}.GetCurrencyRatiosAsync().Value));
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient{}.GetCurrencyMetadataAsync().get()));
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename, CurrencyHttpClient{}.GetCurrencyRatiosAsync().get()));
}
TEST_CLASS(CurrencyConverterLoadTests){ public: TEST_METHOD_INITIALIZE(DeleteCacheFiles){ DeleteCurrencyCacheFiles();
@ -207,7 +207,7 @@ TEST_METHOD(LoadFromCache_Fail_StaticDataFileDoesNotExist)
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, now);
VERIFY_IS_TRUE(DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename));
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename, CurrencyHttpClient{}.GetCurrencyRatiosAsync().Value));
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename, CurrencyHttpClient{}.GetCurrencyRatiosAsync().get()));
CurrencyDataLoader loader{ L"en-US" };
@ -225,7 +225,7 @@ TEST_METHOD(LoadFromCache_Fail_AllRatiosDataFileDoesNotExist)
DateTime now = Utils::GetUniversalSystemTime();
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheTimestampKey, now);
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient{}.GetCurrencyMetadataAsync().Value));
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient{}.GetCurrencyMetadataAsync().get()));
VERIFY_IS_TRUE(DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename));
CurrencyDataLoader loader{ L"en-US" };
@ -245,7 +245,7 @@ TEST_METHOD(LoadFromCache_Fail_ResponseLanguageChanged)
// Tests always use en-US as response language. Insert a different lang-code to fail the test.
InsertToLocalSettings(CurrencyDataLoaderConstants::CacheLangcodeKey, L"ar-SA");
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient{}.GetCurrencyMetadataAsync().Value));
VERIFY_IS_TRUE(WriteToFileInLocalCacheFolder(CurrencyDataLoaderConstants::StaticDataFilename, CurrencyHttpClient{}.GetCurrencyMetadataAsync().get()));
VERIFY_IS_TRUE(DeleteFileFromLocalCacheFolder(CurrencyDataLoaderConstants::AllRatiosDataFilename));
CurrencyDataLoader loader{ L"en-US" };