diff --git a/extension/src/goTest.ts b/extension/src/goTest.ts index ea27f6fe48..986bd18459 100644 --- a/extension/src/goTest.ts +++ b/extension/src/goTest.ts @@ -164,7 +164,7 @@ async function _subTestAtCursor( export function testAtCursor(cmd: TestAtCursorCmd): CommandFactory { return (ctx, goCtx) => (args: any) => { const goConfig = getGoConfig(); - _testAtCursor(goCtx, goConfig, cmd, args).catch((err) => { + return _testAtCursor(goCtx, goConfig, cmd, args).catch((err) => { if (err instanceof NotFoundError) { vscode.window.showInformationMessage(err.message); } else { @@ -299,9 +299,14 @@ export async function debugTestAtCursor( sessionID }; lastDebugConfig = debugConfig; + console.log('✅ debugTestAtCursor', lastDebugConfig, debugConfig); lastDebugWorkspaceFolder = workspaceFolder; vscode.commands.executeCommand('workbench.debug.action.focusRepl'); - return await vscode.debug.startDebugging(workspaceFolder, debugConfig); + console.log('after execute command'); + console.log('workspace', workspaceFolder); + const result = await vscode.debug.startDebugging(workspaceFolder, debugConfig); + console.log('after debugging:', result); + return result; } /** diff --git a/extension/test/gopls/codelens.test.ts b/extension/test/gopls/codelens.test.ts index 31c1fcdb3a..72833af9dc 100644 --- a/extension/test/gopls/codelens.test.ts +++ b/extension/test/gopls/codelens.test.ts @@ -11,9 +11,10 @@ import sinon = require('sinon'); import vscode = require('vscode'); import { updateGoVarsFromConfig } from '../../src/goInstallTools'; import { GoRunTestCodeLensProvider } from '../../src/goRunTestCodelens'; -import { subTestAtCursor } from '../../src/goTest'; +import { subTestAtCursor, testAtCursor } from '../../src/goTest'; import { MockExtensionContext } from '../mocks/MockContext'; import { Env } from './goplsTestEnv.utils'; +import * as testUtils from '../../src/testUtils'; suite('Code lenses for testing and benchmarking', function () { this.timeout(20000); @@ -200,4 +201,141 @@ suite('Code lenses for testing and benchmarking', function () { // Results should match `go test -list`. assert.deepStrictEqual(found, ['TestNotMain']); }); + + test('Debug - debugs a test with cursor on t.Run line', async () => { + const startDebuggingStub = sinon.stub(vscode.debug, 'startDebugging').returns(Promise.resolve(true)); + + const editor = await vscode.window.showTextDocument(document); + editor.selection = new vscode.Selection(7, 4, 7, 4); + const result = await subTestAtCursor('debug')(ctx, env.goCtx)([]); + assert.strictEqual(result, true); + + assert.strictEqual(startDebuggingStub.callCount, 1, 'expected one call to startDebugging'); + const gotConfig = startDebuggingStub.getCall(0).args[1] as vscode.DebugConfiguration; + gotConfig.program = ''; + assert.deepStrictEqual(gotConfig, { + name: 'Debug Test', + type: 'go', + request: 'launch', + args: ['-test.run', '^TestSample$/^sample_test_passing$'], + buildFlags: '', + env: {}, + sessionID: undefined, + mode: 'test', + envFile: null, + program: '' + }); + }); +}); + +suite('Code lenses with stretchr/testify/suite', function () { + const ctx = MockExtensionContext.new(); + + const testdataDir = path.join(__dirname, '..', '..', '..', 'test', 'testdata', 'stretchrTestSuite'); + const env = new Env(); + + this.afterEach(async function () { + // Note: this shouldn't use () => {...}. Arrow functions do not have 'this'. + // I don't know why but this.currentTest.state does not have the expected value when + // used with teardown. + env.flushTrace(this.currentTest?.state === 'failed'); + ctx.teardown(); + sinon.restore(); + }); + + suiteSetup(async () => { + await updateGoVarsFromConfig({}); + await env.startGopls(undefined, undefined, testdataDir); + }); + + suiteTeardown(async () => { + await env.teardown(); + }); + + test('Run test at cursor', async () => { + const goTestStub = sinon.stub(testUtils, 'goTest').returns(Promise.resolve(true)); + + const editor = await vscode.window.showTextDocument(vscode.Uri.file(path.join(testdataDir, 'suite_test.go'))); + editor.selection = new vscode.Selection(25, 4, 25, 4); + + const result = await testAtCursor('test')(ctx, env.goCtx)([]); + assert.strictEqual(result, true); + + assert.strictEqual(goTestStub.callCount, 1, 'expected one call to goTest'); + const gotConfig = goTestStub.getCall(0).args[0]; + assert.deepStrictEqual(gotConfig.functions, ['(*ExampleTestSuite).TestExample', 'TestExampleTestSuite']); + }); + + test('Run test at cursor in different file than test suite definition', async () => { + const goTestStub = sinon.stub(testUtils, 'goTest').returns(Promise.resolve(true)); + + const editor = await vscode.window.showTextDocument( + vscode.Uri.file(path.join(testdataDir, 'another_suite_test.go')) + ); + editor.selection = new vscode.Selection(3, 4, 3, 4); + + const result = await testAtCursor('test')(ctx, env.goCtx)([]); + assert.strictEqual(result, true); + + assert.strictEqual(goTestStub.callCount, 1, 'expected one call to goTest'); + const gotConfig = goTestStub.getCall(0).args[0]; + assert.deepStrictEqual(gotConfig.functions, [ + '(*ExampleTestSuite).TestExampleInAnotherFile', + 'TestExampleTestSuite' + ]); + }); + + test('Debug test at cursor', async () => { + const startDebuggingStub = sinon.stub(vscode.debug, 'startDebugging').returns(Promise.resolve(true)); + + const editor = await vscode.window.showTextDocument(vscode.Uri.file(path.join(testdataDir, 'suite_test.go'))); + editor.selection = new vscode.Selection(25, 4, 25, 4); + + const result = await testAtCursor('debug')(ctx, env.goCtx)([]); + assert.strictEqual(result, true); + + assert.strictEqual(startDebuggingStub.callCount, 1, 'expected one call to startDebugging'); + const gotConfig = startDebuggingStub.getCall(0).args[1] as vscode.DebugConfiguration; + gotConfig.program = ''; + assert.deepStrictEqual(gotConfig, { + name: 'Debug Test', + type: 'go', + request: 'launch', + args: ['-test.run', '^TestExampleTestSuite$', '-testify.m', '^TestExample$'], + buildFlags: '', + env: {}, + sessionID: undefined, + mode: 'test', + envFile: null, + program: '' + }); + }); + + test('Debug test at cursor in different file than test suite definition', async () => { + const startDebuggingStub = sinon.stub(vscode.debug, 'startDebugging').returns(Promise.resolve(true)); + + const editor = await vscode.window.showTextDocument( + vscode.Uri.file(path.join(testdataDir, 'another_suite_test.go')) + ); + editor.selection = new vscode.Selection(3, 4, 3, 4); + + const result = await testAtCursor('debug')(ctx, env.goCtx)([]); + assert.strictEqual(result, true); + + assert.strictEqual(startDebuggingStub.callCount, 1, 'expected one call to startDebugging'); + const gotConfig = startDebuggingStub.getCall(0).args[1] as vscode.DebugConfiguration; + gotConfig.program = ''; + assert.deepStrictEqual(gotConfig, { + name: 'Debug Test', + type: 'go', + request: 'launch', + args: ['-test.run', '^TestExampleTestSuite$', '-testify.m', '^TestExampleInAnotherFile$'], + buildFlags: '', + env: {}, + sessionID: undefined, + mode: 'test', + envFile: null, + program: '' + }); + }); }); diff --git a/extension/test/gopls/goTest.run.test.ts b/extension/test/gopls/goTest.run.test.ts index 112959a42d..d583dc99e9 100644 --- a/extension/test/gopls/goTest.run.test.ts +++ b/extension/test/gopls/goTest.run.test.ts @@ -8,12 +8,17 @@ import { GoTestExplorer } from '../../src/goTest/explore'; import { MockExtensionContext } from '../mocks/MockContext'; import { GoTest } from '../../src/goTest/utils'; import { Env } from './goplsTestEnv.utils'; +import { updateGoVarsFromConfig } from '../../src/goInstallTools'; suite('Go Test Runner', () => { const fixtureDir = path.join(__dirname, '..', '..', '..', 'test', 'testdata'); let testExplorer: GoTestExplorer; + suiteSetup(async () => { + await updateGoVarsFromConfig({}); + }); + suite('parseOutput', () => { const ctx = MockExtensionContext.new(); suiteSetup(async () => { diff --git a/extension/test/integration/test.test.ts b/extension/test/integration/test.test.ts index 1ca2431a47..500b176216 100644 --- a/extension/test/integration/test.test.ts +++ b/extension/test/integration/test.test.ts @@ -97,6 +97,19 @@ suite('Test Go Test Args', () => { flags: ['-run', 'TestC'] }); }); + test('use -testify.m for methods', () => { + runTest({ + expectedArgs: + 'test -timeout 30s -run ^TestExampleTestSuite$ -testify.m ^(TestExample|TestAnotherExample)$ ./...', + expectedOutArgs: + 'test -timeout 30s -run ^TestExampleTestSuite$ -testify.m ^(TestExample|TestAnotherExample)$ ./...', + functions: [ + '(*ExampleTestSuite).TestExample', + '(*ExampleTestSuite).TestAnotherExample', + 'TestExampleTestSuite' + ] + }); + }); }); suite('Test Go Test', function () { diff --git a/extension/test/testdata/stretchrTestSuite/another_suite_test.go b/extension/test/testdata/stretchrTestSuite/another_suite_test.go new file mode 100644 index 0000000000..1af57e7d34 --- /dev/null +++ b/extension/test/testdata/stretchrTestSuite/another_suite_test.go @@ -0,0 +1,7 @@ +package main_test + +func (suite *ExampleTestSuite) TestExampleInAnotherFile() { + if suite.VariableThatShouldStartAtFive != 5 { + suite.T().Fatalf("%d != %d", 5, suite.VariableThatShouldStartAtFive) + } +} diff --git a/extension/test/testdata/stretchrTestSuite/go.mod b/extension/test/testdata/stretchrTestSuite/go.mod index 272ea9c8a5..7703985823 100644 --- a/extension/test/testdata/stretchrTestSuite/go.mod +++ b/extension/test/testdata/stretchrTestSuite/go.mod @@ -1,10 +1,13 @@ module example/a -go 1.16 +go 1.21 + +require github.com/stretchr/testify v1.7.0 require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.1.0 // indirect - github.com/stretchr/testify v1.7.0 + github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect )