greentic-ext-runtime 1.2.26

Wasmtime-based runtime for Greentic Designer Extensions
Documentation
use greentic_ext_runtime::{CapabilityRegistry, OfferedBinding};
use greentic_extension_sdk_contract::{CapabilityRef, ExtensionKind};

fn offer(ext: &str, cap: &str, v: &str) -> OfferedBinding {
    OfferedBinding {
        extension_id: ext.into(),
        cap_id: cap.parse().unwrap(),
        version: v.parse().unwrap(),
        kind: ExtensionKind::Design,
        export_path: "e".into(),
    }
}

fn require(id: &str, v: &str) -> CapabilityRef {
    CapabilityRef {
        id: id.parse().unwrap(),
        version: v.to_string(),
        deprecated: None,
    }
}

#[test]
fn detects_direct_cycle() {
    let mut r = CapabilityRegistry::new();
    r.add_offering(offer("a", "greentic:a/offered", "1.0.0"));
    r.add_offering(offer("b", "greentic:b/offered", "1.0.0"));
    let cycle = r.detect_cycle(&[
        ("a".to_string(), vec![require("greentic:b/offered", "^1.0")]),
        ("b".to_string(), vec![require("greentic:a/offered", "^1.0")]),
    ]);
    assert!(cycle.contains(&"a".to_string()));
    assert!(cycle.contains(&"b".to_string()));
}

#[test]
fn no_cycle_for_linear_dependency() {
    let mut r = CapabilityRegistry::new();
    r.add_offering(offer("a", "greentic:a/offered", "1.0.0"));
    r.add_offering(offer("b", "greentic:b/offered", "1.0.0"));
    let cycle = r.detect_cycle(&[
        ("a".to_string(), vec![require("greentic:b/offered", "^1.0")]),
        ("b".to_string(), vec![]),
    ]);
    assert!(cycle.is_empty());
}