Files
fgl-aircon/tests/CMakeLists.txt
T
petr.polezhaev fa1718f405 core(M3): aircon-слой — шаблоны A/B/F, конверсии+override, публичный API + C-API
- include/fgl-aircon: types.hpp (Prop/State/Error/Value/Template/
  Conversion-linear-custom/PropOverride/Config с задокументированными
  lifetime-контрактами), templates.hpp (PropInfo-таблицы, интроспекция,
  конверсии c контрактом Linear num/den!=0), session.hpp (Session:
  set_int/bool/string, get_prop, batch, cached, set_log_sink с контрактом),
  c_api.h (extern "C" для cffi/pyfglair).
- src/aircon: tables.cpp (шаблоны A=33/B=20/F=34 по PROTOCOL §8.2,
  template_detect + template_is_known; конверсии: default тождественно,
  DisplayTemperature raw 0.01°C(+5000)→API 0.1°C; linear с инверсией
  raw=(api-offset)*den/num и насыщением __builtin_*_overflow; custom fn;
  af_*_swing base_type integer, kind bool), session.cpp (маппинг имя↔Prop,
  коэрсинг int-push к kBool по таблице, кэш со спинлоком, оптимистичный кэш,
  валидация overrides: терминатор/linear/custom_fn), c_api.cpp (шейм,
  static_assert'ы на все enum-значения, fgl_template_detect -1 для
  неизвестных).
- ayla: set_property_string (Command.str_value, coalescing копирует строку
  в т.ч. в batch-ветке); kMaxQueue 48 + static_assert (полный батч A=33);
  commit_batch всегда ставит notify; oversized-строка дропает событие
  (кэш не затирается); max_queue default 40.
- tests/aircon: test_tables (составы/атрибуты/дубли/template_detect/
  swings-integer), test_convert (default/linear/custom/диапазоны/насыщение
  в обе стороны/UB-экстремумы), aircon_runner + test_aircon_mock
  (маппинг+конверсии+batch=1-notify с ожиданием async REG; SET+кэш+
  RO/не-шаблон отказы+клэмпинг raw 450 на модуле; C-API smoke).
- Прибор AP-WC1E: полный батч шаблона A одним notify — 28 int/bool свойств
  (DisplayTemperature 7000→200=20.0°C, DeviceCapabilities=5119), boolean SET
  (JSON true) принят, RO/клэмп/NOTMPL отказы корректны.
- CI: 10/10 ×3 стабильно (3 полных прогона); ESP-IDF esp32 build complete.
Ревью независимым агентом: 3 круга — B1 kMaxQueue<батча, B2 linear div/0,
B3 c_api контракт -1, B4 batch-строки, BL1 INT64_MIN negation UB,
BL2 DisplayTemperature экстремумы, flake aircon_mock — всё закрыто;
APPROVED (условие круга 3: фикс + зелёный CI ×3).
2026-09-28 20:16:54 +03:00

58 lines
2.8 KiB
CMake

# Тесты ядра. Структура зеркалит src: tests/ayla — протоколная часть,
# tests/aircon — конверсии/шаблоны (появятся в M3).
#
# Тесты собираются с исключениями (фреймворк), сама библиотека — без.
include(FetchContent)
FetchContent_Declare(
doctest
GIT_REPOSITORY https://github.com/doctest/doctest.git
GIT_TAG v2.4.12
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(doctest)
function(fgl_add_test name)
add_executable(test_${name} ${ARGN})
target_compile_features(test_${name} PRIVATE cxx_std_20)
target_link_libraries(test_${name} PRIVATE fgl-aircon doctest_with_main)
target_include_directories(test_${name} PRIVATE "${CMAKE_SOURCE_DIR}/src")
add_test(NAME ${name} COMMAND test_${name})
endfunction()
# Раннер сессии — не тест, приложение для интеграционных сценариев
# (запускается tests/ayla/test_session_mock.py через ctest).
add_executable(session_runner ayla/session_runner.cpp)
target_compile_features(session_runner PRIVATE cxx_std_20)
target_link_libraries(session_runner PRIVATE fgl-aircon)
target_include_directories(session_runner PRIVATE "${CMAKE_SOURCE_DIR}/src")
fgl_add_test(ayla_platform ayla/test_platform.cpp)
fgl_add_test(ayla_httpd ayla/test_httpd.cpp)
fgl_add_test(ayla_crypto ayla/test_crypto.cpp)
fgl_add_test(ayla_envelope ayla/test_envelope.cpp)
fgl_add_test(ayla_json ayla/test_json.cpp)
fgl_add_test(ayla_httpc ayla/test_httpc.cpp)
# aircon-слой: юнит-тесты таблиц/конверсий + C-API smoke.
fgl_add_test(aircon_tables aircon/test_tables.cpp)
fgl_add_test(aircon_convert aircon/test_convert.cpp)
target_link_libraries(test_aircon_tables PRIVATE fgl-aircon)
target_link_libraries(test_aircon_convert PRIVATE fgl-aircon)
add_executable(aircon_runner aircon/aircon_runner.cpp)
target_compile_features(aircon_runner PRIVATE cxx_std_20)
target_link_libraries(aircon_runner PRIVATE fgl-aircon)
target_include_directories(aircon_runner PRIVATE "${CMAKE_SOURCE_DIR}/src")
# Интеграционные сценарии с mock-модулем (python, stdlib-only).
find_package(Python3 COMPONENTS Interpreter REQUIRED)
add_test(NAME ayla_session_mock
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/ayla/test_session_mock.py
$<TARGET_FILE:session_runner> ${CMAKE_CURRENT_SOURCE_DIR}/ayla/mock_ac.py)
set_tests_properties(ayla_session_mock PROPERTIES TIMEOUT 180)
add_test(NAME aircon_session_mock
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/aircon/test_aircon_mock.py
$<TARGET_FILE:aircon_runner> ${CMAKE_CURRENT_SOURCE_DIR}/ayla/mock_ac.py)
set_tests_properties(aircon_session_mock PROPERTIES TIMEOUT 180)