| /*--------------------------------------------------------- |
| * Copyright 2020 The Go Authors. All rights reserved. |
| * Licensed under the MIT License. See LICENSE in the project root for license information. |
| *--------------------------------------------------------*/ |
| |
| 'use strict'; |
| |
| import assert from 'assert'; |
| import path = require('path'); |
| import sinon = require('sinon'); |
| import vscode = require('vscode'); |
| import { updateGoVarsFromConfig } from '../../src/goInstallTools'; |
| import { GoRunTestCodeLensProvider } from '../../src/goRunTestCodelens'; |
| import { subTestAtCursor } from '../../src/goTest'; |
| import { MockExtensionContext } from '../mocks/MockContext'; |
| import { Env } from './goplsTestEnv.utils'; |
| |
| suite('Code lenses for testing and benchmarking', function () { |
| this.timeout(20000); |
| |
| let document: vscode.TextDocument; |
| |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| const ctx = new MockExtensionContext() as any; |
| const cancellationTokenSource = new vscode.CancellationTokenSource(); |
| |
| const projectDir = path.join(__dirname, '..', '..', '..'); |
| const testdataDir = path.join(projectDir, 'test', 'testdata', 'codelens'); |
| 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'); |
| sinon.restore(); |
| }); |
| |
| suiteSetup(async () => { |
| await updateGoVarsFromConfig({}); |
| |
| const uri = vscode.Uri.file(path.join(testdataDir, 'codelens_test.go')); |
| await env.startGopls(uri.fsPath); |
| document = await vscode.workspace.openTextDocument(uri); |
| }); |
| |
| suiteTeardown(async () => { |
| await env.teardown(); |
| }); |
| |
| test('Subtests - runs a test with cursor on t.Run line', async () => { |
| const editor = await vscode.window.showTextDocument(document); |
| editor.selection = new vscode.Selection(7, 4, 7, 4); |
| const result = await subTestAtCursor('test')(ctx, env.goCtx)([]); |
| assert.equal(result, true); |
| }); |
| |
| test('Subtests - runs a test with cursor within t.Run function', async () => { |
| const editor = await vscode.window.showTextDocument(document); |
| editor.selection = new vscode.Selection(8, 4, 8, 4); |
| const result = await subTestAtCursor('test')(ctx, env.goCtx)([]); |
| assert.equal(result, true); |
| }); |
| |
| test('Subtests - returns false for a failing test', async () => { |
| const editor = await vscode.window.showTextDocument(document); |
| editor.selection = new vscode.Selection(11, 4, 11, 4); |
| const result = await subTestAtCursor('test')(ctx, env.goCtx)([]); |
| assert.equal(result, false); |
| }); |
| |
| test('Subtests - does nothing for a dynamically defined subtest', async () => { |
| const editor = await vscode.window.showTextDocument(document); |
| editor.selection = new vscode.Selection(17, 4, 17, 4); |
| sinon.stub(vscode.window, 'showInputBox').onFirstCall().resolves(undefined); |
| const result = await subTestAtCursor('test')(ctx, env.goCtx)([]); |
| assert.equal(result, undefined); |
| }); |
| |
| test('Subtests - runs a test with curson on t.Run line and dynamic test name is passed in input box', async () => { |
| const editor = await vscode.window.showTextDocument(document); |
| editor.selection = new vscode.Selection(17, 4, 17, 4); |
| sinon.stub(vscode.window, 'showInputBox').onFirstCall().resolves('dynamic test name'); |
| const result = await subTestAtCursor('test')(ctx, env.goCtx)([]); |
| assert.equal(result, false); |
| }); |
| |
| test('Subtests - does nothing when cursor outside of a test function', async () => { |
| const editor = await vscode.window.showTextDocument(document); |
| editor.selection = new vscode.Selection(5, 0, 5, 0); |
| const result = await subTestAtCursor('test')(ctx, env.goCtx)([]); |
| assert.equal(result, undefined); |
| }); |
| |
| test('Subtests - does nothing when no test function covers the cursor and a function name is passed in', async () => { |
| const editor = await vscode.window.showTextDocument(document); |
| editor.selection = new vscode.Selection(5, 0, 5, 0); |
| const result = await subTestAtCursor('test')(ctx, env.goCtx)({ functionName: 'TestMyFunction' }); |
| assert.equal(result, undefined); |
| }); |
| |
| test('Test codelenses', async () => { |
| const codeLensProvider = new GoRunTestCodeLensProvider(env.goCtx); |
| const codeLenses = await codeLensProvider.provideCodeLenses(document, cancellationTokenSource.token); |
| assert.equal(codeLenses.length, 8); |
| const wantCommands = [ |
| 'go.test.package', |
| 'go.test.file', |
| 'go.test.cursor', |
| 'go.debug.cursor', |
| 'go.subtest.cursor', |
| 'go.debug.subtest.cursor', |
| 'go.subtest.cursor', |
| 'go.debug.subtest.cursor' |
| ]; |
| for (let i = 0; i < codeLenses.length; i++) { |
| assert.equal(codeLenses[i].command?.command, wantCommands[i]); |
| } |
| }); |
| |
| test('Benchmark codelenses', async () => { |
| const codeLensProvider = new GoRunTestCodeLensProvider(env.goCtx); |
| const uri = vscode.Uri.file(path.join(testdataDir, 'codelens_benchmark_test.go')); |
| const benchmarkDocument = await vscode.workspace.openTextDocument(uri); |
| const codeLenses = await codeLensProvider.provideCodeLenses(benchmarkDocument, cancellationTokenSource.token); |
| assert.equal(codeLenses.length, 6); |
| const wantCommands = [ |
| 'go.test.package', |
| 'go.test.file', |
| 'go.benchmark.package', |
| 'go.benchmark.file', |
| 'go.benchmark.cursor', |
| 'go.debug.cursor' |
| ]; |
| for (let i = 0; i < codeLenses.length; i++) { |
| assert.equal(codeLenses[i].command?.command, wantCommands[i]); |
| } |
| }); |
| |
| test('Test codelenses include only valid test function names', async () => { |
| const codeLensProvider = new GoRunTestCodeLensProvider(env.goCtx); |
| const uri = vscode.Uri.file(path.join(testdataDir, 'codelens2_test.go')); |
| const benchmarkDocument = await vscode.workspace.openTextDocument(uri); |
| const codeLenses = await codeLensProvider.provideCodeLenses(benchmarkDocument, cancellationTokenSource.token); |
| assert.equal(codeLenses.length, 20, 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, [ |
| 'Example', |
| 'ExampleFunction', |
| 'Test', |
| 'Test1Function', |
| 'TestFunction', |
| 'TestMain', |
| 'Test_foobar', |
| 'TestΣυνάρτηση', |
| 'Test함수' |
| ]); |
| }); |
| |
| test('Test codelenses include valid fuzz function names', async () => { |
| const codeLensProvider = new GoRunTestCodeLensProvider(env.goCtx); |
| const uri = vscode.Uri.file(path.join(testdataDir, 'codelens_go118_test.go')); |
| const testDocument = await vscode.workspace.openTextDocument(uri); |
| const codeLenses = await codeLensProvider.provideCodeLenses(testDocument, cancellationTokenSource.token); |
| assert.equal(codeLenses.length, 8, 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, ['Fuzz', 'FuzzFunc', 'TestGo118']); |
| }); |
| |
| test('Test codelenses skip TestMain', async () => { |
| const codeLensProvider = new GoRunTestCodeLensProvider(env.goCtx); |
| const uri = vscode.Uri.file(path.join(testdataDir, 'testmain/testmain_test.go')); |
| const testDocument = await vscode.workspace.openTextDocument(uri); |
| const codeLenses = await codeLensProvider.provideCodeLenses(testDocument, cancellationTokenSource.token); |
| assert.equal(codeLenses.length, 4, 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, ['TestNotMain']); |
| }); |
| }); |