Add units tests for Notebook Actions (#8595)

This commit is contained in:
Cory Rivera
2019-12-09 15:37:40 -08:00
committed by GitHub
parent 4fc6f4a13e
commit 184d4bbe27
6 changed files with 327 additions and 117 deletions

View File

@@ -12,13 +12,13 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/
import { NotebookModel } from 'sql/workbench/contrib/notebook/browser/models/notebookModel';
import { ICellModel, CellExecutionState } from 'sql/workbench/contrib/notebook/browser/models/modelInterfaces';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { MultiStateAction, IMultiStateData } from 'sql/workbench/contrib/notebook/browser/notebookActions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ILogService } from 'vs/platform/log/common/log';
import { getErrorMessage } from 'vs/base/common/errors';
let notebookMoreActionMsg = localize('notebook.failed', "Please select active cell and try again");
const emptyExecutionCountLabel = '[ ]';
const HIDE_ICON_CLASS = ' hideIcon';
function hasModelAndCell(context: CellContext, notificationService: INotificationService): boolean {
if (!context || !context.model) {
@@ -63,6 +63,96 @@ export abstract class CellActionBase extends Action {
abstract doRun(context: CellContext): Promise<void>;
}
interface IActionStateData {
className?: string;
label?: string;
tooltip?: string;
hideIcon?: boolean;
commandId?: string;
}
class IMultiStateData<T> {
private _stateMap = new Map<T, IActionStateData>();
constructor(mappings: { key: T, value: IActionStateData }[], private _state: T, private _baseClass?: string) {
if (mappings) {
mappings.forEach(s => this._stateMap.set(s.key, s.value));
}
}
public set state(value: T) {
if (!this._stateMap.has(value)) {
throw new Error('State value must be in stateMap');
}
this._state = value;
}
public updateStateData(state: T, updater: (data: IActionStateData) => void): void {
let data = this._stateMap.get(state);
if (data) {
updater(data);
}
}
public get classes(): string {
let classVal = this.getStateValueOrDefault<string>((data) => data.className, '');
let classes = this._baseClass ? `${this._baseClass} ` : '';
classes += classVal;
if (this.getStateValueOrDefault<boolean>((data) => data.hideIcon, false)) {
classes += HIDE_ICON_CLASS;
}
return classes;
}
public get label(): string {
return this.getStateValueOrDefault<string>((data) => data.label, '');
}
public get tooltip(): string {
return this.getStateValueOrDefault<string>((data) => data.tooltip, '');
}
public get commandId(): string {
return this.getStateValueOrDefault<string>((data) => data.commandId, '');
}
private getStateValueOrDefault<U>(getter: (data: IActionStateData) => U, defaultVal?: U): U {
let data = this._stateMap.get(this._state);
return data ? getter(data) : defaultVal;
}
}
abstract class MultiStateAction<T> extends Action {
constructor(
id: string,
protected states: IMultiStateData<T>,
private _keybindingService: IKeybindingService,
private readonly logService: ILogService) {
super(id, '');
this.updateLabelAndIcon();
}
private updateLabelAndIcon() {
let keyboardShortcut: string;
try {
// If a keyboard shortcut exists for the command id passed in, append that to the label
if (this.states.commandId !== '') {
let binding = this._keybindingService.lookupKeybinding(this.states.commandId);
keyboardShortcut = binding ? binding.getLabel() : undefined;
}
} catch (error) {
this.logService.error(error);
}
this.label = this.states.label;
this.tooltip = keyboardShortcut ? this.states.tooltip + ` (${keyboardShortcut})` : this.states.tooltip;
this.class = this.states.classes;
}
protected updateState(state: T): void {
this.states.state = state;
this.updateLabelAndIcon();
}
}
export class RunCellAction extends MultiStateAction<CellExecutionState> {
public static ID = 'notebook.runCell';
public static LABEL = 'Run cell';