#![cfg(all(target_os = "macos", feature = "macos"))]
use peat_btle::config::BleConfig;
use peat_btle::platform::BleAdapter;
use peat_btle::NodeId;
#[test]
fn test_adapter_creation() {
use peat_btle::platform::apple::CoreBluetoothAdapter;
let result = CoreBluetoothAdapter::new();
match result {
Ok(_adapter) => {
println!("CoreBluetoothAdapter created successfully");
}
Err(e) => {
println!(
"CoreBluetoothAdapter creation failed (expected on CI): {}",
e
);
}
}
}
#[tokio::test]
async fn test_adapter_init_no_segfault() {
use peat_btle::platform::apple::CoreBluetoothAdapter;
let result = CoreBluetoothAdapter::new();
let Ok(mut adapter) = result else {
println!("Skipping test: Bluetooth unavailable");
return;
};
let node_id = NodeId::new(0xDEADBEEF);
let config = BleConfig::new(node_id);
let init_result = adapter.init(&config).await;
match init_result {
Ok(()) => println!("Adapter initialized successfully"),
Err(e) => println!("Adapter init failed (may be expected): {}", e),
}
println!("No segfault during initialization - PASS");
}
#[tokio::test]
async fn test_adapter_start_no_segfault() {
use peat_btle::platform::apple::CoreBluetoothAdapter;
let result = CoreBluetoothAdapter::new();
let Ok(mut adapter) = result else {
println!("Skipping test: Bluetooth unavailable");
return;
};
let node_id = NodeId::new(0xCAFEBABE);
let config = BleConfig::new(node_id);
if let Err(e) = adapter.init(&config).await {
println!("Skipping test: init failed: {}", e);
return;
}
let start_result = adapter.start().await;
match start_result {
Ok(()) => {
println!("Adapter started successfully");
let _ = adapter.stop().await;
}
Err(e) => {
println!("Adapter start failed (may be expected): {}", e);
}
}
println!("No segfault during start - PASS");
}
#[tokio::test]
async fn test_repeated_start_stop_no_crash() {
use peat_btle::platform::apple::CoreBluetoothAdapter;
let result = CoreBluetoothAdapter::new();
let Ok(mut adapter) = result else {
println!("Skipping test: Bluetooth unavailable");
return;
};
let node_id = NodeId::new(0x12345678);
let config = BleConfig::new(node_id);
if let Err(e) = adapter.init(&config).await {
println!("Skipping test: init failed: {}", e);
return;
}
for i in 0..3 {
println!("Cycle {} - starting...", i + 1);
match adapter.start().await {
Ok(()) => {
println!("Cycle {} - started, now stopping...", i + 1);
let _ = adapter.stop().await;
println!("Cycle {} - stopped", i + 1);
}
Err(e) => {
println!("Cycle {} - start failed (expected): {}", i + 1, e);
}
}
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
}
println!("Completed {} cycles without crash - PASS", 3);
}
#[tokio::test]
async fn test_advertising_memory_safety() {
use peat_btle::config::DiscoveryConfig;
use peat_btle::platform::apple::CoreBluetoothAdapter;
let result = CoreBluetoothAdapter::new();
let Ok(mut adapter) = result else {
println!("Skipping test: Bluetooth unavailable");
return;
};
let node_id = NodeId::new(0xABCDEF01);
let config = BleConfig::new(node_id);
if let Err(e) = adapter.init(&config).await {
println!("Skipping test: init failed: {}", e);
return;
}
let discovery_config = DiscoveryConfig::default();
match adapter.start_advertising(&discovery_config).await {
Ok(()) => {
println!("Advertising started successfully");
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
let _ = adapter.stop_advertising().await;
println!("Advertising stopped");
}
Err(e) => {
println!("Advertising failed (may be expected): {}", e);
}
}
println!("Advertising test completed without crash - PASS");
}