Skip to content

Commit

Permalink
integrate styling, fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
mekaem committed Nov 1, 2024
1 parent 4c742f5 commit 1416dd5
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 38 deletions.
31 changes: 13 additions & 18 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,9 @@
//! This module provides the primary application infrastructure, coordinating between
//! the event system, state management, and TUI rendering.
use std::{
future::Future,
sync::Arc,
time::Duration,
};
use std::{future::Future, sync::Arc, time::Duration};

use smol::{
future::FutureExt,
Task,
};
use smol::{future::FutureExt, Task};

use crate::{
error::OxittyResult,
Expand Down Expand Up @@ -105,11 +98,12 @@ impl<S: AtomicState + 'static> App<S> {
let tasks = std::mem::take(&mut self.tasks);
for task in tasks {
// Attempt to join task with timeout
match task.or(async {
smol::Timer::after(Duration::from_secs(1)).await;
Ok(())
})
.await
match task
.or(async {
smol::Timer::after(Duration::from_secs(1)).await;
Ok(())
})
.await
{
Ok(_) => {}
Err(e) => eprintln!("Task cleanup error: {}", e),
Expand Down Expand Up @@ -182,7 +176,10 @@ mod tests {
};

let app_result = App::new(state, Duration::from_millis(50));
assert!(app_result.is_err(), "App creation should fail in test environment");
assert!(
app_result.is_err(),
"App creation should fail in test environment"
);
}

#[test]
Expand All @@ -194,9 +191,7 @@ mod tests {
};

if let Ok(mut app) = App::new(state, Duration::from_millis(50)) {
let spawn_result = app.spawn(async {
Ok(())
});
let spawn_result = app.spawn(async { Ok(()) });
assert!(spawn_result.is_ok());
assert_eq!(app.tasks.len(), 1);
}
Expand Down
32 changes: 24 additions & 8 deletions src/colors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,12 @@ mod tests {

let dark_purple = void::purple_variant(20.0);
let (_h, _s, l) = dark_purple.to_hsl();
assert!(approx_eq(l, 20.0, EPSILON),
"Lightness {} not within {} of target 20.0", l, EPSILON);
assert!(
approx_eq(l, 20.0, EPSILON),
"Lightness {} not within {} of target 20.0",
l,
EPSILON
);
}

#[test]
Expand All @@ -362,11 +366,20 @@ mod tests {
let (h1, s1, _) = warning.to_hsl();
let (h2, _s2, l2) = intense.to_hsl();

assert!(approx_eq(h1, h2, EPSILON),
"Hue changed from {} to {}, diff > {}", h1, h2, EPSILON);
assert!(
approx_eq(h1, h2, EPSILON),
"Hue changed from {} to {}, diff > {}",
h1,
h2,
EPSILON
);
assert!(s1 > 0.0, "Source saturation should be positive");
assert!(approx_eq(l2, 70.0, EPSILON),
"Lightness {} not within {} of target 70.0", l2, EPSILON);
assert!(
approx_eq(l2, 70.0, EPSILON),
"Lightness {} not within {} of target 70.0",
l2,
EPSILON
);
}

#[test]
Expand Down Expand Up @@ -585,9 +598,12 @@ mod theme_tests {
let dark_purple = void::purple_variant(20.0);
let (_h, _s, l) = dark_purple.to_hsl();

assert!((l - 20.0).abs() < EPSILON,
assert!(
(l - 20.0).abs() < EPSILON,
"Lightness too far from target: {} vs 20.0 (diff: {})",
l, (l - 20.0).abs());
l,
(l - 20.0).abs()
);
}

#[test]
Expand Down
152 changes: 140 additions & 12 deletions src/tui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ use crossterm::{
use ratatui::{
backend::CrosstermBackend,
layout::{Rect, Size},
prelude::Line,
style::Style,
widgets::Block,
Terminal,
};

Expand All @@ -39,7 +42,8 @@ impl<S: AtomicState> Tui<S> {
"terminal check",
(0, 0),
"Not a real terminal or terminal capabilities not available".to_string(),
).into());
)
.into());
}

let terminal = Self::setup_terminal()?;
Expand All @@ -65,29 +69,30 @@ impl<S: AtomicState> Tui<S> {
fn setup_terminal() -> OxittyResult<Terminal<CrosstermBackend<Stdout>>> {
let mut stdout = io::stdout();

execute!(stdout, EnterAlternateScreen, EnableMouseCapture).map_err(|e|
execute!(stdout, EnterAlternateScreen, EnableMouseCapture).map_err(|e| {
OxittyError::terminal(
"terminal setup",
(0, 0),
format!("Failed to setup terminal: {}", e),
)
)?;
})?;

terminal::enable_raw_mode().map_err(|e|
terminal::enable_raw_mode().map_err(|e| {
OxittyError::terminal(
"terminal setup",
(0, 0),
format!("Failed to enable raw mode: {}", e),
)
)?;
})?;

Terminal::new(CrosstermBackend::new(stdout)).map_err(|e|
Terminal::new(CrosstermBackend::new(stdout)).map_err(|e| {
OxittyError::terminal(
"terminal setup",
(0, 0),
format!("Failed to create terminal: {}", e),
).into()
)
)
.into()
})
}

/// Restores terminal to original state
Expand Down Expand Up @@ -176,6 +181,84 @@ impl<S: AtomicState> Tui<S> {
)
})?)
}

/// Returns the default theme style
pub fn style() -> Style {
Style::default()
.fg(theme::text::PRIMARY.into())
.bg(theme::background::BASE.into())
}

/// Returns a style with primary text color
pub fn primary() -> Style {
Style::default()
.fg(theme::text::PRIMARY.into())
.bg(theme::background::BASE.into())
}

/// Returns a style with secondary text color
pub fn secondary() -> Style {
Style::default()
.fg(theme::text::SECONDARY.into())
.bg(theme::background::BASE.into())
}

/// Returns a style for error messages
pub fn error() -> Style {
Style::default()
.fg(theme::status::ERROR.into())
.bg(theme::background::BASE.into())
}

/// Returns a style for warning messages
pub fn warning() -> Style {
Style::default()
.fg(theme::status::WARNING.into())
.bg(theme::background::BASE.into())
}

/// Returns a style for info messages
pub fn info() -> Style {
Style::default()
.fg(theme::status::INFO.into())
.bg(theme::background::BASE.into())
}

/// Returns a style for success messages
pub fn success() -> Style {
Style::default()
.fg(theme::status::SUCCESS.into())
.bg(theme::background::BASE.into())
}

/// Returns a style for UI borders
pub fn border() -> Style {
Style::default()
.fg(theme::background::ELEVATION_3.into())
.bg(theme::background::BASE.into())
}

/// Returns a style for focused elements
pub fn focus() -> Style {
Style::default()
.fg(theme::void::PURPLE.into())
.bg(theme::background::BASE.into())
}

/// Returns a style for void elements
pub fn void() -> Style {
Style::default()
.fg(theme::void::GREEN.into())
.bg(theme::background::BASE.into())
}

/// Creates a themed block with the given title
pub fn block(title: impl Into<String>) -> Block<'static> {
Block::default()
.title(Line::from(title.into()))
.style(Self::primary())
.border_style(Self::border())
}
}

impl<S: AtomicState> Drop for Tui<S> {
Expand Down Expand Up @@ -246,13 +329,17 @@ mod tests {
};

let result = Tui::new(state);
assert!(result.is_err(), "Expected TUI creation to fail in mock environment");
assert!(
result.is_err(),
"Expected TUI creation to fail in mock environment"
);

if let Err(e) = result {
let err_msg = e.to_string().to_lowercase();
assert!(
err_msg.contains("terminal") || err_msg.contains("tty"),
"Expected terminal-related error, got: {}", err_msg
"Expected terminal-related error, got: {}",
err_msg
);
}
}
Expand All @@ -266,14 +353,55 @@ mod tests {
};

let result = Tui::new(state);
assert!(result.is_err(), "Expected TUI creation to fail in mock environment");
assert!(
result.is_err(),
"Expected TUI creation to fail in mock environment"
);

if let Err(e) = result {
let err_msg = e.to_string().to_lowercase();
assert!(
err_msg.contains("terminal") || err_msg.contains("tty"),
"Expected terminal-related error, got: {}", err_msg
"Expected terminal-related error, got: {}",
err_msg
);
}
}

#[test]
fn test_theme_styles() {
// Test primary style
let style = Tui::<TestState>::primary();
assert_eq!(style.fg, Some(theme::text::PRIMARY.into()));
assert_eq!(style.bg, Some(theme::background::BASE.into()));

// Test error style
let style = Tui::<TestState>::error();
assert_eq!(style.fg, Some(theme::status::ERROR.into()));
assert_eq!(style.bg, Some(theme::background::BASE.into()));

// Test border style
let style = Tui::<TestState>::border();
assert_eq!(style.fg, Some(theme::background::ELEVATION_3.into()));
assert_eq!(style.bg, Some(theme::background::BASE.into()));
}

#[test]
fn test_themed_block() {
let title = "Test";
let themed_block = Tui::<TestState>::block(title);

// Create styles we expect the block to be created with
let expected_style = Tui::<TestState>::primary();
let expected_border = Tui::<TestState>::border();

// Create a reference block with same styles to compare
let reference_block = Block::default()
.style(expected_style)
.border_style(expected_border)
.title(Line::from(title));

// Assert our themed block matches the reference
assert_eq!(themed_block, reference_block);
}
}

0 comments on commit 1416dd5

Please sign in to comment.