#include "pch.h" #include "CppUnitTest.h" #include // добавьте путь к своему заголовочному файлу using namespace Microsoft::VisualStudio::CppUnitTestFramework; namespace UnitTest1 { TEST_CLASS(UnitTest1) { public: // ===================================================================== // 1. Тесты для get_bit // ===================================================================== TEST_METHOD(Test_get_bit) { // Кейс 1: Чтение установленного младшего бита (position = 0) Assert::IsTrue(get_bit(0x00000001, 0)); // Кейс 2: Чтение сброшенного младшего бита (position = 0) Assert::IsFalse(get_bit(0x00000000, 0)); // Кейс 3: Чтение установленного старшего бита (position = 31) Assert::IsTrue(get_bit(0x80000000, 31)); // Кейс 4: Чтение бита в середине (position = 15, значение 0x00008000) Assert::IsTrue(get_bit(0x00008000, 15)); // Кейс 5: Чтение бита из числа, где все биты сброшены Assert::IsFalse(get_bit(0x00000000, 20)); } // ===================================================================== // 2. Тесты для set_bit // ===================================================================== TEST_METHOD(Test_set_bit) { // Кейс 1: Установка младшего бита (position = 0) в нуле Assert::AreEqual(0x00000001, set_bit(0x00000000, 0)); // Кейс 2: Установка старшего бита (position = 31) в нуле Assert::AreEqual(0x80000000, set_bit(0x00000000, 31)); // Кейс 3: Идемпотентность: установка бита, который уже равен 1 Assert::AreEqual(0x00000001, set_bit(0x00000001, 0)); // Кейс 4: Установка бита в середине (position = 16) Assert::AreEqual(0x00010000, set_bit(0x00000000, 16)); // Кейс 5: Установка бита в числе, где уже все биты равны 1 Assert::AreEqual(0xFFFFFFFF, set_bit(0xFFFFFFFF, 10)); } // ===================================================================== // 3. Тесты для clear_bit // ===================================================================== TEST_METHOD(Test_clear_bit) { // Кейс 1: Сброс младшего бита (position = 0) Assert::AreEqual(0x00000000, clear_bit(0x00000001, 0)); // Кейс 2: Сброс старшего бита (position = 31) Assert::AreEqual(0x00000000, clear_bit(0x80000000, 31)); // Кейс 3: Идемпотентность: сброс бита, который уже равен 0 Assert::AreEqual(0x00000000, clear_bit(0x00000000, 0)); // Кейс 4: Сброс бита в середине (position = 8, значение 0x00000100) Assert::AreEqual(0x00000000, clear_bit(0x00000100, 8)); // Кейс 5: Сброс конкретного бита в числе, где все биты равны 1 (position = 15) // 0xFFFFFFFF без 15-го бита = 0xFFFF7FFF Assert::AreEqual(0xFFFF7FFF, clear_bit(0xFFFFFFFF, 15)); } // ===================================================================== // 4. Тесты для toggle_bit // ===================================================================== TEST_METHOD(Test_toggle_bit) { // Кейс 1: Переключение 0 в 1 на младшей позиции (position = 0) Assert::AreEqual(0x00000001, toggle_bit(0x00000000, 0)); // Кейс 2: Переключение 1 в 0 на младшей позиции (position = 0) Assert::AreEqual(0x00000000, toggle_bit(0x00000001, 0)); // Кейс 3: Переключение старшего бита (position = 31) Assert::AreEqual(0x80000000, toggle_bit(0x00000000, 31)); // Кейс 4: Переключение бита в середине (position = 15) Assert::AreEqual(0x00008000, toggle_bit(0x00000000, 15)); // Кейс 5: Переключение бита в числе, где все биты уже равны 1 (position = 0) Assert::AreEqual(0xFFFFFFFE, toggle_bit(0xFFFFFFFF, 0)); } TEST_METHOD(Test_pack_rgba) { // ----------------------------------------------------------------- // Граничные значения: все нули и все максимумы // ----------------------------------------------------------------- // Кейс 1: Все компоненты равны 0 > 0x00000000 Assert::AreEqual(0x00000000, pack_rgba(0, 0, 0, 0)); // Кейс 2: Все компоненты равны 255 > 0xFFFFFFFF // Этот случай ломает исходную функцию из-за UB! Assert::AreEqual(0xFFFFFFFF, pack_rgba(255, 255, 255, 255)); // ----------------------------------------------------------------- // Отдельные компоненты: проверка правильности позиций битов // ----------------------------------------------------------------- // Кейс 3: Только красный (255, 0, 0, 0) > 0xFF000000 Assert::AreEqual(0xFF000000, pack_rgba(255, 0, 0, 0)); // Кейс 4: Только зеленый (0, 255, 0, 0) > 0x00FF0000 Assert::AreEqual(0x00FF0000, pack_rgba(0, 255, 0, 0)); // Кейс 5: Только синий (0, 0, 255, 0) > 0x0000FF00 Assert::AreEqual(0x0000FF00, pack_rgba(0, 0, 255, 0)); // Кейс 6: Только альфа (0, 0, 0, 255) > 0x000000FF Assert::AreEqual(0x000000FF, pack_rgba(0, 0, 0, 255)); // ----------------------------------------------------------------- // Классические цвета // ----------------------------------------------------------------- // Кейс 7: Белый (255, 255, 255, 255) > 0xFFFFFFFF Assert::AreEqual(0xFFFFFFFF, pack_rgba(255, 255, 255, 255)); // Кейс 8: Черный с полной непрозрачностью (0, 0, 0, 255) > 0x000000FF Assert::AreEqual(0x000000FF, pack_rgba(0, 0, 0, 255)); // Кейс 9: Полупрозрачный красный (255, 0, 0, 128) > 0xFF000080 Assert::AreEqual(0xFF000080, pack_rgba(255, 0, 0, 128)); // ----------------------------------------------------------------- // Произвольные значения и граничные случаи // ----------------------------------------------------------------- // Кейс 10: Произвольные значения (0x12, 0x34, 0x56, 0x78) > 0x12345678 Assert::AreEqual(0x12345678, pack_rgba(0x12, 0x34, 0x56, 0x78)); // Кейс 11: Минимальные ненулевые значения (1, 1, 1, 1) > 0x01010101 Assert::AreEqual(0x01010101, pack_rgba(1, 1, 1, 1)); // Кейс 12: Значения 254 (0xFE) > 0xFEFEFEFE Assert::AreEqual(0xFEFEFEFE, pack_rgba(254, 254, 254, 254)); } TEST_METHOD(Test_unpack_rgba) { std::uint8_t r, g, b, a; // ================================================================= // Кейс 1: Все нули (базовая проверка) // ================================================================= unpack_rgba(0x00000000, r, g, b, a); Assert::AreEqual(static_cast(0), static_cast(r), L"Red должен быть 0"); Assert::AreEqual(static_cast(0), static_cast(g), L"Green должен быть 0"); Assert::AreEqual(static_cast(0), static_cast(b), L"Blue должен быть 0"); Assert::AreEqual(static_cast(0), static_cast(a), L"Alpha должен быть 0"); // ================================================================= // Кейс 2: Все максимумы (проверка маски 0xFF) // ================================================================= unpack_rgba(0xFFFFFFFF, r, g, b, a); Assert::AreEqual(static_cast(255), static_cast(r)); Assert::AreEqual(static_cast(255), static_cast(g)); Assert::AreEqual(static_cast(255), static_cast(b)); Assert::AreEqual(static_cast(255), static_cast(a)); // ================================================================= // Кейс 3: Уникальные значения для каждого канала (Самый важный тест) // ================================================================= // 0x12345678 -> Red=0x12, Green=0x34, Blue=0x56, Alpha=0x78 // Этот тест гарантированно ловит ошибки, если биты "перетекают" в соседние каналы unpack_rgba(0x12345678, r, g, b, a); Assert::AreEqual(static_cast(0x12), static_cast(r)); Assert::AreEqual(static_cast(0x34), static_cast(g)); Assert::AreEqual(static_cast(0x56), static_cast(b)); Assert::AreEqual(static_cast(0x78), static_cast(a)); // ================================================================= // Кейс 4: Только красный канал установлен (проверка старших битов) // ================================================================= unpack_rgba(0xFF000000, r, g, b, a); Assert::AreEqual(static_cast(255), static_cast(r)); Assert::AreEqual(static_cast(0), static_cast(g)); Assert::AreEqual(static_cast(0), static_cast(b)); Assert::AreEqual(static_cast(0), static_cast(a)); // ================================================================= // Кейс 5: Только альфа-канал установлен (проверка младших битов) // ================================================================= unpack_rgba(0x000000FF, r, g, b, a); Assert::AreEqual(static_cast(0), static_cast(r)); Assert::AreEqual(static_cast(0), static_cast(g)); Assert::AreEqual(static_cast(0), static_cast(b)); Assert::AreEqual(static_cast(255), static_cast(a)); // ================================================================= // Кейс 6: Чередующиеся биты (проверка корректности маски) // ================================================================= // 0x55555555 = 01010101 в двоичном виде для каждого байта (значение 85) unpack_rgba(0x55555555, r, g, b, a); Assert::AreEqual(static_cast(85), static_cast(r)); Assert::AreEqual(static_cast(85), static_cast(g)); Assert::AreEqual(static_cast(85), static_cast(b)); Assert::AreEqual(static_cast(85), static_cast(a)); // ================================================================= // Кейс 7: Тест "Round-trip" (Обратная совместимость с pack_rgba) // ================================================================= // Упаковываем известные значения, затем распаковываем и сверяем std::uint8_t original_r = 100, original_g = 150, original_b = 200, original_a = 250; // Встроенная логика pack для теста (или вызов вашей функции pack_rgba) std::uint32_t packed = (static_cast(original_r) << 24) | (static_cast(original_g) << 16) | (static_cast(original_b) << 8) | static_cast(original_a); unpack_rgba(packed, r, g, b, a); Assert::AreEqual(static_cast(original_r), static_cast(r), L"Round-trip Red failed"); Assert::AreEqual(static_cast(original_g), static_cast(g), L"Round-trip Green failed"); Assert::AreEqual(static_cast(original_b), static_cast(b), L"Round-trip Blue failed"); Assert::AreEqual(static_cast(original_a), static_cast(a), L"Round-trip Alpha failed"); } // ===================================================================== // Кейс 1: Проверка близости к теоретическому значению при большом N // ===================================================================== TEST_METHOD(Test_large_experiments_accuracy) { // Теоретическая вероятность: 6/36 = 1/6 ? 0.16667 const double theoretical_probability = 1.0 / 6.0; const int experiments = 100000; std::mt19937 gen(42); // Фиксированный seed double result = estimate_large_sum(gen, experiments); // Для 100000 экспериментов стандартное отклонение ? 0.0012 // 99% доверительный интервал: ±0.003 Assert::IsTrue(std::abs(result - theoretical_probability) < 0.005, L"Результат должен быть близок к теоретической вероятности 1/6"); } // ===================================================================== // Кейс 2: Воспроизводимость (одинаковый seed > одинаковый результат) // ===================================================================== TEST_METHOD(Test_reproducibility) { const int experiments = 10000; std::mt19937 gen1(123); double result1 = estimate_large_sum(gen1, experiments); std::mt19937 gen2(123); // Тот же seed double result2 = estimate_large_sum(gen2, experiments); Assert::AreEqual(result1, result2, L"Одинаковый seed должен давать одинаковый результат"); } // ===================================================================== // Кейс 3: Результат всегда в диапазоне [0, 1] // ===================================================================== TEST_METHOD(Test_result_bounds) { std::mt19937 gen(999); for (int i = 0; i < 10; ++i) { double result = estimate_large_sum(gen, 1000); Assert::IsTrue(result >= 0.0 && result <= 1.0, L"Результат должен быть в диапазоне [0, 1]"); } } // ===================================================================== // Кейс 4: Граничный случай - один эксперимент // ===================================================================== TEST_METHOD(Test_single_experiment) { std::mt19937 gen(777); // Результат должен быть либо 0.0, либо 1.0 double result = estimate_large_sum(gen, 1); Assert::IsTrue(result == 0.0 || result == 1.0, L"При одном эксперименте результат должен быть 0.0 или 1.0"); } // ===================================================================== // Кейс 5: Граничный случай - ноль экспериментов (защита от деления на 0) // ===================================================================== TEST_METHOD(Test_zero_experiments) { std::mt19937 gen(555); double result = estimate_large_sum(gen, 0); Assert::AreEqual(0.0, result, L"При 0 экспериментов функция должна вернуть 0.0"); } // ===================================================================== // Кейс 6: Отрицательное количество экспериментов // ===================================================================== TEST_METHOD(Test_negative_experiments) { std::mt19937 gen(333); double result = estimate_large_sum(gen, -100); Assert::AreEqual(0.0, result, L"При отрицательном количестве функция должна вернуть 0.0"); } // ===================================================================== // Кейс 7: Разные seed дают разные результаты (статистический тест) // ===================================================================== TEST_METHOD(Test_different_seeds) { const int experiments = 5000; std::mt19937 gen1(111); double result1 = estimate_large_sum(gen1, experiments); std::mt19937 gen2(222); double result2 = estimate_large_sum(gen2, experiments); // Результаты должны быть разными (с очень высокой вероятностью) Assert::AreNotEqual(result1, result2, L"Разные seed должны давать разные результаты"); } // ===================================================================== // Кейс 8: Малое количество экспериментов - большая дисперсия // ===================================================================== TEST_METHOD(Test_small_experiments_variance) { std::mt19937 gen(888); // При 10 экспериментах результат может сильно отличаться от 1/6 double result = estimate_large_sum(gen, 10); // Но всё равно должен быть в [0, 1] Assert::IsTrue(result >= 0.0 && result <= 1.0); // И должен быть кратным 0.1 (так как 10 экспериментов) double remainder = std::fmod(result * 10.0, 1.0); Assert::IsTrue(remainder < 0.0001 || remainder > 0.9999, L"При 10 экспериментах результат должен быть кратным 0.1"); } }; }