Add workspace state to app container (#1902)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Disposable } from "../pure/disposable-object";
|
||||
import { AppEventEmitter } from "./events";
|
||||
import { Logger } from "./logging";
|
||||
import { Memento } from "./memento";
|
||||
|
||||
export interface App {
|
||||
createEventEmitter<T>(): AppEventEmitter<T>;
|
||||
@@ -11,6 +12,7 @@ export interface App {
|
||||
extensionPath: string;
|
||||
globalStoragePath: string;
|
||||
workspaceStoragePath?: string;
|
||||
workspaceState: Memento;
|
||||
}
|
||||
|
||||
export enum AppMode {
|
||||
|
||||
44
extensions/ql-vscode/src/common/memento.ts
Normal file
44
extensions/ql-vscode/src/common/memento.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* A memento represents a storage utility. It can store and retrieve
|
||||
* values.
|
||||
*
|
||||
* It is an interface used by the VS Code API. We replicate it here
|
||||
* to avoid the dependency to the VS Code API.
|
||||
*/
|
||||
export interface Memento {
|
||||
/**
|
||||
* Returns the stored keys.
|
||||
*
|
||||
* @return The stored keys.
|
||||
*/
|
||||
keys(): readonly string[];
|
||||
|
||||
/**
|
||||
* Return a value.
|
||||
*
|
||||
* @param key A string.
|
||||
* @return The stored value or `undefined`.
|
||||
*/
|
||||
get<T>(key: string): T | undefined;
|
||||
|
||||
/**
|
||||
* Return a value.
|
||||
*
|
||||
* @param key A string.
|
||||
* @param defaultValue A value that should be returned when there is no
|
||||
* value (`undefined`) with the given key.
|
||||
* @return The stored value or the defaultValue.
|
||||
*/
|
||||
get<T>(key: string, defaultValue: T): T;
|
||||
|
||||
/**
|
||||
* Store a value. The value must be JSON-stringifyable.
|
||||
*
|
||||
* *Note* that using `undefined` as value removes the key from the underlying
|
||||
* storage.
|
||||
*
|
||||
* @param key A string.
|
||||
* @param value A value. MUST not contain cyclic references.
|
||||
*/
|
||||
update(key: string, value: any): Thenable<void>;
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { Disposable } from "../../pure/disposable-object";
|
||||
import { App, AppMode } from "../app";
|
||||
import { AppEventEmitter } from "../events";
|
||||
import { extLogger, Logger } from "../logging";
|
||||
import { Memento } from "../memento";
|
||||
import { VSCodeAppEventEmitter } from "./events";
|
||||
|
||||
export class ExtensionApp implements App {
|
||||
@@ -22,6 +23,10 @@ export class ExtensionApp implements App {
|
||||
return this.extensionContext.storageUri?.fsPath;
|
||||
}
|
||||
|
||||
public get workspaceState(): Memento {
|
||||
return this.extensionContext.workspaceState;
|
||||
}
|
||||
|
||||
public get subscriptions(): Disposable[] {
|
||||
return this.extensionContext.subscriptions;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { App, AppMode } from "../../src/common/app";
|
||||
import { AppEvent, AppEventEmitter } from "../../src/common/events";
|
||||
import { Memento } from "../../src/common/memento";
|
||||
import { Disposable } from "../../src/pure/disposable-object";
|
||||
import { createMockLogger } from "./loggerMock";
|
||||
import { createMockMemento } from "./mementoMock";
|
||||
|
||||
export function createMockApp({
|
||||
extensionPath = "/mock/extension/path",
|
||||
@@ -9,12 +11,14 @@ export function createMockApp({
|
||||
globalStoragePath = "/mock/global/storage/path",
|
||||
createEventEmitter = <T>() => new MockAppEventEmitter<T>(),
|
||||
executeCommand = jest.fn(() => Promise.resolve()),
|
||||
workspaceState = createMockMemento(),
|
||||
}: {
|
||||
extensionPath?: string;
|
||||
workspaceStoragePath?: string;
|
||||
globalStoragePath?: string;
|
||||
createEventEmitter?: <T>() => AppEventEmitter<T>;
|
||||
executeCommand?: () => Promise<void>;
|
||||
workspaceState?: Memento;
|
||||
}): App {
|
||||
return {
|
||||
mode: AppMode.Test,
|
||||
@@ -23,6 +27,7 @@ export function createMockApp({
|
||||
extensionPath,
|
||||
workspaceStoragePath,
|
||||
globalStoragePath,
|
||||
workspaceState,
|
||||
createEventEmitter,
|
||||
executeCommand,
|
||||
};
|
||||
|
||||
28
extensions/ql-vscode/test/__mocks__/mementoMock.ts
Normal file
28
extensions/ql-vscode/test/__mocks__/mementoMock.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Memento } from "../../src/common/memento";
|
||||
|
||||
export function createMockMemento(): Memento {
|
||||
return new MockMemento();
|
||||
}
|
||||
|
||||
export class MockMemento<T> implements Memento {
|
||||
private readonly map: Map<string, T>;
|
||||
|
||||
constructor() {
|
||||
this.map = new Map<string, T>();
|
||||
}
|
||||
|
||||
public keys(): readonly string[] {
|
||||
return Array.from(this.map.keys());
|
||||
}
|
||||
|
||||
public get<T>(key: string): T | undefined;
|
||||
public get<T>(key: string, defaultValue: T): T;
|
||||
public get(key: any, defaultValue?: any): T | T | undefined {
|
||||
return this.map.get(key) || defaultValue;
|
||||
}
|
||||
|
||||
public update(key: string, value: any): Thenable<void> {
|
||||
this.map.set(key, value);
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user