src/goMain.ts: remove goCtx export

Change-Id: Icd3b35cccef0987b5d2f6dccd8d2fb288d44d093
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/405552
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Jamal Carvalho <jamal@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/goDocumentSymbols.ts b/src/goDocumentSymbols.ts
index 2da40ca..ef6959c 100644
--- a/src/goDocumentSymbols.ts
+++ b/src/goDocumentSymbols.ts
@@ -6,29 +6,30 @@
 import vscode = require('vscode');
 import { ExecuteCommandParams, ExecuteCommandRequest } from 'vscode-languageserver-protocol';
 import { getGoConfig } from './config';
-import { goCtx } from './goMain';
+import { GoExtensionContext } from './context';
 import { GoLegacyDocumentSymbolProvider } from './language/legacy/goOutline';
 
 export function GoDocumentSymbolProvider(
+	goCtx: GoExtensionContext,
 	includeImports?: boolean
 ): GoplsDocumentSymbolProvider | GoLegacyDocumentSymbolProvider {
 	const { latestConfig } = goCtx;
 	if (!latestConfig?.enabled) {
 		return new GoLegacyDocumentSymbolProvider(includeImports);
 	}
-	return new GoplsDocumentSymbolProvider(includeImports);
+	return new GoplsDocumentSymbolProvider(goCtx, includeImports);
 }
 
 const GOPLS_LIST_IMPORTS = 'gopls.list_imports';
 export class GoplsDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
-	constructor(private includeImports?: boolean) {}
+	constructor(private readonly goCtx: GoExtensionContext, private includeImports?: boolean) {}
 
 	public async provideDocumentSymbols(document: vscode.TextDocument): Promise<vscode.DocumentSymbol[]> {
 		if (typeof this.includeImports !== 'boolean') {
 			const gotoSymbolConfig = getGoConfig(document.uri)['gotoSymbol'];
 			this.includeImports = gotoSymbolConfig ? gotoSymbolConfig['includeImports'] : false;
 		}
-		const { languageClient, serverInfo } = goCtx;
+		const { languageClient, serverInfo } = this.goCtx;
 		if (!languageClient) {
 			return [];
 		}
@@ -66,7 +67,7 @@
 		packageSymbol.children = symbols;
 		if (this.includeImports && serverInfo?.Commands?.includes(GOPLS_LIST_IMPORTS)) {
 			try {
-				const imports = await listImports(document);
+				const imports = await listImports(this.goCtx, document);
 				imports?.forEach((value) => {
 					packageSymbol.children.unshift(
 						new vscode.DocumentSymbol(
@@ -86,7 +87,10 @@
 	}
 }
 
-async function listImports(document: vscode.TextDocument): Promise<{ Path: string; Name: string }[]> {
+async function listImports(
+	goCtx: GoExtensionContext,
+	document: vscode.TextDocument
+): Promise<{ Path: string; Name: string }[]> {
 	const { languageClient } = goCtx;
 	const uri = languageClient?.code2ProtocolConverter.asTextDocumentIdentifier(document).uri;
 	const params: ExecuteCommandParams = {
diff --git a/src/goGenerateTests.ts b/src/goGenerateTests.ts
index 2a2d0f1..eb67da3 100644
--- a/src/goGenerateTests.ts
+++ b/src/goGenerateTests.ts
@@ -110,7 +110,7 @@
 		return false;
 	}
 
-	const functions = await getFunctions(editor.document);
+	const functions = await getFunctions(goCtx, editor.document);
 	const selection = editor.selection;
 	const currentFunction = functions.find((func) => selection && func.range.contains(selection.start));
 
@@ -235,8 +235,8 @@
 	});
 }
 
-async function getFunctions(doc: vscode.TextDocument): Promise<vscode.DocumentSymbol[]> {
-	const documentSymbolProvider = GoDocumentSymbolProvider();
+async function getFunctions(goCtx: GoExtensionContext, doc: vscode.TextDocument): Promise<vscode.DocumentSymbol[]> {
+	const documentSymbolProvider = GoDocumentSymbolProvider(goCtx);
 	const symbols = await documentSymbolProvider.provideDocumentSymbols(doc);
 	return symbols[0].children.filter((sym) =>
 		[vscode.SymbolKind.Function, vscode.SymbolKind.Method].includes(sym.kind)
diff --git a/src/goMain.ts b/src/goMain.ts
index dd7fece..41b8d31 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -77,9 +77,7 @@
 import { GoExtensionContext } from './context';
 import * as commands from './commands';
 
-// TODO: Remove this export. Temporarily exporting the context for import into the
-// legacy DocumentSymbolProvider.
-export const goCtx: GoExtensionContext = {
+const goCtx: GoExtensionContext = {
 	lastUserAction: new Date(),
 	crashCount: 0,
 	restartHistory: []
@@ -172,8 +170,8 @@
 
 	registerCommand('go.environment.status', expandGoStatusBar);
 
-	GoRunTestCodeLensProvider.activate(ctx);
-	GoReferencesCodeLensProvider.activate(ctx);
+	GoRunTestCodeLensProvider.activate(ctx, goCtx);
+	GoReferencesCodeLensProvider.activate(ctx, goCtx);
 	GoDebugConfigurationProvider.activate(ctx, goCtx);
 	GoDebugFactory.activate(ctx);
 
@@ -220,7 +218,7 @@
 	registerCommand('go.browse.packages', browsePackages);
 
 	if (isVscodeTestingAPIAvailable && cfg.get<boolean>('testExplorer.enable')) {
-		GoTestExplorer.setup(ctx);
+		GoTestExplorer.setup(ctx, goCtx);
 	}
 
 	GoExplorerProvider.setup(ctx);
diff --git a/src/goReferencesCodelens.ts b/src/goReferencesCodelens.ts
index 3dca097..dfb913f 100644
--- a/src/goReferencesCodelens.ts
+++ b/src/goReferencesCodelens.ts
@@ -15,6 +15,7 @@
 import { getBinPath } from './util';
 import vscode = require('vscode');
 import { GO_MODE } from './goMode';
+import { GoExtensionContext } from './context';
 
 const methodRegex = /^func\s+\(\s*\w+\s+\*?\w+\s*\)\s+/;
 
@@ -25,8 +26,8 @@
 }
 
 export class GoReferencesCodeLensProvider extends GoBaseCodeLensProvider {
-	static activate(ctx: vscode.ExtensionContext) {
-		const referencesCodeLensProvider = new this();
+	static activate(ctx: vscode.ExtensionContext, goCtx: GoExtensionContext) {
+		const referencesCodeLensProvider = new this(goCtx);
 		ctx.subscriptions.push(vscode.languages.registerCodeLensProvider(GO_MODE, referencesCodeLensProvider));
 		ctx.subscriptions.push(
 			vscode.workspace.onDidChangeConfiguration(async (e: vscode.ConfigurationChangeEvent) => {
@@ -41,6 +42,10 @@
 		);
 	}
 
+	constructor(private readonly goCtx: GoExtensionContext) {
+		super();
+	}
+
 	public provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable<CodeLens[]> {
 		if (!this.enabled) {
 			return [];
@@ -106,7 +111,7 @@
 		document: TextDocument,
 		token: CancellationToken
 	): Promise<vscode.DocumentSymbol[]> {
-		const symbolProvider = GoDocumentSymbolProvider();
+		const symbolProvider = GoDocumentSymbolProvider(this.goCtx);
 		const isTestFile = document.fileName.endsWith('_test.go');
 		const symbols = await symbolProvider.provideDocumentSymbols(document, token);
 		return symbols[0].children.filter((symbol) => {
diff --git a/src/goRunTestCodelens.ts b/src/goRunTestCodelens.ts
index 6450308..e17aa2c 100644
--- a/src/goRunTestCodelens.ts
+++ b/src/goRunTestCodelens.ts
@@ -17,8 +17,8 @@
 import { GO_MODE } from './goMode';
 
 export class GoRunTestCodeLensProvider extends GoBaseCodeLensProvider {
-	static activate(ctx: vscode.ExtensionContext) {
-		const testCodeLensProvider = new this();
+	static activate(ctx: vscode.ExtensionContext, goCtx: GoExtensionContext) {
+		const testCodeLensProvider = new this(goCtx);
 		ctx.subscriptions.push(vscode.languages.registerCodeLensProvider(GO_MODE, testCodeLensProvider));
 		ctx.subscriptions.push(
 			vscode.workspace.onDidChangeConfiguration(async (e: vscode.ConfigurationChangeEvent) => {
@@ -33,6 +33,10 @@
 		);
 	}
 
+	constructor(private readonly goCtx: GoExtensionContext) {
+		super();
+	}
+
 	private readonly benchmarkRegex = /^Benchmark.+/;
 
 	public async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
@@ -54,7 +58,7 @@
 	}
 
 	private async getCodeLensForPackage(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
-		const documentSymbolProvider = GoDocumentSymbolProvider();
+		const documentSymbolProvider = GoDocumentSymbolProvider(this.goCtx);
 		const symbols = await documentSymbolProvider.provideDocumentSymbols(document, token);
 		if (!symbols || symbols.length === 0) {
 			return [];
@@ -91,7 +95,7 @@
 
 	private async getCodeLensForFunctions(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
 		const testPromise = async (): Promise<CodeLens[]> => {
-			const testFunctions = await getTestFunctions(document, token);
+			const testFunctions = await getTestFunctions(this.goCtx, document, token);
 			if (!testFunctions) {
 				return [];
 			}
@@ -116,7 +120,7 @@
 		};
 
 		const benchmarkPromise = async (): Promise<CodeLens[]> => {
-			const benchmarkFunctions = await getBenchmarkFunctions(document, token);
+			const benchmarkFunctions = await getBenchmarkFunctions(this.goCtx, document, token);
 			if (!benchmarkFunctions) {
 				return [];
 			}
diff --git a/src/goTest.ts b/src/goTest.ts
index b4332e7..4e7fe44 100644
--- a/src/goTest.ts
+++ b/src/goTest.ts
@@ -9,6 +9,7 @@
 import vscode = require('vscode');
 import { CommandFactory } from './commands';
 import { getGoConfig } from './config';
+import { GoExtensionContext } from './context';
 import { isModSupported } from './goModules';
 import {
 	extractInstanceTestName,
@@ -35,7 +36,12 @@
 
 class NotFoundError extends Error {}
 
-async function _testAtCursor(goConfig: vscode.WorkspaceConfiguration, cmd: TestAtCursorCmd, args: any) {
+async function _testAtCursor(
+	goCtx: GoExtensionContext,
+	goConfig: vscode.WorkspaceConfiguration,
+	cmd: TestAtCursorCmd,
+	args: any
+) {
 	const editor = vscode.window.activeTextEditor;
 	if (!editor) {
 		throw new NotFoundError('No editor is active.');
@@ -45,7 +51,7 @@
 	}
 
 	const getFunctions = cmd === 'benchmark' ? getBenchmarkFunctions : getTestFunctions;
-	const testFunctions = (await getFunctions(editor.document)) ?? [];
+	const testFunctions = (await getFunctions(goCtx, editor.document)) ?? [];
 	// We use functionName if it was provided as argument
 	// Otherwise find any test function containing the cursor.
 	const testFunctionName =
@@ -75,9 +81,9 @@
  * @param args
  */
 export function testAtCursor(cmd: TestAtCursorCmd): CommandFactory {
-	return () => (args: any) => {
+	return (ctx, goCtx) => (args: any) => {
 		const goConfig = getGoConfig();
-		_testAtCursor(goConfig, cmd, args).catch((err) => {
+		_testAtCursor(goCtx, goConfig, cmd, args).catch((err) => {
 			if (err instanceof NotFoundError) {
 				vscode.window.showInformationMessage(err.message);
 			} else {
@@ -97,7 +103,7 @@
 	return (ctx, goCtx) => async (args: any) => {
 		const goConfig = getGoConfig();
 		try {
-			await _testAtCursor(goConfig, cmd, args);
+			await _testAtCursor(goCtx, goConfig, cmd, args);
 		} catch (err) {
 			if (err instanceof NotFoundError) {
 				const editor = vscode.window.activeTextEditor;
@@ -147,7 +153,7 @@
  * Executes the sub unit test at the primary cursor using `go test`. Output
  * is sent to the 'Go' channel.
  */
-export function subTestAtCursor() {
+export const subTestAtCursor: CommandFactory = (ctx, goCtx) => {
 	return async (args: any) => {
 		const goConfig = getGoConfig();
 		const editor = vscode.window.activeTextEditor;
@@ -162,7 +168,7 @@
 
 		await editor.document.save();
 		try {
-			const testFunctions = (await getTestFunctions(editor.document)) ?? [];
+			const testFunctions = (await getTestFunctions(goCtx, editor.document)) ?? [];
 			// We use functionName if it was provided as argument
 			// Otherwise find any test function containing the cursor.
 			const currentTestFunctions = testFunctions.filter((func) => func.range.contains(editor.selection.start));
@@ -214,7 +220,7 @@
 			console.error(err);
 		}
 	};
-}
+};
 
 /**
  * Debugs the test at cursor.
@@ -340,7 +346,7 @@
  * @param isBenchmark Boolean flag indicating if these are benchmark tests or not.
  */
 export function testCurrentFile(isBenchmark: boolean, getConfig = getGoConfig): CommandFactory {
-	return () => async (args: string[]) => {
+	return (ctx, goCtx) => async (args: string[]) => {
 		const goConfig = getConfig();
 		const editor = vscode.window.activeTextEditor;
 		if (!editor) {
@@ -358,7 +364,7 @@
 		return editor.document
 			.save()
 			.then(() => {
-				return getFunctions(editor.document).then((testFunctions) => {
+				return getFunctions(goCtx, editor.document).then((testFunctions) => {
 					const testConfig: TestConfig = {
 						goConfig,
 						dir: path.dirname(editor.document.fileName),
diff --git a/src/goTest/explore.ts b/src/goTest/explore.ts
index 412798e..8fd016b 100644
--- a/src/goTest/explore.ts
+++ b/src/goTest/explore.ts
@@ -24,6 +24,7 @@
 import { GoTestResolver, ProvideSymbols } from './resolve';
 import { GoTestRunner } from './run';
 import { GoTestProfiler } from './profile';
+import { GoExtensionContext } from '../context';
 
 // Set true only if the Testing API is available (VSCode version >= 1.59).
 export const isVscodeTestingAPIAvailable =
@@ -31,12 +32,12 @@
 	'object' === typeof (vscode as any).tests && 'function' === typeof (vscode as any).tests.createTestController;
 
 export class GoTestExplorer {
-	static setup(context: ExtensionContext): GoTestExplorer {
+	static setup(context: ExtensionContext, goCtx: GoExtensionContext): GoTestExplorer {
 		if (!isVscodeTestingAPIAvailable) throw new Error('VSCode Testing API is unavailable');
 
 		const ctrl = vscode.tests.createTestController('go', 'Go');
-		const symProvider = GoDocumentSymbolProvider(true);
-		const inst = new this(workspace, ctrl, context.workspaceState, (doc, token) =>
+		const symProvider = GoDocumentSymbolProvider(goCtx, true);
+		const inst = new this(goCtx, workspace, ctrl, context.workspaceState, (doc, token) =>
 			symProvider.provideDocumentSymbols(doc, token)
 		);
 
@@ -203,6 +204,7 @@
 	public readonly profiler: GoTestProfiler;
 
 	constructor(
+		private readonly goCtx: GoExtensionContext,
 		private readonly workspace: Workspace,
 		private readonly ctrl: TestController,
 		workspaceState: Memento,
@@ -210,7 +212,7 @@
 	) {
 		this.resolver = new GoTestResolver(workspace, ctrl, provideDocumentSymbols);
 		this.profiler = new GoTestProfiler(this.resolver, workspaceState);
-		this.runner = new GoTestRunner(workspace, ctrl, this.resolver, this.profiler);
+		this.runner = new GoTestRunner(goCtx, workspace, ctrl, this.resolver, this.profiler);
 	}
 
 	/* ***** Listeners ***** */
diff --git a/src/goTest/run.ts b/src/goTest/run.ts
index 75f425d..a323066 100644
--- a/src/goTest/run.ts
+++ b/src/goTest/run.ts
@@ -26,6 +26,7 @@
 import { dispose, forEachAsync, GoTest, Workspace } from './utils';
 import { GoTestProfiler, ProfilingOptions } from './profile';
 import { debugTestAtCursor } from '../goTest';
+import { GoExtensionContext } from '../context';
 
 let debugSessionID = 0;
 
@@ -74,6 +75,7 @@
 
 export class GoTestRunner {
 	constructor(
+		private readonly goCtx: GoExtensionContext,
 		private readonly workspace: Workspace,
 		private readonly ctrl: TestController,
 		private readonly resolver: GoTestResolver,
@@ -157,7 +159,7 @@
 
 		const goConfig = getGoConfig(test.uri);
 		const getFunctions = kind === 'benchmark' ? getBenchmarkFunctions : getTestFunctions;
-		const testFunctions = await getFunctions(doc, token);
+		const testFunctions = await getFunctions(this.goCtx, doc, token);
 
 		// TODO Can we get output from the debug session, in order to check for
 		// run/pass/fail events?
diff --git a/src/testUtils.ts b/src/testUtils.ts
index 8e8e42d..5497d8b 100644
--- a/src/testUtils.ts
+++ b/src/testUtils.ts
@@ -21,6 +21,7 @@
 import { parseEnvFile } from './utils/envUtils';
 import { envPath, expandFilePathInOutput, getCurrentGoRoot, getCurrentGoWorkspaceFromGOPATH } from './utils/pathUtils';
 import { killProcessTree } from './utils/processUtils';
+import { GoExtensionContext } from './context';
 
 const testOutputChannel = vscode.window.createOutputChannel('Go Tests');
 const STATUS_BAR_ITEM_NAME = 'Go Test Cancel';
@@ -141,10 +142,11 @@
  * @return test function symbols for the source file.
  */
 export async function getTestFunctions(
+	goCtx: GoExtensionContext,
 	doc: vscode.TextDocument,
 	token?: vscode.CancellationToken
 ): Promise<vscode.DocumentSymbol[] | undefined> {
-	const documentSymbolProvider = GoDocumentSymbolProvider(true);
+	const documentSymbolProvider = GoDocumentSymbolProvider(goCtx, true);
 	const symbols = await documentSymbolProvider.provideDocumentSymbols(doc, token);
 	if (!symbols || symbols.length === 0) {
 		return;
@@ -223,10 +225,11 @@
  * @return benchmark function symbols for the source file.
  */
 export async function getBenchmarkFunctions(
+	goCtx: GoExtensionContext,
 	doc: vscode.TextDocument,
 	token?: vscode.CancellationToken
 ): Promise<vscode.DocumentSymbol[] | undefined> {
-	const documentSymbolProvider = GoDocumentSymbolProvider();
+	const documentSymbolProvider = GoDocumentSymbolProvider(goCtx);
 	const symbols = await documentSymbolProvider.provideDocumentSymbols(doc, token);
 	if (!symbols || symbols.length === 0) {
 		return;
diff --git a/test/integration/codelens.test.ts b/test/integration/codelens.test.ts
index ca6f093..30d0d0f 100644
--- a/test/integration/codelens.test.ts
+++ b/test/integration/codelens.test.ts
@@ -10,12 +10,12 @@
 import path = require('path');
 import sinon = require('sinon');
 import vscode = require('vscode');
-import { getGoConfig } from '../../src/config';
 import { updateGoVarsFromConfig } from '../../src/goInstallTools';
 import { GoExtensionContext } from '../../src/context';
 import { GoRunTestCodeLensProvider } from '../../src/goRunTestCodelens';
 import { subTestAtCursor } from '../../src/goTest';
 import { getCurrentGoPath, getGoVersion } from '../../src/util';
+import { MockExtensionContext } from '../mocks/MockContext';
 
 suite('Code lenses for testing and benchmarking', function () {
 	this.timeout(20000);
@@ -28,15 +28,16 @@
 	let goConfig: vscode.WorkspaceConfiguration;
 	let document: vscode.TextDocument;
 
+	const ctx = new MockExtensionContext() as any;
+	const goCtx: GoExtensionContext = {
+		lastUserAction: new Date(),
+		crashCount: 0,
+		restartHistory: []
+	};
 	const cancellationTokenSource = new vscode.CancellationTokenSource();
-	const codeLensProvider = new GoRunTestCodeLensProvider();
+	const codeLensProvider = new GoRunTestCodeLensProvider(goCtx);
 
 	suiteSetup(async () => {
-		const goCtx: GoExtensionContext = {
-			lastUserAction: new Date(),
-			crashCount: 0,
-			restartHistory: []
-		};
 		await updateGoVarsFromConfig(goCtx);
 
 		gopath = getCurrentGoPath();
@@ -69,21 +70,21 @@
 	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()([]);
+		const result = await subTestAtCursor(ctx, 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()([]);
+		const result = await subTestAtCursor(ctx, 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()([]);
+		const result = await subTestAtCursor(ctx, goCtx)([]);
 		assert.equal(result, false);
 	});
 
@@ -91,7 +92,7 @@
 		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()([]);
+		const result = await subTestAtCursor(ctx, goCtx)([]);
 		assert.equal(result, undefined);
 	});
 
@@ -99,21 +100,21 @@
 		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()([]);
+		const result = await subTestAtCursor(ctx, 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()([]);
+		const result = await subTestAtCursor(ctx, 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()({ functionName: 'TestMyFunction' });
+		const result = await subTestAtCursor(ctx, goCtx)({ functionName: 'TestMyFunction' });
 		assert.equal(result, undefined);
 	});
 
diff --git a/test/integration/extension.test.ts b/test/integration/extension.test.ts
index 5377284..2a6f93e 100644
--- a/test/integration/extension.test.ts
+++ b/test/integration/extension.test.ts
@@ -768,7 +768,12 @@
 	test('Test Outline document symbols', async () => {
 		const uri = vscode.Uri.file(path.join(fixturePath, 'outlineTest', 'test.go'));
 		const document = await vscode.workspace.openTextDocument(uri);
-		const symbolProvider = GoDocumentSymbolProvider();
+		const goCtx: GoExtensionContext = {
+			lastUserAction: new Date(),
+			crashCount: 0,
+			restartHistory: []
+		};
+		const symbolProvider = GoDocumentSymbolProvider(goCtx);
 
 		const outlines = await symbolProvider.provideDocumentSymbols(document, dummyCancellationSource.token);
 		const packages = outlines.filter((x) => x.kind === vscode.SymbolKind.Package);
diff --git a/test/integration/goTest.explore.test.ts b/test/integration/goTest.explore.test.ts
index 31a581f..7ee4b0f 100644
--- a/test/integration/goTest.explore.test.ts
+++ b/test/integration/goTest.explore.test.ts
@@ -15,6 +15,7 @@
 import { GoTestResolver } from '../../src/goTest/resolve';
 import * as testUtils from '../../src/testUtils';
 import { GoTest } from '../../src/goTest/utils';
+import { GoExtensionContext } from '../../src/context';
 
 type Files = Record<string, string | { contents: string; language: string }>;
 
@@ -30,7 +31,12 @@
 ) {
 	const ws = MockTestWorkspace.from(folders, files);
 	const ctrl = new MockTestController();
-	const expl = new ctor(ws, ctrl, new MockMemento(), getSymbols_Regex);
+	const goCtx: GoExtensionContext = {
+		lastUserAction: new Date(),
+		crashCount: 0,
+		restartHistory: []
+	};
+	const expl = new ctor(goCtx, ws, ctrl, new MockMemento(), getSymbols_Regex);
 	populateModulePathCache(ws);
 	return { ctrl, expl, ws };
 }
@@ -193,12 +199,17 @@
 	suite('stretchr', () => {
 		const fixtureDir = path.join(__dirname, '..', '..', '..', 'test', 'testdata', 'stretchrTestSuite');
 		const ctx = MockExtensionContext.new();
+		const goCtx: GoExtensionContext = {
+			lastUserAction: new Date(),
+			crashCount: 0,
+			restartHistory: []
+		};
 
 		let document: TextDocument;
 		let testExplorer: GoTestExplorer;
 
 		suiteSetup(async () => {
-			testExplorer = GoTestExplorer.setup(ctx);
+			testExplorer = GoTestExplorer.setup(ctx, goCtx);
 
 			const uri = Uri.file(path.join(fixtureDir, 'suite_test.go'));
 			document = await forceDidOpenTextDocument(workspace, testExplorer, uri);
diff --git a/test/integration/goTest.run.test.ts b/test/integration/goTest.run.test.ts
index ce4923f..c4619cf 100644
--- a/test/integration/goTest.run.test.ts
+++ b/test/integration/goTest.run.test.ts
@@ -7,6 +7,7 @@
 import { GoTestExplorer } from '../../src/goTest/explore';
 import { MockExtensionContext } from '../mocks/MockContext';
 import { GoTest } from '../../src/goTest/utils';
+import { GoExtensionContext } from '../../src/context';
 
 suite('Go Test Runner', () => {
 	const fixtureDir = path.join(__dirname, '..', '..', '..', 'test', 'testdata');
@@ -16,12 +17,17 @@
 	suite('Profile', () => {
 		const sandbox = sinon.createSandbox();
 		const ctx = MockExtensionContext.new();
+		const goCtx: GoExtensionContext = {
+			lastUserAction: new Date(),
+			crashCount: 0,
+			restartHistory: []
+		};
 
 		let uri: Uri;
 		let stub: sinon.SinonStub<[testUtils.TestConfig], Promise<boolean>>;
 
 		suiteSetup(async () => {
-			testExplorer = GoTestExplorer.setup(ctx);
+			testExplorer = GoTestExplorer.setup(ctx, goCtx);
 
 			uri = Uri.file(path.join(fixtureDir, 'codelens', 'codelens2_test.go'));
 			await forceDidOpenTextDocument(workspace, testExplorer, uri);
@@ -98,12 +104,17 @@
 		const sandbox = sinon.createSandbox();
 		const subTestDir = path.join(fixtureDir, 'subTest');
 		const ctx = MockExtensionContext.new();
+		const goCtx: GoExtensionContext = {
+			lastUserAction: new Date(),
+			crashCount: 0,
+			restartHistory: []
+		};
 
 		let uri: Uri;
 		let spy: sinon.SinonSpy<[testUtils.TestConfig], Promise<boolean>>;
 
 		suiteSetup(async () => {
-			testExplorer = GoTestExplorer.setup(ctx);
+			testExplorer = GoTestExplorer.setup(ctx, goCtx);
 
 			uri = Uri.file(path.join(subTestDir, 'sub_test.go'));
 			await forceDidOpenTextDocument(workspace, testExplorer, uri);