Revamped tests into separate files
This commit is contained in:
205
tests/test_mock_arduino.rs
Normal file
205
tests/test_mock_arduino.rs
Normal file
@@ -0,0 +1,205 @@
|
||||
use anvil::templates::{TemplateManager, TemplateContext};
|
||||
use std::fs;
|
||||
use tempfile::TempDir;
|
||||
|
||||
// ==========================================================================
|
||||
// Mock Arduino: template file content verification
|
||||
// ==========================================================================
|
||||
|
||||
#[test]
|
||||
fn test_mock_arduino_header_has_core_api() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = TemplateContext {
|
||||
project_name: "mock_test".to_string(),
|
||||
anvil_version: "1.0.0".to_string(),
|
||||
board_name: "uno".to_string(),
|
||||
fqbn: "arduino:avr:uno".to_string(),
|
||||
baud: 115200,
|
||||
};
|
||||
TemplateManager::extract("basic", tmp.path(), &ctx).unwrap();
|
||||
|
||||
let header = fs::read_to_string(tmp.path().join("test/mocks/mock_arduino.h")).unwrap();
|
||||
|
||||
// Core Arduino constants
|
||||
assert!(header.contains("#define INPUT"), "Should define INPUT");
|
||||
assert!(header.contains("#define OUTPUT"), "Should define OUTPUT");
|
||||
assert!(header.contains("#define HIGH"), "Should define HIGH");
|
||||
assert!(header.contains("#define LOW"), "Should define LOW");
|
||||
assert!(header.contains("#define LED_BUILTIN"), "Should define LED_BUILTIN");
|
||||
assert!(header.contains("#define A0"), "Should define A0");
|
||||
|
||||
// Core Arduino functions (declarations use aligned whitespace)
|
||||
assert!(header.contains("pinMode("), "Should declare pinMode");
|
||||
assert!(header.contains("digitalWrite("), "Should declare digitalWrite");
|
||||
assert!(header.contains("digitalRead("), "Should declare digitalRead");
|
||||
assert!(header.contains("analogRead("), "Should declare analogRead");
|
||||
assert!(header.contains("analogWrite("), "Should declare analogWrite");
|
||||
assert!(header.contains("millis()"), "Should declare millis");
|
||||
assert!(header.contains("delay("), "Should declare delay");
|
||||
|
||||
// Serial class
|
||||
assert!(header.contains("class MockSerial"), "Should declare MockSerial");
|
||||
assert!(header.contains("extern MockSerial Serial"), "Should declare global Serial");
|
||||
|
||||
// Test control API
|
||||
assert!(header.contains("mock_arduino_reset()"), "Should have reset");
|
||||
assert!(header.contains("mock_arduino_advance_millis("), "Should have advance_millis");
|
||||
assert!(header.contains("mock_arduino_set_digital("), "Should have set_digital");
|
||||
assert!(header.contains("mock_arduino_set_analog("), "Should have set_analog");
|
||||
|
||||
// String class
|
||||
assert!(header.contains("class String"), "Should declare String class");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mock_arduino_shims_exist() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = TemplateContext {
|
||||
project_name: "shim_test".to_string(),
|
||||
anvil_version: "1.0.0".to_string(),
|
||||
board_name: "uno".to_string(),
|
||||
fqbn: "arduino:avr:uno".to_string(),
|
||||
baud: 115200,
|
||||
};
|
||||
TemplateManager::extract("basic", tmp.path(), &ctx).unwrap();
|
||||
|
||||
// Arduino.h shim should include mock_arduino.h
|
||||
let arduino_h = fs::read_to_string(tmp.path().join("test/mocks/Arduino.h")).unwrap();
|
||||
assert!(
|
||||
arduino_h.contains("mock_arduino.h"),
|
||||
"Arduino.h shim should redirect to mock_arduino.h"
|
||||
);
|
||||
|
||||
// Wire.h shim should provide MockWire
|
||||
let wire_h = fs::read_to_string(tmp.path().join("test/mocks/Wire.h")).unwrap();
|
||||
assert!(wire_h.contains("class MockWire"), "Wire.h should declare MockWire");
|
||||
assert!(wire_h.contains("extern MockWire Wire"), "Wire.h should declare global Wire");
|
||||
|
||||
// SPI.h shim should provide MockSPI
|
||||
let spi_h = fs::read_to_string(tmp.path().join("test/mocks/SPI.h")).unwrap();
|
||||
assert!(spi_h.contains("class MockSPI"), "SPI.h should declare MockSPI");
|
||||
assert!(spi_h.contains("extern MockSPI SPI"), "SPI.h should declare global SPI");
|
||||
assert!(spi_h.contains("SPI_MODE0"), "SPI.h should define SPI modes");
|
||||
assert!(spi_h.contains("struct SPISettings"), "SPI.h should define SPISettings");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mock_arduino_all_files_ascii() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = TemplateContext {
|
||||
project_name: "ascii_mock".to_string(),
|
||||
anvil_version: "1.0.0".to_string(),
|
||||
board_name: "uno".to_string(),
|
||||
fqbn: "arduino:avr:uno".to_string(),
|
||||
baud: 115200,
|
||||
};
|
||||
TemplateManager::extract("basic", tmp.path(), &ctx).unwrap();
|
||||
|
||||
let mock_files = vec![
|
||||
"test/mocks/mock_arduino.h",
|
||||
"test/mocks/mock_arduino.cpp",
|
||||
"test/mocks/Arduino.h",
|
||||
"test/mocks/Wire.h",
|
||||
"test/mocks/SPI.h",
|
||||
];
|
||||
|
||||
for filename in &mock_files {
|
||||
let content = fs::read_to_string(tmp.path().join(filename)).unwrap();
|
||||
for (line_num, line) in content.lines().enumerate() {
|
||||
for (col, ch) in line.chars().enumerate() {
|
||||
assert!(
|
||||
ch.is_ascii(),
|
||||
"Non-ASCII in {} at {}:{}: '{}' (U+{:04X})",
|
||||
filename, line_num + 1, col + 1, ch, ch as u32
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cmake_links_mock_arduino() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = TemplateContext {
|
||||
project_name: "cmake_test".to_string(),
|
||||
anvil_version: "1.0.0".to_string(),
|
||||
board_name: "uno".to_string(),
|
||||
fqbn: "arduino:avr:uno".to_string(),
|
||||
baud: 115200,
|
||||
};
|
||||
TemplateManager::extract("basic", tmp.path(), &ctx).unwrap();
|
||||
|
||||
let cmake = fs::read_to_string(tmp.path().join("test/CMakeLists.txt")).unwrap();
|
||||
|
||||
// Should define mock_arduino library
|
||||
assert!(cmake.contains("add_library(mock_arduino"), "Should define mock_arduino library");
|
||||
assert!(cmake.contains("mock_arduino.cpp"), "Should compile mock_arduino.cpp");
|
||||
|
||||
// Both test targets should link mock_arduino
|
||||
assert!(cmake.contains("target_link_libraries(test_unit"), "Should have test_unit target");
|
||||
assert!(cmake.contains("target_link_libraries(test_system"), "Should have test_system target");
|
||||
|
||||
// System test target
|
||||
assert!(cmake.contains("add_executable(test_system"), "Should build test_system");
|
||||
assert!(cmake.contains("test_system.cpp"), "Should compile test_system.cpp");
|
||||
|
||||
// gtest discovery for both
|
||||
assert!(cmake.contains("gtest_discover_tests(test_unit)"), "Should discover unit tests");
|
||||
assert!(cmake.contains("gtest_discover_tests(test_system)"), "Should discover system tests");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_system_test_template_uses_simhal() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = TemplateContext {
|
||||
project_name: "sys_test".to_string(),
|
||||
anvil_version: "1.0.0".to_string(),
|
||||
board_name: "uno".to_string(),
|
||||
fqbn: "arduino:avr:uno".to_string(),
|
||||
baud: 115200,
|
||||
};
|
||||
TemplateManager::extract("basic", tmp.path(), &ctx).unwrap();
|
||||
|
||||
let system_test = fs::read_to_string(tmp.path().join("test/test_system.cpp")).unwrap();
|
||||
|
||||
// Should include mock_arduino and sim_hal
|
||||
assert!(system_test.contains("mock_arduino.h"), "Should include mock_arduino.h");
|
||||
assert!(system_test.contains("sim_hal.h"), "Should include sim_hal.h");
|
||||
assert!(system_test.contains("sys_test_app.h"), "Should reference project app header");
|
||||
|
||||
// Should use SimHal, not MockHal
|
||||
assert!(system_test.contains("SimHal"), "Should use SimHal for system tests");
|
||||
|
||||
// Should call mock_arduino_reset
|
||||
assert!(system_test.contains("mock_arduino_reset()"), "Should reset mock state in SetUp");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_root_test_scripts_exist_and_reference_test_dir() {
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let ctx = TemplateContext {
|
||||
project_name: "script_test".to_string(),
|
||||
anvil_version: "1.0.0".to_string(),
|
||||
board_name: "uno".to_string(),
|
||||
fqbn: "arduino:avr:uno".to_string(),
|
||||
baud: 115200,
|
||||
};
|
||||
TemplateManager::extract("basic", tmp.path(), &ctx).unwrap();
|
||||
|
||||
// test.sh
|
||||
let test_sh = fs::read_to_string(tmp.path().join("test.sh")).unwrap();
|
||||
assert!(test_sh.contains("TEST_DIR="), "test.sh should set TEST_DIR");
|
||||
assert!(test_sh.contains("cmake"), "test.sh should invoke cmake");
|
||||
assert!(test_sh.contains("ctest"), "test.sh should invoke ctest");
|
||||
assert!(test_sh.contains("--unit"), "test.sh should support --unit flag");
|
||||
assert!(test_sh.contains("--system"), "test.sh should support --system flag");
|
||||
assert!(test_sh.contains("--clean"), "test.sh should support --clean flag");
|
||||
|
||||
// test.bat
|
||||
let test_bat = fs::read_to_string(tmp.path().join("test.bat")).unwrap();
|
||||
assert!(test_bat.contains("TEST_DIR"), "test.bat should set TEST_DIR");
|
||||
assert!(test_bat.contains("cmake"), "test.bat should invoke cmake");
|
||||
assert!(test_bat.contains("ctest"), "test.bat should invoke ctest");
|
||||
assert!(test_bat.contains("--unit"), "test.bat should support --unit flag");
|
||||
assert!(test_bat.contains("--system"), "test.bat should support --system flag");
|
||||
}
|
||||
Reference in New Issue
Block a user