@@ -31,7 +31,7 @@ mod tests {
3131 use crate :: parse:: { get_life_chunk, parse_date, process_line, LifeChunk , LineParseResult } ;
3232
3333 #[ test]
34- fn parsing_1 ( ) {
34+ fn parsing_1_valid_datetime_string_returns_datetime ( ) {
3535 let dt = Local . ymd ( 2014 , 11 , 28 ) . and_hms ( 12 , 0 , 0 ) ;
3636 assert_eq ! (
3737 Local
@@ -42,24 +42,24 @@ mod tests {
4242 }
4343
4444 #[ test]
45- fn test_parse_date_custom_format ( ) {
45+ fn parse_date_custom_format_returns_datetime ( ) {
4646 let dt = Local . ymd ( 2023 , 10 , 26 ) . and_hms ( 14 , 30 , 0 ) ;
4747 assert_eq ! ( parse_date( "2023-10-26 14h30" ) , Some ( dt) ) ;
4848 }
4949
5050 #[ test]
51- fn test_parse_date_invalid_string ( ) {
51+ fn parse_date_invalid_string_returns_none ( ) {
5252 assert_eq ! ( parse_date( "invalid-date-string" ) , None ) ;
5353 }
5454
5555 #[ test]
56- fn test_parse_date_empty_string ( ) {
56+ fn parse_date_empty_string_returns_none ( ) {
5757 assert_eq ! ( parse_date( "" ) , None ) ;
5858 }
5959
6060 // Tests for get_life_chunk
6161 #[ test]
62- fn test_get_life_chunk_full_input ( ) {
62+ fn get_life_chunk_full_input_returns_populated_lifechunk ( ) {
6363 let line = "1 30 Meeting with team @Work @Q2" ;
6464 let lc = get_life_chunk ( line) ;
6565 assert_eq ! ( lc. description, "Meeting with team" ) ;
@@ -71,7 +71,7 @@ mod tests {
7171 }
7272
7373 #[ test]
74- fn test_get_life_chunk_missing_duration ( ) {
74+ fn get_life_chunk_missing_duration_returns_zero_duration ( ) {
7575 let line = "그냥 프로젝트 작업 @Dev" ; // "Just working on a project @Dev"
7676 let lc = get_life_chunk ( line) ;
7777 assert_eq ! ( lc. description, "작업" ) ; // Adjusted for current behavior
@@ -83,7 +83,7 @@ mod tests {
8383 }
8484
8585 #[ test]
86- fn test_get_life_chunk_missing_categories ( ) {
86+ fn get_life_chunk_missing_categories_returns_empty_categories ( ) {
8787 let line = "2 0 Quick break" ;
8888 let lc = get_life_chunk ( line) ;
8989 assert_eq ! ( lc. description, "Quick break" ) ;
@@ -95,7 +95,7 @@ mod tests {
9595 }
9696
9797 #[ test]
98- fn test_get_life_chunk_user_quadrant ( ) {
98+ fn get_life_chunk_user_quadrant_returns_parsed_quadrant ( ) {
9999 let line = "0 45 Planning session @Q1" ;
100100 let lc = get_life_chunk ( line) ;
101101 assert_eq ! ( lc. description, "Planning session" ) ;
@@ -107,7 +107,7 @@ mod tests {
107107 }
108108
109109 #[ test]
110- fn test_get_life_chunk_default_quadrant ( ) {
110+ fn get_life_chunk_no_quadrant_returns_default_quadrant ( ) {
111111 let line = "3 0 Reading a book @Leisure" ;
112112 let lc = get_life_chunk ( line) ;
113113 assert_eq ! ( lc. description, "Reading a book" ) ;
@@ -120,7 +120,7 @@ mod tests {
120120
121121 // Tests for process_line
122122 #[ test]
123- fn test_process_line_date ( ) {
123+ fn process_line_date_string_returns_date_result ( ) {
124124 let line = "2024-03-10 10:00" ;
125125 let expected_date = Local . ymd ( 2024 , 3 , 10 ) . and_hms ( 10 , 0 , 0 ) ;
126126 match process_line ( line) {
@@ -130,7 +130,7 @@ mod tests {
130130 }
131131
132132 #[ test]
133- fn test_process_line_life_chunk ( ) {
133+ fn process_line_life_chunk_string_returns_lc_result ( ) {
134134 let line = "1 0 Coding @Dev" ;
135135 match process_line ( line) {
136136 LineParseResult :: Lc { life_chunk : lc } => {
@@ -146,7 +146,7 @@ mod tests {
146146 }
147147
148148 #[ test]
149- fn test_process_line_comment ( ) {
149+ fn process_line_comment_string_returns_lc_result_with_zero_duration ( ) {
150150 let line = "# This is a comment" ;
151151 match process_line ( line) {
152152 LineParseResult :: Lc { life_chunk : lc } => {
@@ -164,7 +164,7 @@ mod tests {
164164 }
165165
166166 #[ test]
167- fn test_process_line_empty_string ( ) {
167+ fn process_line_empty_string_returns_empty_lc_result ( ) {
168168 let line = "" ;
169169 match process_line ( line) {
170170 LineParseResult :: Lc { life_chunk : lc } => {
@@ -178,6 +178,53 @@ mod tests {
178178 _ => panic ! ( "Expected LineParseResult::Lc for an empty line" ) ,
179179 }
180180 }
181+ #[ test]
182+ fn get_all_life_lapses_single_file_returns_parsed_lapses ( ) {
183+ use crate :: config:: Config ;
184+ use crate :: parse:: get_all_life_lapses;
185+
186+ let lines = vec ! [ vec![
187+ "2020-12-01 10:00" . to_string( ) ,
188+ "1 0 Task 1 @work" . to_string( ) ,
189+ "2 0 Task 2 @home" . to_string( ) ,
190+ ] ] ;
191+ let config = Config :: default ( ) ;
192+ let ( start, lapses) = get_all_life_lapses ( lines, & config) ;
193+
194+ assert_eq ! ( start, Local . ymd( 2020 , 12 , 1 ) . and_hms( 10 , 0 , 0 ) ) ;
195+ assert_eq ! ( lapses. len( ) , 1 ) ;
196+ assert_eq ! ( lapses[ 0 ] . tokens_as_ref( ) . len( ) , 2 ) ;
197+ }
198+
199+ #[ test]
200+ fn get_all_life_lapses_multiple_files_returns_merged_lapses ( ) {
201+ use crate :: config:: Config ;
202+ use crate :: parse:: get_all_life_lapses;
203+
204+ let lines = vec ! [
205+ vec![ "2020-12-01 10:00" . to_string( ) , "1 0 Task 1" . to_string( ) ] ,
206+ vec![ "2020-12-01 11:00" . to_string( ) , "1 0 Task 2" . to_string( ) ] ,
207+ ] ;
208+ let config = Config :: default ( ) ;
209+ let ( start, lapses) = get_all_life_lapses ( lines, & config) ;
210+
211+ // Start time should be the min of all start times
212+ assert_eq ! ( start, Local . ymd( 2020 , 12 , 1 ) . and_hms( 10 , 0 , 0 ) ) ;
213+ // They should be merged if compatible
214+ // 10:00 + 1h = 11:00. Second file starts at 11:00.
215+ // They are compatible and touching.
216+ assert_eq ! ( lapses. len( ) , 1 ) ;
217+ assert_eq ! ( lapses[ 0 ] . tokens_as_ref( ) . len( ) , 2 ) ;
218+ }
219+
220+ #[ test]
221+ fn get_life_chunk_extra_spaces_returns_correct_description ( ) {
222+ let line = "1 0 Task with spaces @work" ;
223+ let lc = get_life_chunk ( line) ;
224+ assert_eq ! ( lc. description, "Task with spaces" ) ;
225+ assert_eq ! ( lc. duration, Duration :: hours( 1 ) ) ;
226+ assert_eq ! ( lc. categories, vec![ "@work" . to_string( ) ] ) ;
227+ }
181228}
182229
183230/// A continuous series of life chunks.
@@ -400,7 +447,9 @@ fn parse_date(s: &str) -> Option<Timestamp> {
400447
401448pub ( crate ) fn get_life_chunk ( line : & str ) -> LifeChunk {
402449 // Made pub(crate)
403- let mut tokens = line. split ( |c : char | c == ',' || c. is_whitespace ( ) ) ;
450+ let mut tokens = line
451+ . split ( |c : char | c == ',' || c. is_whitespace ( ) )
452+ . filter ( |s| !s. is_empty ( ) ) ;
404453
405454 let mut parse_token_as_duration = |parse_as : fn ( i64 ) -> Duration | {
406455 tokens
0 commit comments