@@ -41,7 +41,7 @@ static VERSION_REGEX: LazyLock<Regex> =
4141 LazyLock :: new ( || Regex :: new ( r"\d+\.\d+\.\d+" ) . expect ( "Failed to create VERSION_REGEX" ) ) ;
4242
4343static GO_ESCAPE_SUBTEST_NAME_REGEX : LazyLock < Regex > = LazyLock :: new ( || {
44- Regex :: new ( r#"[.*+?^${}()|\[\]\\]"# ) . expect ( "Failed to create GO_ESCAPE_SUBTEST_NAME_REGEX" )
44+ Regex :: new ( r#"[.*+?^${}()|\[\]\\"' ]"# ) . expect ( "Failed to create GO_ESCAPE_SUBTEST_NAME_REGEX" )
4545} ) ;
4646
4747const BINARY : & str = if cfg ! ( target_os = "windows" ) {
@@ -685,11 +685,20 @@ impl ContextProvider for GoContextProvider {
685685}
686686
687687fn extract_subtest_name ( input : & str ) -> Option < String > {
688- let replaced_spaces = input. trim_matches ( '"' ) . replace ( ' ' , "_" ) ;
688+ let content = if input. starts_with ( '`' ) && input. ends_with ( '`' ) {
689+ input. trim_matches ( '`' )
690+ } else {
691+ input. trim_matches ( '"' )
692+ } ;
693+
694+ let processed = content
695+ . chars ( )
696+ . map ( |c| if c. is_whitespace ( ) { '_' } else { c } )
697+ . collect :: < String > ( ) ;
689698
690699 Some (
691700 GO_ESCAPE_SUBTEST_NAME_REGEX
692- . replace_all ( & replaced_spaces , |caps : & regex:: Captures | {
701+ . replace_all ( & processed , |caps : & regex:: Captures | {
693702 format ! ( "\\ {}" , & caps[ 0 ] )
694703 } )
695704 . to_string ( ) ,
@@ -700,7 +709,7 @@ fn extract_subtest_name(input: &str) -> Option<String> {
700709mod tests {
701710 use super :: * ;
702711 use crate :: language;
703- use gpui:: Hsla ;
712+ use gpui:: { AppContext , Hsla , TestAppContext } ;
704713 use theme:: SyntaxTheme ;
705714
706715 #[ gpui:: test]
@@ -790,4 +799,108 @@ mod tests {
790799 } )
791800 ) ;
792801 }
802+
803+ #[ gpui:: test]
804+ fn test_go_runnable_detection ( cx : & mut TestAppContext ) {
805+ let language = language ( "go" , tree_sitter_go:: LANGUAGE . into ( ) ) ;
806+
807+ let interpreted_string_subtest = r#"
808+ package main
809+
810+ import "testing"
811+
812+ func TestExample(t *testing.T) {
813+ t.Run("subtest with double quotes", func(t *testing.T) {
814+ // test code
815+ })
816+ }
817+ "# ;
818+
819+ let raw_string_subtest = r#"
820+ package main
821+
822+ import "testing"
823+
824+ func TestExample(t *testing.T) {
825+ t.Run(`subtest with
826+ multiline
827+ backticks`, func(t *testing.T) {
828+ // test code
829+ })
830+ }
831+ "# ;
832+
833+ let buffer = cx. new ( |cx| {
834+ crate :: Buffer :: local ( interpreted_string_subtest, cx) . with_language ( language. clone ( ) , cx)
835+ } ) ;
836+ cx. executor ( ) . run_until_parked ( ) ;
837+
838+ let runnables: Vec < _ > = buffer. update ( cx, |buffer, _| {
839+ let snapshot = buffer. snapshot ( ) ;
840+ snapshot
841+ . runnable_ranges ( 0 ..interpreted_string_subtest. len ( ) )
842+ . collect ( )
843+ } ) ;
844+
845+ assert ! (
846+ runnables. len( ) == 2 ,
847+ "Should find test function and subtest with double quotes, found: {}" ,
848+ runnables. len( )
849+ ) ;
850+
851+ let buffer = cx. new ( |cx| {
852+ crate :: Buffer :: local ( raw_string_subtest, cx) . with_language ( language. clone ( ) , cx)
853+ } ) ;
854+ cx. executor ( ) . run_until_parked ( ) ;
855+
856+ let runnables: Vec < _ > = buffer. update ( cx, |buffer, _| {
857+ let snapshot = buffer. snapshot ( ) ;
858+ snapshot
859+ . runnable_ranges ( 0 ..raw_string_subtest. len ( ) )
860+ . collect ( )
861+ } ) ;
862+
863+ assert ! (
864+ runnables. len( ) == 2 ,
865+ "Should find test function and subtest with backticks, found: {}" ,
866+ runnables. len( )
867+ ) ;
868+ }
869+
870+ #[ test]
871+ fn test_extract_subtest_name ( ) {
872+ // Interpreted string literal
873+ let input_double_quoted = r#""subtest with double quotes""# ;
874+ let result = extract_subtest_name ( input_double_quoted) ;
875+ assert_eq ! ( result, Some ( r#"subtest_with_double_quotes"# . to_string( ) ) ) ;
876+
877+ let input_double_quoted_with_backticks = r#""test with `backticks` inside""# ;
878+ let result = extract_subtest_name ( input_double_quoted_with_backticks) ;
879+ assert_eq ! ( result, Some ( r#"test_with_`backticks`_inside"# . to_string( ) ) ) ;
880+
881+ // Raw string literal
882+ let input_with_backticks = r#"`subtest with backticks`"# ;
883+ let result = extract_subtest_name ( input_with_backticks) ;
884+ assert_eq ! ( result, Some ( r#"subtest_with_backticks"# . to_string( ) ) ) ;
885+
886+ let input_raw_with_quotes = r#"`test with "quotes" and other chars`"# ;
887+ let result = extract_subtest_name ( input_raw_with_quotes) ;
888+ assert_eq ! (
889+ result,
890+ Some ( r#"test_with_\"quotes\"_and_other_chars"# . to_string( ) )
891+ ) ;
892+
893+ let input_multiline = r#"`subtest with
894+ multiline
895+ backticks`"# ;
896+ let result = extract_subtest_name ( input_multiline) ;
897+ assert_eq ! (
898+ result,
899+ Some ( r#"subtest_with_________multiline_________backticks"# . to_string( ) )
900+ ) ;
901+
902+ let input_with_double_quotes = r#"`test with "double quotes"`"# ;
903+ let result = extract_subtest_name ( input_with_double_quotes) ;
904+ assert_eq ! ( result, Some ( r#"test_with_\"double_quotes\""# . to_string( ) ) ) ;
905+ }
793906}
0 commit comments