1mod go_locator {
2 use collections::HashMap;
3 use dap::{DapLocator, adapters::DebugAdapterName};
4 use gpui::TestAppContext;
5 use project::debugger::locators::go::{DelveLaunchRequest, GoLocator};
6 use task::{HideStrategy, RevealStrategy, RevealTarget, SaveStrategy, Shell, TaskTemplate};
7 #[gpui::test]
8 async fn test_create_scenario_for_go_build(_: &mut TestAppContext) {
9 let locator = GoLocator;
10 let task = TaskTemplate {
11 label: "go build".into(),
12 command: "go".into(),
13 args: vec!["build".into(), ".".into()],
14 env: Default::default(),
15 cwd: Some("${ZED_WORKTREE_ROOT}".into()),
16 use_new_terminal: false,
17 allow_concurrent_runs: false,
18 reveal: RevealStrategy::Always,
19 reveal_target: RevealTarget::Dock,
20 hide: HideStrategy::Never,
21 shell: Shell::System,
22 tags: vec![],
23 show_summary: true,
24 show_command: true,
25 save: SaveStrategy::default(),
26 };
27
28 let scenario = locator
29 .create_scenario(&task, "test label", &DebugAdapterName("Delve".into()))
30 .await;
31
32 assert!(scenario.is_none());
33 }
34
35 #[gpui::test]
36 async fn test_skip_non_go_commands_with_non_delve_adapter(_: &mut TestAppContext) {
37 let locator = GoLocator;
38 let task = TaskTemplate {
39 label: "cargo build".into(),
40 command: "cargo".into(),
41 args: vec!["build".into()],
42 env: Default::default(),
43 cwd: Some("${ZED_WORKTREE_ROOT}".into()),
44 use_new_terminal: false,
45 allow_concurrent_runs: false,
46 reveal: RevealStrategy::Always,
47 reveal_target: RevealTarget::Dock,
48 hide: HideStrategy::Never,
49 shell: Shell::System,
50 tags: vec![],
51 show_summary: true,
52 show_command: true,
53 save: SaveStrategy::default(),
54 };
55
56 let scenario = locator
57 .create_scenario(
58 &task,
59 "test label",
60 &DebugAdapterName("SomeOtherAdapter".into()),
61 )
62 .await;
63 assert!(scenario.is_none());
64
65 let scenario = locator
66 .create_scenario(&task, "test label", &DebugAdapterName("Delve".into()))
67 .await;
68 assert!(scenario.is_none());
69 }
70 #[gpui::test]
71 async fn test_go_locator_run(_: &mut TestAppContext) {
72 let locator = GoLocator;
73 let delve = DebugAdapterName("Delve".into());
74
75 let task = TaskTemplate {
76 label: "go run with flags".into(),
77 command: "go".into(),
78 args: vec![
79 "run".to_string(),
80 "-race".to_string(),
81 "-ldflags".to_string(),
82 "-X main.version=1.0".to_string(),
83 "./cmd/myapp".to_string(),
84 "--config".to_string(),
85 "production.yaml".to_string(),
86 "--verbose".to_string(),
87 ],
88 env: {
89 let mut env = HashMap::default();
90 env.insert("GO_ENV".to_string(), "production".to_string());
91 env
92 },
93 cwd: Some("/project/root".into()),
94 ..Default::default()
95 };
96
97 let scenario = locator
98 .create_scenario(&task, "test run label", &delve)
99 .await
100 .unwrap();
101
102 let config: DelveLaunchRequest = serde_json::from_value(scenario.config).unwrap();
103
104 assert_eq!(
105 config,
106 DelveLaunchRequest {
107 request: "launch".to_string(),
108 mode: "debug".to_string(),
109 program: "./cmd/myapp".to_string(),
110 build_flags: vec![
111 "-race".to_string(),
112 "-ldflags".to_string(),
113 "-X main.version=1.0".to_string()
114 ],
115 args: vec![
116 "--config".to_string(),
117 "production.yaml".to_string(),
118 "--verbose".to_string(),
119 ],
120 env: {
121 let mut env = HashMap::default();
122 env.insert("GO_ENV".to_string(), "production".to_string());
123 env
124 },
125 cwd: Some("/project/root".to_string()),
126 }
127 );
128 }
129
130 #[gpui::test]
131 async fn test_go_locator_test(_: &mut TestAppContext) {
132 let locator = GoLocator;
133 let delve = DebugAdapterName("Delve".into());
134
135 // Test with tags and run flag
136 let task_with_tags = TaskTemplate {
137 label: "test".into(),
138 command: "go".into(),
139 args: vec![
140 "test".to_string(),
141 "-tags".to_string(),
142 "integration,unit".to_string(),
143 "-run".to_string(),
144 "Foo".to_string(),
145 ".".to_string(),
146 ],
147 ..Default::default()
148 };
149 let result = locator
150 .create_scenario(&task_with_tags, "", &delve)
151 .await
152 .unwrap();
153
154 let config: DelveLaunchRequest = serde_json::from_value(result.config).unwrap();
155
156 assert_eq!(
157 config,
158 DelveLaunchRequest {
159 request: "launch".to_string(),
160 mode: "test".to_string(),
161 program: ".".to_string(),
162 build_flags: vec!["-tags".to_string(), "integration,unit".to_string(),],
163 args: vec![
164 "-test.run".to_string(),
165 "Foo".to_string(),
166 "-test.v".to_string()
167 ],
168 env: Default::default(),
169 cwd: None,
170 }
171 );
172 }
173
174 #[gpui::test]
175 async fn test_skip_unsupported_go_commands(_: &mut TestAppContext) {
176 let locator = GoLocator;
177 let task = TaskTemplate {
178 label: "go clean".into(),
179 command: "go".into(),
180 args: vec!["clean".into()],
181 env: Default::default(),
182 cwd: Some("${ZED_WORKTREE_ROOT}".into()),
183 use_new_terminal: false,
184 allow_concurrent_runs: false,
185 reveal: RevealStrategy::Always,
186 reveal_target: RevealTarget::Dock,
187 hide: HideStrategy::Never,
188 shell: Shell::System,
189 tags: vec![],
190 show_summary: true,
191 show_command: true,
192 save: SaveStrategy::default(),
193 };
194
195 let scenario = locator
196 .create_scenario(&task, "test label", &DebugAdapterName("Delve".into()))
197 .await;
198 assert!(scenario.is_none());
199 }
200}
201
202mod python_locator {
203 use dap::{DapLocator, adapters::DebugAdapterName};
204 use serde_json::json;
205
206 use project::debugger::locators::python::*;
207 use task::{DebugScenario, TaskTemplate};
208
209 #[gpui::test]
210 async fn test_python_locator() {
211 let adapter = DebugAdapterName("Debugpy".into());
212 let build_task = TaskTemplate {
213 label: "run module '$ZED_FILE'".into(),
214 command: "$ZED_CUSTOM_PYTHON_ACTIVE_ZED_TOOLCHAIN".into(),
215 args: vec!["-m".into(), "$ZED_CUSTOM_PYTHON_MODULE_NAME".into()],
216 env: Default::default(),
217 cwd: Some("$ZED_WORKTREE_ROOT".into()),
218 use_new_terminal: false,
219 allow_concurrent_runs: false,
220 reveal: task::RevealStrategy::Always,
221 reveal_target: task::RevealTarget::Dock,
222 hide: task::HideStrategy::Never,
223 tags: vec!["python-module-main-method".into()],
224 shell: task::Shell::System,
225 show_summary: false,
226 show_command: false,
227 save: task::SaveStrategy::default(),
228 };
229
230 let expected_scenario = DebugScenario {
231 adapter: "Debugpy".into(),
232 label: "run module 'main.py'".into(),
233 build: None,
234 config: json!({
235 "request": "launch",
236 "python": "$ZED_CUSTOM_PYTHON_ACTIVE_ZED_TOOLCHAIN",
237 "args": [],
238 "cwd": "$ZED_WORKTREE_ROOT",
239 "module": "$ZED_CUSTOM_PYTHON_MODULE_NAME",
240 }),
241 tcp_connection: None,
242 };
243
244 assert_eq!(
245 PythonLocator
246 .create_scenario(&build_task, "run module 'main.py'", &adapter)
247 .await
248 .expect("Failed to create a scenario"),
249 expected_scenario
250 );
251 }
252}
253
254mod memory {
255 use project::debugger::{
256 MemoryCell,
257 memory::{MemoryIterator, PageAddress, PageContents},
258 };
259
260 #[test]
261 fn iterate_over_unmapped_memory() {
262 let empty_iterator = MemoryIterator::new(0..=127, Default::default());
263 let actual = empty_iterator.collect::<Vec<_>>();
264 let expected = vec![MemoryCell(None); 128];
265 assert_eq!(actual.len(), expected.len());
266 assert_eq!(actual, expected);
267 }
268
269 #[test]
270 fn iterate_over_partially_mapped_memory() {
271 let it = MemoryIterator::new(
272 0..=127,
273 vec![(PageAddress(5), PageContents::mapped(vec![1]))].into_iter(),
274 );
275 let actual = it.collect::<Vec<_>>();
276 let expected = std::iter::repeat_n(MemoryCell(None), 5)
277 .chain(std::iter::once(MemoryCell(Some(1))))
278 .chain(std::iter::repeat_n(MemoryCell(None), 122))
279 .collect::<Vec<_>>();
280 assert_eq!(actual.len(), expected.len());
281 assert_eq!(actual, expected);
282 }
283
284 #[test]
285 fn reads_from_the_middle_of_a_page() {
286 let partial_iter = MemoryIterator::new(
287 20..=30,
288 vec![(PageAddress(0), PageContents::mapped((0..255).collect()))].into_iter(),
289 );
290 let actual = partial_iter.collect::<Vec<_>>();
291 let expected = (20..=30)
292 .map(|val| MemoryCell(Some(val)))
293 .collect::<Vec<_>>();
294 assert_eq!(actual.len(), expected.len());
295 assert_eq!(actual, expected);
296 }
297}