mirror of
https://github.com/VSCodeVim/Vim.git
synced 2024-09-11 12:25:59 +03:00
185 lines
5.6 KiB
TypeScript
185 lines
5.6 KiB
TypeScript
import { strict as assert } from 'assert';
|
|
import * as fs from 'fs';
|
|
import * as os from 'os';
|
|
import * as path from 'path';
|
|
import { join } from 'path';
|
|
import { promisify } from 'util';
|
|
import * as vscode from 'vscode';
|
|
|
|
import { ExCommandLine } from '../src/cmd_line/commandLine';
|
|
import { IConfiguration } from '../src/configuration/iconfiguration';
|
|
import { Globals } from '../src/globals';
|
|
import { StatusBar } from '../src/statusBar';
|
|
import { Configuration } from './testConfiguration';
|
|
|
|
class TestMemento implements vscode.Memento {
|
|
private mapping = new Map<string, any>();
|
|
get<T>(key: string): T | undefined;
|
|
get<T>(key: string, defaultValue: T): T;
|
|
get(key: any, defaultValue?: any) {
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-argument
|
|
return this.mapping.get(key) || defaultValue;
|
|
}
|
|
|
|
setKeysForSync(keys: string[]): void {
|
|
throw new Error('`TestMemento.setKeysForSync` is currently unimplemented');
|
|
}
|
|
|
|
async update(key: string, value: any): Promise<void> {
|
|
this.mapping.set(key, value);
|
|
}
|
|
|
|
keys(): readonly string[] {
|
|
return Array.from(this.mapping.keys());
|
|
}
|
|
}
|
|
|
|
export class TestExtensionContext implements vscode.ExtensionContext {
|
|
extension!: vscode.Extension<any>;
|
|
subscriptions: Array<{ dispose(): any }> = [];
|
|
workspaceState: vscode.Memento = new TestMemento();
|
|
globalState: vscode.Memento & {
|
|
setKeysForSync(keys: string[]): void;
|
|
} = new TestMemento();
|
|
secrets!: vscode.SecretStorage;
|
|
extensionUri!: vscode.Uri;
|
|
extensionPath: string = 'inmem:///test';
|
|
environmentVariableCollection!: vscode.EnvironmentVariableCollection;
|
|
|
|
asAbsolutePath(relativePath: string): string {
|
|
return path.resolve(this.extensionPath, relativePath);
|
|
}
|
|
|
|
storageUri: vscode.Uri | undefined;
|
|
storagePath: string | undefined;
|
|
globalStorageUri!: vscode.Uri;
|
|
globalStoragePath!: string;
|
|
logUri!: vscode.Uri;
|
|
logPath!: string;
|
|
extensionMode!: vscode.ExtensionMode;
|
|
}
|
|
|
|
export function rndName(): string {
|
|
return Math.random()
|
|
.toString(36)
|
|
.replace(/[^a-z]+/g, '')
|
|
.substring(0, 10);
|
|
}
|
|
|
|
export async function createRandomFile(contents: string, fileExtension: string): Promise<string> {
|
|
const tmpFile = join(os.tmpdir(), rndName() + fileExtension);
|
|
await promisify(fs.writeFile)(tmpFile, contents);
|
|
return tmpFile;
|
|
}
|
|
|
|
export async function createRandomDir() {
|
|
return createDir(join(os.tmpdir(), rndName()));
|
|
}
|
|
|
|
export async function createEmptyFile(fsPath: string) {
|
|
await promisify(fs.writeFile)(fsPath, '');
|
|
return fsPath;
|
|
}
|
|
|
|
export async function createDir(fsPath: string) {
|
|
await promisify(fs.mkdir)(fsPath);
|
|
return fsPath;
|
|
}
|
|
|
|
/**
|
|
* Waits for the number of text editors in the current window to equal the
|
|
* given expected number of text editors.
|
|
*
|
|
* @param numExpectedEditors Expected number of editors in the window
|
|
*/
|
|
export async function waitForEditorsToClose(numExpectedEditors: number = 0): Promise<void> {
|
|
const waitForTextEditorsToClose = new Promise<void>((c, e) => {
|
|
if (vscode.window.visibleTextEditors.length === numExpectedEditors) {
|
|
return c();
|
|
}
|
|
|
|
const subscription = vscode.window.onDidChangeVisibleTextEditors(() => {
|
|
if (vscode.window.visibleTextEditors.length === numExpectedEditors) {
|
|
subscription.dispose();
|
|
c();
|
|
}
|
|
});
|
|
});
|
|
|
|
try {
|
|
await waitForTextEditorsToClose;
|
|
} catch (error) {
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
assert.fail(error);
|
|
}
|
|
}
|
|
|
|
export function assertEqualLines(expectedLines: string[]) {
|
|
assert.strictEqual(
|
|
vscode.window.activeTextEditor?.document.getText(),
|
|
expectedLines.join(os.EOL),
|
|
'Document content does not match.',
|
|
);
|
|
}
|
|
|
|
export function assertStatusBarEqual(
|
|
expectedText: string,
|
|
message: string = 'Status bar text does not match',
|
|
) {
|
|
assert.strictEqual(StatusBar.getText(), expectedText, message);
|
|
}
|
|
|
|
// TODO: convert parameters to destructured object & make config: Partial<IConfiguration>
|
|
export async function setupWorkspace(
|
|
config: IConfiguration = new Configuration(),
|
|
fileExtension: string = '',
|
|
): Promise<void> {
|
|
await ExCommandLine.loadHistory(new TestExtensionContext());
|
|
|
|
const filePath = await createRandomFile('', fileExtension);
|
|
const doc = await vscode.workspace.openTextDocument(vscode.Uri.file(filePath));
|
|
await vscode.window.showTextDocument(doc);
|
|
|
|
Globals.mockConfiguration = config;
|
|
await reloadConfiguration();
|
|
|
|
const activeTextEditor = vscode.window.activeTextEditor;
|
|
assert.ok(activeTextEditor);
|
|
|
|
activeTextEditor.options.tabSize = config.tabstop;
|
|
activeTextEditor.options.insertSpaces = config.expandtab;
|
|
}
|
|
|
|
export async function cleanUpWorkspace(): Promise<void> {
|
|
await vscode.commands.executeCommand('workbench.action.closeAllEditors');
|
|
assert.strictEqual(vscode.window.visibleTextEditors.length, 0, 'Expected all editors closed.');
|
|
assert(!vscode.window.activeTextEditor, 'Expected no active text editor.');
|
|
}
|
|
|
|
export async function reloadConfiguration() {
|
|
const validatorResults = await (
|
|
await import('../src/configuration/configuration')
|
|
).configuration.load();
|
|
for (const validatorResult of validatorResults.get()) {
|
|
console.warn(validatorResult);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Waits for the tabs to change after a command like 'gt' or 'gT' is run.
|
|
* Sometimes it is not immediate, so we must busy wait
|
|
* On certain versions, the tab changes are synchronous
|
|
* For those, a timeout is given
|
|
*/
|
|
export async function waitForTabChange(): Promise<void> {
|
|
await new Promise((resolve, reject) => {
|
|
setTimeout(resolve, 500);
|
|
|
|
const subscription = vscode.window.onDidChangeActiveTextEditor((textEditor) => {
|
|
subscription.dispose();
|
|
|
|
resolve(textEditor);
|
|
});
|
|
});
|
|
}
|