diff --git a/gopls/internal/lsp/source/code_lens_gox.go b/gopls/internal/lsp/source/code_lens_gox.go index fe5ea5433ed..0767ec3edec 100644 --- a/gopls/internal/lsp/source/code_lens_gox.go +++ b/gopls/internal/lsp/source/code_lens_gox.go @@ -189,6 +189,9 @@ func gopCommandCodeLens(ctx context.Context, snapshot Snapshot, fh FileHandle) ( if err != nil { return nil, err } + if classType, isGoxTest := GoxTestClassType(pgf.File, filename); isGoxTest { + return goxTestCodeLens(pgf, classType) + } if pgf.File.Name.Name == "main" { rng, err := pgf.PosRange(pgf.File.Pos(), pgf.File.Pos()) if err != nil { @@ -206,3 +209,36 @@ func gopCommandCodeLens(ctx context.Context, snapshot Snapshot, fh FileHandle) ( } return nil, nil } + +func goxTestCodeLens(pgf *ParsedGopFile, classType string) ([]protocol.CodeLens, error) { + rng, err := pgf.PosRange(pgf.File.Pos(), pgf.File.Pos()) + if err != nil { + return nil, err + } + codelens := []protocol.CodeLens{ + {Range: rng, Command: &protocol.Command{ + Title: "run test package", + Command: "gop.test.package", + }}, + } + if pgf.File.IsProj && classType == "main" { //goxls:proj gox test + return codelens, nil + } + args, err := command.MarshalArgs( + map[string]string{ + "functionName": "Test_" + classType, + }, + ) + if err != nil { + return nil, err + } + codelens = append(codelens, protocol.CodeLens{ + Range: rng, + Command: &protocol.Command{ + Title: "run file tests", + Command: "gop.test.cursor", + Arguments: args, + }, + }) + return codelens, nil +} diff --git a/gopls/internal/lsp/source/util_gox.go b/gopls/internal/lsp/source/util_gox.go index 24b9dcc35eb..a306e86ef2b 100644 --- a/gopls/internal/lsp/source/util_gox.go +++ b/gopls/internal/lsp/source/util_gox.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/goplus/gop/ast" + "github.com/goplus/gop/cl" "github.com/goplus/gop/printer" "github.com/goplus/gop/token" "github.com/goplus/gop/x/typesutil" @@ -287,3 +288,16 @@ func gopEmbeddedIdent(x ast.Expr) *ast.Ident { } return nil } + +func GoxTestClassType(file *ast.File, filename string) (classType string, isGoxTest bool) { + if file.IsClass { + var ext string + classType, _, ext = cl.ClassNameAndExt(filename) + if file.IsNormalGox { + isGoxTest = strings.HasSuffix(ext, "_test.gox") + } else { + isGoxTest = strings.HasSuffix(ext, "test.gox") + } + } + return +} diff --git a/gopls/internal/lsp/source/util_gox_test.go b/gopls/internal/lsp/source/util_gox_test.go new file mode 100644 index 00000000000..d65acfd717f --- /dev/null +++ b/gopls/internal/lsp/source/util_gox_test.go @@ -0,0 +1,59 @@ +package source + +import ( + "github.com/goplus/gop/ast" + + "testing" +) + +func TestGoxTestClassType(t *testing.T) { + type testData struct { + isClass bool + isNormalGox bool + isProj bool + fileName string + classType string + isGoxTest bool + } + tests := + []*testData{ + {false, false, false, "abc.gop", "", false}, + {false, false, false, "abc_test.gop", "", false}, + + {true, true, false, "abc.gox", "abc", false}, + {true, true, false, "Abc.gox", "Abc", false}, + {true, true, false, "abc_demo.gox", "abc", false}, + {true, true, false, "Abc_demo.gox", "Abc", false}, + + {true, false, false, "get.yap", "get", false}, + {true, false, false, "get_p_#id.yap", "get_p_id", false}, + {true, false, true, "main.yap", "main", false}, + + {true, true, false, "main.gox", "main", false}, + {true, true, false, "main_demo.gox", "main", false}, + {true, true, false, "abc_xtest.gox", "abc", false}, + {true, true, false, "main_xtest.gox", "main", false}, + + {true, true, false, "abc_test.gox", "abc", true}, + {true, true, false, "Abc_test.gox", "Abc", true}, + {true, true, false, "main_test.gox", "main", true}, + + {true, false, false, "abc_yap.gox", "abc", false}, + {true, false, false, "Abc_yap.gox", "Abc", false}, + {true, false, true, "main_yap.gox", "main", false}, + + {true, false, false, "abc_ytest.gox", "abc", true}, + {true, false, false, "Abc_ytest.gox", "Abc", true}, + {true, false, true, "main_ytest.gox", "main", true}, + } + for _, test := range tests { + f := &ast.File{IsClass: test.isClass, IsNormalGox: test.isNormalGox, IsProj: test.isProj} + classType, isGoxTest := GoxTestClassType(f, test.fileName) + if isGoxTest != test.isGoxTest { + t.Fatalf("%v check classType isTest want %v, got %v.", test.fileName, test.isGoxTest, isGoxTest) + } + if classType != test.classType { + t.Fatalf("%v getClassType want %v, got %v.", test.fileName, test.classType, classType) + } + } +}