Skip to content

Commit 6efe29a

Browse files
committed
fix ut
1 parent 35a1290 commit 6efe29a

File tree

1 file changed

+115
-21
lines changed

1 file changed

+115
-21
lines changed

crates/chat-cli/src/cli/chat/tools/fs_read.rs

Lines changed: 115 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -717,28 +717,49 @@ mod tests {
717717

718718
#[test]
719719
fn test_fs_read_deser() {
720-
serde_json::from_value::<FsRead>(serde_json::json!({ "path": "/test_file.txt", "mode": "Line" })).unwrap();
720+
// Test single operations (wrapped in operations array)
721721
serde_json::from_value::<FsRead>(
722-
serde_json::json!({ "path": "/test_file.txt", "mode": "Line", "end_line": 5 }),
722+
serde_json::json!({ "operations": [{ "path": "/test_file.txt", "mode": "Line" }] }),
723723
)
724724
.unwrap();
725725
serde_json::from_value::<FsRead>(
726-
serde_json::json!({ "path": "/test_file.txt", "mode": "Line", "start_line": -1 }),
726+
serde_json::json!({ "operations": [{ "path": "/test_file.txt", "mode": "Line", "end_line": 5 }] }),
727727
)
728728
.unwrap();
729729
serde_json::from_value::<FsRead>(
730-
serde_json::json!({ "path": "/test_file.txt", "mode": "Line", "start_line": None::<usize> }),
730+
serde_json::json!({ "operations": [{ "path": "/test_file.txt", "mode": "Line", "start_line": -1 }] }),
731731
)
732732
.unwrap();
733-
serde_json::from_value::<FsRead>(serde_json::json!({ "path": "/", "mode": "Directory" })).unwrap();
734733
serde_json::from_value::<FsRead>(
735-
serde_json::json!({ "path": "/test_file.txt", "mode": "Directory", "depth": 2 }),
734+
serde_json::json!({ "operations": [{ "path": "/test_file.txt", "mode": "Line", "start_line": None::<usize> }] }),
736735
)
737736
.unwrap();
737+
serde_json::from_value::<FsRead>(serde_json::json!({ "operations": [{ "path": "/", "mode": "Directory" }] }))
738+
.unwrap();
738739
serde_json::from_value::<FsRead>(
739-
serde_json::json!({ "path": "/test_file.txt", "mode": "Search", "pattern": "hello" }),
740+
serde_json::json!({ "operations": [{ "path": "/test_file.txt", "mode": "Directory", "depth": 2 }] }),
740741
)
741742
.unwrap();
743+
serde_json::from_value::<FsRead>(
744+
serde_json::json!({ "operations": [{ "path": "/test_file.txt", "mode": "Search", "pattern": "hello" }] }),
745+
)
746+
.unwrap();
747+
serde_json::from_value::<FsRead>(serde_json::json!({
748+
"operations": [{ "image_paths": ["/img1.png", "/img2.jpg"], "mode": "Image" }]
749+
}))
750+
.unwrap();
751+
752+
// Test mixed batch operations
753+
serde_json::from_value::<FsRead>(serde_json::json!({
754+
"operations": [
755+
{ "path": "/file.txt", "mode": "Line" },
756+
{ "path": "/dir", "mode": "Directory", "depth": 1 },
757+
{ "path": "/log.txt", "mode": "Search", "pattern": "warning" },
758+
{ "image_paths": ["/photo.jpg"], "mode": "Image" }
759+
],
760+
"purpose": "Comprehensive file analysis"
761+
}))
762+
.unwrap();
742763
}
743764

744765
#[tokio::test]
@@ -750,10 +771,11 @@ mod tests {
750771
macro_rules! assert_lines {
751772
($start_line:expr, $end_line:expr, $expected:expr) => {
752773
let v = serde_json::json!({
774+
"operations": [{
753775
"path": TEST_FILE_PATH,
754776
"mode": "Line",
755777
"start_line": $start_line,
756-
"end_line": $end_line,
778+
"end_line": $end_line,}]
757779
});
758780
let output = serde_json::from_value::<FsRead>(v)
759781
.unwrap()
@@ -783,11 +805,11 @@ mod tests {
783805
let os = setup_test_directory().await;
784806
let mut stdout = std::io::stdout();
785807
let v = serde_json::json!({
808+
"operations": [{
786809
"path": TEST_FILE_PATH,
787810
"mode": "Line",
788811
"start_line": 100,
789-
"end_line": None::<i32>,
790-
});
812+
"end_line": None::<i32>,}]});
791813
assert!(
792814
serde_json::from_value::<FsRead>(v)
793815
.unwrap()
@@ -818,9 +840,10 @@ mod tests {
818840

819841
// Testing without depth
820842
let v = serde_json::json!({
843+
"operations": [{
821844
"mode": "Directory",
822845
"path": "/",
823-
});
846+
}]});
824847
let output = serde_json::from_value::<FsRead>(v)
825848
.unwrap()
826849
.invoke(&os, &mut stdout)
@@ -835,9 +858,10 @@ mod tests {
835858

836859
// Testing with depth level 1
837860
let v = serde_json::json!({
861+
"operations": [{
838862
"mode": "Directory",
839863
"path": "/",
840-
"depth": 1,
864+
"depth": 1,}]
841865
});
842866
let output = serde_json::from_value::<FsRead>(v)
843867
.unwrap()
@@ -880,9 +904,10 @@ mod tests {
880904
}
881905

882906
let matches = invoke_search!({
907+
"operations": [{
883908
"mode": "Search",
884909
"path": TEST_FILE_PATH,
885-
"pattern": "hello",
910+
"pattern": "hello",}]
886911
});
887912
assert_eq!(matches.len(), 2);
888913
assert_eq!(matches[0].line_number, 1);
@@ -907,8 +932,9 @@ mod tests {
907932
os.fs.write(binary_file_path, &binary_data).await.unwrap();
908933

909934
let v = serde_json::json!({
935+
"operations": [{
910936
"path": binary_file_path,
911-
"mode": "Line"
937+
"mode": "Line"}]
912938
});
913939
let output = serde_json::from_value::<FsRead>(v)
914940
.unwrap()
@@ -938,8 +964,9 @@ mod tests {
938964
os.fs.write(latin1_file_path, &latin1_data).await.unwrap();
939965

940966
let v = serde_json::json!({
967+
"operations": [{
941968
"path": latin1_file_path,
942-
"mode": "Line"
969+
"mode": "Line"}]
943970
});
944971
let output = serde_json::from_value::<FsRead>(v)
945972
.unwrap()
@@ -973,9 +1000,10 @@ mod tests {
9731000
os.fs.write(mixed_file_path, &mixed_data).await.unwrap();
9741001

9751002
let v = serde_json::json!({
1003+
"operations": [{
9761004
"mode": "Search",
9771005
"path": mixed_file_path,
978-
"pattern": "hello"
1006+
"pattern": "hello"}]
9791007
});
9801008
let output = serde_json::from_value::<FsRead>(v)
9811009
.unwrap()
@@ -996,9 +1024,10 @@ mod tests {
9961024
}
9971025

9981026
let v = serde_json::json!({
1027+
"operations": [{
9991028
"mode": "Search",
10001029
"path": mixed_file_path,
1001-
"pattern": "goodbye"
1030+
"pattern": "goodbye"}]
10021031
});
10031032
let output = serde_json::from_value::<FsRead>(v)
10041033
.unwrap()
@@ -1033,8 +1062,9 @@ mod tests {
10331062
os.fs.write(windows1252_file_path, &windows1252_data).await.unwrap();
10341063

10351064
let v = serde_json::json!({
1065+
"operations": [{
10361066
"path": windows1252_file_path,
1037-
"mode": "Line"
1067+
"mode": "Line"}]
10381068
});
10391069
let output = serde_json::from_value::<FsRead>(v)
10401070
.unwrap()
@@ -1071,9 +1101,10 @@ mod tests {
10711101
.unwrap();
10721102

10731103
let v = serde_json::json!({
1104+
"operations": [{
10741105
"mode": "Search",
10751106
"path": invalid_utf8_file_path,
1076-
"pattern": "caf"
1107+
"pattern": "caf"}]
10771108
});
10781109
let output = serde_json::from_value::<FsRead>(v)
10791110
.unwrap()
@@ -1101,8 +1132,9 @@ mod tests {
11011132
os.fs.write(invalid_only_file_path, &invalid_only_data).await.unwrap();
11021133

11031134
let v = serde_json::json!({
1135+
"operations": [{
11041136
"path": invalid_only_file_path,
1105-
"mode": "Line"
1137+
"mode": "Line"}]
11061138
});
11071139
let output = serde_json::from_value::<FsRead>(v)
11081140
.unwrap()
@@ -1118,9 +1150,10 @@ mod tests {
11181150
}
11191151

11201152
let v = serde_json::json!({
1153+
"operations": [{
11211154
"mode": "Search",
11221155
"path": invalid_only_file_path,
1123-
"pattern": "test"
1156+
"pattern": "test"}]
11241157
});
11251158
let output = serde_json::from_value::<FsRead>(v)
11261159
.unwrap()
@@ -1139,4 +1172,65 @@ mod tests {
11391172
panic!("expected Text output");
11401173
}
11411174
}
1175+
1176+
#[tokio::test]
1177+
async fn test_fs_read_batch_mixed_operations() {
1178+
let os = setup_test_directory().await;
1179+
let mut stdout = Vec::new();
1180+
1181+
let v = serde_json::json!({
1182+
"operations": [
1183+
{ "path": TEST_FILE_PATH, "mode": "Line", "start_line": 1, "end_line": 2 },
1184+
{ "path": "/", "mode": "Directory" },
1185+
{ "path": TEST_FILE_PATH, "mode": "Search", "pattern": "hello" }
1186+
],
1187+
"purpose": "Test mixed text operations"
1188+
});
1189+
1190+
let output = serde_json::from_value::<FsRead>(v)
1191+
.unwrap()
1192+
.invoke(&os, &mut stdout)
1193+
.await
1194+
.unwrap();
1195+
print!("output {:?}", output);
1196+
// All text operations should return combined text
1197+
if let OutputKind::Text(text) = output.output {
1198+
// Check all operations are included
1199+
assert!(text.contains("=== Operation 1 Result (Text) ==="));
1200+
assert!(text.contains("=== Operation 2 Result (Text) ==="));
1201+
assert!(text.contains("=== Operation 3 Result (Text) ==="));
1202+
1203+
// Check operation 1 (Line mode)
1204+
assert!(text.contains("Hello world!"));
1205+
assert!(text.contains("This is line 2"));
1206+
1207+
// Check operation 2 (Directory mode)
1208+
assert!(text.contains("test_file.txt"));
1209+
1210+
// Check operation 3 (Search mode)
1211+
assert!(text.contains("\"line_number\":1"));
1212+
} else {
1213+
panic!("expected text output for batch operations");
1214+
}
1215+
}
1216+
#[tokio::test]
1217+
async fn test_fs_read_empty_operations() {
1218+
let os = Os::new().await.unwrap();
1219+
1220+
// Test empty operations array
1221+
let v = serde_json::json!({
1222+
"operations": []
1223+
});
1224+
1225+
let mut fs_read = serde_json::from_value::<FsRead>(v).unwrap();
1226+
let result = fs_read.validate(&os).await;
1227+
1228+
assert!(result.is_err());
1229+
assert!(
1230+
result
1231+
.unwrap_err()
1232+
.to_string()
1233+
.contains("At least one operation must be provided")
1234+
);
1235+
}
11421236
}

0 commit comments

Comments
 (0)