mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
what is up with those tests!
This commit is contained in:
parent
01835c8077
commit
7ddb95d521
6 changed files with 87 additions and 88 deletions
|
|
@ -30,8 +30,8 @@ mod edn_token; pub use self::edn_token::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_edn_layout () -> Result<(), ParseError> {
|
#[cfg(test)] #[test] fn test_edn_layout () -> Result<(), ParseError> {
|
||||||
EdnItem::<String>::read_all(include_str!("../tek/examples/edn01.edn"))?;
|
EdnItem::<String>::read_all(include_str!("../../tek/examples/edn01.edn"))?;
|
||||||
EdnItem::<String>::read_all(include_str!("../tek/examples/edn02.edn"))?;
|
EdnItem::<String>::read_all(include_str!("../../tek/examples/edn02.edn"))?;
|
||||||
//panic!("{layout:?}");
|
//panic!("{layout:?}");
|
||||||
//let content = <dyn EdnViewData<::tek_engine::tui::Tui>>::from(&layout);
|
//let content = <dyn EdnViewData<::tek_engine::tui::Tui>>::from(&layout);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
/// Event source
|
|
||||||
pub trait Input: Send + Sync + Sized {
|
|
||||||
/// Type of input event
|
|
||||||
type Event;
|
|
||||||
/// Result of handling input
|
|
||||||
type Handled;
|
|
||||||
/// Currently handled event
|
|
||||||
fn event (&self) -> &Self::Event;
|
|
||||||
/// Whether component should exit
|
|
||||||
fn is_done (&self) -> bool;
|
|
||||||
/// Mark component as done
|
|
||||||
fn done (&self);
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
pub struct EventMap<'a, S, I: PartialEq, C> {
|
pub struct EventMap<'a, S, I: PartialEq, C> {
|
||||||
pub bindings: &'a [(I, &'a dyn Fn(&S) -> Option<C>)],
|
pub bindings: &'a [(I, &'a dyn Fn(&S) -> Option<C>)],
|
||||||
pub fallback: Option<&'a dyn Fn(&S, &I) -> Option<C>>
|
pub fallback: Option<&'a dyn Fn(&S, &I) -> Option<C>>
|
||||||
|
|
@ -40,3 +42,32 @@ impl<'a, S, I: PartialEq, C> EventMap<'a, S, I, C> {
|
||||||
input_to_command!($(<$lt>)? $Command: |$state: $State, input: $Input|$KEYS.handle($state, input)?);
|
input_to_command!($(<$lt>)? $Command: |$state: $State, input: $Input|$KEYS.handle($state, input)?);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
#[macro_export] macro_rules! input_to_command {
|
||||||
|
(<$($l:lifetime),+> $Command:ty: |$state:ident:$State:ty, $input:ident:$Input:ty| $handler:expr) => {
|
||||||
|
impl<$($l),+> InputToCommand<$Input, $State> for $Command {
|
||||||
|
fn input_to_command ($state: &$State, $input: &$Input) -> Option<Self> {
|
||||||
|
Some($handler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($Command:ty: |$state:ident:$State:ty, $input:ident:$Input:ty| $handler:expr) => {
|
||||||
|
impl InputToCommand<$Input, $State> for $Command {
|
||||||
|
fn input_to_command ($state: &$State, $input: &$Input) -> Option<Self> {
|
||||||
|
Some($handler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait InputToCommand<I, S>: Command<S> + Sized {
|
||||||
|
fn input_to_command (state: &S, input: &I) -> Option<Self>;
|
||||||
|
fn execute_with_state (state: &mut S, input: &I) -> Perhaps<bool> {
|
||||||
|
Ok(if let Some(command) = Self::input_to_command(state, input) {
|
||||||
|
let _undo = command.execute(state)?;
|
||||||
|
Some(true)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,14 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
#[macro_export] macro_rules! input_to_command {
|
/// Event source
|
||||||
(<$($l:lifetime),+> $Command:ty: |$state:ident:$State:ty, $input:ident:$Input:ty| $handler:expr) => {
|
pub trait Input: Send + Sync + Sized {
|
||||||
impl<$($l),+> InputToCommand<$Input, $State> for $Command {
|
/// Type of input event
|
||||||
fn input_to_command ($state: &$State, $input: &$Input) -> Option<Self> {
|
type Event;
|
||||||
Some($handler)
|
/// Result of handling input
|
||||||
}
|
type Handled;
|
||||||
}
|
/// Currently handled event
|
||||||
};
|
fn event (&self) -> &Self::Event;
|
||||||
($Command:ty: |$state:ident:$State:ty, $input:ident:$Input:ty| $handler:expr) => {
|
/// Whether component should exit
|
||||||
impl InputToCommand<$Input, $State> for $Command {
|
fn is_done (&self) -> bool;
|
||||||
fn input_to_command ($state: &$State, $input: &$Input) -> Option<Self> {
|
/// Mark component as done
|
||||||
Some($handler)
|
fn done (&self);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait InputToCommand<I, S>: Command<S> + Sized {
|
|
||||||
fn input_to_command (state: &S, input: &I) -> Option<Self>;
|
|
||||||
fn execute_with_state (state: &mut S, input: &I) -> Perhaps<bool> {
|
|
||||||
Ok(if let Some(command) = Self::input_to_command(state, input) {
|
|
||||||
let _undo = command.execute(state)?;
|
|
||||||
Some(true)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,25 @@
|
||||||
#![feature(associated_type_defaults)]
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
//mod component; pub use self::component::*;
|
//mod component; pub use self::component::*;
|
||||||
mod engine; pub use self::engine::*;
|
|
||||||
mod input; pub use self::input::*;
|
mod input; pub use self::input::*;
|
||||||
mod handle; pub use self::handle::*;
|
mod handle; pub use self::handle::*;
|
||||||
mod command; pub use self::command::*;
|
mod command; pub use self::command::*;
|
||||||
mod event_map; pub use self::event_map::*;
|
mod event_map; pub use self::event_map::*;
|
||||||
|
|
||||||
pub(crate) use std::marker::PhantomData;
|
/// Standard error trait.
|
||||||
pub(crate) use std::error::Error;
|
pub(crate) use std::error::Error;
|
||||||
|
|
||||||
/// Standard result type.
|
/// Standard result type.
|
||||||
pub(crate) type Usually<T> = Result<T, Box<dyn Error>>;
|
pub(crate) type Usually<T> = Result<T, Box<dyn Error>>;
|
||||||
|
|
||||||
/// Standard optional result type.
|
/// Standard optional result type.
|
||||||
pub(crate) type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
pub(crate) type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_dimensions () {
|
#[cfg(test)] #[test] fn test_stub_input () -> Usually<()> {
|
||||||
assert_eq!(Area::center(&[10u16, 10, 20, 20]), [20, 20]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_stub_engine () -> Usually<()> {
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
struct TestEngine(bool);
|
|
||||||
struct TestInput(bool);
|
struct TestInput(bool);
|
||||||
struct TestOutput([u16;4]);
|
|
||||||
enum TestEvent { Test1 }
|
enum TestEvent { Test1 }
|
||||||
impl Engine for TestEngine {
|
impl Input for TestInput {
|
||||||
type Input = TestInput;
|
|
||||||
type Handled = ();
|
|
||||||
type Output = TestOutput;
|
|
||||||
type Unit = u16;
|
|
||||||
type Size = [u16;2];
|
|
||||||
type Area = [u16;4];
|
|
||||||
fn exited (&self) -> bool {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Input<TestEngine> for TestInput {
|
|
||||||
type Event = TestEvent;
|
type Event = TestEvent;
|
||||||
|
type Handled = ();
|
||||||
fn event (&self) -> &Self::Event {
|
fn event (&self) -> &Self::Event {
|
||||||
&TestEvent::Test1
|
&TestEvent::Test1
|
||||||
}
|
}
|
||||||
|
|
@ -47,21 +28,5 @@ pub(crate) type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
||||||
}
|
}
|
||||||
fn done (&self) {}
|
fn done (&self) {}
|
||||||
}
|
}
|
||||||
impl Output<TestEngine> for TestOutput {
|
|
||||||
fn area (&self) -> [u16;4] {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
fn area_mut (&mut self) -> &mut [u16;4] {
|
|
||||||
&mut self.0
|
|
||||||
}
|
|
||||||
fn place (&mut self, _: [u16;4], _: &impl Render<TestEngine>) {
|
|
||||||
()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Content<TestEngine> for String {
|
|
||||||
fn render (&self, to: &mut TestOutput) {
|
|
||||||
to.area_mut().set_w(self.len() as u16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,23 +35,55 @@ pub type Usually<T> = Result<T, Box<dyn Error>>;
|
||||||
/// Standard optional result type.
|
/// Standard optional result type.
|
||||||
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
||||||
|
|
||||||
|
#[cfg(test)] #[test] fn test_stub_output () -> Usually<()> {
|
||||||
|
use crate::*;
|
||||||
|
struct TestOutput([u16;4]);
|
||||||
|
impl Output for TestOutput {
|
||||||
|
type Unit = u16;
|
||||||
|
type Size = [u16;2];
|
||||||
|
type Area = [u16;4];
|
||||||
|
fn area (&self) -> [u16;4] {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
fn area_mut (&mut self) -> &mut [u16;4] {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
fn place (&mut self, _: [u16;4], _: &impl Render<TestOutput>) {
|
||||||
|
()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Content<TestOutput> for String {
|
||||||
|
fn render (&self, to: &mut TestOutput) {
|
||||||
|
to.area_mut().set_w(self.len() as u16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)] #[test] fn test_dimensions () {
|
||||||
|
use crate::*;
|
||||||
|
assert_eq!(Area::center(&[10u16, 10, 20, 20]), [20, 20]);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_layout () -> Usually<()> {
|
#[cfg(test)] #[test] fn test_layout () -> Usually<()> {
|
||||||
use ::tek_tui::Tui;
|
use ::tek_tui::{*, tek_output::*};
|
||||||
let area: [u16;4] = [10, 10, 20, 20];
|
let area: [u16;4] = [10, 10, 20, 20];
|
||||||
|
|
||||||
let unit = ();
|
let unit = ();
|
||||||
|
|
||||||
assert_eq!(Content::<TuiOut>::layout(&unit, area), [20, 20, 0, 0]);
|
assert_eq!(Content::<TuiOut>::layout(&unit, area), [20, 20, 0, 0]);
|
||||||
|
|
||||||
assert_eq!(Fill::<TuiOut>::x(unit).layout(area), [10, 20, 20, 0]);
|
assert_eq!(Content::<TuiOut>::layout(&Fill::<()>::x(unit), area), [10, 20, 20, 0]);
|
||||||
assert_eq!(Fill::<TuiOut>::y(unit).layout(area), [20, 10, 0, 20]);
|
assert_eq!(Render::<TuiOut>::layout(&Fill::<()>::x(unit), area), [10, 20, 20, 0]);
|
||||||
assert_eq!(Fill::<TuiOut>::xy(unit).layout(area), area);
|
|
||||||
|
assert_eq!(Fill::<()>::y(unit).layout(area), [20, 10, 0, 20]);
|
||||||
|
assert_eq!(Fill::<()>::xy(unit).layout(area), area);
|
||||||
|
|
||||||
assert_eq!(Fixed::<TuiOut, u16>::x(4, unit).layout(area), [18, 20, 4, 0]);
|
assert_eq!(Fixed::<TuiOut, u16>::x(4, unit).layout(area), [18, 20, 4, 0]);
|
||||||
assert_eq!(Fixed::<TuiOut, u16>::y(4, unit).layout(area), [20, 18, 0, 4]);
|
assert_eq!(Fixed::<TuiOut, u16>::y(4, unit).layout(area), [20, 18, 0, 4]);
|
||||||
assert_eq!(Fixed::<TuiOut, u16>::xy(4, 4, unit).layout(area), [18, 18, 4, 4]);
|
assert_eq!(Fixed::<TuiOut, u16>::xy(4, 4, unit).layout(area), [18, 18, 4, 4]);
|
||||||
|
|
||||||
let four = ||Fixed::<TuiOut>::xy(4, 4, unit);
|
let four = ||Fixed::<TuiOut, _>::xy(4, 4, unit);
|
||||||
|
|
||||||
assert_eq!(Align::nw(four()).layout(area), [10, 10, 4, 4]);
|
assert_eq!(Align::nw(four()).layout(area), [10, 10, 4, 4]);
|
||||||
assert_eq!(Align::n(four()).layout(area), [18, 10, 4, 4]);
|
assert_eq!(Align::n(four()).layout(area), [18, 10, 4, 4]);
|
||||||
|
|
@ -62,7 +94,7 @@ pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
|
||||||
assert_eq!(Align::sw(four()).layout(area), [10, 26, 4, 4]);
|
assert_eq!(Align::sw(four()).layout(area), [10, 26, 4, 4]);
|
||||||
assert_eq!(Align::w(four()).layout(area), [10, 18, 4, 4]);
|
assert_eq!(Align::w(four()).layout(area), [10, 18, 4, 4]);
|
||||||
|
|
||||||
let two_by_four = ||Fixed::<TuiOut>::xy(4, 2, unit);
|
let two_by_four = ||Fixed::<TuiOut, _>::xy(4, 2, unit);
|
||||||
|
|
||||||
assert_eq!(Align::nw(two_by_four()).layout(area), [10, 10, 4, 2]);
|
assert_eq!(Align::nw(two_by_four()).layout(area), [10, 10, 4, 2]);
|
||||||
assert_eq!(Align::n(two_by_four()).layout(area), [18, 10, 4, 2]);
|
assert_eq!(Align::n(two_by_four()).layout(area), [18, 10, 4, 2]);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue