src/testUtils: tighten test function detection regex
According to https://golang.org/pkg/testing/
test function names should be of form
func TestXxx(*testing.T)
where Xxx does not start with a lowercase letter.
Go uses unicode for this. Mimic the behavior encoded in
https://github.com/golang/go/blob/117b1c84d3678a586c168a5f7f2f0a750c27f0c2/src/cmd/go/internal/load/test.go#L48
by using unicode regexp and property.
Fixes golang/vscode-go#1417
Change-Id: I3fa510e5e567722b5b09c2618034686a9c5c3d90
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/309631
Trust: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/src/testUtils.ts b/src/testUtils.ts
index 2433a4b..77e812d 100644
--- a/src/testUtils.ts
+++ b/src/testUtils.ts
@@ -32,9 +32,14 @@
*/
const runningTestProcesses: cp.ChildProcess[] = [];
-const testFuncRegex = /^Test.*|^Example.*/;
-const testMethodRegex = /^\(([^)]+)\)\.(Test.*)$/;
-const benchmarkRegex = /^Benchmark.*/;
+// https://github.com/golang/go/blob/117b1c84d3678a586c168a5f7f2f0a750c27f0c2/src/cmd/go/internal/load/test.go#L487
+// uses !unicode.isLower to find test/example/benchmark functions.
+// There could be slight difference between \P{Ll} (not lowercase letter)
+// & go unicode package's uppercase detection. But hopefully
+// these will be replaced by gopls's codelens computation soon.
+const testFuncRegex = /^Test\P{Ll}.*|^Example\P{Ll}.*/u;
+const testMethodRegex = /^\(([^)]+)\)\.(Test\P{Ll}.*)$/u;
+const benchmarkRegex = /^Benchmark\P{Ll}.*/u;
/**
* Input to goTest.
diff --git a/test/integration/codelens.test.ts b/test/integration/codelens.test.ts
index bee6b27..bbe2f61 100644
--- a/test/integration/codelens.test.ts
+++ b/test/integration/codelens.test.ts
@@ -129,4 +129,21 @@
assert.equal(codeLenses[i].command.command, wantCommands[i]);
}
});
+
+ test('Test codelenses include only valid test function names', async () => {
+ const uri = vscode.Uri.file(path.join(fixturePath, 'codelens2_test.go'));
+ const benchmarkDocument = await vscode.workspace.openTextDocument(uri);
+ const codeLenses = await codeLensProvider.provideCodeLenses(benchmarkDocument, cancellationTokenSource.token);
+ assert.equal(codeLenses.length, 12, JSON.stringify(codeLenses, null, 2));
+ const found = [] as string[];
+ for (let i = 0; i < codeLenses.length; i++) {
+ const lens = codeLenses[i];
+ if (lens.command.command === 'go.test.cursor') {
+ found.push(lens.command.arguments[0].functionName);
+ }
+ }
+ found.sort();
+ // Results should match `go test -list`.
+ assert.deepStrictEqual(found, ['Test1Function', 'TestFunction', 'Test_foobar', 'TestΣυνάρτηση', 'Test함수']);
+ });
});
diff --git a/test/testdata/codelens/codelens2_test.go b/test/testdata/codelens/codelens2_test.go
new file mode 100644
index 0000000..405f4ef
--- /dev/null
+++ b/test/testdata/codelens/codelens2_test.go
@@ -0,0 +1,39 @@
+package main
+
+import (
+ "testing"
+)
+
+// As of Go1.16, `go test -list` returns
+// TestFunction
+// Test1Function
+// TestΣυνάρτηση
+// Test함수
+// Test_foobar
+func TestFunction(t *testing.T) {
+ t.Log("this is a valid test function")
+}
+
+func Testfunction(t *testing.T) {
+ t.Fatal("this is not a valid test function")
+}
+
+func Test1Function(t *testing.T) {
+ t.Log("this is an acceptable test function")
+}
+
+func TestΣυνάρτηση(t *testing.T) {
+ t.Log("this is a valid test function")
+}
+
+func Testσυνάρτηση(t *testing.T) {
+ t.Fatal("this is not a valid test function")
+}
+
+func Test함수(t *testing.T) {
+ t.Log("this is a valid test function")
+}
+
+func Test_foobar(t *testing.T) {
+ t.Log("this is an acceptable test function")
+}
\ No newline at end of file