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.operations.call(route()).await.unwrap();
assert_eq!(routed.points, corner());
let validated = runtime
.operations
.call(validate::ValidateSchematic { schematic: Snapshot { symbols: vec![1, 1], connections: vec![Connection { from: 1, to: 2 }] } })
.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.operations.call(route()).await.unwrap();
assert_eq!(routed.points, corner());
runtime.plugin.stop(PLUGIN).await.unwrap();
assert!(runtime.operations.call(route()).await.is_err());
runtime.stop().await.unwrap();
}