use super::helpers::month_name;
use super::render::Rendering;
use super::types::{DateTime, DateTimeFormat, DateTimeMode, Time, TimeField};
use super::{date_picker, datetime_picker, time_picker, DateTimePicker};
use crate::event::Key;
use crate::layout::Rect;
use crate::render::Buffer;
use crate::widget::data::calendar::Date;
use crate::widget::data::calendar::FirstDayOfWeek;
use crate::widget::traits::{RenderContext, View};
#[test]
fn test_time_new() {
let t = Time::new(14, 30, 45);
assert_eq!(t.hour, 14);
assert_eq!(t.minute, 30);
assert_eq!(t.second, 45);
}
#[test]
fn test_time_clamp() {
let t = Time::new(25, 70, 80);
assert_eq!(t.hour, 23);
assert_eq!(t.minute, 59);
assert_eq!(t.second, 59);
}
#[test]
fn test_time_format() {
let t = Time::new(14, 5, 9);
assert_eq!(t.format_hm(), "14:05");
assert_eq!(t.format_hms(), "14:05:09");
}
#[test]
fn test_time_format_12h() {
assert_eq!(Time::new(0, 30, 0).format_12h(), "12:30 AM");
assert_eq!(Time::new(9, 15, 0).format_12h(), " 9:15 AM");
assert_eq!(Time::new(12, 0, 0).format_12h(), "12:00 PM");
assert_eq!(Time::new(15, 45, 0).format_12h(), " 3:45 PM");
}
#[test]
fn test_datetime_new() {
let dt = DateTime::new(Date::new(2025, 6, 15), Time::new(10, 30, 0));
assert_eq!(dt.date.year, 2025);
assert_eq!(dt.date.month, 6);
assert_eq!(dt.date.day, 15);
assert_eq!(dt.time.hour, 10);
assert_eq!(dt.time.minute, 30);
}
#[test]
fn test_picker_new() {
let p = DateTimePicker::new();
assert_eq!(p.mode, DateTimeMode::Date);
assert_eq!(p.format, DateTimeFormat::DateTime);
}
#[test]
fn test_picker_date_only() {
let p = DateTimePicker::date_only();
assert_eq!(p.format, DateTimeFormat::DateOnly);
}
#[test]
fn test_picker_time_only() {
let p = DateTimePicker::time_only();
assert_eq!(p.format, DateTimeFormat::TimeOnly);
assert_eq!(p.mode, DateTimeMode::Time);
}
#[test]
fn test_picker_selected() {
let p = datetime_picker()
.selected_date(Date::new(2025, 3, 20))
.selected_time(Time::new(15, 45, 0));
assert_eq!(p.date, Date::new(2025, 3, 20));
assert_eq!(p.time, Time::new(15, 45, 0));
}
#[test]
fn test_picker_constraints() {
let p = datetime_picker()
.min_date(Date::new(2025, 1, 1))
.max_date(Date::new(2025, 12, 31));
assert!(p.is_date_valid(&Date::new(2025, 6, 15)));
assert!(!p.is_date_valid(&Date::new(2024, 12, 31)));
assert!(!p.is_date_valid(&Date::new(2026, 1, 1)));
}
#[test]
fn test_picker_handle_key_tab() {
let mut p = datetime_picker();
assert_eq!(p.mode, DateTimeMode::Date);
p.handle_key(&Key::Tab);
assert_eq!(p.mode, DateTimeMode::Time);
p.handle_key(&Key::Tab);
assert_eq!(p.mode, DateTimeMode::Date);
}
#[test]
fn test_picker_time_navigation() {
let mut p = datetime_picker().selected_time(Time::new(10, 30, 0));
p.mode = DateTimeMode::Time;
p.handle_key(&Key::Up);
assert_eq!(p.time.hour, 11);
p.handle_key(&Key::Right);
assert_eq!(p.time_field, TimeField::Minute);
p.handle_key(&Key::Down);
assert_eq!(p.time.minute, 29);
}
#[test]
fn test_picker_month_navigation() {
let mut p = datetime_picker().selected_date(Date::new(2025, 6, 15));
p.handle_key(&Key::Char(']'));
assert_eq!(p.date.month, 7);
p.handle_key(&Key::Char('['));
assert_eq!(p.date.month, 6);
}
#[test]
fn test_picker_year_navigation() {
let mut p = datetime_picker().selected_date(Date::new(2025, 6, 15));
p.handle_key(&Key::Char('}'));
assert_eq!(p.date.year, 2026);
p.handle_key(&Key::Char('{'));
assert_eq!(p.date.year, 2025);
}
#[test]
fn test_helper_functions() {
let _ = datetime_picker();
let _ = date_picker();
let _ = time_picker();
}
#[test]
fn test_month_name() {
assert_eq!(month_name(1), "January");
assert_eq!(month_name(6), "June");
assert_eq!(month_name(12), "December");
assert_eq!(month_name(13), "Unknown");
}
#[test]
fn test_first_weekday() {
let p = datetime_picker().selected_date(Date::new(2025, 1, 1));
let weekday = p.first_weekday();
assert!(weekday <= 6);
}
#[test]
fn test_first_weekday_monday_start() {
let p = datetime_picker()
.selected_date(Date::new(2025, 1, 1))
.first_day(FirstDayOfWeek::Monday);
let weekday = p.first_weekday();
assert!(weekday <= 6);
}
#[test]
fn test_picker_cursor_navigation() {
let mut p = datetime_picker().selected_date(Date::new(2025, 6, 15));
p.handle_key(&Key::Right);
assert_eq!(p.cursor_day, 16);
p.handle_key(&Key::Left);
assert_eq!(p.cursor_day, 15);
p.handle_key(&Key::Down);
assert_eq!(p.cursor_day, 22);
p.handle_key(&Key::Up);
assert_eq!(p.cursor_day, 15);
}
#[test]
fn test_picker_vim_navigation() {
let mut p = datetime_picker().selected_date(Date::new(2025, 6, 15));
p.handle_key(&Key::Char('l'));
assert_eq!(p.cursor_day, 16);
p.handle_key(&Key::Char('h'));
assert_eq!(p.cursor_day, 15);
p.handle_key(&Key::Char('j'));
assert_eq!(p.cursor_day, 22);
p.handle_key(&Key::Char('k'));
assert_eq!(p.cursor_day, 15);
}
#[test]
fn test_picker_select_date() {
let mut p = datetime_picker().selected_date(Date::new(2025, 6, 15));
p.cursor_day = 20;
p.handle_key(&Key::Enter);
assert_eq!(p.date.day, 20);
}
#[test]
fn test_picker_time_vim_keys() {
let mut p = datetime_picker().selected_time(Time::new(10, 30, 0));
p.mode = DateTimeMode::Time;
p.handle_key(&Key::Char('k')); assert_eq!(p.time.hour, 11);
p.handle_key(&Key::Char('l')); assert_eq!(p.time_field, TimeField::Minute);
p.handle_key(&Key::Char('j')); assert_eq!(p.time.minute, 29);
p.handle_key(&Key::Char('h')); assert_eq!(p.time_field, TimeField::Hour);
}
#[test]
fn test_picker_month_boundary() {
let mut p = datetime_picker().selected_date(Date::new(2025, 1, 31));
p.cursor_day = 31;
p.handle_key(&Key::Char(']'));
assert!(p.cursor_day <= 28);
}
#[test]
fn test_picker_year_boundary() {
let mut p = datetime_picker().selected_date(Date::new(2024, 2, 29));
p.cursor_day = 29;
p.handle_key(&Key::Char('}'));
assert_eq!(p.cursor_day, 28);
}
#[test]
fn test_picker_render_datetime() {
let p = datetime_picker()
.selected_date(Date::new(2025, 6, 15))
.selected_time(Time::new(14, 30, 0));
let mut buffer = Buffer::new(30, 15);
let area = Rect::new(0, 0, 30, 15);
let mut ctx = RenderContext::new(&mut buffer, area);
p.render(&mut ctx);
}
#[test]
fn test_picker_render_date_only() {
let p = date_picker().selected_date(Date::new(2025, 6, 15));
let mut buffer = Buffer::new(25, 10);
let area = Rect::new(0, 0, 25, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
p.render(&mut ctx);
}
#[test]
fn test_picker_render_time_only() {
let p = time_picker().selected_time(Time::new(14, 30, 0));
let mut buffer = Buffer::new(20, 5);
let area = Rect::new(0, 0, 20, 5);
let mut ctx = RenderContext::new(&mut buffer, area);
p.render(&mut ctx);
}
#[test]
fn test_picker_render_small_area() {
let p = datetime_picker();
let mut buffer = Buffer::new(10, 3);
let area = Rect::new(0, 0, 10, 3);
let mut ctx = RenderContext::new(&mut buffer, area);
p.render(&mut ctx);
}
#[test]
fn test_picker_render_with_seconds() {
let p = time_picker()
.selected_time(Time::new(14, 30, 45))
.show_seconds(true);
let mut buffer = Buffer::new(25, 10);
let area = Rect::new(0, 0, 25, 10);
let mut ctx = RenderContext::new(&mut buffer, area);
p.render(&mut ctx);
}
#[test]
fn test_picker_time_field_second() {
let mut p = datetime_picker()
.selected_time(Time::new(10, 30, 45))
.show_seconds(true);
p.mode = DateTimeMode::Time;
p.time_field = TimeField::Second;
p.handle_key(&Key::Up);
assert_eq!(p.time.second, 46);
p.handle_key(&Key::Down);
assert_eq!(p.time.second, 45);
}
#[test]
fn test_picker_time_wrap() {
let mut p = datetime_picker().selected_time(Time::new(23, 59, 59));
p.mode = DateTimeMode::Time;
p.handle_key(&Key::Up);
assert_eq!(p.time.hour, 0);
p.time_field = TimeField::Minute;
p.handle_key(&Key::Up);
assert_eq!(p.time.minute, 0);
p.time_field = TimeField::Second;
p.handle_key(&Key::Up);
assert_eq!(p.time.second, 0);
}
#[test]
fn test_picker_time_wrap_down() {
let mut p = datetime_picker().selected_time(Time::new(0, 0, 0));
p.mode = DateTimeMode::Time;
p.handle_key(&Key::Down);
assert_eq!(p.time.hour, 23);
p.time_field = TimeField::Minute;
p.handle_key(&Key::Down);
assert_eq!(p.time.minute, 59);
p.time_field = TimeField::Second;
p.handle_key(&Key::Down);
assert_eq!(p.time.second, 59);
}
#[test]
fn test_picker_unhandled_key() {
let mut p = datetime_picker();
let handled = p.handle_key(&Key::Char('x'));
assert!(!handled);
}
#[test]
fn test_picker_space_select() {
let mut p = datetime_picker().selected_date(Date::new(2025, 6, 15));
p.cursor_day = 20;
p.handle_key(&Key::Char(' '));
assert_eq!(p.date.day, 20);
}
#[test]
fn test_picker_default() {
let p = DateTimePicker::default();
assert_eq!(p.format, DateTimeFormat::DateTime);
}
#[test]
fn test_picker_get_mode() {
let p = datetime_picker();
assert_eq!(p.get_mode(), DateTimeMode::Date);
}
#[test]
fn test_datetime_format_variants() {
let p1 = datetime_picker().format(DateTimeFormat::DateTime);
assert_eq!(p1.format, DateTimeFormat::DateTime);
let p2 = datetime_picker().format(DateTimeFormat::DateOnly);
assert_eq!(p2.format, DateTimeFormat::DateOnly);
let p3 = datetime_picker().format(DateTimeFormat::TimeOnly);
assert_eq!(p3.format, DateTimeFormat::TimeOnly);
let p4 = datetime_picker().format(DateTimeFormat::TimeWithSeconds);
assert_eq!(p4.format, DateTimeFormat::TimeWithSeconds);
}
#[test]
fn test_picker_cursor_boundary_right() {
let mut p = datetime_picker().selected_date(Date::new(2025, 6, 30));
p.cursor_day = 30;
p.handle_key(&Key::Right);
assert_eq!(p.date.month, 7);
assert_eq!(p.cursor_day, 1);
}
#[test]
fn test_picker_cursor_boundary_left() {
let mut p = datetime_picker().selected_date(Date::new(2025, 6, 1));
p.cursor_day = 1;
p.handle_key(&Key::Left);
assert_eq!(p.date.month, 5);
}
#[test]
fn test_picker_cursor_boundary_down() {
let mut p = datetime_picker().selected_date(Date::new(2025, 6, 28));
p.cursor_day = 28;
p.handle_key(&Key::Down);
assert_eq!(p.date.month, 7);
}
#[test]
fn test_picker_cursor_boundary_up() {
let mut p = datetime_picker().selected_date(Date::new(2025, 6, 3));
p.cursor_day = 3;
p.handle_key(&Key::Up);
assert_eq!(p.date.month, 5);
}
#[test]
fn test_picker_month_wrap_december() {
let mut p = datetime_picker().selected_date(Date::new(2025, 12, 15));
p.handle_key(&Key::Char(']'));
assert_eq!(p.date.month, 1);
assert_eq!(p.date.year, 2026);
}
#[test]
fn test_picker_month_wrap_january() {
let mut p = datetime_picker().selected_date(Date::new(2025, 1, 15));
p.handle_key(&Key::Char('['));
assert_eq!(p.date.month, 12);
assert_eq!(p.date.year, 2024);
}
#[test]
fn test_picker_constraint_select() {
let mut p = datetime_picker()
.selected_date(Date::new(2025, 6, 15))
.min_date(Date::new(2025, 6, 10))
.max_date(Date::new(2025, 6, 20));
p.cursor_day = 5;
p.handle_key(&Key::Enter);
assert_eq!(p.date.day, 15);
}
#[test]
fn test_time_field_navigation_wrap() {
let mut p = datetime_picker().show_seconds(true);
p.mode = DateTimeMode::Time;
p.time_field = TimeField::Second;
p.handle_key(&Key::Right);
assert_eq!(p.time_field, TimeField::Hour);
p.handle_key(&Key::Left);
assert_eq!(p.time_field, TimeField::Second);
}
#[test]
fn test_time_field_navigation_no_seconds() {
let mut p = datetime_picker().show_seconds(false);
p.mode = DateTimeMode::Time;
p.time_field = TimeField::Minute;
p.handle_key(&Key::Right);
assert_eq!(p.time_field, TimeField::Hour);
p.handle_key(&Key::Left);
assert_eq!(p.time_field, TimeField::Minute);
}