Add mock Arduino for x86_64 host-side testing
Complete Arduino API mock (mock_arduino.h/cpp) enabling application code to compile and run on PC without hardware. Includes MockSerial, String class, GPIO/analog/timing/interrupt mocks with state tracking and test control API. - Arduino.h, Wire.h, SPI.h shims intercept includes in test builds - System test template (test_system.cpp) using SimHal - CMakeLists.txt builds mock_arduino as static lib, links both suites - Root test.sh/test.bat with --unit/--system/--clean/--verbose flags - test.bat auto-detects MSVC via vswhere + vcvarsall.bat - Doctor reports nuanced compiler status (on PATH vs installed) - Refresh pulls mock infrastructure into existing projects - 15 tests passing: 7 unit (MockHal) + 8 system (SimHal)
This commit is contained in:
@@ -13,6 +13,7 @@ pub struct SystemHealth {
|
||||
pub dialout_ok: bool,
|
||||
pub cmake_ok: bool,
|
||||
pub cpp_compiler_ok: bool,
|
||||
pub cpp_on_path: bool,
|
||||
pub git_ok: bool,
|
||||
pub ports_found: usize,
|
||||
}
|
||||
@@ -99,7 +100,14 @@ pub fn check_system_health() -> SystemHealth {
|
||||
let cmake_ok = which::which("cmake").is_ok();
|
||||
|
||||
// C++ compiler (optional -- for host tests)
|
||||
let cpp_compiler_ok = has_cpp_compiler();
|
||||
let cpp_on_path = which::which("g++").is_ok()
|
||||
|| which::which("clang++").is_ok()
|
||||
|| which::which("cl").is_ok();
|
||||
let cpp_compiler_ok = if cpp_on_path {
|
||||
true
|
||||
} else {
|
||||
has_cpp_compiler()
|
||||
};
|
||||
|
||||
// git
|
||||
let git_ok = which::which("git").is_ok();
|
||||
@@ -115,6 +123,7 @@ pub fn check_system_health() -> SystemHealth {
|
||||
dialout_ok,
|
||||
cmake_ok,
|
||||
cpp_compiler_ok,
|
||||
cpp_on_path,
|
||||
git_ok,
|
||||
ports_found,
|
||||
}
|
||||
@@ -130,6 +139,20 @@ fn has_cpp_compiler() -> bool {
|
||||
if which::which("cl").is_ok() {
|
||||
return true;
|
||||
}
|
||||
// cl.exe may be installed via VS Build Tools but not on PATH.
|
||||
// Check via vswhere.exe (ships with VS installer).
|
||||
if let Ok(output) = std::process::Command::new(
|
||||
r"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe",
|
||||
)
|
||||
.args(["-latest", "-property", "installationPath"])
|
||||
.output()
|
||||
{
|
||||
let path = String::from_utf8_lossy(&output.stdout);
|
||||
let vcvarsall = format!("{}\\VC\\Auxiliary\\Build\\vcvarsall.bat", path.trim());
|
||||
if std::path::Path::new(&vcvarsall).exists() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
@@ -217,8 +240,14 @@ fn print_diagnostics(health: &SystemHealth) {
|
||||
}
|
||||
|
||||
// C++ compiler
|
||||
if health.cpp_compiler_ok {
|
||||
if health.cpp_on_path {
|
||||
println!(" {} C++ compiler", "ok".green());
|
||||
} else if health.cpp_compiler_ok {
|
||||
println!(
|
||||
" {} C++ compiler {}",
|
||||
"ok".green(),
|
||||
"(MSVC installed; test.bat will configure automatically)".bright_black()
|
||||
);
|
||||
} else {
|
||||
println!(
|
||||
" {} C++ compiler {}",
|
||||
@@ -655,16 +684,16 @@ fn fix_spec_cmake(pm: Option<&str>) -> FixSpec {
|
||||
|
||||
fn fix_spec_cpp(pm: Option<&str>) -> FixSpec {
|
||||
match pm {
|
||||
Some("winget") => FixSpec::Auto {
|
||||
prompt: "Install Visual Studio Build Tools via winget?",
|
||||
program: "winget",
|
||||
args: &["install", "--id", "Microsoft.VisualStudio.2022.BuildTools", "-e"],
|
||||
},
|
||||
Some("choco") => FixSpec::Auto {
|
||||
prompt: "Install MinGW g++ via Chocolatey?",
|
||||
prompt: "Install MinGW g++ via Chocolatey? (recommended -- lands on PATH)",
|
||||
program: "choco",
|
||||
args: &["install", "mingw", "-y"],
|
||||
},
|
||||
Some("winget") => FixSpec::Auto {
|
||||
prompt: "Install Visual Studio Build Tools via winget? (test.bat will find it automatically)",
|
||||
program: "winget",
|
||||
args: &["install", "--id", "Microsoft.VisualStudio.2022.BuildTools", "-e"],
|
||||
},
|
||||
Some("brew") => FixSpec::Manual {
|
||||
message: "run: xcode-select --install",
|
||||
},
|
||||
@@ -751,7 +780,7 @@ fn hint_cmake() -> &'static str {
|
||||
|
||||
fn hint_cpp_compiler() -> &'static str {
|
||||
if cfg!(target_os = "windows") {
|
||||
"install: winget install Microsoft.VisualStudio.2022.BuildTools (or MinGW g++)"
|
||||
"install: choco install mingw (or open Developer Command Prompt for MSVC)"
|
||||
} else if cfg!(target_os = "macos") {
|
||||
"install: xcode-select --install"
|
||||
} else {
|
||||
|
||||
@@ -16,10 +16,20 @@ const REFRESHABLE_FILES: &[&str] = &[
|
||||
"upload.bat",
|
||||
"monitor.sh",
|
||||
"monitor.bat",
|
||||
"test.sh",
|
||||
"test.bat",
|
||||
"_detect_port.ps1",
|
||||
"_monitor_filter.ps1",
|
||||
"test/run_tests.sh",
|
||||
"test/run_tests.bat",
|
||||
"test/CMakeLists.txt",
|
||||
"test/mocks/mock_arduino.h",
|
||||
"test/mocks/mock_arduino.cpp",
|
||||
"test/mocks/Arduino.h",
|
||||
"test/mocks/Wire.h",
|
||||
"test/mocks/SPI.h",
|
||||
"test/mocks/mock_hal.h",
|
||||
"test/mocks/sim_hal.h",
|
||||
];
|
||||
|
||||
pub fn run_refresh(project_dir: Option<&str>, force: bool) -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user