src/stateUtils.ts: add command to reset memento state
It may sometimes be necessary to reset the memento state,
particularly for testing the extension's behavior when the
state is different.
Change-Id: I8cfed3b8b49a0f5064b4927e86772d32ea358a54
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/285679
Trust: Suzy Mueller <suzmue@golang.org>
Run-TryBot: Suzy Mueller <suzmue@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/docs/commands.md b/docs/commands.md
index 7777fab..9e4cbe5 100644
--- a/docs/commands.md
+++ b/docs/commands.md
@@ -207,6 +207,14 @@
Reset the current Go survey configuration history
+### `Go: Reset Workspace State`
+
+Reset keys in workspace state to undefined.
+
+### `Go: Reset Global State`
+
+Reset keys in global state to undefined.
+
### `Go: Toggle Workspace Trust Flag`
Toggle the workspace trust flag. Workspace settings that determine tool locations are disabled by default in untrusted workspaces.
diff --git a/package.json b/package.json
index 0556c31..a46cc30 100644
--- a/package.json
+++ b/package.json
@@ -402,6 +402,16 @@
"description": "Reset the current Go survey configuration history"
},
{
+ "command": "go.workspace.resetState",
+ "title": "Go: Reset Workspace State",
+ "description": "Reset keys in workspace state to undefined."
+ },
+ {
+ "command": "go.global.resetState",
+ "title": "Go: Reset Global State",
+ "description": "Reset keys in global state to undefined."
+ },
+ {
"command": "go.workspace.isTrusted.toggle",
"title": "Go: Toggle Workspace Trust Flag",
"description": "Toggle the workspace trust flag. Workspace settings that determine tool locations are disabled by default in untrusted workspaces."
diff --git a/src/goMain.ts b/src/goMain.ts
index b2c0b81..890a324 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -54,7 +54,13 @@
import { vetCode } from './goVet';
import { pickProcess } from './pickProcess';
import {
- getFromGlobalState, getFromWorkspaceState, setGlobalState, setWorkspaceState, updateGlobalState,
+ getFromGlobalState,
+ getFromWorkspaceState,
+ resetGlobalState,
+ resetWorkspaceState,
+ setGlobalState,
+ setWorkspaceState,
+ updateGlobalState,
updateWorkspaceState
} from './stateUtils';
import { cancelRunningTests, showTestOutput } from './testUtils';
@@ -507,10 +513,17 @@
showServerOutputChannel();
}));
- ctx.subscriptions.push(
- vscode.commands.registerCommand('go.welcome', () => {
- WelcomePanel.createOrShow(ctx.extensionUri);
- }));
+ ctx.subscriptions.push(vscode.commands.registerCommand('go.welcome', () => {
+ WelcomePanel.createOrShow(ctx.extensionUri);
+ }));
+
+ ctx.subscriptions.push(vscode.commands.registerCommand('go.workspace.resetState', () => {
+ resetWorkspaceState();
+ }));
+
+ ctx.subscriptions.push(vscode.commands.registerCommand('go.global.resetState', () => {
+ resetGlobalState();
+ }));
ctx.subscriptions.push(vscode.commands.registerCommand('go.toggle.gc_details', () => {
if (!languageServerIsRunning) {
diff --git a/src/stateUtils.ts b/src/stateUtils.ts
index cb57157..2f93a2f 100644
--- a/src/stateUtils.ts
+++ b/src/stateUtils.ts
@@ -30,6 +30,10 @@
return globalState;
}
+export function resetGlobalState() {
+ resetStateQuickPick(globalState, updateGlobalState);
+}
+
export function getFromWorkspaceState(key: string, defaultValue?: any) {
if (!workspaceState) {
return defaultValue;
@@ -51,3 +55,40 @@
export function getWorkspaceState(): vscode.Memento {
return workspaceState;
}
+
+export function resetWorkspaceState() {
+ const keys = getMementoKeys(workspaceState);
+ resetStateQuickPick(workspaceState, updateWorkspaceState);
+}
+
+export function getMementoKeys(state: vscode.Memento): string[] {
+ if (!state) {
+ return [];
+ }
+ // tslint:disable-next-line: no-empty
+ if ((state as any)._value) {
+ const keys = Object.keys((state as any)._value);
+ // Filter out keys with undefined values, so they are not shown
+ // in the quick pick menu.
+ return keys.filter((key) => state.get(key) !== undefined);
+ }
+ return [];
+}
+
+async function resetStateQuickPick(state: vscode.Memento, updateFn: (key: string, value: any) => {}) {
+ const items = await vscode.window.showQuickPick(
+ getMementoKeys(state),
+ {
+ canPickMany: true,
+ placeHolder: 'Select the keys to reset.'
+ }
+ );
+ resetItemsState(items, updateFn);
+}
+
+export function resetItemsState(items: string[], updateFn: (key: string, value: any) => {}) {
+ if (!items) {
+ return;
+ }
+ items.forEach((item) => updateFn(item, undefined));
+}
diff --git a/test/integration/stateUtils.test.ts b/test/integration/stateUtils.test.ts
new file mode 100644
index 0000000..cd80b12
--- /dev/null
+++ b/test/integration/stateUtils.test.ts
@@ -0,0 +1,100 @@
+/*---------------------------------------------------------
+ * Copyright 2021 The Go Authors. All rights reserved.
+ * Licensed under the MIT License. See LICENSE in the project root for license information.
+ *--------------------------------------------------------*/
+
+import * as assert from 'assert';
+import * as vscode from 'vscode';
+import { getMementoKeys, getWorkspaceState, resetItemsState, setWorkspaceState, updateWorkspaceState } from '../../src/stateUtils';
+import { MockMemento } from '../mocks/MockMemento';
+
+suite('Workspace State Modification Tests', () => {
+ let defaultMemento: vscode.Memento;
+
+ setup(async () => {
+ defaultMemento = getWorkspaceState();
+ });
+
+ teardown(async () => {
+ setWorkspaceState(defaultMemento);
+ });
+
+ test('test getMementoKeys', () => {
+ interface TestCase {
+ keys: string[];
+ values: any[];
+ want: string[];
+ }
+ const testCases: TestCase[] = [
+ {keys: [], values: [], want: []},
+ {keys: ['hello'], values: [false], want: ['hello']},
+ {keys: ['hello', 'goodbye'], values: [false, 25], want: ['hello', 'goodbye']},
+ ];
+
+ testCases.forEach((tc) => {
+ setWorkspaceState(new MockMemento());
+
+ const keys = tc.keys;
+ const values = tc.values;
+ assert.strictEqual(keys.length, values.length, 'List of keys and values does not have same length');
+
+ for (let i = 0; i < keys.length; i ++) {
+ updateWorkspaceState(keys[i], values[i]);
+ }
+
+ const got = getMementoKeys(getWorkspaceState());
+ const want = tc.want;
+
+ assert.strictEqual(got.length, tc.want.length);
+ got.forEach((key) => {
+ assert.ok(want.includes(key));
+ });
+ });
+ });
+
+ test('test resetItemsState', () => {
+ interface TestCase {
+ keys: string[];
+ values: any[];
+ items: string[];
+ want: string[];
+ }
+ const testCases: TestCase[] = [
+ {keys: [], values: [], items: undefined, want: []},
+ {keys: ['hello'], values: [false], items: undefined, want: ['hello']},
+ {keys: ['hello', 'goodbye'], values: [false, 25], items: undefined, want: ['hello', 'goodbye']},
+
+ {keys: [], values: [], items: [], want: []},
+ {keys: ['hello'], values: [false], items: [], want: ['hello']},
+ {keys: ['hello', 'goodbye'], values: [false, 25], items: [], want: ['hello', 'goodbye']},
+
+ {keys: ['hello'], values: [false], items: ['hello'], want: []},
+ {keys: ['hello', 'goodbye'], values: [false, 25], items: ['hello'], want: ['goodbye']},
+
+ {keys: ['hello'], values: [false], items: ['hello'], want: []},
+ {keys: ['hello', 'goodbye'], values: [false, 25], items: ['hello', 'goodbye'], want: []},
+ ];
+
+ testCases.forEach((tc) => {
+ setWorkspaceState(new MockMemento());
+
+ const keys = tc.keys;
+ const values = tc.values;
+ assert.strictEqual(keys.length, values.length, 'List of keys and values does not have same length');
+
+ for (let i = 0; i < keys.length; i ++) {
+ updateWorkspaceState(keys[i], values[i]);
+ }
+
+ resetItemsState(tc.items, updateWorkspaceState);
+ const got = getMementoKeys(getWorkspaceState());
+ const want = tc.want;
+
+ assert.strictEqual(got.length, want.length);
+ got.forEach((key) => {
+ assert.ok(want.includes(key));
+ });
+ });
+ });
+
+});