mirror of
https://github.com/kdheepak/taskwarrior-tui.git
synced 2025-08-24 05:26:42 +02:00
fix: Disable event loop for testing 🐛
This commit is contained in:
parent
ad3a88aed2
commit
3ffa5bdc77
3 changed files with 109 additions and 86 deletions
76
src/app.rs
76
src/app.rs
|
@ -238,7 +238,7 @@ pub struct TaskwarriorTui {
|
|||
}
|
||||
|
||||
impl TaskwarriorTui {
|
||||
pub async fn new(report: &str) -> Result<Self> {
|
||||
pub async fn new(report: &str, init_event_loop: bool) -> Result<Self> {
|
||||
let output = std::process::Command::new("task")
|
||||
.arg("rc.color=off")
|
||||
.arg("rc._forcecolor=off")
|
||||
|
@ -280,7 +280,7 @@ impl TaskwarriorTui {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
let event_loop = crate::event::EventLoop::new(tick_rate);
|
||||
let event_loop = crate::event::EventLoop::new(tick_rate, init_event_loop);
|
||||
|
||||
let mut app = Self {
|
||||
should_quit: false,
|
||||
|
@ -372,7 +372,14 @@ impl TaskwarriorTui {
|
|||
|
||||
pub async fn abort_event_loop(&mut self) -> Result<()> {
|
||||
self.event_loop.abort.send(())?;
|
||||
self.event_loop.handle.abort();
|
||||
loop {
|
||||
if let Some(event) = self.next().await {
|
||||
match event {
|
||||
Event::Closed => break,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -382,7 +389,7 @@ impl TaskwarriorTui {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
self.event_loop = crate::event::EventLoop::new(tick_rate);
|
||||
self.event_loop = crate::event::EventLoop::new(tick_rate, true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -418,6 +425,9 @@ impl TaskwarriorTui {
|
|||
debug!("Tick event");
|
||||
self.update(false).await?;
|
||||
}
|
||||
Event::Closed => {
|
||||
debug!("Event loop closed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3782,7 +3792,7 @@ mod tests {
|
|||
}
|
||||
|
||||
async fn test_taskwarrior_tui_history() {
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
// setup();
|
||||
app.mode = Mode::Tasks(Action::Add);
|
||||
app.update_completion_list();
|
||||
|
@ -3857,9 +3867,17 @@ mod tests {
|
|||
// teardown();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
|
||||
async fn test_taskwarrior_tui() {
|
||||
let app = TaskwarriorTui::new("next").await;
|
||||
#[test]
|
||||
fn test_taskwarrior_tui() {
|
||||
let r = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap()
|
||||
.block_on(async { _test_taskwarrior_tui().await });
|
||||
}
|
||||
|
||||
async fn _test_taskwarrior_tui() {
|
||||
let app = TaskwarriorTui::new("next", false).await;
|
||||
if app.is_err() {
|
||||
return;
|
||||
}
|
||||
|
@ -3867,7 +3885,7 @@ mod tests {
|
|||
|
||||
assert!(app.task_by_index(0).is_none(), "Expected task data to be empty but found {} tasks. Delete contents of {:?} and {:?} and run the tests again.", app.tasks.len(), Path::new(env!("TASKDATA")), Path::new(env!("TASKDATA")).parent().unwrap().join(".config"));
|
||||
|
||||
let app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
assert!(app
|
||||
.task_by_uuid(Uuid::parse_str("3f43831b-88dc-45e2-bf0d-4aea6db634cc").unwrap())
|
||||
.is_none());
|
||||
|
@ -3879,10 +3897,10 @@ mod tests {
|
|||
|
||||
setup();
|
||||
|
||||
let app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
assert!(app.task_by_index(0).is_some());
|
||||
|
||||
let app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
assert!(app
|
||||
.task_by_uuid(Uuid::parse_str("3f43831b-88dc-45e2-bf0d-4aea6db634cc").unwrap())
|
||||
.is_some());
|
||||
|
@ -3902,7 +3920,7 @@ mod tests {
|
|||
|
||||
async fn test_task_tags() {
|
||||
// testing tags
|
||||
let app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
let task = app.task_by_id(1).unwrap();
|
||||
|
||||
let tags = vec!["PENDING".to_string(), "PRIORITY".to_string()];
|
||||
|
@ -3911,7 +3929,7 @@ mod tests {
|
|||
assert!(task.tags().unwrap().contains(&tag));
|
||||
}
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
let task = app.task_by_id(11).unwrap();
|
||||
let tags = vec!["finance", "UNBLOCKED", "PENDING", "TAGGED", "UDA"]
|
||||
.iter()
|
||||
|
@ -3954,7 +3972,7 @@ mod tests {
|
|||
}
|
||||
|
||||
async fn test_task_style() {
|
||||
let app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
let task = app.task_by_id(1).unwrap();
|
||||
for r in vec![
|
||||
"active",
|
||||
|
@ -3984,7 +4002,7 @@ mod tests {
|
|||
}
|
||||
|
||||
async fn test_task_context() {
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
|
||||
assert!(app.update(true).await.is_ok());
|
||||
|
||||
|
@ -4019,7 +4037,7 @@ mod tests {
|
|||
async fn test_task_tomorrow() {
|
||||
let total_tasks: u64 = 26;
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
assert!(app.update(true).await.is_ok());
|
||||
assert_eq!(app.tasks.len(), total_tasks as usize);
|
||||
assert_eq!(app.current_context_filter, "");
|
||||
|
@ -4077,7 +4095,7 @@ mod tests {
|
|||
.output()
|
||||
.unwrap();
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
assert!(app.update(true).await.is_ok());
|
||||
assert_eq!(app.tasks.len(), total_tasks as usize);
|
||||
assert_eq!(app.current_context_filter, "");
|
||||
|
@ -4086,7 +4104,7 @@ mod tests {
|
|||
async fn test_task_earlier_today() {
|
||||
let total_tasks: u64 = 26;
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
assert!(app.update(true).await.is_ok());
|
||||
assert_eq!(app.tasks.len(), total_tasks as usize);
|
||||
assert_eq!(app.current_context_filter, "");
|
||||
|
@ -4136,7 +4154,7 @@ mod tests {
|
|||
.output()
|
||||
.unwrap();
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
assert!(app.update(true).await.is_ok());
|
||||
assert_eq!(app.tasks.len(), total_tasks as usize);
|
||||
assert_eq!(app.current_context_filter, "");
|
||||
|
@ -4145,7 +4163,7 @@ mod tests {
|
|||
async fn test_task_later_today() {
|
||||
let total_tasks: u64 = 26;
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
assert!(app.update(true).await.is_ok());
|
||||
assert_eq!(app.tasks.len(), total_tasks as usize);
|
||||
assert_eq!(app.current_context_filter, "");
|
||||
|
@ -4202,7 +4220,7 @@ mod tests {
|
|||
.output()
|
||||
.unwrap();
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
assert!(app.update(true).await.is_ok());
|
||||
assert_eq!(app.tasks.len(), total_tasks as usize);
|
||||
assert_eq!(app.current_context_filter, "");
|
||||
|
@ -4248,7 +4266,7 @@ mod tests {
|
|||
.set_style(Style::default().add_modifier(Modifier::REVERSED));
|
||||
}
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
|
||||
app.task_report_next();
|
||||
app.context_next();
|
||||
|
@ -4308,7 +4326,7 @@ mod tests {
|
|||
.set_style(Style::default().add_modifier(Modifier::REVERSED));
|
||||
}
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
|
||||
let total_tasks: u64 = 26;
|
||||
|
||||
|
@ -4513,7 +4531,7 @@ mod tests {
|
|||
.set_style(Style::default().fg(Color::Indexed(1)).bg(Color::Indexed(4)));
|
||||
}
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
|
||||
app.task_report_next();
|
||||
app.context_next();
|
||||
|
@ -4659,7 +4677,7 @@ mod tests {
|
|||
.set_style(Style::default().bg(Color::Reset).add_modifier(Modifier::UNDERLINED));
|
||||
}
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
|
||||
app.task_report_next();
|
||||
app.context_next();
|
||||
|
@ -4704,7 +4722,7 @@ mod tests {
|
|||
.set_style(Style::default().add_modifier(Modifier::BOLD));
|
||||
}
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
|
||||
app.mode = Mode::Tasks(Action::HelpPopup);
|
||||
app.task_report_next();
|
||||
|
@ -4773,7 +4791,7 @@ mod tests {
|
|||
.set_style(Style::default().add_modifier(Modifier::BOLD));
|
||||
}
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
|
||||
app.mode = Mode::Tasks(Action::ContextMenu);
|
||||
app.task_report_next();
|
||||
|
@ -4798,7 +4816,7 @@ mod tests {
|
|||
dbg!(UnicodeWidthStr::width("写作业"));
|
||||
dbg!(UnicodeWidthStr::width("abc"));
|
||||
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
|
||||
if let Some(task) = app.task_by_id(27) {
|
||||
let i = app.task_index_by_uuid(*task.uuid()).unwrap_or_default();
|
||||
|
@ -4827,7 +4845,7 @@ mod tests {
|
|||
|
||||
// #[test]
|
||||
async fn test_taskwarrior_tui_completion() {
|
||||
let mut app = TaskwarriorTui::new("next").await.unwrap();
|
||||
let mut app = TaskwarriorTui::new("next", false).await.unwrap();
|
||||
app.handle_input(KeyCode::Char('z')).await.unwrap();
|
||||
app.mode = Mode::Tasks(Action::Add);
|
||||
app.update_completion_list();
|
||||
|
|
17
src/event.rs
17
src/event.rs
|
@ -15,6 +15,7 @@ use crossterm::event::{
|
|||
pub enum Event<I> {
|
||||
Input(I),
|
||||
Tick,
|
||||
Closed,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, PartialOrd, Eq)]
|
||||
|
@ -48,27 +49,31 @@ pub struct EventLoop {
|
|||
pub rx: mpsc::UnboundedReceiver<Event<KeyCode>>,
|
||||
pub tx: mpsc::UnboundedSender<Event<KeyCode>>,
|
||||
pub abort: mpsc::UnboundedSender<()>,
|
||||
pub handle: JoinHandle<()>,
|
||||
pub tick_rate: std::time::Duration,
|
||||
}
|
||||
|
||||
impl EventLoop {
|
||||
pub fn new(tick_rate: Option<std::time::Duration>) -> Self {
|
||||
pub fn new(tick_rate: Option<std::time::Duration>, init: bool) -> Self {
|
||||
let (tx, rx) = mpsc::unbounded_channel();
|
||||
let _tx = tx.clone();
|
||||
let mut reader = crossterm::event::EventStream::new();
|
||||
let should_tick = tick_rate.is_some();
|
||||
let tick_rate = tick_rate.unwrap_or(std::time::Duration::from_millis(250));
|
||||
|
||||
let (abort, mut recv) = mpsc::unbounded_channel();
|
||||
let (abort, mut abort_recv) = mpsc::unbounded_channel();
|
||||
|
||||
let handle = tokio::spawn(async move {
|
||||
if init {
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
let delay = tokio::time::sleep(tick_rate);
|
||||
let event = reader.next();
|
||||
|
||||
tokio::select! {
|
||||
_ = recv.recv() => break,
|
||||
_ = abort_recv.recv() => {
|
||||
_tx.send(Event::Closed).unwrap();
|
||||
_tx.send(Event::Tick).unwrap();
|
||||
break;
|
||||
},
|
||||
_ = delay, if should_tick => {
|
||||
_tx.send(Event::Tick).unwrap();
|
||||
},
|
||||
|
@ -118,11 +123,11 @@ impl EventLoop {
|
|||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Self {
|
||||
tx,
|
||||
rx,
|
||||
handle,
|
||||
tick_rate,
|
||||
abort,
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ async fn tui_main(report: &str) -> Result<()> {
|
|||
better_panic::Settings::auto().create_panic_handler()(panic_info);
|
||||
}));
|
||||
|
||||
let mut app = app::TaskwarriorTui::new(report).await?;
|
||||
let mut app = app::TaskwarriorTui::new(report, true).await?;
|
||||
|
||||
let mut terminal = app.start_tui().await?;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue