languages: Fix Debug Test for Go subtests

Kunall Banerjee created

The go-subtest task template wrapped the -run arg in single quotes
for shell safety. This works for Run Test (terminal strips quotes),
but Debug Test sends the arg through Delve's DAP protocol with no
shell involved, so the literal quote characters ended up in the
regex and prevented any match.

All other Go task templates (go-test, go-testify-suite,
go-table-test-case) use the backslash-escaped format which the
GoLocator already knows how to handle. Align the go-subtest
template to the same format.

Change summary

crates/languages/src/go.rs                   |  2 
crates/project/tests/integration/debugger.rs | 40 ++++++++++++++++++++++
2 files changed, 41 insertions(+), 1 deletion(-)

Detailed changes

crates/languages/src/go.rs 🔗

@@ -706,7 +706,7 @@ impl ContextProvider for GoContextProvider {
                     "-v".into(),
                     "-run".into(),
                     format!(
-                        "'^{}$/^{}$'",
+                        "\\^{}\\$/\\^{}\\$",
                         VariableName::Symbol.template_value(),
                         GO_SUBTEST_NAME_TASK_VARIABLE.template_value(),
                     ),

crates/project/tests/integration/debugger.rs 🔗

@@ -173,6 +173,46 @@ mod go_locator {
         );
     }
 
+    #[gpui::test]
+    async fn test_go_locator_subtest(_: &mut TestAppContext) {
+        let locator = GoLocator;
+        let delve = DebugAdapterName("Delve".into());
+
+        // The `go-subtest` task template uses the \^...\$ format for the `-run`
+        // arg so the GoLocator strips the shell escaping before passing it to
+        // Delve. Previously the template used single quotes ('^...$') which
+        // Delve passed literally to the test binary, breaking all subtests.
+        let task = TaskTemplate {
+            label: "test subtest".into(),
+            command: "go".into(),
+            args: vec![
+                "test".to_string(),
+                "-v".to_string(),
+                "-run".to_string(),
+                "\\^TestFoo\\$/\\^simple_subtest\\$".to_string(),
+            ],
+            ..Default::default()
+        };
+        let result = locator.create_scenario(&task, "", &delve).await.unwrap();
+        let config: DelveLaunchRequest = serde_json::from_value(result.config).unwrap();
+        assert_eq!(
+            config,
+            DelveLaunchRequest {
+                request: "launch".to_string(),
+                mode: "test".to_string(),
+                program: ".".to_string(),
+                build_flags: vec![],
+                args: vec![
+                    "-test.v".to_string(),
+                    "-test.run".to_string(),
+                    "^TestFoo$/^simple_subtest$".to_string(),
+                ],
+                env: Default::default(),
+                cwd: None,
+            }
+        );
+    }
+
     #[gpui::test]
     async fn test_skip_unsupported_go_commands(_: &mut TestAppContext) {
         let locator = GoLocator;