mecha10-core 0.6.5

Mecha10 core runtime and foundational types
Documentation
use mecha10_core::topic_utils::*;

#[test]
fn test_extract_category() {
    assert_eq!(extract_category("/sensor/camera"), "/sensor");
    assert_eq!(extract_category("/actuator/motor/left"), "/actuator");
    assert_eq!(extract_category("sensor/camera"), "/sensor");
    assert_eq!(extract_category(""), "uncategorized");
}

#[test]
fn test_format_elapsed_time() {
    assert_eq!(format_elapsed_time(500), "500ms ago");
    assert_eq!(format_elapsed_time(5000), "5s ago");
    assert_eq!(format_elapsed_time(65000), "1m ago");
    assert_eq!(format_elapsed_time(3700000), "1h ago");
    assert_eq!(format_elapsed_time(90000000), "1d ago");
}

#[test]
fn test_topic_metadata() {
    let metadata = TopicMetadata::new("/sensor/camera".to_string())
        .with_message_count(100)
        .with_timestamp_range(1000, 11000);

    assert_eq!(metadata.topic, "/sensor/camera");
    assert_eq!(metadata.message_count, Some(100));
    assert_eq!(metadata.category(), "/sensor");

    let rate = metadata.calculate_rate();
    assert!(rate.is_some());
    assert!((rate.unwrap() - 10.0).abs() < 0.01);
}

#[test]
fn test_topic_metadata_no_rate_insufficient_duration() {
    let metadata = TopicMetadata::new("/test".to_string())
        .with_message_count(10)
        .with_timestamp_range(1000, 1500);

    assert!(metadata.calculate_rate().is_none());
}

#[test]
fn test_topic_metadata_builder() {
    let metadata = TopicMetadata::new("/test".to_string())
        .with_message_count(42)
        .with_last_update(123456789);

    assert_eq!(metadata.message_count, Some(42));
    assert_eq!(metadata.last_update_ms, Some(123456789));
}