//! File reloads, immutable calls, debounce, offline edits, and host-side recovery without subprocesses. use sausage::{ exec::{Command, Exec, Options, Stream}, world::World, }; use std::sync::Arc; const BUNDLE: &str = include_str!("../../js/extensions-test-bundle.js"); struct NoExec; #[async_trait::async_trait] impl Exec for NoExec { async fn exec( &self, command: Command, _: Options, _: &mut (dyn for<'a> FnMut(Stream, &'a [u8]) + Send), ) -> anyhow::Result { anyhow::bail!("Extension loading must not spawn commands: {command:?}") } } #[tokio::test(flavor = "current_thread")] async fn edits_and_restart() -> anyhow::Result<()> { let dir = tempfile::tempdir()?; let repo = dir.path().join("world/src/sausage"); std::fs::create_dir_all(&repo)?; for (phase, expected) in [ ("edits", "C"), ("broken", "C"), ("offline", "D"), ("broken", "D"), ] { if phase == "offline" { std::fs::copy( repo.join("offline-source.txt"), repo.join("extensions/demo/server.ts"), )?; } else if phase == "broken" { std::fs::write(repo.join("extensions/demo/server.ts"), "syntax !!! error")?; } let world = World::open(dir.path())?; sausage::harness::run_module(world, Arc::new(NoExec), &format!( "globalThis.extensionPhase={phase:?};globalThis.extensionExpected={expected:?};\n{BUNDLE}" )).await?; assert!(!repo.join(".git").exists()); } Ok(()) }