use schematic_domain as schematic;
use std::num::NonZeroUsize;
use crate::support;
use harmos_runtime::Runtime;
use harmos_runtime::plugin::PluginState;
use schematic::model::{Connection, Point, Snapshot};
use schematic_operations::Operations;
use schematic_operations::schematic::{analyze, propose, validate};
const PLUGIN: &str = "schematic_tools";
#[harmos_runtime::lanes]
enum Lanes {
#[default]
Open,
}
fn route() -> propose::ProposeRoute {
propose::ProposeRoute {
from: Point { x: 0, y: 0 },
to: Point { x: 3, y: 4 },
}
}
fn corner() -> [Point; 3] {
[Point { x: 0, y: 0 }, Point { x: 3, y: 0 }, Point { x: 3, y: 4 }]
}
#[tokio::test]
async fn guest_composition_walks() {
let _report = crate::report::system();
let runtime = Runtime::builder(support::Ledger::default(), ())
.register(Lanes::catalog())
.register(support::catalog())
.operation_settings(harmos_runtime::operations::Settings {
preparation_bytes: Some(NonZeroUsize::new(4096).unwrap()),
..Default::default()
})
.runtime()
.await
.expect("an empty ledger has nothing to recover");
assert!(runtime.plugin.status(PLUGIN).is_none());
let bytes = support::fixtures::component("schematic-guest");
let host = harmos_runtime::guest::Host::new(&runtime).unwrap();
let loaded = host.load(&bytes).unwrap();
let declaration = loaded.declaration();
assert_eq!(declaration.id, PLUGIN);
let mut declared: Vec<_> = declaration.operations.iter().map(|operation| operation.id.to_string()).collect();
declared.sort();
assert_eq!(declared, ["schematic.analyze", "schematic.route", "schematic.validate"]);
let settings = harmos_runtime::config::PluginSettings {
configuration: b"null".to_vec(),
..Default::default()
};
runtime.plugin.register_guest::<Operations>(loaded, settings, Lanes::Open).await.unwrap();
runtime.plugin.initialize().await.unwrap();
let ready = runtime.plugin.status(PLUGIN).unwrap();
assert_eq!(ready.state, PluginState::Ready);
let routed = runtime.operation(route()).run().await.unwrap();
assert_eq!(routed.points, corner());
let validated = runtime
.operation(validate::ValidateSchematic {
schematic: Snapshot {
symbols: vec![1, 1],
connections: vec![Connection { from: 1, to: 2 }],
},
})
.run()
.await
.unwrap();
assert_eq!(validated.diagnostics, ["Duplicate Symbol IDs", "Connection 1 To 2 References A Missing Symbol"]);
let settings = harmos_runtime::operations::StreamSettings {
items: NonZeroUsize::MIN,
bytes: NonZeroUsize::new(4096).unwrap(),
};
let request = analyze::AnalyzeSchematic {
schematic: Snapshot {
symbols: vec![1, 2],
connections: vec![Connection { from: 1, to: 2 }],
},
};
let mut download = runtime.operations.download::<analyze::AnalyzeSchematic>(request, settings).unwrap();
for expected in ["2 symbols", "1 connections", "Analysis complete"] {
assert_eq!(download.next().await.unwrap().unwrap().text, expected);
}
assert!(download.next().await.unwrap().is_none());
assert_eq!(download.join().await.unwrap().checked, 3);
runtime.plugin.reload(PLUGIN).await.unwrap();
let reloaded = runtime.plugin.status(PLUGIN).unwrap();
assert_eq!(reloaded.state, PluginState::Ready);
assert_ne!(reloaded.generation, ready.generation);
let routed = runtime.operation(route()).run().await.unwrap();
assert_eq!(routed.points, corner());
runtime.plugin.stop(PLUGIN).await.unwrap();
assert!(runtime.operation(route()).run().await.is_err());
runtime.stop().await.unwrap();
}