lgui-core 0.2.2

Platform-neutral runtime and UI primitives for LGUI
Documentation
use std::{
    future::Future,
    task::{Context, Poll, Waker},
};

use crate::application::ApplicationContext;

use super::*;

struct Add;

impl Command for Add {
    type Args = (i32, i32);
    type Output = i32;
    type Error = &'static str;

    const NAME: &'static str = "test.add";
}

fn run_ready<T>(future: impl Future<Output = T>) -> T {
    let mut future = Box::pin(future);
    let waker = Waker::noop();
    let mut context = Context::from_waker(waker);
    match future.as_mut().poll(&mut context) {
        Poll::Ready(output) => output,
        Poll::Pending => panic!("test future unexpectedly pending"),
    }
}

#[test]
fn typed_commands_preserve_arguments_outputs_and_errors() {
    let application = ApplicationContext::empty(crate::memory::test_memory_options());
    assert!(application
        .command_registry()
        .register::<Add>(|_, (left, right)| async move {
            if left < 0 {
                Err("negative")
            } else {
                Ok(left + right)
            }
        }));

    let command = application.command::<Add>();
    assert_eq!(run_ready(command.invoke((2, 3))), Ok(5));
    assert_eq!(run_ready(command.invoke((-1, 3))), Err("negative"));
}

#[test]
fn duplicate_command_registration_is_rejected() {
    let application = ApplicationContext::empty(crate::memory::test_memory_options());
    assert!(application
        .command_registry()
        .register::<Add>(|_, _| async { Ok(0) }));
    assert!(!application
        .command_registry()
        .register::<Add>(|_, _| async { Ok(1) }));
}

#[test]
fn free_invoke_routes_through_the_scoped_application() {
    let application = ApplicationContext::empty(crate::memory::test_memory_options());
    assert!(application
        .command_registry()
        .register::<Add>(|_, (left, right)| async move { Ok(left + right) }));

    assert_eq!(run_ready(application.scope(invoke::<Add>((4, 5)))), Ok(9));
}