/
githubmirror
/
PowerToys
Обзор
Документация
Войти
/
githubmirror
/
PowerToys
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/common/UnitTests-CommonUtils/Serialized.Tests.cpp
286 строк
8 KB
Kai Tao
UT: Add ut to protect common utils codes (#45290)
03 фев 2026, 10:12
Не верифицирован
03 фев 2026, 10:12
27ba536
Код
Авторство
О чём код?
#include "pch.h" #include "TestHelpers.h" #include <serialized.h> using namespace Microsoft::VisualStudio::CppUnitTestFramework; namespace UnitTestsCommonUtils { TEST_CLASS(SerializedTests) { public: // Basic Read tests TEST_METHOD(Read_DefaultState_ReturnsDefaultValue) { Serialized<int> s; int value = -1; s.Read([&value](const int& v) { value = v; }); Assert::AreEqual(0, value); // Default constructed int is 0 } TEST_METHOD(Read_StringType_ReturnsEmpty) { Serialized<std::string> s; std::string value = "initial"; s.Read([&value](const std::string& v) { value = v; }); Assert::AreEqual(std::string(""), value); } // Basic Access tests TEST_METHOD(Access_ModifyValue_ValueIsModified) { Serialized<int> s; s.Access([](int& v) { v = 42; }); int value = 0; s.Read([&value](const int& v) { value = v; }); Assert::AreEqual(42, value); } TEST_METHOD(Access_ModifyString_StringIsModified) { Serialized<std::string> s; s.Access([](std::string& v) { v = "hello"; }); std::string value; s.Read([&value](const std::string& v) { value = v; }); Assert::AreEqual(std::string("hello"), value); } TEST_METHOD(Access_MultipleModifications_LastValuePersists) { Serialized<int> s; s.Access([](int& v) { v = 1; }); s.Access([](int& v) { v = 2; }); s.Access([](int& v) { v = 3; }); int value = 0; s.Read([&value](const int& v) { value = v; }); Assert::AreEqual(3, value); } // Reset tests TEST_METHOD(Reset_AfterModification_ReturnsDefault) { Serialized<int> s; s.Access([](int& v) { v = 42; }); s.Reset(); int value = -1; s.Read([&value](const int& v) { value = v; }); Assert::AreEqual(0, value); } TEST_METHOD(Reset_String_ReturnsEmpty) { Serialized<std::string> s; s.Access([](std::string& v) { v = "hello"; }); s.Reset(); std::string value = "initial"; s.Read([&value](const std::string& v) { value = v; }); Assert::AreEqual(std::string(""), value); } // Complex type tests TEST_METHOD(Serialized_VectorType_Works) { Serialized<std::vector<int>> s; s.Access([](std::vector<int>& v) { v.push_back(1); v.push_back(2); v.push_back(3); }); size_t size = 0; int sum = 0; s.Read([&size, &sum](const std::vector<int>& v) { size = v.size(); for (int i : v) sum += i; }); Assert::AreEqual(static_cast<size_t>(3), size); Assert::AreEqual(6, sum); } TEST_METHOD(Serialized_MapType_Works) { Serialized<std::map<std::string, int>> s; s.Access([](std::map<std::string, int>& v) { v["one"] = 1; v["two"] = 2; }); int value = 0; s.Read([&value](const std::map<std::string, int>& v) { auto it = v.find("two"); if (it != v.end()) { value = it->second; } }); Assert::AreEqual(2, value); } // Thread safety tests TEST_METHOD(ThreadSafety_ConcurrentReads_NoDataRace) { Serialized<int> s; s.Access([](int& v) { v = 42; }); std::atomic<int> readCount{ 0 }; std::vector<std::thread> threads; for (int i = 0; i < 10; ++i) { threads.emplace_back([&s, &readCount]() { for (int j = 0; j < 100; ++j) { s.Read([&readCount](const int& v) { if (v == 42) { readCount++; } }); } }); } for (auto& t : threads) { t.join(); } Assert::AreEqual(1000, readCount.load()); } TEST_METHOD(ThreadSafety_ConcurrentAccessAndRead_NoDataRace) { Serialized<int> s; std::atomic<bool> done{ false }; std::atomic<int> accessCount{ 0 }; std::atomic<int> readersReady{ 0 }; std::atomic<bool> start{ false }; // Writer thread std::thread writer([&s, &done, &accessCount, &readersReady, &start]() { while (readersReady.load() < 5) { std::this_thread::yield(); } start = true; for (int i = 0; i < 100; ++i) { s.Access([i](int& v) { v = i; }); accessCount++; } done = true; }); // Reader threads std::vector<std::thread> readers; std::atomic<int> readAttempts{ 0 }; for (int i = 0; i < 5; ++i) { readers.emplace_back([&s, &done, &readAttempts, &readersReady, &start]() { readersReady++; while (!start) { std::this_thread::yield(); } while (!done) { s.Read([](const int& v) { // Just read the value (void)v; }); readAttempts++; } }); } writer.join(); for (auto& t : readers) { t.join(); } // Verify all access calls completed Assert::AreEqual(100, accessCount.load()); // Verify reads happened Assert::IsTrue(readAttempts > 0); } // Struct type test TEST_METHOD(Serialized_StructType_Works) { struct TestStruct { int x = 0; std::string name; }; Serialized<TestStruct> s; s.Access([](TestStruct& v) { v.x = 10; v.name = "test"; }); int x = 0; std::string name; s.Read([&x, &name](const TestStruct& v) { x = v.x; name = v.name; }); Assert::AreEqual(10, x); Assert::AreEqual(std::string("test"), name); } TEST_METHOD(Reset_StructType_ResetsToDefault) { struct TestStruct { int x = 0; std::string name; }; Serialized<TestStruct> s; s.Access([](TestStruct& v) { v.x = 10; v.name = "test"; }); s.Reset(); int x = -1; std::string name = "not empty"; s.Read([&x, &name](const TestStruct& v) { x = v.x; name = v.name; }); Assert::AreEqual(0, x); Assert::AreEqual(std::string(""), name); } }; }