test/gopls: fix strict type errors

For golang/vscode-go#56.

Change-Id: Icacb414ebd54f6511102e7a0cc0af3cf5cf5d934
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/403776
Run-TryBot: Jamal Carvalho <jamal@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/test/gopls/extension.test.ts b/test/gopls/extension.test.ts
index 53c1684..246672c 100644
--- a/test/gopls/extension.test.ts
+++ b/test/gopls/extension.test.ts
@@ -65,14 +65,14 @@
 // Currently, this works only in module-aware mode.
 class Env {
 	public languageClient?: LanguageClient;
-	private fakeOutputChannel: FakeOutputChannel;
+	private fakeOutputChannel?: FakeOutputChannel;
 	private disposables = [] as { dispose(): any }[];
 
 	public flushTrace(print: boolean) {
 		if (print) {
-			console.log(this.fakeOutputChannel.toString());
+			console.log(this.fakeOutputChannel?.toString());
 		}
-		this.fakeOutputChannel.clear();
+		this.fakeOutputChannel?.clear();
 	}
 
 	// This is a hack to check the progress of package loading.
@@ -84,7 +84,7 @@
 				this.flushTrace(true);
 				reject(`Timed out while waiting for '${msg}'`);
 			}, timeoutMS);
-			this.fakeOutputChannel.onPattern(msg, () => {
+			this.fakeOutputChannel?.onPattern(msg, () => {
 				clearTimeout(timeout);
 				resolve();
 			});
@@ -105,6 +105,9 @@
 		const cfg: BuildLanguageClientOption = buildLanguageServerConfig(goConfig);
 		cfg.outputChannel = this.fakeOutputChannel; // inject our fake output channel.
 		this.languageClient = await buildLanguageClient(cfg);
+		if (!this.languageClient) {
+			throw new Error('Language client not initialized.');
+		}
 		this.disposables.push(this.languageClient.start());
 
 		await this.languageClient.onReady();
@@ -148,7 +151,7 @@
 		// 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');
+		env.flushTrace(this.currentTest?.state === 'failed');
 	});
 
 	test('HoverProvider', async () => {
@@ -204,7 +207,7 @@
 		const { uri } = await env.openDoc(testdataDir, 'gogetdocTestData', 'test.go');
 		const testCases: [string, vscode.Position, string][] = [['fmt.P<>', new vscode.Position(19, 6), 'Print']];
 		for (const [name, position, wantFilterText] of testCases) {
-			let list: vscode.CompletionList<vscode.CompletionItem>;
+			let list: vscode.CompletionList<vscode.CompletionItem> | undefined;
 			// Query completion items. We expect the hard coded filter text hack
 			// has been applied and gopls returns an incomplete list by default
 			// to avoid reordering by vscode. But, if the query is made before
@@ -225,7 +228,7 @@
 				console.log(`${new Date()}: retrying...`);
 			}
 			// Confirm that the hardcoded filter text hack has been applied.
-			if (!list.isIncomplete) {
+			if (!list || !list.isIncomplete) {
 				assert.fail('gopls should provide an incomplete list by default');
 			}
 
diff --git a/test/gopls/survey.test.ts b/test/gopls/survey.test.ts
index 51f1a20..0d9c169 100644
--- a/test/gopls/survey.test.ts
+++ b/test/gopls/survey.test.ts
@@ -13,7 +13,7 @@
 suite('gopls survey tests', () => {
 	test('prompt for survey', () => {
 		// global state -> offer survey
-		const testCases: [goSurvey.GoplsSurveyConfig, boolean][] = [
+		const testCases: [goSurvey.GoplsSurveyConfig, boolean | undefined][] = [
 			// User who is activating the extension for the first time.
 			[{}, true],
 			// User who has already taken the survey.
@@ -99,7 +99,7 @@
 
 	test('prompt for survey', () => {
 		// global state -> offer survey
-		const testCases: [goDeveloperSurvey.DeveloperSurveyConfig, boolean][] = [
+		const testCases: [goDeveloperSurvey.DeveloperSurveyConfig, boolean | undefined][] = [
 			// User who is activating the extension for the first time.
 			[{}, true],
 			// User who has already taken the survey.
@@ -231,7 +231,7 @@
 			if (choice === 'Yes') assert.strictEqual(got.prompt, false, 'unexpected prompt config stored');
 			if (wantCount > 0)
 				assert(
-					got.lastDatePrompted >= today,
+					got.lastDatePrompted && got.lastDatePrompted >= today,
 					`unexpected lastDatePrompted: ${JSON.stringify(got.lastDatePrompted)}`
 				);
 		});
diff --git a/test/gopls/update.test.ts b/test/gopls/update.test.ts
index f56b19b..61af046 100644
--- a/test/gopls/update.test.ts
+++ b/test/gopls/update.test.ts
@@ -23,7 +23,7 @@
 	const defaultConfigInspector = getGoConfig().inspect(CHECK_FOR_UPDATES);
 
 	test('default is as expected', () => {
-		const { key, defaultValue, globalValue, workspaceValue } = defaultConfigInspector;
+		const { key, defaultValue, globalValue, workspaceValue } = defaultConfigInspector ?? {};
 		assert.deepStrictEqual(
 			{ key, defaultValue, globalValue, workspaceValue },
 			{
@@ -120,10 +120,10 @@
 		const latestPrereleaseVersionTimestamp = moment('2020-05-20', 'YYYY-MM-DD');
 
 		// name, usersVersion, acceptPrerelease, want
-		const testCases: [string, string, boolean, semver.SemVer][] = [
+		const testCases: [string, string, boolean, semver.SemVer | null][] = [
 			['outdated, tagged', 'v0.3.1', false, latestVersion],
 			['outdated, tagged (pre-release)', '0.3.1', true, latestPrereleaseVersion],
-			['up-to-date, tagged', latestVersion.format(), false, null],
+			['up-to-date, tagged', latestVersion?.format() ?? '', false, null],
 			['up-to-date tagged (pre-release)', 'v0.4.0', true, latestPrereleaseVersion],
 			['developer version', '(devel)', false, null],
 			['developer version (pre-release)', '(devel)', true, null],
@@ -167,11 +167,12 @@
 				if (version === latestPrereleaseVersion) {
 					return latestPrereleaseVersionTimestamp;
 				}
+				return null;
 			});
 			const got = await lsp.shouldUpdateLanguageServer(tool, {
 				enabled: true,
 				path: 'bad/path/to/gopls',
-				version: null,
+				version: undefined,
 				checkForUpdates: 'proxy',
 				env: {},
 				features: {
@@ -201,7 +202,7 @@
 		assert.strictEqual(
 			expected,
 			got,
-			`hard-coded minimum: ${tool.latestVersion.toString()} vs localVersion: ${moduleVersion}`
+			`hard-coded minimum: ${tool.latestVersion?.toString()} vs localVersion: ${moduleVersion}`
 		);
 	}
 
@@ -210,24 +211,24 @@
 	});
 
 	test('local delve is the minimum required version', async () => {
-		await testShouldUpdateTool(false, 'v' + latestVersion.toString());
+		await testShouldUpdateTool(false, 'v' + latestVersion?.toString());
 	});
 
 	test('local delve is newer', async () => {
-		await testShouldUpdateTool(false, `v${latestVersion.major}.${latestVersion.minor + 1}.0`);
+		await testShouldUpdateTool(false, `v${latestVersion?.major}.${(latestVersion?.minor ?? 0) + 1}.0`);
 	});
 
 	test('local delve is slightly older', async () => {
 		await testShouldUpdateTool(
 			true,
-			`v${latestVersion.major}.${latestVersion.minor}.${latestVersion.patch}-0.20201231000000-5360c6286949`
+			`v${latestVersion?.major}.${latestVersion?.minor}.${latestVersion?.patch}-0.20201231000000-5360c6286949`
 		);
 	});
 
 	test('local delve is slightly newer', async () => {
 		await testShouldUpdateTool(
 			false,
-			`v{$latestVersion.major}.${latestVersion.minor}.${latestVersion.patch}-0.30211231000000-5360c6286949`
+			`v{$latestVersion.major}.${latestVersion?.minor}.${latestVersion?.patch}-0.30211231000000-5360c6286949`
 		);
 	});
 
diff --git a/tsconfig.strict.json b/tsconfig.strict.json
index 21f3f44..e25c93e 100644
--- a/tsconfig.strict.json
+++ b/tsconfig.strict.json
@@ -3,6 +3,7 @@
 	"exclude": [
 		"node_modules",
 		"third_party",
-		"test"
+		"test/integration",
+		"test/mocks"
 	]
 }
\ No newline at end of file