Add embedded device library registry with full lifecycle management, automated test integration, and pin assignment workflow. Library system: - Library registry embedded in binary via include_dir! (same as templates) - library.toml metadata format: name, version, bus type, pins, provided files - anvil add <name> extracts headers to lib/drivers/<name>/, test files to test/ - anvil remove <name> cleans up all files, config entries, and include paths - anvil lib lists installed libraries with status - anvil lib --available shows registry with student-friendly wiring summary - [libraries] section in .anvil.toml tracks installed libraries and versions - CMake auto-discovers lib/drivers/*/ for include paths at configure time TMP36 analog temperature sensor (reference implementation): - TempSensor abstract interface (readCelsius/readFahrenheit/readRaw) - Tmp36Analog: real hardware impl via Hal::analogRead with configurable Vref - Tmp36Mock: programmable values, read counting, no hardware needed - Tmp36Sim: deterministic noise via seeded LCG for repeatable system tests - test_tmp36.cpp: 21 Google Test cases covering mock, analog, sim, polymorphism - TMP36 formula: voltage_mV = raw * Vref_mV / 1024, temp_C = (mV - 500) / 10 Automated test integration: - Library test files (test_*.cpp) route to test/ during extraction - CMakeLists.txt auto-discovers test_*.cpp via GLOB, builds each as own target - anvil remove cleans up test files alongside driver headers - Zero manual CMake editing: add library, run test --clean, tests appear Pin assignment integration: - anvil add <name> --pin A0 does extract + pin assignment in one step - Without --pin, prints step-by-step wiring guidance with copy-paste commands - anvil pin --audit flags installed libraries with unassigned pins - Audit works even with zero existing pin assignments (fixed early-return bug) - LibraryMeta helpers: wiring_summary(), pin_roles(), default_mode() - Bus-aware guidance: analog pins, I2C bus registration, SPI with CS selection UX improvements: - anvil lib --available shows "Needs: 1 analog pin (e.g. A0)" not raw metadata - anvil add prints app code example, test code example, and next step - anvil pin --audit prints exact commands to resolve missing library pins - anvil remove shows test file deletion in output Files added: - libraries/tmp36/library.toml - libraries/tmp36/src/tmp36.h, tmp36_analog.h, tmp36_mock.h, tmp36_sim.h - libraries/tmp36/src/test_tmp36.cpp - src/library/mod.rs Files modified: - src/lib.rs, src/main.rs, src/commands/mod.rs - src/commands/lib.rs (add/remove/list/list_available with --pin support) - src/commands/pin.rs (audit library pin warnings, print_library_pin_warnings) - src/project/config.rs (libraries HashMap field) - templates/basic/test/CMakeLists.txt.tmpl (driver + test auto-discovery) Tests: 254 total (89 unit + 165 integration) - 12 library/mod.rs unit tests (registry, extraction, helpers) - 2 commands/lib.rs unit tests (class name derivation) - 30+ new integration tests covering library lifecycle, pin integration, audit flows, file routing, CMake discovery, config roundtrips, ASCII compliance, polymorphism contracts, and idempotent add/remove cycles
101 lines
3.3 KiB
Cheetah
101 lines
3.3 KiB
Cheetah
cmake_minimum_required(VERSION 3.14)
|
|
project({{PROJECT_NAME}}_tests LANGUAGES CXX)
|
|
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Google Test (fetched automatically on first build)
|
|
# --------------------------------------------------------------------------
|
|
include(FetchContent)
|
|
FetchContent_Declare(
|
|
googletest
|
|
GIT_REPOSITORY https://github.com/google/googletest.git
|
|
GIT_TAG v1.14.0
|
|
)
|
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
|
FetchContent_MakeAvailable(googletest)
|
|
|
|
enable_testing()
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Include paths -- same headers the Arduino sketch uses
|
|
# --------------------------------------------------------------------------
|
|
set(LIB_DIR ${CMAKE_SOURCE_DIR}/../lib)
|
|
|
|
include_directories(
|
|
${LIB_DIR}/hal
|
|
${LIB_DIR}/app
|
|
${CMAKE_SOURCE_DIR}/mocks
|
|
)
|
|
|
|
# Auto-discover driver libraries (added by: anvil add <driver>)
|
|
if(IS_DIRECTORY ${LIB_DIR}/drivers)
|
|
file(GLOB DRIVER_DIRS ${LIB_DIR}/drivers/*)
|
|
foreach(DRIVER_DIR ${DRIVER_DIRS})
|
|
if(IS_DIRECTORY ${DRIVER_DIR})
|
|
include_directories(${DRIVER_DIR})
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Mock Arduino library -- provides Arduino API on x86_64
|
|
# --------------------------------------------------------------------------
|
|
add_library(mock_arduino STATIC
|
|
mocks/mock_arduino.cpp
|
|
)
|
|
target_include_directories(mock_arduino PUBLIC
|
|
${CMAKE_SOURCE_DIR}/mocks
|
|
${LIB_DIR}/hal
|
|
${LIB_DIR}/app
|
|
)
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Unit tests (Google Mock -- verifies exact HAL call sequences)
|
|
# --------------------------------------------------------------------------
|
|
add_executable(test_unit
|
|
test_unit.cpp
|
|
)
|
|
target_link_libraries(test_unit
|
|
GTest::gtest_main
|
|
GTest::gmock
|
|
mock_arduino
|
|
)
|
|
|
|
# --------------------------------------------------------------------------
|
|
# System tests (SimHal -- exercises full application logic)
|
|
# --------------------------------------------------------------------------
|
|
add_executable(test_system
|
|
test_system.cpp
|
|
)
|
|
target_link_libraries(test_system
|
|
GTest::gtest_main
|
|
mock_arduino
|
|
)
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Register with CTest
|
|
# --------------------------------------------------------------------------
|
|
include(GoogleTest)
|
|
gtest_discover_tests(test_unit)
|
|
gtest_discover_tests(test_system)
|
|
|
|
# --------------------------------------------------------------------------
|
|
# Driver tests (added automatically by: anvil add <driver>)
|
|
# --------------------------------------------------------------------------
|
|
file(GLOB DRIVER_TEST_SOURCES ${CMAKE_SOURCE_DIR}/test_*.cpp)
|
|
# Exclude test_unit.cpp and test_system.cpp (already handled above)
|
|
list(FILTER DRIVER_TEST_SOURCES EXCLUDE REGEX "test_unit\\.cpp$")
|
|
list(FILTER DRIVER_TEST_SOURCES EXCLUDE REGEX "test_system\\.cpp$")
|
|
|
|
foreach(TEST_SOURCE ${DRIVER_TEST_SOURCES})
|
|
get_filename_component(TEST_NAME ${TEST_SOURCE} NAME_WE)
|
|
add_executable(${TEST_NAME} ${TEST_SOURCE})
|
|
target_link_libraries(${TEST_NAME}
|
|
GTest::gtest_main
|
|
mock_arduino
|
|
)
|
|
gtest_discover_tests(${TEST_NAME})
|
|
endforeach()
|