Add more tests

This commit is contained in:
Dheepak Krishnamurthy 2021-02-18 00:00:11 -07:00
parent 4da96f4864
commit 6c336c472f
4 changed files with 276 additions and 31 deletions

View file

@ -41,6 +41,7 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: test
args: --all -- --test-threads=1
fmt:
name: Rustfmt

28
Cargo.lock generated
View file

@ -15,6 +15,15 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
version = "0.11.0"
@ -488,6 +497,12 @@ version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
[[package]]
name = "once_cell"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
[[package]]
name = "parking_lot"
version = "0.10.2"
@ -608,7 +623,10 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
@ -791,6 +809,7 @@ dependencies = [
"crossterm",
"itertools",
"rand",
"regex",
"rustyline",
"serde",
"serde_json",
@ -820,6 +839,15 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "thread_local"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
dependencies = [
"once_cell",
]
[[package]]
name = "time"
version = "0.1.43"

View file

@ -18,6 +18,7 @@ default = ["crossterm-backend"]
crossterm-backend = ["tui/crossterm", "crossterm"]
[dependencies]
regex = "1"
itertools = "0.9"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

View file

@ -45,6 +45,8 @@ use rustyline::Word;
use std::io;
use tui::{backend::CrosstermBackend, Terminal};
use regex::Regex;
const MAX_LINE: usize = 4096;
pub fn cmp(t1: &Task, t2: &Task) -> Ordering {
@ -675,7 +677,6 @@ impl TTApp {
break;
}
}
let selected = self.task_table_state.selected().unwrap_or_default();
let header = headers.iter();
let mut rows = vec![];
@ -1377,8 +1378,12 @@ impl TTApp {
if (reference - chrono::Duration::nanoseconds(1)).month() % 4 == now.month() % 4 {
add_tag(&mut task, "QUARTER".to_string());
}
if reference.year() == now.year() {
add_tag(&mut task, "YEAR".to_string());
}
match get_date_state(&d, self.config.due) {
DateState::EarlierToday | DateState::LaterToday => {
add_tag(&mut task, "DUE".to_string());
add_tag(&mut task, "TODAY".to_string());
add_tag(&mut task, "DUETODAY".to_string());
}
@ -1387,9 +1392,6 @@ impl TTApp {
if reference.day() == now.day() + 1 {
add_tag(&mut task, "TOMORROW".to_string());
}
if reference.year() == now.year() {
add_tag(&mut task, "YEAR".to_string());
}
}
_ => (),
}
@ -1723,6 +1725,8 @@ pub fn remove_tag(task: &mut Task, tag: String) {
#[cfg(test)]
mod tests {
use super::*;
use tui::backend::TestBackend;
use tui::buffer::Buffer;
#[test]
fn test_app() {
@ -1742,21 +1746,10 @@ mod tests {
let app = TTApp::new().unwrap();
let task = app.task_by_id(11).unwrap();
let tags = vec![
"COLOR",
"PENDING",
"ANNOTATED",
"TAGGED",
// "MONTH",
// "QUARTER",
// "DUE",
// "TOMORROW",
// "YEAR",
]
let tags = vec!["finance", "UNBLOCKED", "PENDING", "TAGGED", "UDA"]
.iter()
.map(|s| s.to_string())
.collect::<Vec<String>>();
dbg!(task.tags());
for tag in tags {
assert!(task.tags().unwrap().contains(&tag));
}
@ -1767,19 +1760,19 @@ mod tests {
let app = TTApp::new().unwrap();
let task = app.task_by_id(1).unwrap();
for r in vec![
"deleted",
"completed",
"active",
"keyword.",
"tag.",
"project.",
"overdue",
"scheduled",
"due.today",
"due",
"blocked",
"blocking",
"completed",
"deleted",
"due",
"due.today",
"keyword.",
"overdue",
"project.",
"recurring",
"scheduled",
"tag.",
"tagged",
"uda.",
] {
@ -1787,13 +1780,10 @@ mod tests {
}
let style = app.style_for_task(&task);
dbg!(style);
assert_eq!(style, Style::default().fg(Color::Indexed(2)));
let task = app.task_by_id(11).unwrap();
dbg!(task.tags().unwrap());
let style = app.style_for_task(&task);
dbg!(style);
}
#[test]
@ -1831,4 +1821,229 @@ mod tests {
assert_eq!(app.tasks.lock().unwrap().len(), 26);
assert_eq!(app.current_context_filter, "");
}
#[test]
fn test_task_tomorrow() {
let total_tasks: u64 = 26;
let mut app = TTApp::new().unwrap();
assert!(app.get_context().is_ok());
assert!(app.update().is_ok());
assert_eq!(app.tasks.lock().unwrap().len(), total_tasks as usize);
assert_eq!(app.current_context_filter, "");
let now = Local::now();
let now = TimeZone::from_utc_datetime(now.offset(), &now.naive_utc());
let mut command = Command::new("task");
command.arg("add");
let message = format!(
"'new task for testing tomorrow' due:{:04}-{:02}-{:02}",
now.year(),
now.month(),
now.day() + 1
);
let shell = message.as_str().replace("'", "\\'");
let cmd = shlex::split(&shell).unwrap();
for s in cmd {
command.arg(&s);
}
let output = command.output().unwrap();
let s = String::from_utf8_lossy(&output.stdout);
let re = Regex::new(r"^Created task (?P<task_id>\d+).\n$").unwrap();
let caps = re.captures(&s).unwrap();
let task_id = caps["task_id"].parse::<u64>().unwrap();
assert_eq!(task_id, total_tasks + 1);
assert!(app.get_context().is_ok());
assert!(app.update().is_ok());
assert_eq!(app.tasks.lock().unwrap().len(), (total_tasks + 1) as usize);
assert_eq!(app.current_context_filter, "");
let task = app.task_by_id(task_id).unwrap();
for s in &[
"DUE",
"MONTH",
"PENDING",
"QUARTER",
"TOMORROW",
"UDA",
"UNBLOCKED",
"YEAR",
] {
assert!(task.tags().unwrap().contains(&s.to_string()));
}
let output = Command::new("task")
.arg("rc.confirmation=off")
.arg("undo")
.output()
.unwrap();
let mut app = TTApp::new().unwrap();
assert!(app.get_context().is_ok());
assert!(app.update().is_ok());
assert_eq!(app.tasks.lock().unwrap().len(), total_tasks as usize);
assert_eq!(app.current_context_filter, "");
}
#[test]
fn test_task_earlier_today() {
let total_tasks: u64 = 26;
let mut app = TTApp::new().unwrap();
assert!(app.get_context().is_ok());
assert!(app.update().is_ok());
assert_eq!(app.tasks.lock().unwrap().len(), total_tasks as usize);
assert_eq!(app.current_context_filter, "");
let now = Local::now();
let now = TimeZone::from_utc_datetime(now.offset(), &now.naive_utc());
let mut command = Command::new("task");
command.arg("add");
let message = format!(
"'new task for testing earlier today' due:{:04}-{:02}-{:02}",
now.year(),
now.month(),
now.day()
);
let shell = message.as_str().replace("'", "\\'");
let cmd = shlex::split(&shell).unwrap();
for s in cmd {
command.arg(&s);
}
let output = command.output().unwrap();
let s = String::from_utf8_lossy(&output.stdout);
let re = Regex::new(r"^Created task (?P<task_id>\d+).\n$").unwrap();
let caps = re.captures(&s).unwrap();
let task_id = caps["task_id"].parse::<u64>().unwrap();
assert_eq!(task_id, total_tasks + 1);
assert!(app.get_context().is_ok());
assert!(app.update().is_ok());
assert_eq!(app.tasks.lock().unwrap().len(), (total_tasks + 1) as usize);
assert_eq!(app.current_context_filter, "");
let task = app.task_by_id(task_id).unwrap();
for s in &[
"DUE",
"DUETODAY",
"MONTH",
"OVERDUE",
"PENDING",
"QUARTER",
"TODAY",
"UDA",
"UNBLOCKED",
"YEAR",
] {
assert!(task.tags().unwrap().contains(&s.to_string()));
}
let output = Command::new("task")
.arg("rc.confirmation=off")
.arg("undo")
.output()
.unwrap();
let mut app = TTApp::new().unwrap();
assert!(app.get_context().is_ok());
assert!(app.update().is_ok());
assert_eq!(app.tasks.lock().unwrap().len(), total_tasks as usize);
assert_eq!(app.current_context_filter, "");
}
use tui::widgets::{BarChart, Block, Borders};
#[test]
fn test_draw_task_report() {
let test_case = |expected: &Buffer| {
let mut app = TTApp::new().unwrap();
app.task_report_next();
app.context_next();
let backend = TestBackend::new(50, 15);
let mut terminal = Terminal::new(backend).unwrap();
terminal
.draw(|f| {
app.draw(f);
app.draw(f);
})
.unwrap();
assert_eq!(terminal.backend().size().unwrap(), expected.area);
terminal.backend().assert_buffer(expected);
};
let mut expected = Buffer::with_lines(vec![
"╭Task|Calendar───────────────────────────────────╮",
"│ ID Age Deps P Proj Tag Due Until Descr Urg │",
"│ │",
"│• 8 4mo U Run … 23.00│",
"│ 10 4mo colo COLOR -8d … [2] 14.80│",
"╰────────────────────────────────────────────────╯",
"╭Task 8──────────────────────────────────────────╮",
"│ │",
"│Name Value │",
"│----------- ------------------------------------│",
"│ID 8 │",
"╰────────────────────────────────────────────────╯",
"╭Filter Tasks────────────────────────────────────╮",
"│status:pending -private │",
"╰────────────────────────────────────────────────╯",
]);
for i in 1..=4 {
// Task
expected
.get_mut(i, 0)
.set_style(Style::default().add_modifier(Modifier::BOLD));
}
for i in 6..=13 {
// Calendar
expected
.get_mut(i, 0)
.set_style(Style::default().add_modifier(Modifier::DIM));
}
for r in &[
1..=4, // ID
6..=8, // Age
10..=13, // Deps
15..=15, // P
17..=20, // Proj
22..=26, // Tag
28..=30, // Due
32..=36, // Until
38..=42, // Descr
44..=48, // Urg
] {
for i in r.clone().into_iter() {
expected
.get_mut(i, 1)
.set_style(Style::default().add_modifier(Modifier::UNDERLINED));
}
}
for i in 1..expected.area().width - 1 {
expected.get_mut(i, 3).set_style(
Style::default()
.fg(Color::Indexed(0))
.bg(Color::Indexed(15))
.add_modifier(Modifier::BOLD),
);
}
for i in 1..expected.area().width - 1 {
expected
.get_mut(i, 4)
.set_style(Style::default().fg(Color::Indexed(9)).bg(Color::Indexed(4)));
}
test_case(&expected);
}
}