@@ -230,10 +230,118 @@ async fn test_unzip_file_non_existent() {
230230async fn test_read_file ( ) {
231231 let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
232232 let file_path = create_temp_file ( temp_dir. join ( "dir1" ) . as_path ( ) , "test.txt" , "content" ) ;
233- let content = service. read_text_file ( & file_path) . await . unwrap ( ) ;
233+ let content = service. read_text_file ( & file_path, false ) . await . unwrap ( ) ;
234234 assert_eq ! ( content, "content" ) ;
235235}
236236
237+ #[ tokio:: test]
238+ async fn test_read_text_file_with_line_numbers ( ) {
239+ let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
240+ let file_path = create_temp_file (
241+ temp_dir. join ( "dir1" ) . as_path ( ) ,
242+ "test.txt" ,
243+ "line1\n line2\n line3" ,
244+ ) ;
245+ let content = service. read_text_file ( & file_path, true ) . await . unwrap ( ) ;
246+ assert_eq ! ( content, " 1 | line1\n 2 | line2\n 3 | line3" ) ;
247+ }
248+
249+ #[ tokio:: test]
250+ async fn test_read_text_file_without_line_numbers ( ) {
251+ let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
252+ let file_path = create_temp_file (
253+ temp_dir. join ( "dir1" ) . as_path ( ) ,
254+ "test.txt" ,
255+ "line1\n line2\n line3" ,
256+ ) ;
257+ let content = service. read_text_file ( & file_path, false ) . await . unwrap ( ) ;
258+ assert_eq ! ( content, "line1\n line2\n line3" ) ;
259+ }
260+
261+ #[ tokio:: test]
262+ async fn test_read_text_file_with_line_numbers_empty_file ( ) {
263+ let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
264+ let file_path = create_temp_file ( temp_dir. join ( "dir1" ) . as_path ( ) , "empty.txt" , "" ) ;
265+ let content = service. read_text_file ( & file_path, true ) . await . unwrap ( ) ;
266+ assert_eq ! ( content, "" ) ;
267+ }
268+
269+ #[ tokio:: test]
270+ async fn test_read_text_file_with_line_numbers_single_line ( ) {
271+ let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
272+ let file_path = create_temp_file ( temp_dir. join ( "dir1" ) . as_path ( ) , "single.txt" , "single line" ) ;
273+ let content = service. read_text_file ( & file_path, true ) . await . unwrap ( ) ;
274+ assert_eq ! ( content, " 1 | single line" ) ;
275+ }
276+
277+ #[ tokio:: test]
278+ async fn test_read_text_file_with_line_numbers_no_trailing_newline ( ) {
279+ let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
280+ let file_path = create_temp_file (
281+ temp_dir. join ( "dir1" ) . as_path ( ) ,
282+ "no_newline.txt" ,
283+ "line1\n line2" ,
284+ ) ;
285+ let content = service. read_text_file ( & file_path, true ) . await . unwrap ( ) ;
286+ assert_eq ! ( content, " 1 | line1\n 2 | line2" ) ;
287+ }
288+
289+ #[ tokio:: test]
290+ async fn test_read_text_file_with_line_numbers_large_file ( ) {
291+ let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
292+ // Create a file with more than 999 lines to test padding
293+ let mut lines = Vec :: new ( ) ;
294+ for i in 1 ..=1000 {
295+ lines. push ( format ! ( "line{i}" ) ) ;
296+ }
297+ let file_content = lines. join ( "\n " ) ;
298+ let file_path = create_temp_file ( temp_dir. join ( "dir1" ) . as_path ( ) , "large.txt" , & file_content) ;
299+ let content = service. read_text_file ( & file_path, true ) . await . unwrap ( ) ;
300+
301+ // Check first line
302+ assert ! ( content. starts_with( " 1 | line1\n " ) ) ;
303+ // Check line 999
304+ assert ! ( content. contains( " 999 | line999\n " ) ) ;
305+ // Check line 1000 (6 digits with right padding)
306+ assert ! ( content. contains( " 1000 | line1000" ) ) ;
307+ }
308+
309+ #[ tokio:: test]
310+ async fn test_read_text_file_with_line_numbers_windows_line_endings ( ) {
311+ let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
312+ let file_path = create_temp_file (
313+ temp_dir. join ( "dir1" ) . as_path ( ) ,
314+ "windows.txt" ,
315+ "line1\r \n line2\r \n line3" ,
316+ ) ;
317+ let content = service. read_text_file ( & file_path, true ) . await . unwrap ( ) ;
318+ assert_eq ! ( content, " 1 | line1\n 2 | line2\n 3 | line3" ) ;
319+ }
320+
321+ #[ tokio:: test]
322+ async fn test_read_text_file_with_line_numbers_single_newline_unix ( ) {
323+ let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
324+ // A file with just "\n" is treated by lines() as having one empty line before the newline
325+ // To get two empty lines, we need "\n\n"
326+ let file_path = create_temp_file ( temp_dir. join ( "dir1" ) . as_path ( ) , "newline_unix.txt" , "\n \n " ) ;
327+ let content = service. read_text_file ( & file_path, true ) . await . unwrap ( ) ;
328+ assert_eq ! ( content, " 1 | \n 2 | " ) ;
329+ }
330+
331+ #[ tokio:: test]
332+ async fn test_read_text_file_with_line_numbers_single_newline_windows ( ) {
333+ let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
334+ // A file with just "\r\n" is treated by lines() as having one empty line
335+ // To get two empty lines, we need "\r\n\r\n"
336+ let file_path = create_temp_file (
337+ temp_dir. join ( "dir1" ) . as_path ( ) ,
338+ "newline_windows.txt" ,
339+ "\r \n \r \n " ,
340+ ) ;
341+ let content = service. read_text_file ( & file_path, true ) . await . unwrap ( ) ;
342+ assert_eq ! ( content, " 1 | \n 2 | " ) ;
343+ }
344+
237345#[ tokio:: test]
238346async fn test_create_directory ( ) {
239347 let ( temp_dir, service, _allowed_dirs) = setup_service ( vec ! [ "dir1" . to_string( ) ] ) ;
0 commit comments