frame-cli 0.1.0

CLI for Frame — scaffold applications, manage components, run dev server
Documentation
//! Generated application lifecycle and Gleam component acceptance tests.

use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};

use frame_core::component::ComponentId;
use frame_state::ComponentStateStore;

#[test]
fn install_start_round_trip_read_and_ordered_stop() -> Result<(), Box<dyn std::error::Error>> {
    let unique = SystemTime::now().duration_since(UNIX_EPOCH)?.as_nanos();
    let state = std::env::temp_dir().join(format!("frame-generated-e2e-{unique}"));
    let entity = app_host::run_application(&state)?;
    assert_eq!(entity.to_string().len(), 64);
    assert_eq!(app_host::run_application(&state)?, entity);

    let reopened = ComponentStateStore::open(&state)?;
    reopened.reconcile()?;
    let id = ComponentId::derive("frame.generated", "{{NAME}}");
    let handle = reopened.component_handle(id)?;
    assert_eq!(
        handle.get(entity)?.as_deref(),
        Some(br#"{"kind":"welcome","message":"hello from {{NAME}}"}"#.as_slice())
    );
    remove_if_present(&state)?;
    Ok(())
}

#[test]
fn gleam_component_test_passes() -> Result<(), Box<dyn std::error::Error>> {
    let component = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../component");
    let output = std::process::Command::new("gleam")
        .arg("test")
        .current_dir(component)
        .output()
        .map_err(|error| {
            std::io::Error::new(
                error.kind(),
                format!("Gleam toolchain is required for component tests; install it from https://gleam.run/getting-started/installing/: {error}"),
            )
        })?;
    if !output.status.success() {
        return Err(std::io::Error::other(format!(
            "gleam test failed: {}",
            String::from_utf8_lossy(&output.stderr)
        ))
        .into());
    }
    Ok(())
}

fn remove_if_present(path: &std::path::Path) -> std::io::Result<()> {
    match std::fs::remove_dir_all(path) {
        Ok(()) => Ok(()),
        Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(()),
        Err(error) => Err(error),
    }
}