Inital platform relayering (#6385)

* moving test files and inital refactoring

* relayer extension host code

* fix imports

* make insights work

* relayer dashboard

* relayer notebooks

* moveing more code around

* formatting

* accept angular as browser

* fix serializer

* add missing files

* remove declarations from extensions

* fix build errors

* more relayering

* change urls to relative to help code relayering

* remove layering to prep for merge

* fix hygiene errors

* fix hygiene errors

* fix tests
This commit is contained in:
Anthony Dresser
2019-07-18 17:29:17 -07:00
committed by GitHub
parent 45c13116de
commit c23738f935
576 changed files with 2090 additions and 2788 deletions

View File

@@ -14,7 +14,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
import { MouseWheelSupport } from 'sql/base/browser/ui/table/plugins/mousewheelTableScroll.plugin';
import { AutoColumnSize } from 'sql/base/browser/ui/table/plugins/autoSizeColumns.plugin';
import { AdditionalKeyBindings } from 'sql/base/browser/ui/table/plugins/additionalKeyBindings.plugin';
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/parts/query/browser/queryResultsEditor';
import { RESULTS_GRID_DEFAULTS } from 'sql/workbench/parts/query/common/resultsGridContribution';
/**
* Render DataResource as a grid into a host node.

View File

@@ -3,7 +3,7 @@
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/
import { IRenderMime } from './renderMimeInterfaces';
import { ReadonlyJSONObject } from '../../models/jsonext';
import { ReadonlyJSONObject } from './jsonext';
import { IThemeService } from 'vs/platform/theme/common/themeService';
/**

View File

@@ -4,9 +4,9 @@
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/
import { JSONObject, isPrimitive } from '../../models/jsonext';
import { JSONObject, isPrimitive } from './jsonext';
import { MimeModel } from './mimemodel';
import { nbformat } from '../../models/nbformat';
import { nbformat } from './nbformat';
import { nb } from 'azdata';
/**

View File

@@ -3,7 +3,7 @@
| Copyright (c) Jupyter Development Team.
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/
import { ReadonlyJSONObject } from '../../models/jsonext';
import { ReadonlyJSONObject } from './jsonext';
import { IThemeService } from 'vs/platform/theme/common/themeService';
/**

View File

@@ -1,7 +1,7 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
import { JSONObject } from '../../models/jsonext';
import { JSONObject } from './jsonext';
import { URI } from 'vs/base/common/uri';
/**

View File

@@ -12,13 +12,13 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import * as DOM from 'vs/base/browser/dom';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { CellContext, CellActionBase } from 'sql/workbench/parts/notebook/cellViews/codeActions';
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
import { ToggleMoreWidgetAction } from 'sql/workbench/parts/dashboard/common/actions';
import { CellTypes, CellType } from 'sql/workbench/parts/notebook/models/contracts';
import { CellModel } from 'sql/workbench/parts/notebook/models/cell';
import { INotebookService } from 'sql/workbench/services/notebook/common/notebookService';
import { CellActionBase, CellContext } from 'sql/workbench/parts/notebook/electron-browser/cellViews/codeActions';
import { CellTypes, CellType } from 'sql/workbench/parts/notebook/common/models/contracts';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { ToggleMoreWidgetAction } from 'sql/workbench/parts/dashboard/browser/core/actions';
import { CellModel } from 'sql/workbench/parts/notebook/node/models/cell';
export const HIDDEN_CLASS = 'actionhidden';
@@ -181,4 +181,4 @@ export class RunCellsAction extends CellActionBase {
}
return Promise.resolve();
}
}
}

View File

@@ -6,13 +6,13 @@ import 'vs/css!./code';
import { OnInit, Component, Input, Inject, ElementRef, ViewChild, Output, EventEmitter, OnChanges, SimpleChange, forwardRef, ChangeDetectorRef } from '@angular/core';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { QueryTextEditor } from 'sql/workbench/electron-browser/modelComponents/queryTextEditor';
import { CellToggleMoreActions } from 'sql/workbench/parts/notebook/cellToggleMoreActions';
import { ICellModel, notebookConstants, CellExecutionState } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { QueryTextEditor } from 'sql/workbench/browser/modelComponents/queryTextEditor';
import { CellToggleMoreActions } from 'sql/workbench/parts/notebook/electron-browser/cellToggleMoreActions';
import { ICellModel, notebookConstants, CellExecutionState } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
import { RunCellAction, CellContext } from 'sql/workbench/parts/notebook/cellViews/codeActions';
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
import { RunCellAction, CellContext } from 'sql/workbench/parts/notebook/electron-browser/cellViews/codeActions';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import * as themeColors from 'vs/workbench/common/theme';
@@ -27,9 +27,9 @@ import { IModeService } from 'vs/editor/common/services/modeService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { Event, Emitter } from 'vs/base/common/event';
import { CellTypes } from 'sql/workbench/parts/notebook/models/contracts';
import { CellTypes } from 'sql/workbench/parts/notebook/common/models/contracts';
import { OVERRIDE_EDITOR_THEMING_SETTING } from 'sql/workbench/services/notebook/common/notebookService';
import * as notebookUtils from 'sql/workbench/parts/notebook/notebookUtils';
import * as notebookUtils from 'sql/workbench/parts/notebook/node/models/notebookUtils';
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { ILogService } from 'vs/platform/log/common/log';

View File

@@ -31,18 +31,18 @@ code-component .toolbar .carbon-taskbar {
code-component .toolbarIconRun {
height: 20px;
background-image: url('../media/light/execute_cell.svg');
background-image: url('./media/light/execute_cell.svg');
padding-bottom: 10px;
}
.vs-dark code-component .toolbarIconRun,
.hc-black code-component .toolbarIconRun {
background-image: url('../media/dark/execute_cell_inverse.svg');
background-image: url('./media/dark/execute_cell_inverse.svg');
}
code-component .toolbarIconRunError {
height: 20px;
background-image: url('../media/light/execute_cell_error.svg');
background-image: url('./media/light/execute_cell_error.svg');
padding-bottom: 10px;
}
@@ -54,7 +54,7 @@ code-component .toolbarIconStop {
.vs-dark code-component .toolbarIconStop,
.hc-black code-component .toolbarIconStop {
background-image: url('../media/dark/stop_cell_solidanimation_inverse.svg');
background-image: url('./media/dark/stop_cell_solidanimation_inverse.svg');
}
code-component .editor {

View File

@@ -9,13 +9,13 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import * as types from 'vs/base/common/types';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
import { getErrorMessage } from 'sql/workbench/parts/notebook/notebookUtils';
import { ICellModel, CellExecutionState } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { ICellModel, CellExecutionState } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { MultiStateAction, IMultiStateData } from 'sql/workbench/parts/notebook/notebookActions';
import { MultiStateAction, IMultiStateData } from 'sql/workbench/parts/notebook/electron-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 = '[ ]';

View File

@@ -5,9 +5,9 @@
import { nb } from 'azdata';
import { OnInit, Component, Input, Inject, forwardRef, ChangeDetectorRef, SimpleChange, OnChanges, HostListener } from '@angular/core';
import { CellView } from 'sql/workbench/parts/notebook/cellViews/interfaces';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
import { CellView } from 'sql/workbench/parts/notebook/electron-browser/cellViews/interfaces';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { Deferred } from 'sql/base/common/promise';

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { OnDestroy } from '@angular/core';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
export abstract class CellView extends AngularDisposable implements OnDestroy {
constructor() {
@@ -13,5 +13,3 @@ export abstract class CellView extends AngularDisposable implements OnDestroy {
public abstract layout(): void;
}

View File

@@ -6,21 +6,21 @@ import 'vs/css!./code';
import 'vs/css!./media/output';
import { OnInit, Component, Input, Inject, ElementRef, ViewChild, SimpleChange, AfterViewInit, forwardRef, ChangeDetectorRef, ComponentRef, ComponentFactoryResolver } from '@angular/core';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { Event } from 'vs/base/common/event';
import { nb } from 'azdata';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import * as outputProcessor from 'sql/workbench/parts/notebook/outputs/common/outputProcessor';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import * as outputProcessor from 'sql/workbench/parts/notebook/common/models/outputProcessor';
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
import * as DOM from 'vs/base/browser/dom';
import { ComponentHostDirective } from 'sql/workbench/parts/dashboard/common/componentHost.directive';
import { Extensions, IMimeComponent, IMimeComponentRegistry } from 'sql/workbench/parts/notebook/outputs/mimeRegistry';
import { ComponentHostDirective } from 'sql/workbench/parts/dashboard/browser/core/componentHost.directive';
import { Extensions, IMimeComponent, IMimeComponentRegistry } from 'sql/workbench/parts/notebook/electron-browser/outputs/mimeRegistry';
import * as colors from 'vs/platform/theme/common/colorRegistry';
import * as themeColors from 'vs/workbench/common/theme';
import { Registry } from 'vs/platform/registry/common/platform';
import { localize } from 'vs/nls';
import * as types from 'vs/base/common/types';
import { getErrorMessage } from 'sql/workbench/parts/notebook/notebookUtils';
import { getErrorMessage } from 'vs/base/common/errors';
export const OUTPUT_SELECTOR: string = 'output-component';
const USER_SELECT_CLASS = 'actionselect';

View File

@@ -5,8 +5,8 @@
import 'vs/css!./code';
import 'vs/css!./outputArea';
import { OnInit, Component, Input, Inject, ElementRef, ViewChild, forwardRef, ChangeDetectorRef } from '@angular/core';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import * as themeColors from 'vs/workbench/common/theme';
import { IWorkbenchThemeService, IColorTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { URI } from 'vs/base/common/uri';

View File

@@ -5,11 +5,11 @@
import 'vs/css!./placeholder';
import { OnInit, Component, Input, Inject, forwardRef, ElementRef, ChangeDetectorRef, OnDestroy, ViewChild, SimpleChange, OnChanges } from '@angular/core';
import { CellView } from 'sql/workbench/parts/notebook/cellViews/interfaces';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
import { CellView } from 'sql/workbench/parts/notebook/electron-browser/cellViews/interfaces';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { localize } from 'vs/nls';
import { CellType } from 'sql/workbench/parts/notebook/models/contracts';
import { CellType } from 'sql/workbench/parts/notebook/common/models/contracts';
export const PLACEHOLDER_SELECTOR: string = 'placeholder-cell-component';

View File

@@ -21,9 +21,9 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import { InputBox } from 'sql/base/browser/ui/inputBox/inputBox';
import { attachInputBoxStyler } from 'sql/platform/theme/common/styler';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { Deferred } from 'sql/base/common/promise';
import { ICellModel, CellExecutionState } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { ICellModel, CellExecutionState } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
export const STDIN_SELECTOR: string = 'stdin-component';
@Component({

View File

@@ -18,18 +18,18 @@ import { Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import * as DOM from 'vs/base/browser/dom';
import { CommonServiceInterface } from 'sql/platform/bootstrap/node/commonServiceInterface.service';
import { CellView } from 'sql/workbench/parts/notebook/cellViews/interfaces';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { ISanitizer, defaultSanitizer } from 'sql/workbench/parts/notebook/outputs/sanitizer';
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
import { CellToggleMoreActions } from 'sql/workbench/parts/notebook/cellToggleMoreActions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { toDisposable } from 'vs/base/common/lifecycle';
import { IMarkdownRenderResult } from 'vs/editor/contrib/markdown/markdownRenderer';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { NotebookMarkdownRenderer } from 'sql/workbench/parts/notebook/outputs/notebookMarkdown';
import { convertVscodeResourceToFileInSubDirectories, useInProcMarkdown } from 'sql/workbench/parts/notebook/notebookUtils';
import { CellView } from 'sql/workbench/parts/notebook/electron-browser/cellViews/interfaces';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { ISanitizer, defaultSanitizer } from 'sql/workbench/parts/notebook/electron-browser/outputs/sanitizer';
import { CellToggleMoreActions } from 'sql/workbench/parts/notebook/electron-browser/cellToggleMoreActions';
import { CommonServiceInterface } from 'sql/platform/bootstrap/browser/commonServiceInterface.service';
import { useInProcMarkdown, convertVscodeResourceToFileInSubDirectories } from 'sql/workbench/parts/notebook/node/models/notebookUtils';
export const TEXT_SELECTOR: string = 'text-cell-component';
const USER_SELECT_CLASS = 'actionselect';

View File

Before

Width:  |  Height:  |  Size: 818 B

After

Width:  |  Height:  |  Size: 818 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 494 B

After

Width:  |  Height:  |  Size: 494 B

View File

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 261 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import { nb } from 'azdata';
import * as vscode from 'vscode';
import { OnInit, Component, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild, OnDestroy } from '@angular/core';
import { IColorTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
@@ -22,27 +21,26 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import * as DOM from 'vs/base/browser/dom';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { CellTypes, CellType } from 'sql/workbench/parts/notebook/models/contracts';
import { ICellModel, IModelFactory, INotebookModel, NotebookContentChange } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { CellTypes, CellType } from 'sql/workbench/parts/notebook/common/models/contracts';
import { ICellModel, IModelFactory, INotebookModel, NotebookContentChange } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { INotebookService, INotebookParams, INotebookManager, INotebookEditor, INotebookSection, DEFAULT_NOTEBOOK_PROVIDER, SQL_NOTEBOOK_PROVIDER, INavigationProvider } from 'sql/workbench/services/notebook/common/notebookService';
import { IBootstrapParams } from 'sql/platform/bootstrap/node/bootstrapService';
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
import { ModelFactory } from 'sql/workbench/parts/notebook/models/modelFactory';
import * as notebookUtils from 'sql/workbench/parts/notebook/notebookUtils';
import { INotebookService, INotebookParams, INotebookManager, INotebookEditor, DEFAULT_NOTEBOOK_PROVIDER, SQL_NOTEBOOK_PROVIDER, INotebookSection, INavigationProvider } from 'sql/workbench/services/notebook/common/notebookService';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { ModelFactory } from 'sql/workbench/parts/notebook/node/models/modelFactory';
import * as notebookUtils from 'sql/workbench/parts/notebook/node/models/notebookUtils';
import { Deferred } from 'sql/base/common/promise';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { Taskbar } from 'sql/base/browser/ui/taskbar/taskbar';
import { KernelsDropdown, AttachToDropdown, AddCellAction, TrustedAction, RunAllCellsAction, ClearAllOutputsAction } from 'sql/workbench/parts/notebook/notebookActions';
import { KernelsDropdown, AttachToDropdown, AddCellAction, TrustedAction, RunAllCellsAction, ClearAllOutputsAction } from 'sql/workbench/parts/notebook/electron-browser/notebookActions';
import { IObjectExplorerService } from 'sql/workbench/services/objectExplorer/common/objectExplorerService';
import * as TaskUtilities from 'sql/workbench/common/taskUtilities';
import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes';
import { IConnectionDialogService } from 'sql/workbench/services/connection/common/connectionDialogService';
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
import { CellMagicMapper } from 'sql/workbench/parts/notebook/models/cellMagicMapper';
import { CellMagicMapper } from 'sql/workbench/parts/notebook/node/models/cellMagicMapper';
import { IExtensionsViewlet, VIEWLET_ID } from 'vs/workbench/contrib/extensions/common/extensions';
import { CellModel } from 'sql/workbench/parts/notebook/models/cell';
import { CellModel } from 'sql/workbench/parts/notebook/node/models/cell';
import { FileOperationError, FileOperationResult } from 'vs/platform/files/common/files';
import { isValidBasename } from 'vs/base/common/extpath';
import { basename } from 'vs/base/common/resources';
@@ -54,6 +52,8 @@ import { LabeledMenuItemActionItem, fillInActions } from 'vs/platform/actions/br
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { Button } from 'sql/base/browser/ui/button/button';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { IBootstrapParams } from 'sql/platform/bootstrap/common/bootstrapParams';
import { getErrorMessage } from 'vs/base/common/errors';
import product from 'vs/platform/product/node/product';
@@ -257,7 +257,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
}
}
} else {
this.setViewInErrorState(localize('displayFailed', "Could not display contents: {0}", notebookUtils.getErrorMessage(error)));
this.setViewInErrorState(localize('displayFailed', "Could not display contents: {0}", getErrorMessage(error)));
this.setLoading(false);
this._modelReadyDeferred.reject(error);
@@ -395,7 +395,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
private setViewInErrorState(error: any): any {
this._isInErrorState = true;
this._errorMessage = notebookUtils.getErrorMessage(error);
this._errorMessage = getErrorMessage(error);
// For now, send message as error notification #870 covers having dedicated area for this
this.notificationService.error(error);
}
@@ -634,7 +634,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
this._navProvider.onNext(this.model.notebookUri);
}
} catch (error) {
this.notificationService.error(notebookUtils.getErrorMessage(error));
this.notificationService.error(getErrorMessage(error));
}
}
@@ -644,7 +644,7 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe
this._navProvider.onPrevious(this.model.notebookUri);
}
} catch (error) {
this.notificationService.error(notebookUtils.getErrorMessage(error));
this.notificationService.error(getErrorMessage(error));
}
}
@@ -692,4 +692,4 @@ class NotebookSection implements INotebookSection {
get header(): string {
return this.headerEl.textContent;
}
}
}

View File

@@ -8,19 +8,19 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { NotebookInput } from 'sql/workbench/parts/notebook/notebookInput';
import { NotebookEditor } from 'sql/workbench/parts/notebook/notebookEditor';
import { NewNotebookAction } from 'sql/workbench/parts/notebook/notebookActions';
import { NotebookInput } from 'sql/workbench/parts/notebook/node/notebookInput';
import { NotebookEditor } from 'sql/workbench/parts/notebook/electron-browser/notebookEditor';
import { NewNotebookAction } from 'sql/workbench/parts/notebook/electron-browser/notebookActions';
import { KeyMod } from 'vs/editor/common/standalone/standaloneBase';
import { KeyCode } from 'vs/base/common/keyCodes';
import { IConfigurationRegistry, Extensions as ConfigExtensions } from 'vs/platform/configuration/common/configurationRegistry';
import { localize } from 'vs/nls';
import product from 'vs/platform/product/node/product';
import { registerComponentType } from 'sql/workbench/parts/notebook/outputs/mimeRegistry';
import { MimeRendererComponent as MimeRendererComponent } from 'sql/workbench/parts/notebook/outputs/mimeRenderer.component';
import { MarkdownOutputComponent } from 'sql/workbench/parts/notebook/outputs/markdownOutput.component';
import { GridOutputComponent } from 'sql/workbench/parts/notebook/outputs/gridOutput.component';
import { PlotlyOutputComponent } from 'sql/workbench/parts/notebook/outputs/plotlyOutput.component';
import { registerComponentType } from 'sql/workbench/parts/notebook/electron-browser/outputs/mimeRegistry';
import { MimeRendererComponent } from 'sql/workbench/parts/notebook/electron-browser/outputs/mimeRenderer.component';
import { MarkdownOutputComponent } from 'sql/workbench/parts/notebook/electron-browser/outputs/markdownOutput.component';
// Model View editor registration
const viewModelEditorDescriptor = new EditorDescriptor(
@@ -181,4 +181,4 @@ registerComponentType({
safe: true,
ctor: PlotlyOutputComponent,
selector: PlotlyOutputComponent.SELECTOR
});
});

View File

@@ -8,26 +8,27 @@ import { FormsModule } from '@angular/forms';
import { CommonModule, APP_BASE_HREF } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { ComponentHostDirective } from 'sql/workbench/parts/dashboard/common/componentHost.directive';
import { IBootstrapParams, ISelector, providerIterator } from 'sql/platform/bootstrap/node/bootstrapService';
import { CommonServiceInterface } from 'sql/platform/bootstrap/node/commonServiceInterface.service';
import { EditableDropDown } from 'sql/platform/electron-browser/editableDropdown/editableDropdown.component';
import { NotebookComponent } from 'sql/workbench/parts/notebook/notebook.component';
import { ComponentHostDirective } from 'sql/workbench/parts/dashboard/browser/core/componentHost.directive';
import { providerIterator } from 'sql/platform/bootstrap/browser/bootstrapService';
import { CommonServiceInterface } from 'sql/platform/bootstrap/browser/commonServiceInterface.service';
import { EditableDropDown } from 'sql/platform/browser/editableDropdown/editableDropdown.component';
import { NotebookComponent } from 'sql/workbench/parts/notebook/electron-browser/notebook.component';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { CodeComponent } from 'sql/workbench/parts/notebook/cellViews/code.component';
import { CodeCellComponent } from 'sql/workbench/parts/notebook/cellViews/codeCell.component';
import { TextCellComponent } from 'sql/workbench/parts/notebook/cellViews/textCell.component';
import { OutputAreaComponent } from 'sql/workbench/parts/notebook/cellViews/outputArea.component';
import { OutputComponent } from 'sql/workbench/parts/notebook/cellViews/output.component';
import { StdInComponent } from 'sql/workbench/parts/notebook/cellViews/stdin.component';
import { PlaceholderCellComponent } from 'sql/workbench/parts/notebook/cellViews/placeholderCell.component';
import LoadingSpinner from 'sql/workbench/electron-browser/modelComponents/loadingSpinner.component';
import { Checkbox } from 'sql/base/electron-browser/ui/checkbox/checkbox.component';
import { SelectBox } from 'sql/platform/ui/electron-browser/selectBox/selectBox.component';
import { InputBox } from 'sql/base/electron-browser/ui/inputBox/inputBox.component';
import { IMimeComponentRegistry, Extensions } from 'sql/workbench/parts/notebook/outputs/mimeRegistry';
import { CodeComponent } from 'sql/workbench/parts/notebook/electron-browser/cellViews/code.component';
import { CodeCellComponent } from 'sql/workbench/parts/notebook/electron-browser/cellViews/codeCell.component';
import { TextCellComponent } from 'sql/workbench/parts/notebook/electron-browser/cellViews/textCell.component';
import { OutputAreaComponent } from 'sql/workbench/parts/notebook/electron-browser/cellViews/outputArea.component';
import { OutputComponent } from 'sql/workbench/parts/notebook/electron-browser/cellViews/output.component';
import { StdInComponent } from 'sql/workbench/parts/notebook/electron-browser/cellViews/stdin.component';
import { PlaceholderCellComponent } from 'sql/workbench/parts/notebook/electron-browser/cellViews/placeholderCell.component';
import LoadingSpinner from 'sql/workbench/browser/modelComponents/loadingSpinner.component';
import { Checkbox } from 'sql/base/browser/ui/checkbox/checkbox.component';
import { SelectBox } from 'sql/platform/browser/selectBox/selectBox.component';
import { InputBox } from 'sql/platform/browser/inputbox/inputBox.component';
import { IMimeComponentRegistry, Extensions } from 'sql/workbench/parts/notebook/electron-browser/outputs/mimeRegistry';
import { Registry } from 'vs/platform/registry/common/platform';
import { LinkHandlerDirective } from 'sql/workbench/parts/notebook/cellViews/linkHandler.directive';
import { LinkHandlerDirective } from 'sql/workbench/parts/notebook/electron-browser/cellViews/linkHandler.directive';
import { IBootstrapParams, ISelector } from 'sql/platform/bootstrap/common/bootstrapParams';
export const NotebookModule = (params, selector: string, instantiationService: IInstantiationService): any => {
let outputComponents = Registry.as<IMimeComponentRegistry>(Extensions.MimeComponentContribution).getAllCtors();

View File

@@ -11,20 +11,20 @@ import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview
import { INotificationService, Severity, INotificationActions } from 'vs/platform/notification/common/notification';
import { SelectBox, ISelectBoxOptionsWithLabel } from 'sql/base/browser/ui/selectBox/selectBox';
import { INotebookModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { CellType, CellTypes } from 'sql/workbench/parts/notebook/models/contracts';
import { NotebookComponent } from 'sql/workbench/parts/notebook/notebook.component';
import { getErrorMessage, getServerFromFormattedAttachToName, getDatabaseFromFormattedAttachToName } from 'sql/workbench/parts/notebook/notebookUtils';
import { IConnectionManagementService, ConnectionType } from 'sql/platform/connection/common/connectionManagement';
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import { noKernel } from 'sql/workbench/services/notebook/common/sessionManager';
import { IConnectionDialogService } from 'sql/workbench/services/connection/common/connectionDialogService';
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { generateUri } from 'sql/platform/connection/common/utils';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ILogService } from 'vs/platform/log/common/log';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { CellType } from 'sql/workbench/parts/notebook/common/models/contracts';
import { NotebookComponent } from 'sql/workbench/parts/notebook/electron-browser/notebook.component';
import { getErrorMessage } from 'vs/base/common/errors';
import { INotebookModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
const msgLoading = localize('loading', "Loading kernels...");
const msgChanging = localize('changing', "Changing kernel...");
@@ -560,4 +560,4 @@ export class NewNotebookAction extends Action {
return this.commandService.executeCommand(NewNotebookAction.INTERNAL_NEW_NOTEBOOK_CMD_ID, context);
}
}
}

View File

@@ -7,13 +7,13 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { EditorOptions } from 'vs/workbench/common/editor';
import * as DOM from 'vs/base/browser/dom';
import { bootstrapAngular } from 'sql/platform/bootstrap/node/bootstrapService';
import { bootstrapAngular } from 'sql/platform/bootstrap/browser/bootstrapService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { CancellationToken } from 'vs/base/common/cancellation';
import { NotebookInput } from 'sql/workbench/parts/notebook/notebookInput';
import { NotebookModule } from 'sql/workbench/parts/notebook/notebook.module';
import { NOTEBOOK_SELECTOR } from 'sql/workbench/parts/notebook/notebook.component';
import { NotebookInput } from 'sql/workbench/parts/notebook/node/notebookInput';
import { NotebookModule } from 'sql/workbench/parts/notebook/electron-browser/notebook.module';
import { NOTEBOOK_SELECTOR } from 'sql/workbench/parts/notebook/electron-browser/notebook.component';
import { INotebookParams } from 'sql/workbench/services/notebook/common/notebookService';
import { IStorageService } from 'vs/platform/storage/common/storage';

View File

@@ -4,7 +4,7 @@
|----------------------------------------------------------------------------*/
import * as widgets from './widgets';
import { IRenderMime } from './common/renderMimeInterfaces';
import { IRenderMime } from '../../common/models/renderMimeInterfaces';
/**
* A mime renderer factory for raw html.

View File

@@ -9,16 +9,16 @@ import 'vs/css!../cellViews/media/highlight';
import { OnInit, Component, Input, Inject, forwardRef, ElementRef, ChangeDetectorRef, ViewChild } from '@angular/core';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { ISanitizer, defaultSanitizer } from 'sql/workbench/parts/notebook/outputs/sanitizer';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { IMimeComponent } from 'sql/workbench/parts/notebook/outputs/mimeRegistry';
import { ISanitizer, defaultSanitizer } from 'sql/workbench/parts/notebook/electron-browser/outputs/sanitizer';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { IMimeComponent } from 'sql/workbench/parts/notebook/electron-browser/outputs/mimeRegistry';
import { INotebookService } from 'sql/workbench/services/notebook/common/notebookService';
import { MimeModel } from 'sql/workbench/parts/notebook/outputs/common/mimemodel';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { convertVscodeResourceToFileInSubDirectories, useInProcMarkdown } from 'sql/workbench/parts/notebook/notebookUtils';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { NotebookMarkdownRenderer } from 'sql/workbench/parts/notebook/outputs/notebookMarkdown';
import { MimeModel } from 'sql/workbench/parts/notebook/common/models/mimemodel';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { useInProcMarkdown, convertVscodeResourceToFileInSubDirectories } from 'sql/workbench/parts/notebook/node/models/notebookUtils';
import { URI } from 'vs/base/common/uri';
@Component({
@@ -151,4 +151,4 @@ export class MarkdownOutputComponent extends AngularDisposable implements IMimeC
public handleContentChanged(): void {
this.updatePreview();
}
}
}

View File

@@ -5,11 +5,10 @@
import { Type } from '@angular/core';
import * as platform from 'vs/platform/registry/common/platform';
import { ReadonlyJSONObject } from 'sql/workbench/parts/notebook/models/jsonext';
import { MimeModel } from 'sql/workbench/parts/notebook/outputs/common/mimemodel';
import { ReadonlyJSONObject } from 'sql/workbench/parts/notebook/common/models/jsonext';
import { MimeModel } from 'sql/workbench/parts/notebook/common/models/mimemodel';
import * as types from 'vs/base/common/types';
import { IRenderMime } from 'sql/workbench/parts/notebook/outputs/common/renderMimeInterfaces';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
export type FactoryIdentifier = string;

View File

@@ -3,12 +3,12 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IMimeComponent } from 'sql/workbench/parts/notebook/outputs/mimeRegistry';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { IMimeComponent } from 'sql/workbench/parts/notebook/electron-browser/outputs/mimeRegistry';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { ElementRef, forwardRef, Inject, Component, OnInit, Input } from '@angular/core';
import { MimeModel } from 'sql/workbench/parts/notebook/outputs/common/mimemodel';
import { MimeModel } from 'sql/workbench/parts/notebook/common/models/mimemodel';
import { INotebookService } from 'sql/workbench/services/notebook/common/notebookService';
import { RenderMimeRegistry } from 'sql/workbench/parts/notebook/outputs/registry';
import { RenderMimeRegistry } from 'sql/workbench/parts/notebook/electron-browser/outputs/registry';
import { localize } from 'vs/nls';
@Component({
@@ -75,4 +75,4 @@ export class MimeRendererComponent extends AngularDisposable implements IMimeCom
Object.keys(options.data).join(', '));
}
}
}
}

View File

@@ -3,9 +3,9 @@
| Copyright (c) Jupyter Development Team.
| Distributed under the terms of the Modified BSD License.
|----------------------------------------------------------------------------*/
import { IRenderMime } from './common/renderMimeInterfaces';
import { MimeModel } from './common/mimemodel';
import { ReadonlyJSONObject } from '../models/jsonext';
import { IRenderMime } from '../../common/models/renderMimeInterfaces';
import { MimeModel } from '../../common/models/mimemodel';
import { ReadonlyJSONObject } from '../../common/models/jsonext';
import { defaultSanitizer } from './sanitizer';
/**

View File

@@ -4,8 +4,8 @@
|----------------------------------------------------------------------------*/
import { default as AnsiUp } from 'ansi_up';
import { IRenderMime } from './common/renderMimeInterfaces';
import { URLExt } from './common/url';
import { IRenderMime } from '../../common/models/renderMimeInterfaces';
import { URLExt } from '../../common/models/url';
import { URI } from 'vs/base/common/uri';

View File

@@ -118,7 +118,7 @@ class CssProp {
rgb: String.raw`rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)`,
rgba: String.raw`rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(${
CssProp.N.integer_zero_ff
}|${CssProp.N.number_zero_one}|${CssProp.B.percentage_zero_hundred})\s*\)`
}|${CssProp.N.number_zero_one}|${CssProp.B.percentage_zero_hundred})\s*\)`
};
/*
@@ -127,19 +127,19 @@ class CssProp {
private static readonly _C = {
alpha: `${CssProp.N.integer_zero_ff}|${CssProp.N.number_zero_one}|${
CssProp.B.percentage_zero_hundred
}`,
}`,
alphavalue: CssProp.N.number_zero_one,
bg_position: `((${
CssProp.B.len_or_perc
}|left|center|right|top|bottom)\\s*){1,4}`,
}|left|center|right|top|bottom)\\s*){1,4}`,
bg_size: `(${CssProp.B.length_pos}|${
CssProp.B.percentage
}|auto){1,2}|cover|contain`,
}|auto){1,2}|cover|contain`,
border_width: `thin|medium|thick|${CssProp.B.length}`,
bottom: `${CssProp.B.length}|auto`,
color: `${CssProp._COLOR.hex}|${CssProp._COLOR.rgb}|${
CssProp._COLOR.rgba
}|${CssProp._COLOR.name}`,
}|${CssProp._COLOR.name}`,
family_name: `${CssProp.B.string}|(${CssProp.B.ident}\\s*)+`,
image_decl: CssProp.B.url,
left: `${CssProp.B.length}|auto`,
@@ -149,24 +149,24 @@ class CssProp {
page_url: CssProp.B.url,
position: `((${
CssProp.B.len_or_perc
}|left|center|right|top|bottom)\\s*){1,4}`,
}|left|center|right|top|bottom)\\s*){1,4}`,
right: `${CssProp.B.length}|auto`,
shadow: '',
size: `closest-side|farthest-side|closest-corner|farthest-corner|${
CssProp.B.length
}|(${CssProp.B.len_or_perc})\\s+(${CssProp.B.len_or_perc})`,
}|(${CssProp.B.len_or_perc})\\s+(${CssProp.B.len_or_perc})`,
top: `${CssProp.B.length}|auto`
};
private static readonly _C1 = {
image_list: `image\\(\\s*(${CssProp.B.url})*\\s*(${CssProp.B.url}|${
CssProp._C.color
})\\s*\\)`,
})\\s*\\)`,
shadow: `((${CssProp._C.color})\\s+((${
CssProp.B.length
})\\s*){2,4}(\s+inset)?)|((inset\\s+)?((${
})\\s*){2,4}(\s+inset)?)|((inset\\s+)?((${
CssProp.B.length
})\\s*){2,4}\\s*(${CssProp._C.color})?)`
})\\s*){2,4}\\s*(${CssProp._C.color})?)`
};
private static readonly _C2 = {
@@ -174,7 +174,7 @@ class CssProp {
image: `${CssProp.B.url}|${CssProp._C1.image_list}`,
shape: `rect\\(\\s*(${CssProp._C.top})\\s*,\\s*(${
CssProp._C.right
})\\s*,\\s*(${CssProp._C.bottom})\\s*,\\s*(${CssProp._C.left})\\s*\\)`
})\\s*,\\s*(${CssProp._C.bottom})\\s*,\\s*(${CssProp._C.left})\\s*\\)`
};
private static readonly C = { ...CssProp._C, ...CssProp._C1, ...CssProp._C2 };
@@ -226,18 +226,18 @@ class CssProp {
private static readonly _CP = {
background_attachment: `${CssProp.A.attachment}(,\\s*${
CssProp.A.attachment
})*`,
})*`,
background_color: CssProp.C.color,
background_origin: `${CssProp.A.box}(,\\s*${CssProp.A.box})*`,
background_repeat: `${CssProp.A.repeat_style}(,\\s*${
CssProp.A.repeat_style
})*`,
})*`,
border: `((${CssProp.C.border_width}|${CssProp.A.border_style}|${
CssProp.C.color
})\\s*){1,3}`,
})\\s*){1,3}`,
border_radius: `((${CssProp.B.len_or_perc})\\s*){1,4}(\\/\\s*((${
CssProp.B.len_or_perc
})\\s*){1,4})?`,
})\\s*){1,4})?`,
border_spacing: `${CssProp.B.length}\\s*(${CssProp.B.length})?`,
border_top_color: CssProp.C.color,
border_top_style: CssProp.A.border_style,
@@ -245,15 +245,15 @@ class CssProp {
color: CssProp.C.color,
cursor: `(${
CssProp.B.url
}(\\s*,\\s*)?)*(auto|crosshair|default|pointer|move|e-resize|ne-resize|nw-resize|n-resize|se-resize|sw-resize|s-resize|w-resize|text|wait|help|progress|all-scroll|col-resize|hand|no-drop|not-allowed|row-resize|vertical-text)`,
}(\\s*,\\s*)?)*(auto|crosshair|default|pointer|move|e-resize|ne-resize|nw-resize|n-resize|se-resize|sw-resize|s-resize|w-resize|text|wait|help|progress|all-scroll|col-resize|hand|no-drop|not-allowed|row-resize|vertical-text)`,
display: `inline|block|list-item|run-in|inline-list-item|inline-block|table|inline-table|table-cell|table-caption|flex|inline-flex|grid|inline-grid|${
CssProp.A.display_inside
}|${CssProp.A.display_outside}|inherit|inline-box|inline-stack`,
}|${CssProp.A.display_outside}|inherit|inline-box|inline-stack`,
display_outside: CssProp.A.display_outside,
elevation: `${CssProp.B.angle}|below|level|above|higher|lower`,
font_family: `(${CssProp.C.family_name}|${
CssProp.A.generic_family
})(,\\s*(${CssProp.C.family_name}|${CssProp.A.generic_family}))*`,
})(,\\s*(${CssProp.C.family_name}|${CssProp.A.generic_family}))*`,
height: `${CssProp.B.length}|${CssProp.B.percentage}|auto`,
letter_spacing: `normal|${CssProp.B.length}`,
list_style_image: `${CssProp.C.image}|none`,
@@ -272,14 +272,14 @@ class CssProp {
text_shadow: `none|${CssProp.C.shadow}(,\\s*(${CssProp.C.shadow}))*`,
volume: `${CssProp.N.number_pos}|${
CssProp.B.percentage_pos
}|silent|x-soft|soft|medium|loud|x-loud`,
}|silent|x-soft|soft|medium|loud|x-loud`,
word_wrap: CssProp.AP.overflow_wrap,
zoom: `normal|${CssProp.N.number_pos}|${CssProp.B.percentage_pos}`,
backface_visibility: CssProp.AP.visibility,
background_clip: `${CssProp.A.box}(,\\s*(${CssProp.A.box}))*`,
background_position: `${CssProp.C.bg_position}(,\\s*(${
CssProp.C.bg_position
}))*`,
}))*`,
border_bottom_color: CssProp.C.color,
border_bottom_style: CssProp.A.border_style,
border_color: `((${CssProp.C.color})\\s*){1,4}`,
@@ -288,17 +288,17 @@ class CssProp {
border_style: `((${CssProp.A.border_style})\\s*){1,4}`,
border_top_left_radius: `(${CssProp.B.length}|${
CssProp.B.percentage
})(\\s*(${CssProp.B.length}|${CssProp.B.percentage}))?`,
})(\\s*(${CssProp.B.length}|${CssProp.B.percentage}))?`,
border_top_width: CssProp.C.border_width,
box_shadow: `none|${CssProp.C.shadow}(,\\s*(${CssProp.C.shadow}))*`,
clip: `${CssProp.C.shape}|auto`,
display_inside: CssProp.A.display_inside,
font_size: `${CssProp.A.absolute_size}|${CssProp.A.relative_size}|${
CssProp.B.length_pos
}|${CssProp.B.percentage_pos}`,
}|${CssProp.B.percentage_pos}`,
line_height: `normal|${CssProp.N.number_pos}|${CssProp.B.length_pos}|${
CssProp.B.percentage_pos
}`,
}`,
margin_left: CssProp.C.margin_width,
max_width: `${CssProp.B.length_pos}|${CssProp.B.percentage_pos}|none|auto`,
outline_style: CssProp.A.border_style,
@@ -313,37 +313,37 @@ class CssProp {
// Simplified background
background: `(((${CssProp.C.bg_position}\\s*(\\/\\s*${
CssProp.C.bg_size
})?)|(${CssProp.A.repeat_style})|(${CssProp.A.attachment})|(${
})?)|(${CssProp.A.repeat_style})|(${CssProp.A.attachment})|(${
CssProp.A.bg_origin
})|(${CssProp.C.bg_image})|(${CssProp.C.color}))\\s*)+`,
})|(${CssProp.C.bg_image})|(${CssProp.C.color}))\\s*)+`,
background_size: `${CssProp.C.bg_size}(,\\s*${CssProp.C.bg_size})*`,
border_bottom_left_radius: `(${CssProp.B.length}|${
CssProp.B.percentage
})(\\s*(${CssProp.B.length}|${CssProp.B.percentage}))?`,
})(\\s*(${CssProp.B.length}|${CssProp.B.percentage}))?`,
border_bottom_width: CssProp.C.border_width,
border_left_style: CssProp.A.border_style,
border_right_style: CssProp.A.border_style,
border_top: `((${CssProp.C.border_width}|${CssProp.A.border_style}|${
CssProp.C.color
})\\s*){1,3}`,
})\\s*){1,3}`,
bottom: `${CssProp.B.len_or_perc}|auto`,
list_style: `((${CssProp.AP.list_style_type}|${
CssProp.AP.list_style_position
}|${CssProp.C.image}|none})\\s*){1,3}`,
}|${CssProp.C.image}|none})\\s*){1,3}`,
margin_top: CssProp.C.margin_width,
outline: `((${CssProp.C.color}|invert|${CssProp.A.border_style}|${
CssProp.C.border_width
})\\s*){1,3}`,
})\\s*){1,3}`,
overflow_y: CssProp.AP.overflow_x,
pitch: `${CssProp.B.frequency}|x-low|low|medium|high|x-high`,
vertical_align: `baseline|sub|super|top|text-top|middle|bottom|text-bottom|${
CssProp.B.len_or_perc
}`,
}`,
word_spacing: `normal|${CssProp.B.length}`,
background_image: `${CssProp.C.bg_image}(,\\s*${CssProp.C.bg_image})*`,
border_bottom_right_radius: `(${CssProp.B.length}|${
CssProp.B.percentage
})(\\s*(${CssProp.B.length}|${CssProp.B.percentage}))?`,
})(\\s*(${CssProp.B.length}|${CssProp.B.percentage}))?`,
border_left_width: CssProp.C.border_width,
border_right_width: CssProp.C.border_width,
left: `${CssProp.B.len_or_perc}|auto`,
@@ -351,34 +351,34 @@ class CssProp {
pause_after: `${CssProp.B.time}|${CssProp.B.percentage}`,
speech_rate: `${
CssProp.N.number
}|x-slow|slow|medium|fast|x-fast|faster|slower`,
}|x-slow|slow|medium|fast|x-fast|faster|slower`,
transition_duration: `${CssProp.B.time}(,\\s*${CssProp.B.time})*`,
border_bottom: `((${CssProp.C.border_width}|${CssProp.A.border_style}|${
CssProp.C.color
})\\s*){1,3}`,
})\\s*){1,3}`,
border_right: `((${CssProp.C.border_width}|${CssProp.A.border_style}|${
CssProp.C.color
})\\s*){1,3}`,
})\\s*){1,3}`,
margin: `((${CssProp.C.margin_width})\\s*){1,4}`,
padding_left: CssProp.C.padding_width,
border_left: `((${CssProp.C.border_width}|${CssProp.A.border_style}|${
CssProp.C.color
})\\s*){1,3}`,
})\\s*){1,3}`,
quotes: `(${CssProp.B.string}\\s*${CssProp.B.string})+|none`,
border_top_right_radius: `(${CssProp.B.length}|${
CssProp.B.percentage
})(\\s*(${CssProp.B.length}|${CssProp.B.percentage}))?`,
})(\\s*(${CssProp.B.length}|${CssProp.B.percentage}))?`,
min_width: `${CssProp.B.length_pos}|${CssProp.B.percentage_pos}|auto`
};
private static readonly _CP1 = {
font: `(((((${CssProp.AP.font_style}|${CssProp.AP.font_variant}|${
CssProp.AP.font_weight
})\\s*){1,3})?\\s*(${CssProp._CP.font_size})\\s*(\\/\\s*(${
})\\s*){1,3})?\\s*(${CssProp._CP.font_size})\\s*(\\/\\s*(${
CssProp._CP.line_height
}))?\\s+(${
}))?\\s+(${
CssProp._CP.font_family
}))|caption|icon|menu|message-box|small-caption|status-bar)`
}))|caption|icon|menu|message-box|small-caption|status-bar)`
};
private static readonly CP = { ...CssProp._CP, ...CssProp._CP1 };

View File

@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import * as renderers from './renderers';
import { IRenderMime } from './common/renderMimeInterfaces';
import { ReadonlyJSONObject } from '../models/jsonext';
import * as tableRenderers from 'sql/workbench/parts/notebook/outputs/tableRenderers';
import { IRenderMime } from '../../common/models/renderMimeInterfaces';
import { ReadonlyJSONObject } from '../../common/models/jsonext';
import * as tableRenderers from 'sql/workbench/parts/notebook/browser/outputs/tableRenderers';
/**
* A common base class for mime renderers.

View File

@@ -9,10 +9,10 @@ import { Event, Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
import * as notebookUtils from '../notebookUtils';
import { CellTypes, CellType, NotebookChangeType } from 'sql/workbench/parts/notebook/models/contracts';
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
import { ICellModel, notebookConstants, IOutputChangedEvent } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import * as notebookUtils from './notebookUtils';
import { CellTypes, CellType, NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/contracts';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { ICellModel, notebookConstants, IOutputChangedEvent } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { ICellModelOptions, FutureInternal, CellExecutionState } from './modelInterfaces';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
@@ -20,6 +20,7 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/
import { Schemas } from 'vs/base/common/network';
import { INotebookService } from 'sql/workbench/services/notebook/common/notebookService';
import { optional } from 'vs/platform/instantiation/common/instantiation';
import { getErrorMessage } from 'vs/base/common/errors';
let modelId = 0;
export class CellModel implements ICellModel {
@@ -288,7 +289,7 @@ export class CellModel implements ICellModel {
if (error.message === 'Canceled') {
message = localize('executionCanceled', 'Query execution was canceled');
} else {
message = notebookUtils.getErrorMessage(error);
message = getErrorMessage(error);
}
this.sendNotification(notificationService, Severity.Error, message);
// TODO track error state for the cell

View File

@@ -3,7 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ICellMagicMapper, ILanguageMagic } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { ICellMagicMapper } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { ILanguageMagic } from 'sql/workbench/services/notebook/common/notebookService';
const defaultKernel = '*';
export class CellMagicMapper implements ICellMagicMapper {

View File

@@ -13,9 +13,9 @@ import { localize } from 'vs/nls';
import { IClientSession, IKernelPreference, IClientSessionOptions } from './modelInterfaces';
import { Deferred } from 'sql/base/common/promise';
import * as notebookUtils from '../notebookUtils';
import { INotebookManager } from 'sql/workbench/services/notebook/common/notebookService';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { getErrorMessage } from 'vs/base/common/errors';
type KernelChangeHandler = (kernel: nb.IKernelChangedArgs) => Promise<void>;
/**
@@ -67,7 +67,7 @@ export class ClientSession implements IClientSession {
await this.initializeSession();
await this.updateCachedKernelSpec();
} catch (err) {
this._errorMessage = notebookUtils.getErrorMessage(err) || localize('clientSession.unknownError', "An error occurred while starting the notebook session");
this._errorMessage = getErrorMessage(err) || localize('clientSession.unknownError', "An error occurred while starting the notebook session");
}
// Always resolving for now. It's up to callers to check for error case
this._isReady = true;

View File

@@ -11,16 +11,16 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { CellType, NotebookChangeType } from 'sql/workbench/parts/notebook/models/contracts';
import { INotebookManager } from 'sql/workbench/services/notebook/common/notebookService';
import { CellType, NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/contracts';
import { INotebookManager, ILanguageMagic } from 'sql/workbench/services/notebook/common/notebookService';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes';
import { IStandardKernelWithProvider } from 'sql/workbench/parts/notebook/notebookUtils';
import { IStandardKernelWithProvider } from 'sql/workbench/parts/notebook/node/models/notebookUtils';
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
import { localize } from 'vs/nls';
import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
export interface IClientSessionOptions {
@@ -514,13 +514,6 @@ export interface INotebookModelOptions {
editorLoadedTimestamp?: number;
}
export interface ILanguageMagic {
magic: string;
language: string;
kernels?: string[];
executionTarget?: string;
}
export interface ICellMagicMapper {
/**
* Tries to find a language mapping for an identified cell magic

View File

@@ -6,7 +6,7 @@
import { nb } from 'azdata';
import { localize } from 'vs/nls';
import { IDefaultConnection, notebookConstants } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { IDefaultConnection, notebookConstants } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';

View File

@@ -10,12 +10,12 @@ import { Event, Emitter } from 'vs/base/common/event';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { IClientSession, INotebookModel, IDefaultConnection, INotebookModelOptions, ICellModel, NotebookContentChange, notebookConstants } from './modelInterfaces';
import { NotebookChangeType, CellType, CellTypes } from 'sql/workbench/parts/notebook/models/contracts';
import { nbversion } from '../notebookConstants';
import * as notebookUtils from '../notebookUtils';
import * as TelemetryKeys from 'sql/platform/telemetry/telemetryKeys';
import { NotebookChangeType, CellType, CellTypes } from 'sql/workbench/parts/notebook/common/models/contracts';
import { nbversion } from '../../common/models/notebookConstants';
import * as notebookUtils from './notebookUtils';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { INotebookManager, SQL_NOTEBOOK_PROVIDER, DEFAULT_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/common/notebookService';
import { NotebookContexts } from 'sql/workbench/parts/notebook/models/notebookContexts';
import { NotebookContexts } from 'sql/workbench/parts/notebook/node/models/notebookContexts';
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { INotification, Severity, INotificationService } from 'vs/platform/notification/common/notification';
import { URI } from 'vs/base/common/uri';
@@ -25,6 +25,7 @@ import { uriPrefixes } from 'sql/platform/connection/common/utils';
import { keys } from 'vs/base/common/map';
import { ILogService } from 'vs/platform/log/common/log';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { getErrorMessage } from 'vs/base/common/errors';
/*
* Used to control whether a message in a dialog/wizard is displayed as an error,
@@ -626,13 +627,13 @@ export class NotebookModel extends Disposable implements INotebookModel {
await this.updateKernelInfoOnKernelChange(kernel);
} catch (err2) {
// TODO should we handle this in any way?
this.logService.error(`doChangeKernel: ignoring error ${notebookUtils.getErrorMessage(err2)}`);
this.logService.error(`doChangeKernel: ignoring error ${getErrorMessage(err2)}`);
}
}
}
} catch (err) {
if (oldDisplayName && restoreOnFail) {
this.notifyError(localize('changeKernelFailedRetry', "Failed to change kernel. Kernel {0} will be used. Error was: {1}", oldDisplayName, notebookUtils.getErrorMessage(err)));
this.notifyError(localize('changeKernelFailedRetry', "Failed to change kernel. Kernel {0} will be used. Error was: {1}", oldDisplayName, getErrorMessage(err)));
// Clear out previous kernel
let failedProviderId = this.tryFindProviderForKernel(displayName, true);
let oldProviderId = this.tryFindProviderForKernel(oldDisplayName, true);
@@ -643,7 +644,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
}
return this.doChangeKernel(oldDisplayName, mustSetProvider, false);
} else {
this.notifyError(localize('changeKernelFailed', "Failed to change kernel due to error: {0}", notebookUtils.getErrorMessage(err)));
this.notifyError(localize('changeKernelFailed', "Failed to change kernel due to error: {0}", getErrorMessage(err)));
this._kernelChangedEmitter.fire({
newValue: undefined,
oldValue: undefined
@@ -698,7 +699,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
error => {
if (error) {
if (!hideErrorMessage) {
this.notifyError(notebookUtils.getErrorMessage(error));
this.notifyError(getErrorMessage(error));
}
//Selected a wrong connection, Attach to should be defaulted with 'Select connection'
this._onValidConnectionSelected.fire(false);
@@ -708,7 +709,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
this._onValidConnectionSelected.fire(false);
}
} catch (err) {
let msg = notebookUtils.getErrorMessage(err);
let msg = getErrorMessage(err);
this.notifyError(localize('changeContextFailed', "Changing context failed: {0}", msg));
}
}
@@ -807,7 +808,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
}
await this.shutdownActiveSession();
} catch (err) {
this.logService.error('An error occurred when closing the notebook: {0}', notebookUtils.getErrorMessage(err));
this.logService.error('An error occurred when closing the notebook: {0}', getErrorMessage(err));
}
}
@@ -817,7 +818,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
await this._activeClientSession.ready;
}
catch (err) {
this.notifyError(localize('shutdownClientSessionError', "A client session error occurred when closing the notebook: {0}", notebookUtils.getErrorMessage(err)));
this.notifyError(localize('shutdownClientSessionError', "A client session error occurred when closing the notebook: {0}", getErrorMessage(err)));
}
await this._activeClientSession.shutdown();
this.clearClientSessionListeners();

View File

@@ -11,8 +11,8 @@ import { localize } from 'vs/nls';
import { DEFAULT_NOTEBOOK_PROVIDER, DEFAULT_NOTEBOOK_FILETYPE, INotebookService } from 'sql/workbench/services/notebook/common/notebookService';
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import { IOutputChannel } from 'vs/workbench/contrib/output/common/output';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
/**
@@ -22,10 +22,6 @@ export function isStream(output: nb.ICellOutput): output is nb.IStreamResult {
return output.output_type === 'stream';
}
export function getErrorMessage(error: Error | string): string {
return (error instanceof Error) ? error.message : error;
}
export function getUserHome(): string {
return process.env.HOME || process.env.USERPROFILE;
}

View File

@@ -10,11 +10,11 @@ import { URI } from 'vs/base/common/uri';
import * as resources from 'vs/base/common/resources';
import * as azdata from 'azdata';
import { IStandardKernelWithProvider, getProvidersForFileName, getStandardKernelsForProvider } from 'sql/workbench/parts/notebook/notebookUtils';
import { IStandardKernelWithProvider, getProvidersForFileName, getStandardKernelsForProvider } from 'sql/workbench/parts/notebook/node/models/notebookUtils';
import { INotebookService, DEFAULT_NOTEBOOK_PROVIDER, IProviderInfo } from 'sql/workbench/services/notebook/common/notebookService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { INotebookModel, IContentManager, NotebookContentChange } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { INotebookModel, IContentManager, NotebookContentChange } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel';
import { Range } from 'vs/editor/common/core/range';
import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel';
@@ -25,7 +25,7 @@ import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IDisposable } from 'vs/base/common/lifecycle';
import { NotebookChangeType } from 'sql/workbench/parts/notebook/models/contracts';
import { NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/contracts';
export type ModeViewSaveHandler = (handle: number) => Thenable<boolean>;

View File

@@ -3,14 +3,9 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { OnInit, Component, Input, Inject, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { OnInit, Component, Input, Inject, ViewChild, ElementRef } from '@angular/core';
import * as azdata from 'azdata';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { IMimeComponent } from 'sql/workbench/parts/notebook/outputs/mimeRegistry';
import { MimeModel } from 'sql/workbench/parts/notebook/outputs/common/mimemodel';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { GridTableBase, GridTableState } from 'sql/workbench/parts/query/electron-browser/gridPanel';
import { IGridDataProvider, getResultsString } from 'sql/platform/query/common/gridDataProvider';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -25,9 +20,15 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { attachTableStyler } from 'sql/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { getErrorMessage } from 'sql/workbench/parts/notebook/notebookUtils';
import { localize } from 'vs/nls';
import { IAction } from 'vs/base/common/actions';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { IMimeComponent } from 'sql/workbench/parts/notebook/electron-browser/outputs/mimeRegistry';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { MimeModel } from 'sql/workbench/parts/notebook/common/models/mimemodel';
import { GridTableState } from 'sql/workbench/parts/query/common/gridPanelState';
import { GridTableBase } from 'sql/workbench/parts/query/browser/gridPanel';
import { getErrorMessage } from 'vs/base/common/errors';
@Component({
selector: GridOutputComponent.SELECTOR,

View File

@@ -5,14 +5,14 @@
import { OnInit, Component, Input, Inject, ElementRef, ViewChild } from '@angular/core';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { IMimeComponent } from 'sql/workbench/parts/notebook/outputs/mimeRegistry';
import { MimeModel } from 'sql/workbench/parts/notebook/outputs/common/mimemodel';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { getErrorMessage } from 'sql/workbench/parts/notebook/notebookUtils';
import { localize } from 'vs/nls';
import * as types from 'vs/base/common/types';
import { AngularDisposable } from 'sql/base/browser/lifecycle';
import { IMimeComponent } from 'sql/workbench/parts/notebook/electron-browser/outputs/mimeRegistry';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { MimeModel } from 'sql/workbench/parts/notebook/common/models/mimemodel';
import { getErrorMessage } from 'vs/base/common/errors';
type ObjectType = object;
@@ -154,4 +154,4 @@ export class PlotlyOutputComponent extends AngularDisposable implements IMimeCom
return !types.isUndefinedOrNull(this.errorText);
}
}
}

View File

@@ -0,0 +1,312 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as should from 'should';
import * as TypeMoq from 'typemoq';
import { nb } from 'azdata';
import * as objects from 'vs/base/common/objects';
import { CellTypes } from 'sql/workbench/parts/notebook/common/models/contracts';
import { ModelFactory } from 'sql/workbench/parts/notebook/node/models/modelFactory';
import { NotebookModelStub } from './common';
import { EmptyFuture } from 'sql/workbench/services/notebook/common/sessionManager';
import { ICellModel } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { Deferred } from 'sql/base/common/promise';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
let instantiationService: IInstantiationService;
suite('Cell Model', function (): void {
let serviceCollection = new ServiceCollection();
instantiationService = new InstantiationService(serviceCollection, true);
let factory = new ModelFactory(instantiationService);
test('Should set default values if none defined', async function (): Promise<void> {
let cell = factory.createCell(undefined, undefined);
should(cell.cellType).equal(CellTypes.Code);
should(cell.source).equal('');
});
test('Should update values', async function (): Promise<void> {
let cell = factory.createCell(undefined, undefined);
cell.setOverrideLanguage('sql');
should(cell.language).equal('sql');
cell.source = 'abcd';
should(cell.source).equal('abcd');
});
test('Should match ICell values if defined', async function (): Promise<void> {
let output: nb.IStreamResult = {
output_type: 'stream',
text: 'Some output',
name: 'stdout'
};
let cellData: nb.ICellContents = {
cell_type: CellTypes.Markdown,
source: 'some *markdown*',
outputs: [output],
metadata: { language: 'python' },
execution_count: 1
};
let cell = factory.createCell(cellData, undefined);
should(cell.cellType).equal(cellData.cell_type);
should(cell.source).equal(cellData.source);
should(cell.outputs).have.length(1);
should(cell.outputs[0].output_type).equal('stream');
should((<nb.IStreamResult>cell.outputs[0]).text).equal('Some output');
});
test('Should set cell language to python if defined as python in languageInfo', async function (): Promise<void> {
let cellData: nb.ICellContents = {
cell_type: CellTypes.Code,
source: 'print(\'1\')',
metadata: { language: 'python' },
execution_count: 1
};
let notebookModel = new NotebookModelStub({
name: 'python',
version: '',
mimetype: ''
});
let cell = factory.createCell(cellData, { notebook: notebookModel, isTrusted: false });
should(cell.language).equal('python');
});
test('Should set cell language to python if defined as pyspark in languageInfo', async function (): Promise<void> {
let cellData: nb.ICellContents = {
cell_type: CellTypes.Code,
source: 'print(\'1\')',
metadata: { language: 'python' },
execution_count: 1
};
let notebookModel = new NotebookModelStub({
name: 'pyspark',
version: '',
mimetype: ''
});
let cell = factory.createCell(cellData, { notebook: notebookModel, isTrusted: false });
should(cell.language).equal('python');
});
test('Should keep cell language as python if cell has language override', async function (): Promise<void> {
let cellData: nb.ICellContents = {
cell_type: CellTypes.Code,
source: 'print(\'1\')',
metadata: { language: 'python' },
execution_count: 1
};
let notebookModel = new NotebookModelStub({
name: 'scala',
version: '',
mimetype: ''
});
let cell = factory.createCell(cellData, { notebook: notebookModel, isTrusted: false });
should(cell.language).equal('python');
});
test('Should set cell language to python if no language defined', async function (): Promise<void> {
let cellData: nb.ICellContents = {
cell_type: CellTypes.Code,
source: 'print(\'1\')',
metadata: { language: 'python' },
execution_count: 1
};
let notebookModel = new NotebookModelStub({
name: '',
version: '',
mimetype: ''
});
let cell = factory.createCell(cellData, { notebook: notebookModel, isTrusted: false });
should(cell.language).equal('python');
});
suite('Model Future handling', function (): void {
let future: TypeMoq.Mock<EmptyFuture>;
let cell: ICellModel;
const stdInDefaultMessage: nb.IStdinMessage = {
channel: 'stdin',
type: 'stdin',
parent_header: undefined,
metadata: undefined,
header: <nb.IHeader>{
msg_type: 'stream'
},
content: {
prompt: 'Prompt',
password: false
}
};
setup(() => {
future = TypeMoq.Mock.ofType(EmptyFuture);
cell = factory.createCell({
cell_type: CellTypes.Code,
source: 'print "Hello"',
metadata: { language: 'python' },
execution_count: 1
}, {
notebook: new NotebookModelStub({
name: '',
version: '',
mimetype: 'x-scala'
}),
isTrusted: false
});
});
test('should send and handle incoming messages', async () => {
// Given a future
let onReply: nb.MessageHandler<nb.IShellMessage>;
let onIopub: nb.MessageHandler<nb.IIOPubMessage>;
future.setup(f => f.setReplyHandler(TypeMoq.It.isAny())).callback((handler) => onReply = handler);
future.setup(f => f.setIOPubHandler(TypeMoq.It.isAny())).callback((handler) => onIopub = handler);
let outputs: ReadonlyArray<nb.ICellOutput> = undefined;
cell.onOutputsChanged((o => outputs = o.outputs));
// When I set it on the cell
cell.setFuture(future.object);
// Then I expect outputs to have been cleared
should(outputs).have.length(0);
should(onReply).not.be.undefined();
// ... And when I send an IoPub message
let message: nb.IIOPubMessage = {
channel: 'iopub',
type: 'iopub',
parent_header: undefined,
metadata: undefined,
header: <nb.IHeader>{
msg_type: 'stream'
},
content: {
text: 'Printed hello world'
}
};
onIopub.handle(message);
// Then I expect an output to be added
should(outputs).have.length(1);
should(outputs[0].output_type).equal('stream');
message = objects.deepClone(message);
message.header.msg_type = 'display_data';
onIopub.handle(message);
should(outputs[1].output_type).equal('display_data');
});
test('stdin should return void if no handler registered', async () => {
// Given stdIn does not have a request handler setup
let onStdIn: nb.MessageHandler<nb.IStdinMessage>;
future.setup(f => f.setStdInHandler(TypeMoq.It.isAny())).callback((handler) => onStdIn = handler);
// When I set it on the cell
cell.setFuture(future.object);
// Then I expect stdIn to have been hooked up
should(onStdIn).not.be.undefined();
// ... And when I send a stdIn request message
let result = onStdIn.handle(stdInDefaultMessage);
// Then I expect the promise to resolve
await result;
future.verify(f => f.sendInputReply(TypeMoq.It.isAny()), TypeMoq.Times.never());
});
test('stdin should wait on handler if handler registered', async () => {
// Given stdIn has a handler set up
let onStdIn: nb.MessageHandler<nb.IStdinMessage>;
future.setup(f => f.setStdInHandler(TypeMoq.It.isAny())).callback((handler) => onStdIn = handler);
let deferred = new Deferred<void>();
let stdInMessage: nb.IStdinMessage = undefined;
cell.setStdInHandler({
handle: (msg: nb.IStdinMessage) => {
stdInMessage = msg;
return deferred.promise;
}
});
// When I send a stdIn request message
cell.setFuture(future.object);
let result = onStdIn.handle(stdInDefaultMessage);
deferred.resolve();
// Then I expect promise to resolve since it should wait on upstream handling
await result;
// And I expect message to have been passed upstream and no message sent from the cell
should(stdInMessage).not.be.undefined();
should(stdInMessage.content.prompt).equal(stdInDefaultMessage.content.prompt);
should(stdInMessage.content.password).equal(stdInDefaultMessage.content.password);
future.verify(f => f.sendInputReply(TypeMoq.It.isAny()), TypeMoq.Times.never());
});
test('stdin should send default response if there is upstream error', async () => {
// Given stdIn has a handler set up
let onStdIn: nb.MessageHandler<nb.IStdinMessage>;
future.setup(f => f.setStdInHandler(TypeMoq.It.isAny())).callback((handler) => onStdIn = handler);
let deferred = new Deferred<void>();
let stdInMessage: nb.IStdinMessage = undefined;
cell.setStdInHandler({
handle: (msg: nb.IStdinMessage) => {
stdInMessage = msg;
return deferred.promise;
}
});
// When I send a stdIn request message
cell.setFuture(future.object);
let result = onStdIn.handle(stdInDefaultMessage);
deferred.reject('Something went wrong');
// Then I expect promise to resolve since it should wait on upstream handling
await result;
future.verify(f => f.sendInputReply(TypeMoq.It.isAny()), TypeMoq.Times.once());
});
test('should delete transient tag while handling incoming messages', async () => {
// Given a future
let onIopub: nb.MessageHandler<nb.IIOPubMessage>;
future.setup(f => f.setIOPubHandler(TypeMoq.It.isAny())).callback((handler) => onIopub = handler);
let outputs: ReadonlyArray<nb.ICellOutput> = undefined;
cell.onOutputsChanged((o => outputs = o.outputs));
//Set the future
cell.setFuture(future.object);
// ... And when I send an IoPub message
let message: nb.IIOPubMessage = {
channel: 'iopub',
type: 'iopub',
parent_header: undefined,
metadata: undefined,
header: <nb.IHeader>{
msg_type: 'display_data'
},
content: {
text: 'Printed hello world',
transient: 'transient data'
}
};
onIopub.handle(message);
//Output array's length should be 1
//'transient' tag should no longer exist in the output
should(outputs).have.length(1);
should(outputs[0]['transient']).be.undefined();
});
test('should dispose old future', async () => {
let oldFuture = TypeMoq.Mock.ofType(EmptyFuture);
cell.setFuture(oldFuture.object);
cell.setFuture(future.object);
oldFuture.verify(f => f.dispose(), TypeMoq.Times.once());
});
});
});

View File

@@ -0,0 +1,183 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as should from 'should';
import * as TypeMoq from 'typemoq';
import { nb } from 'azdata';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
import { URI } from 'vs/base/common/uri';
import { ClientSession } from 'sql/workbench/parts/notebook/node/models/clientSession';
import { SessionManager, EmptySession } from 'sql/workbench/services/notebook/common/sessionManager';
import { NotebookManagerStub, ServerManagerStub } from './common';
suite('Client Session', function (): void {
let path = URI.file('my/notebook.ipynb');
let notebookManager: NotebookManagerStub;
let serverManager: ServerManagerStub;
let mockSessionManager: TypeMoq.Mock<nb.SessionManager>;
let notificationService: TypeMoq.Mock<INotificationService>;
let session: ClientSession;
let remoteSession: ClientSession;
setup(() => {
serverManager = new ServerManagerStub();
mockSessionManager = TypeMoq.Mock.ofType(SessionManager);
notebookManager = new NotebookManagerStub();
notebookManager.serverManager = serverManager;
notebookManager.sessionManager = mockSessionManager.object;
notificationService = TypeMoq.Mock.ofType(TestNotificationService, TypeMoq.MockBehavior.Loose);
session = new ClientSession({
notebookManager: notebookManager,
notebookUri: path,
notificationService: notificationService.object,
kernelSpec: undefined
});
let serverlessNotebookManager = new NotebookManagerStub();
serverlessNotebookManager.sessionManager = mockSessionManager.object;
remoteSession = new ClientSession({
notebookManager: serverlessNotebookManager,
notebookUri: path,
notificationService: notificationService.object,
kernelSpec: undefined
});
});
test('Should set path, isReady and ready on construction', function (): void {
should(session.notebookUri).equal(path);
should(session.ready).not.be.undefined();
should(session.isReady).be.false();
should(session.status).equal('starting');
should(session.isInErrorState).be.false();
should(session.errorMessage).be.undefined();
});
test('Should call on serverManager startup if set', async function (): Promise<void> {
// Given I have a serverManager that starts successfully
serverManager.result = Promise.resolve();
should(session.isReady).be.false();
// When I kick off initialization
await session.initialize();
// Then I expect ready to be completed too
await session.ready;
should(serverManager.calledStart).be.true();
should(session.isReady).be.true();
});
test('Should go to error state if serverManager startup fails', async function (): Promise<void> {
// Given I have a serverManager that fails to start
serverManager.result = Promise.reject('error');
should(session.isInErrorState).be.false();
// When I initialize
await session.initialize();
// Then I expect ready to complete, but isInErrorState to be true
await session.ready;
should(session.isReady).be.true();
should(serverManager.calledStart).be.true();
should(session.isInErrorState).be.true();
should(session.errorMessage).equal('error');
});
test('Should be ready when session manager is ready', async function (): Promise<void> {
serverManager.result = new Promise((resolve) => {
serverManager.isStarted = true;
resolve();
});
mockSessionManager.setup(s => s.ready).returns(() => Promise.resolve());
// When I call initialize
await session.initialize();
// Then
should(session.isReady).be.true();
should(session.isInErrorState).be.false();
await session.ready;
});
test('Should be in error state if server fails to start', async function (): Promise<void> {
serverManager.result = new Promise((resolve) => {
serverManager.isStarted = false;
resolve();
});
mockSessionManager.setup(s => s.ready).returns(() => Promise.resolve());
// When I call initialize
await session.initialize();
// Then
await session.ready;
should(session.isReady).be.true();
should(session.isInErrorState).be.true();
});
test('Should go to error state if sessionManager fails', async function (): Promise<void> {
serverManager.isStarted = true;
mockSessionManager.setup(s => s.isReady).returns(() => false);
mockSessionManager.setup(s => s.ready).returns(() => Promise.reject('error'));
// When I call initialize
await session.initialize();
// Then
should(session.isReady).be.true();
should(session.isInErrorState).be.true();
should(session.errorMessage).equal('error');
});
// test('Should start session automatically if kernel preference requests it', async function (): Promise<void> {
// serverManager.isStarted = true;
// mockSessionManager.setup(s => s.ready).returns(() => Promise.resolve());
// let sessionMock = TypeMoq.Mock.ofType(EmptySession);
// let startOptions: nb.ISessionOptions = undefined;
// mockSessionManager.setup(s => s.startNew(TypeMoq.It.isAny())).returns((options) => {
// startOptions = options;
// return Promise.resolve(sessionMock.object);
// });
// // When I call initialize after defining kernel preferences
// session.kernelPreference = {
// shouldStart: true,
// name: 'python'
// };
// await session.initialize();
// // Then
// should(session.isReady).be.true();
// should(session.isInErrorState).be.false();
// should(startOptions.kernelName).equal('python');
// should(startOptions.path).equal(path.fsPath);
// });
// test('Should shutdown session even if no serverManager is set', async function (): Promise<void> {
// // Given a session against a remote server
// let expectedId = 'abc';
// mockSessionManager.setup(s => s.isReady).returns(() => true);
// mockSessionManager.setup(s => s.shutdown(TypeMoq.It.isAny())).returns(() => Promise.resolve());
// let sessionMock = TypeMoq.Mock.ofType(EmptySession);
// sessionMock.setup(s => s.id).returns(() => expectedId);
// mockSessionManager.setup(s => s.startNew(TypeMoq.It.isAny())).returns(() => Promise.resolve(sessionMock.object));
// remoteSession.kernelPreference = {
// shouldStart: true,
// name: 'python'
// };
// await remoteSession.initialize();
// // When I call shutdown
// await remoteSession.shutdown();
// // Then
// mockSessionManager.verify(s => s.shutdown(TypeMoq.It.isValue(expectedId)), TypeMoq.Times.once());
// });
});

View File

@@ -0,0 +1,134 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { nb, IConnectionProfile } from 'azdata';
import { Event, Emitter } from 'vs/base/common/event';
import { INotebookModel, ICellModel, IClientSession, IDefaultConnection, NotebookContentChange } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { NotebookChangeType, CellType } from 'sql/workbench/parts/notebook/common/models/contracts';
import { INotebookManager } from 'sql/workbench/services/notebook/common/notebookService';
import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes';
import { IStandardKernelWithProvider } from 'sql/workbench/parts/notebook/node/models/notebookUtils';
export class NotebookModelStub implements INotebookModel {
constructor(private _languageInfo?: nb.ILanguageInfo) {
}
public trustedMode: boolean;
language: string;
standardKernels: IStandardKernelWithProvider[];
public get languageInfo(): nb.ILanguageInfo {
return this._languageInfo;
}
onCellChange(cell: ICellModel, change: NotebookChangeType): void {
// Default: do nothing
}
get cells(): ReadonlyArray<ICellModel> {
throw new Error('method not implemented.');
}
get activeCell(): ICellModel {
throw new Error('method not implemented.');
}
get clientSession(): IClientSession {
throw new Error('method not implemented.');
}
get notebookManagers(): INotebookManager[] {
throw new Error('method not implemented.');
}
get kernelChanged(): Event<nb.IKernelChangedArgs> {
throw new Error('method not implemented.');
}
get kernelsChanged(): Event<nb.IKernelSpec> {
throw new Error('method not implemented.');
}
get layoutChanged(): Event<void> {
throw new Error('method not implemented.');
}
get defaultKernel(): nb.IKernelSpec {
throw new Error('method not implemented.');
}
get contextsChanged(): Event<void> {
throw new Error('method not implemented.');
}
get contextsLoading(): Event<void> {
throw new Error('method not implemented.');
}
get contentChanged(): Event<NotebookContentChange> {
throw new Error('method not implemented.');
}
get specs(): nb.IAllKernels {
throw new Error('method not implemented.');
}
get contexts(): IDefaultConnection {
throw new Error('method not implemented.');
}
get providerId(): string {
throw new Error('method not implemented.');
}
get applicableConnectionProviderIds(): string[] {
throw new Error('method not implemented.');
}
getStandardKernelFromName(name: string): IStandardKernelWithProvider {
throw new Error('Method not implemented.');
}
changeKernel(displayName: string): void {
throw new Error('Method not implemented.');
}
changeContext(host: string, connection?: IConnectionProfile, hideErrorMessage?: boolean): Promise<void> {
throw new Error('Method not implemented.');
}
findCellIndex(cellModel: ICellModel): number {
throw new Error('Method not implemented.');
}
addCell(cellType: CellType, index?: number): void {
throw new Error('Method not implemented.');
}
deleteCell(cellModel: ICellModel): void {
throw new Error('Method not implemented.');
}
pushEditOperations(edits: ISingleNotebookEditOperation[]): void {
throw new Error('Method not implemented.');
}
getApplicableConnectionProviderIds(kernelName: string): string[] {
throw new Error('Method not implemented.');
}
get onValidConnectionSelected(): Event<boolean> {
throw new Error('method not implemented.');
}
get onProviderIdChange(): Event<string> {
throw new Error('method not impelemented.');
}
toJSON(): nb.INotebookContents {
throw new Error('Method not implemented.');
}
serializationStateChanged(changeType: NotebookChangeType): void {
throw new Error('Method not implemented.');
}
}
export class NotebookManagerStub implements INotebookManager {
providerId: string;
contentManager: nb.ContentManager;
sessionManager: nb.SessionManager;
serverManager: nb.ServerManager;
}
export class ServerManagerStub implements nb.ServerManager {
public onServerStartedEmitter = new Emitter<void>();
onServerStarted: Event<void> = this.onServerStartedEmitter.event;
isStarted: boolean = false;
calledStart: boolean = false;
calledEnd: boolean = false;
public result: Promise<void> = undefined;
startServer(): Promise<void> {
this.calledStart = true;
return this.result;
}
stopServer(): Promise<void> {
this.calledEnd = true;
return this.result;
}
}

View File

@@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as should from 'should';
import { nb } from 'azdata';
import { URI } from 'vs/base/common/uri';
import * as tempWrite from 'temp-write';
import { LocalContentManager } from 'sql/workbench/services/notebook/node/localContentManager';
import * as testUtils from '../../../../../../sqltest/utils/testUtils';
import { CellTypes } from 'sql/workbench/parts/notebook/common/models/contracts';
let expectedNotebookContent: nb.INotebookContents = {
cells: [{
cell_type: CellTypes.Code,
source: 'insert into t1 values (c1, c2)',
metadata: { language: 'python' },
execution_count: 1
}],
metadata: {
kernelspec: {
name: 'mssql',
language: 'sql'
}
},
nbformat: 4,
nbformat_minor: 2
};
let notebookContentString = JSON.stringify(expectedNotebookContent);
function verifyMatchesExpectedNotebook(notebook: nb.INotebookContents): void {
should(notebook.cells).have.length(1, 'Expected 1 cell');
should(notebook.cells[0].cell_type).equal(CellTypes.Code);
should(notebook.cells[0].source).equal(expectedNotebookContent.cells[0].source);
should(notebook.metadata.kernelspec.name).equal(expectedNotebookContent.metadata.kernelspec.name);
should(notebook.nbformat).equal(expectedNotebookContent.nbformat);
should(notebook.nbformat_minor).equal(expectedNotebookContent.nbformat_minor);
}
suite('Local Content Manager', function (): void {
let contentManager = new LocalContentManager();
test('Should return undefined if path is undefined', async function (): Promise<void> {
let content = await contentManager.getNotebookContents(undefined);
should(content).be.undefined();
// tslint:disable-next-line:no-null-keyword
content = await contentManager.getNotebookContents(null);
should(content).be.undefined();
});
test('Should throw if file does not exist', async function (): Promise<void> {
await testUtils.assertThrowsAsync(async () => await contentManager.getNotebookContents(URI.file('/path/doesnot/exist.ipynb')), undefined);
});
test('Should return notebook contents parsed as INotebook when valid notebook file parsed', async function (): Promise<void> {
// Given a file containing a valid notebook
let localFile = tempWrite.sync(notebookContentString, 'notebook.ipynb');
// when I read the content
let notebook = await contentManager.getNotebookContents(URI.file(localFile));
// then I expect notebook format to match
verifyMatchesExpectedNotebook(notebook);
});
test('Should ignore invalid content in the notebook file', async function (): Promise<void> {
// Given a file containing a notebook with some garbage properties
let invalidContent = notebookContentString + '\\nasddfdsafasdf';
let localFile = tempWrite.sync(invalidContent, 'notebook.ipynb');
// when I read the content
let notebook = await contentManager.getNotebookContents(URI.file(localFile));
// then I expect notebook format to still be valid
verifyMatchesExpectedNotebook(notebook);
});
test('Should inline mime data into a single string', async function (): Promise<void> {
let mimeNotebook: nb.INotebookContents = {
cells: [{
cell_type: CellTypes.Code,
source: 'insert into t1 values (c1, c2)',
metadata: { language: 'python' },
execution_count: 1,
outputs: [
<nb.IDisplayData>{
output_type: 'display_data',
data: {
'text/html': [
'<div>',
'</div>'
]
}
}
]
}],
metadata: {
kernelspec: {
name: 'mssql',
language: 'sql'
}
},
nbformat: 4,
nbformat_minor: 2
};
let mimeContentString = JSON.stringify(mimeNotebook);
// Given a file containing a valid notebook with multiline mime type
let localFile = tempWrite.sync(mimeContentString, 'notebook.ipynb');
// when I read the content
let notebook = await contentManager.getNotebookContents(URI.file(localFile));
// then I expect output to have been normalized into a single string
let displayOutput = <nb.IDisplayData>notebook.cells[0].outputs[0];
should(displayOutput.data['text/html']).equal('<div></div>');
});
});

View File

@@ -0,0 +1,304 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as should from 'should';
import * as TypeMoq from 'typemoq';
import { nb } from 'azdata';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
import { URI } from 'vs/base/common/uri';
import { LocalContentManager } from 'sql/workbench/services/notebook/node/localContentManager';
import { NotebookManagerStub } from './common';
import { NotebookModel } from 'sql/workbench/parts/notebook/node/models/notebookModel';
import { ModelFactory } from 'sql/workbench/parts/notebook/node/models/modelFactory';
import { IClientSession, ICellModel, INotebookModelOptions, NotebookContentChange } from 'sql/workbench/parts/notebook/node/models/modelInterfaces';
import { ClientSession } from 'sql/workbench/parts/notebook/node/models/clientSession';
import { CellTypes, NotebookChangeType } from 'sql/workbench/parts/notebook/common/models/contracts';
import { Deferred } from 'sql/base/common/promise';
import { ConnectionManagementService } from 'sql/platform/connection/common/connectionManagementService';
import { Memento } from 'vs/workbench/common/memento';
import { Emitter } from 'vs/base/common/event';
import { TestCapabilitiesService } from 'sql/platform/capabilities/test/common/testCapabilitiesService';
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
import { TestStorageService } from 'vs/workbench/test/workbenchTestServices';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
import { NullLogService } from 'vs/platform/log/common/log';
let expectedNotebookContent: nb.INotebookContents = {
cells: [{
cell_type: CellTypes.Code,
source: 'insert into t1 values (c1, c2)',
metadata: { language: 'python' },
execution_count: 1
}, {
cell_type: CellTypes.Markdown,
source: 'I am *markdown*',
metadata: { language: 'python' },
execution_count: 1
}],
metadata: {
kernelspec: {
name: 'mssql',
language: 'sql'
}
},
nbformat: 4,
nbformat_minor: 5
};
let expectedNotebookContentOneCell: nb.INotebookContents = {
cells: [{
cell_type: CellTypes.Code,
source: 'insert into t1 values (c1, c2)',
metadata: { language: 'python' },
execution_count: 1
}],
metadata: {
kernelspec: {
name: 'mssql',
language: 'sql'
}
},
nbformat: 4,
nbformat_minor: 5
};
let defaultUri = URI.file('/some/path.ipynb');
let mockClientSession: TypeMoq.Mock<IClientSession>;
let sessionReady: Deferred<void>;
let mockModelFactory: TypeMoq.Mock<ModelFactory>;
let notificationService: TypeMoq.Mock<INotificationService>;
let capabilitiesService: TypeMoq.Mock<ICapabilitiesService>;
let instantiationService: IInstantiationService;
suite('notebook model', function (): void {
let notebookManagers = [new NotebookManagerStub()];
let memento: TypeMoq.Mock<Memento>;
let queryConnectionService: TypeMoq.Mock<ConnectionManagementService>;
let defaultModelOptions: INotebookModelOptions;
const logService = new NullLogService();
setup(() => {
sessionReady = new Deferred<void>();
notificationService = TypeMoq.Mock.ofType(TestNotificationService, TypeMoq.MockBehavior.Loose);
capabilitiesService = TypeMoq.Mock.ofType(TestCapabilitiesService);
memento = TypeMoq.Mock.ofType(Memento, TypeMoq.MockBehavior.Loose, '');
memento.setup(x => x.getMemento(TypeMoq.It.isAny())).returns(() => void 0);
queryConnectionService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, memento.object, undefined, new TestStorageService());
queryConnectionService.callBase = true;
let serviceCollection = new ServiceCollection();
instantiationService = new InstantiationService(serviceCollection, true);
defaultModelOptions = {
notebookUri: defaultUri,
factory: new ModelFactory(instantiationService),
notebookManagers,
contentManager: undefined,
notificationService: notificationService.object,
connectionService: queryConnectionService.object,
providerId: 'SQL',
cellMagicMapper: undefined,
defaultKernel: undefined,
layoutChanged: undefined,
capabilitiesService: capabilitiesService.object
};
mockClientSession = TypeMoq.Mock.ofType(ClientSession, undefined, defaultModelOptions);
mockClientSession.setup(c => c.initialize()).returns(() => {
return Promise.resolve();
});
mockClientSession.setup(c => c.ready).returns(() => sessionReady.promise);
mockModelFactory = TypeMoq.Mock.ofType(ModelFactory);
mockModelFactory.callBase = true;
mockModelFactory.setup(f => f.createClientSession(TypeMoq.It.isAny())).returns(() => {
return mockClientSession.object;
});
});
test('Should create no cells if model has no contents', async function (): Promise<void> {
// Given an empty notebook
let emptyNotebook: nb.INotebookContents = {
cells: [],
metadata: {
kernelspec: {
name: 'mssql',
language: 'sql'
}
},
nbformat: 4,
nbformat_minor: 5
};
let mockContentManager = TypeMoq.Mock.ofType(LocalContentManager);
mockContentManager.setup(c => c.getNotebookContents(TypeMoq.It.isAny())).returns(() => Promise.resolve(emptyNotebook));
notebookManagers[0].contentManager = mockContentManager.object;
// When I initialize the model
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, undefined);
await model.loadContents();
// Then I expect to have 0 code cell as the contents
should(model.cells).have.length(0);
// And Trust should be false by default
should(model.trustedMode).be.false();
});
test('Should use trusted state set in model load', async function (): Promise<void> {
// Given a notebook
let mockContentManager = TypeMoq.Mock.ofType(LocalContentManager);
mockContentManager.setup(c => c.getNotebookContents(TypeMoq.It.isAny())).returns(() => Promise.resolve(expectedNotebookContent));
notebookManagers[0].contentManager = mockContentManager.object;
// When I initialize the model
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, undefined);
await model.loadContents(true);
await model.requestModelLoad();
// Then Trust should be true
should(model.trustedMode).be.true();
});
// test('Should throw if model load fails', async function(): Promise<void> {
// // Given a call to get Contents fails
// let error = new Error('File not found');
// let mockContentManager = TypeMoq.Mock.ofType(LocalContentManager);
// mockContentManager.setup(c => c.getNotebookContents(TypeMoq.It.isAny())).throws(error);
// notebookManagers[0].contentManager = mockContentManager.object;
// // When I initalize the model
// // Then it should throw
// let model = new NotebookModel(defaultModelOptions);
// should(model.inErrorState).be.false();
// await testUtils.assertThrowsAsync(() => model.requestModelLoad(), error.message);
// should(model.inErrorState).be.true();
// });
// test('Should convert cell info to CellModels', async function(): Promise<void> {
// // Given a notebook with 2 cells
// let mockContentManager = TypeMoq.Mock.ofType(LocalContentManager);
// mockContentManager.setup(c => c.getNotebookContents(TypeMoq.It.isAny())).returns(() => Promise.resolve(expectedNotebookContent));
// notebookManagers[0].contentManager = mockContentManager.object;
// // When I initalize the model
// let model = new NotebookModel(defaultModelOptions);
// await model.requestModelLoad();
// // Then I expect all cells to be in the model
// should(model.cells).have.length(2);
// should(model.cells[0].source).be.equal(expectedNotebookContent.cells[0].source);
// should(model.cells[1].source).be.equal(expectedNotebookContent.cells[1].source);
// });
// test('Should load contents but then go to error state if client session startup fails', async function(): Promise<void> {
// let mockContentManager = TypeMoq.Mock.ofType(LocalContentManager);
// mockContentManager.setup(c => c.getNotebookContents(TypeMoq.It.isAny())).returns(() => Promise.resolve(expectedNotebookContentOneCell));
// notebookManagers[0].contentManager = mockContentManager.object;
// // Given I have a session that fails to start
// mockClientSession.setup(c => c.isInErrorState).returns(() => true);
// mockClientSession.setup(c => c.errorMessage).returns(() => 'Error');
// sessionReady.resolve();
// let sessionFired = false;
// let options: INotebookModelOptions = Object.assign({}, defaultModelOptions, <Partial<INotebookModelOptions>> {
// factory: mockModelFactory.object
// });
// let model = new NotebookModel(options);
// model.onClientSessionReady((session) => sessionFired = true);
// await model.requestModelLoad();
// model.startSession(notebookManagers[0]);
// // Then I expect load to succeed
// shouldHaveOneCell(model);
// should(model.clientSession).not.be.undefined();
// // but on server load completion I expect error state to be set
// // Note: do not expect serverLoad event to throw even if failed
// await model.sessionLoadFinished;
// should(model.inErrorState).be.true();
// should(sessionFired).be.false();
// });
test('Should not be in error state if client session initialization succeeds', async function (): Promise<void> {
let mockContentManager = TypeMoq.Mock.ofType(LocalContentManager);
mockContentManager.setup(c => c.getNotebookContents(TypeMoq.It.isAny())).returns(() => Promise.resolve(expectedNotebookContentOneCell));
notebookManagers[0].contentManager = mockContentManager.object;
let kernelChangedEmitter: Emitter<nb.IKernelChangedArgs> = new Emitter<nb.IKernelChangedArgs>();
let statusChangedEmitter: Emitter<nb.ISession> = new Emitter<nb.ISession>();
mockClientSession.setup(c => c.isInErrorState).returns(() => false);
mockClientSession.setup(c => c.isReady).returns(() => true);
mockClientSession.setup(c => c.kernelChanged).returns(() => kernelChangedEmitter.event);
mockClientSession.setup(c => c.statusChanged).returns(() => statusChangedEmitter.event);
queryConnectionService.setup(c => c.getActiveConnections(TypeMoq.It.isAny())).returns(() => null);
sessionReady.resolve();
let actualSession: IClientSession = undefined;
let options: INotebookModelOptions = Object.assign({}, defaultModelOptions, <Partial<INotebookModelOptions>>{
factory: mockModelFactory.object
});
let model = new NotebookModel(options, undefined, logService, undefined, undefined);
model.onClientSessionReady((session) => actualSession = session);
await model.requestModelLoad();
await model.startSession(notebookManagers[0]);
// Then I expect load to succeed
should(model.clientSession).not.be.undefined();
// but on server load completion I expect error state to be set
// Note: do not expect serverLoad event to throw even if failed
let kernelChangedArg: nb.IKernelChangedArgs = undefined;
model.kernelChanged((kernel) => kernelChangedArg = kernel);
await model.sessionLoadFinished;
should(model.inErrorState).be.false();
should(actualSession).equal(mockClientSession.object);
should(model.clientSession).equal(mockClientSession.object);
});
test('Should sanitize kernel display name when IP is included', async function (): Promise<void> {
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, undefined);
let displayName = 'PySpark (1.1.1.1)';
let sanitizedDisplayName = model.sanitizeDisplayName(displayName);
should(sanitizedDisplayName).equal('PySpark');
});
test('Should sanitize kernel display name properly when IP is not included', async function (): Promise<void> {
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, undefined);
let displayName = 'PySpark';
let sanitizedDisplayName = model.sanitizeDisplayName(displayName);
should(sanitizedDisplayName).equal('PySpark');
});
test('Should notify on trust set', async function () {
// Given a notebook that's been loaded
let mockContentManager = TypeMoq.Mock.ofType(LocalContentManager);
mockContentManager.setup(c => c.getNotebookContents(TypeMoq.It.isAny())).returns(() => Promise.resolve(expectedNotebookContent));
notebookManagers[0].contentManager = mockContentManager.object;
let model = new NotebookModel(defaultModelOptions, undefined, logService, undefined, undefined);
await model.requestModelLoad();
let actualChanged: NotebookContentChange;
model.contentChanged((changed) => actualChanged = changed);
// When I change trusted state
model.trustedMode = true;
// Then content changed notification should be sent
should(model.trustedMode).be.true();
should(actualChanged).not.be.undefined();
should(actualChanged.changeType).equal(NotebookChangeType.TrustChanged);
});
function shouldHaveOneCell(model: NotebookModel): void {
should(model.cells).have.length(1);
verifyCellModel(model.cells[0], { cell_type: CellTypes.Code, source: 'insert into t1 values (c1, c2)', metadata: { language: 'python' }, execution_count: 1 });
}
function verifyCellModel(cellModel: ICellModel, expected: nb.ICellContents): void {
should(cellModel.cellType).equal(expected.cell_type);
should(cellModel.source).equal(expected.source);
}
});

View File

@@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as should from 'should';
import { IConnectionProfile } from 'azdata';
import { TestCapabilitiesService } from 'sql/platform/capabilities/test/common/testCapabilitiesService';
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import { formatServerNameWithDatabaseNameForAttachTo, getServerFromFormattedAttachToName, getDatabaseFromFormattedAttachToName } from 'sql/workbench/parts/notebook/node/models/notebookUtils';
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
suite('notebookUtils', function (): void {
let conn: IConnectionProfile = {
connectionName: '',
serverName: '',
databaseName: '',
userName: '',
password: '',
authenticationType: '',
savePassword: true,
groupFullName: '',
groupId: '',
providerName: mssqlProviderName,
saveProfile: true,
id: '',
options: {},
azureTenantId: undefined
};
test('Should format server and database name correctly for attach to', async function (): Promise<void> {
let capabilitiesService = new TestCapabilitiesService();
let connProfile = new ConnectionProfile(capabilitiesService, conn);
connProfile.serverName = 'serverName';
connProfile.databaseName = 'databaseName';
let attachToNameFormatted = formatServerNameWithDatabaseNameForAttachTo(connProfile);
should(attachToNameFormatted).equal('serverName (databaseName)');
});
test('Should format server name correctly for attach to', async function (): Promise<void> {
let capabilitiesService = new TestCapabilitiesService();
let connProfile = new ConnectionProfile(capabilitiesService, conn);
connProfile.serverName = 'serverName';
let attachToNameFormatted = formatServerNameWithDatabaseNameForAttachTo(connProfile);
should(attachToNameFormatted).equal('serverName');
});
test('Should format server name correctly for attach to when database is undefined', async function (): Promise<void> {
let capabilitiesService = new TestCapabilitiesService();
let connProfile = new ConnectionProfile(capabilitiesService, conn);
connProfile.serverName = 'serverName';
connProfile.databaseName = undefined;
let attachToNameFormatted = formatServerNameWithDatabaseNameForAttachTo(connProfile);
should(attachToNameFormatted).equal('serverName');
});
test('Should format server name as empty string when server/database are undefined', async function (): Promise<void> {
let capabilitiesService = new TestCapabilitiesService();
let connProfile = new ConnectionProfile(capabilitiesService, conn);
connProfile.serverName = undefined;
connProfile.databaseName = undefined;
let attachToNameFormatted = formatServerNameWithDatabaseNameForAttachTo(connProfile);
should(attachToNameFormatted).equal('');
});
test('Should extract server name when no database specified', async function (): Promise<void> {
let serverName = getServerFromFormattedAttachToName('serverName');
let databaseName = getDatabaseFromFormattedAttachToName('serverName');
should(serverName).equal('serverName');
should(databaseName).equal('');
});
test('Should extract server and database name', async function (): Promise<void> {
let serverName = getServerFromFormattedAttachToName('serverName (databaseName)');
let databaseName = getDatabaseFromFormattedAttachToName('serverName (databaseName)');
should(serverName).equal('serverName');
should(databaseName).equal('databaseName');
});
test('Should extract server and database name with other parentheses', async function (): Promise<void> {
let serverName = getServerFromFormattedAttachToName('serv()erName (databaseName)');
let databaseName = getDatabaseFromFormattedAttachToName('serv()erName (databaseName)');
should(serverName).equal('serv()erName');
should(databaseName).equal('databaseName');
});
});