max / goingson
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
- Claude-Session
- https://claude.ai/code/session_01WFBzMprSmNCfvdj2cGZyka
2 files changed,
+57 insertions,
-60 deletions
| @@ -1048,63 +1048,3 @@ | |||
| 1048 | 1048 | ||
| 1049 | 1049 | #[cfg(test)] | |
| 1050 | 1050 | mod tests; | |
| 1051 | - | ||
| 1052 | - | #[cfg(test)] | |
| 1053 | - | mod split_description_tests { | |
| 1054 | - | use super::{MAX_TITLE_LEN, split_description}; | |
| 1055 | - | ||
| 1056 | - | #[test] | |
| 1057 | - | fn a_short_single_line_is_all_title() { | |
| 1058 | - | let (title, body) = split_description("Fix the bug"); | |
| 1059 | - | assert_eq!(title, "Fix the bug"); | |
| 1060 | - | assert_eq!(body, "", "a one-line task has no detail to show"); | |
| 1061 | - | } | |
| 1062 | - | ||
| 1063 | - | #[test] | |
| 1064 | - | fn the_first_line_becomes_the_title_and_the_rest_the_body() { | |
| 1065 | - | let (title, body) = split_description("Ship the release\n\nTag it, then push tags."); | |
| 1066 | - | assert_eq!(title, "Ship the release"); | |
| 1067 | - | assert_eq!(body, "Tag it, then push tags."); | |
| 1068 | - | } | |
| 1069 | - | ||
| 1070 | - | #[test] | |
| 1071 | - | fn a_long_first_line_truncates_on_a_word_boundary() { | |
| 1072 | - | let first = "Walk the human_todo sign-off table on the live server and record every row that still fails"; | |
| 1073 | - | let (title, body) = split_description(first); | |
| 1074 | - | assert!(title.chars().count() <= MAX_TITLE_LEN); | |
| 1075 | - | assert!(title.ends_with("...")); | |
| 1076 | - | assert!( | |
| 1077 | - | !title.trim_end_matches("...").ends_with(char::is_whitespace), | |
| 1078 | - | "no dangling space before the ellipsis: {title:?}" | |
| 1079 | - | ); | |
| 1080 | - | assert!( | |
| 1081 | - | first.starts_with(title.trim_end_matches("...")), | |
| 1082 | - | "the title is a prefix of the text it summarizes" | |
| 1083 | - | ); | |
| 1084 | - | assert_eq!(body, first, "truncating must not lose the tail"); | |
| 1085 | - | } | |
| 1086 | - | ||
| 1087 | - | #[test] | |
| 1088 | - | fn a_single_unbreakable_word_still_yields_a_title() { | |
| 1089 | - | let word = "x".repeat(MAX_TITLE_LEN * 2); | |
| 1090 | - | let (title, body) = split_description(&word); | |
| 1091 | - | assert_eq!(title.chars().count(), MAX_TITLE_LEN); | |
| 1092 | - | assert!(title.ends_with("...")); | |
| 1093 | - | assert_eq!(body, word); | |
| 1094 | - | } | |
| 1095 | - | ||
| 1096 | - | #[test] | |
| 1097 | - | fn a_title_of_exactly_the_limit_is_not_truncated() { | |
| 1098 | - | let exact = "y".repeat(MAX_TITLE_LEN); | |
| 1099 | - | let (title, body) = split_description(&exact); | |
| 1100 | - | assert_eq!(title, exact); | |
| 1101 | - | assert_eq!(body, ""); | |
| 1102 | - | } | |
| 1103 | - | ||
| 1104 | - | #[test] | |
| 1105 | - | fn surrounding_whitespace_is_not_carried_into_either_field() { | |
| 1106 | - | let (title, body) = split_description("\n Trim me \n\n body text\n\n"); | |
| 1107 | - | assert_eq!(title, "Trim me"); | |
| 1108 | - | assert_eq!(body, "body text"); | |
| 1109 | - | } | |
| 1110 | - | } |
| @@ -417,3 +417,60 @@ | |||
| 417 | 417 | .build(); | |
| 418 | 418 | assert_eq!(nt.tags, vec!["x".to_string(), "y".to_string()]); | |
| 419 | 419 | } | |
| 420 | + | ||
| 421 | + | // ── split_description ── | |
| 422 | + | ||
| 423 | + | #[test] | |
| 424 | + | fn a_short_single_line_is_all_title() { | |
| 425 | + | let (title, body) = split_description("Fix the bug"); | |
| 426 | + | assert_eq!(title, "Fix the bug"); | |
| 427 | + | assert_eq!(body, "", "a one-line task has no detail to show"); | |
| 428 | + | } | |
| 429 | + | ||
| 430 | + | #[test] | |
| 431 | + | fn the_first_line_becomes_the_title_and_the_rest_the_body() { | |
| 432 | + | let (title, body) = split_description("Ship the release\n\nTag it, then push tags."); | |
| 433 | + | assert_eq!(title, "Ship the release"); | |
| 434 | + | assert_eq!(body, "Tag it, then push tags."); | |
| 435 | + | } | |
| 436 | + | ||
| 437 | + | #[test] | |
| 438 | + | fn a_long_first_line_truncates_on_a_word_boundary() { | |
| 439 | + | let first = "Walk the human_todo sign-off table on the live server and record every row that still fails"; | |
| 440 | + | let (title, body) = split_description(first); | |
| 441 | + | assert!(title.chars().count() <= MAX_TITLE_LEN); | |
| 442 | + | assert!(title.ends_with("...")); | |
| 443 | + | assert!( | |
| 444 | + | !title.trim_end_matches("...").ends_with(char::is_whitespace), | |
| 445 | + | "no dangling space before the ellipsis: {title:?}" | |
| 446 | + | ); | |
| 447 | + | assert!( | |
| 448 | + | first.starts_with(title.trim_end_matches("...")), | |
| 449 | + | "the title is a prefix of the text it summarizes" | |
| 450 | + | ); | |
| 451 | + | assert_eq!(body, first, "truncating must not lose the tail"); | |
| 452 | + | } | |
| 453 | + | ||
| 454 | + | #[test] | |
| 455 | + | fn a_single_unbreakable_word_still_yields_a_title() { | |
| 456 | + | let word = "x".repeat(MAX_TITLE_LEN * 2); | |
| 457 | + | let (title, body) = split_description(&word); | |
| 458 | + | assert_eq!(title.chars().count(), MAX_TITLE_LEN); | |
| 459 | + | assert!(title.ends_with("...")); | |
| 460 | + | assert_eq!(body, word); | |
| 461 | + | } | |
| 462 | + | ||
| 463 | + | #[test] | |
| 464 | + | fn a_title_of_exactly_the_limit_is_not_truncated() { | |
| 465 | + | let exact = "y".repeat(MAX_TITLE_LEN); | |
| 466 | + | let (title, body) = split_description(&exact); | |
| 467 | + | assert_eq!(title, exact); | |
| 468 | + | assert_eq!(body, ""); | |
| 469 | + | } | |
| 470 | + | ||
| 471 | + | #[test] | |
| 472 | + | fn surrounding_whitespace_is_not_carried_into_either_field() { | |
| 473 | + | let (title, body) = split_description("\n Trim me \n\n body text\n\n"); | |
| 474 | + | assert_eq!(title, "Trim me"); | |
| 475 | + | assert_eq!(body, "body text"); | |
| 476 | + | } |