63_smoother-todo-editing #73
1 changed files with 127 additions and 0 deletions
|
|
@ -170,6 +170,26 @@ pub fn run() -> Result<(), StreamdError> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use chrono::{Duration, TimeZone};
|
||||
use indexmap::IndexMap;
|
||||
|
||||
fn make_task_shard(moment: chrono::DateTime<Utc>, file: &str) -> LocalizedShard {
|
||||
let mut location = IndexMap::new();
|
||||
location.insert("file".to_string(), file.to_string());
|
||||
location.insert("task".to_string(), "open".to_string());
|
||||
|
||||
LocalizedShard {
|
||||
markers: vec!["Task".to_string()],
|
||||
tags: vec![],
|
||||
start_line: 1,
|
||||
end_line: 1,
|
||||
moment,
|
||||
location,
|
||||
children: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_insert_done_after_task() {
|
||||
let line = "Some content @Task with more text";
|
||||
|
|
@ -184,6 +204,13 @@ mod tests {
|
|||
assert_eq!(result, "Some content @Task @Done");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_insert_done_only_first_task() {
|
||||
let line = "Some @Task content @Task again";
|
||||
let result = line.replacen("@Task", "@Task @Done", 1);
|
||||
assert_eq!(result, "Some @Task @Done content @Task again");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_task_count_single() {
|
||||
let line = "Some content @Task with more text";
|
||||
|
|
@ -201,4 +228,104 @@ mod tests {
|
|||
let line = "Some content without task marker";
|
||||
assert_eq!(line.matches("@Task").count(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filter_future_tasks_excludes_future_when_show_future_false() {
|
||||
let now = Utc::now();
|
||||
let past = now - Duration::hours(1);
|
||||
let future = now + Duration::hours(1);
|
||||
|
||||
let tasks = vec![
|
||||
make_task_shard(past, "past.md"),
|
||||
make_task_shard(future, "future.md"),
|
||||
];
|
||||
|
||||
let filtered: Vec<_> = tasks
|
||||
.into_iter()
|
||||
.filter(|shard| shard.moment <= now)
|
||||
.collect();
|
||||
|
||||
assert_eq!(filtered.len(), 1);
|
||||
assert_eq!(filtered[0].location.get("file").unwrap(), "past.md");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filter_future_tasks_includes_all_when_show_future_true() {
|
||||
let now = Utc::now();
|
||||
let past = now - Duration::hours(1);
|
||||
let future = now + Duration::hours(1);
|
||||
|
||||
let tasks = vec![
|
||||
make_task_shard(past, "past.md"),
|
||||
make_task_shard(future, "future.md"),
|
||||
];
|
||||
|
||||
let filtered: Vec<_> = tasks.into_iter().filter(|_| true).collect();
|
||||
|
||||
assert_eq!(filtered.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort_tasks_by_moment_ascending() {
|
||||
let oldest = Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap();
|
||||
let middle = Utc.with_ymd_and_hms(2021, 1, 1, 0, 0, 0).unwrap();
|
||||
let newest = Utc.with_ymd_and_hms(2022, 1, 1, 0, 0, 0).unwrap();
|
||||
|
||||
let mut tasks = vec![
|
||||
make_task_shard(newest, "newest.md"),
|
||||
make_task_shard(oldest, "oldest.md"),
|
||||
make_task_shard(middle, "middle.md"),
|
||||
];
|
||||
|
||||
tasks.sort_by(|a, b| a.moment.cmp(&b.moment));
|
||||
|
||||
assert_eq!(tasks[0].location.get("file").unwrap(), "oldest.md");
|
||||
assert_eq!(tasks[1].location.get("file").unwrap(), "middle.md");
|
||||
assert_eq!(tasks[2].location.get("file").unwrap(), "newest.md");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_preserve_trailing_newline() {
|
||||
let content_with_newline = "line1\nline2\n";
|
||||
let content_without_newline = "line1\nline2";
|
||||
|
||||
assert!(content_with_newline.ends_with('\n'));
|
||||
assert!(!content_without_newline.ends_with('\n'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_task_number_zero() {
|
||||
let result = StreamdError::InvalidTaskNumber(0, 5);
|
||||
assert_eq!(
|
||||
result.to_string(),
|
||||
"Invalid task number 0: only 5 tasks available"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_task_number_exceeds_count() {
|
||||
let result = StreamdError::InvalidTaskNumber(10, 3);
|
||||
assert_eq!(
|
||||
result.to_string(),
|
||||
"Invalid task number 10: only 3 tasks available"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_task_markers_error_message() {
|
||||
let result = StreamdError::MultipleTaskMarkers("/path/file.md".to_string(), 42);
|
||||
assert_eq!(
|
||||
result.to_string(),
|
||||
"Multiple @Task markers found in /path/file.md:42 - cannot auto-insert @Done"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_task_marker_error_message() {
|
||||
let result = StreamdError::NoTaskMarker("/path/file.md".to_string(), 42);
|
||||
assert_eq!(
|
||||
result.to_string(),
|
||||
"No @Task marker found in /path/file.md:42"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue