Add workspace state to app container (#1902)

This commit is contained in:
Charis Kyriakou
2022-12-21 17:58:34 +00:00
committed by GitHub
parent 7004e94b32
commit 19a9ad38d5
5 changed files with 84 additions and 0 deletions

View File

@@ -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 {

View 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>;
}

View File

@@ -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;
}

View File

@@ -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,
};

View 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();
}
}