[Notebook] Run Parameters Action openNotebook Functionality in Core (#14978)

* NotebookService update

* openNotebook functionality in NbService

* Add tests for RunParametersAction
This commit is contained in:
Vasu Bhog
2021-04-08 14:48:37 -07:00
committed by GitHub
parent 4f67f32262
commit d76a6698a9
18 changed files with 245 additions and 101 deletions

View File

@@ -113,7 +113,10 @@ suite('CellToolbarActions', function (): void {
undefined,
undefined,
new MockContextKeyService(),
instantiationService.get(IProductService)
instantiationService.get(IProductService),
undefined,
undefined,
undefined,
);
instantiationService.stub(INotificationService, new TestNotificationService());
instantiationService.stub(INotebookService, notebookService);

View File

@@ -67,7 +67,10 @@ suite('MarkdownTextTransformer', () => {
undefined,
undefined,
new MockContextKeyService(),
instantiationService.get(IProductService)
instantiationService.get(IProductService),
undefined,
undefined,
undefined,
);
mockNotebookService = TypeMoq.Mock.ofInstance(notebookService);

View File

@@ -13,19 +13,20 @@ import { NotebookEditorStub } from 'sql/workbench/contrib/notebook/test/testComm
import { ICellModel, INotebookModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
import { IStandardKernelWithProvider } from 'sql/workbench/services/notebook/browser/models/notebookUtils';
import { INotebookEditor, INotebookService } from 'sql/workbench/services/notebook/browser/notebookService';
import { CellType } from 'sql/workbench/services/notebook/common/contracts';
import { CellType, CellTypes } from 'sql/workbench/services/notebook/common/contracts';
import * as TypeMoq from 'typemoq';
import { Emitter } from 'vs/base/common/event';
import { TestCommandService } from 'vs/editor/test/browser/editorTestServices';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IConfigurationChangeEvent, IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { URI } from 'vs/base/common/uri';
import { NullAdsTelemetryService } from 'sql/platform/telemetry/common/adsTelemetryService';
import { MockQuickInputService } from 'sql/workbench/contrib/notebook/test/common/quickInputServiceMock';
import { localize } from 'vs/nls';
class TestClientSession extends ClientSessionStub {
private _errorState: boolean = false;
@@ -259,22 +260,91 @@ suite('Notebook Actions', function (): void {
assert.strictEqual(actualCmdId, NewNotebookAction.INTERNAL_NEW_NOTEBOOK_CMD_ID);
});
test.skip('Run with Parameters Action', async function (): Promise<void> {
test('Run with Parameters Action', async function (): Promise<void> {
const testContents: azdata.nb.INotebookContents = {
cells: [{
cell_type: CellTypes.Code,
source: ['x=2.0\n', 'y=5.0'],
metadata: { language: 'python' },
execution_count: 1
}],
metadata: {
kernelspec: {
name: 'python',
language: 'python',
display_name: 'Python 3'
}
},
nbformat: 4,
nbformat_minor: 5
};
let mockNotification = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService);
mockNotification.setup(n => n.notify(TypeMoq.It.isAny()));
let quickInputService = new MockQuickInputService;
let mockNotebookModel = new NotebookModelStub(undefined, undefined, testContents);
let action = new RunParametersAction('TestId', true, testUri, quickInputService, mockNotebookService.object, mockNotification.object);
// Normal use case
const testCells = [<ICellModel>{
isParameter: true,
source: ['x=2.0\n', 'y=5.0']
}];
mockNotebookEditor.setup(x => x.model).returns(() => mockNotebookModel);
mockNotebookEditor.setup(x => x.cells).returns(() => testCells);
assert.doesNotThrow(() => action.run(testUri));
// Run Parameters Action
await action.run(testUri);
let testShowOptions = {
initialContent: JSON.stringify(mockNotebookModel.toJSON()),
preserveFocus: true
};
assert.call(mockNotebookService.object.openNotebook(testUri, testShowOptions), 'Should Open Parameterized Notebook');
});
test('Run with Parameters Action with no parameters in notebook', async function (): Promise<void> {
const testContents: azdata.nb.INotebookContents = {
cells: [{
cell_type: CellTypes.Code,
source: [''],
metadata: { language: 'python' },
execution_count: 1
}],
metadata: {
kernelspec: {
name: 'python',
language: 'python',
display_name: 'Python 3'
}
},
nbformat: 4,
nbformat_minor: 5
};
let expectedMsg: string = localize('noParametersCell', "This notebook cannot run with parameters until a parameter cell is added. [Learn more](https://docs.microsoft.com/sql/azure-data-studio/notebooks/notebooks-parameterization).");
let notification = {
severity: Severity.Info,
message: expectedMsg,
};
let actualMsg: string;
let mockNotification = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService);
mockNotification.setup(n => n.notify(TypeMoq.It.isAny())).returns(notification => {
actualMsg = notification.message;
return undefined;
});
let quickInputService = new MockQuickInputService;
let mockNotebookModel = new NotebookModelStub(undefined, undefined, testContents);
let action = new RunParametersAction('TestId', true, testUri, quickInputService, mockNotebookService.object, mockNotification.object);
mockNotebookEditor.setup(x => x.model).returns(() => mockNotebookModel);
// Run Parameters Action
await action.run(testUri);
assert.ok(actualMsg !== undefined, 'Should have received a notification');
assert.call(mockNotification.object.notify(notification), 'Should notify user there is no parameter cell');
assert.strictEqual(actualMsg, expectedMsg);
});
suite('Kernels dropdown', async () => {

View File

@@ -697,7 +697,10 @@ function setupServices(arg: { workbenchThemeService?: WorkbenchThemeService, ins
instantiationService.get(ILogService),
queryManagementService,
instantiationService.get(IContextKeyService),
instantiationService.get(IProductService)
instantiationService.get(IProductService),
undefined,
undefined,
undefined,
);
instantiationService.stub(INotebookService, notebookService);

View File

@@ -30,6 +30,9 @@ import { ExtensionManagementService } from 'vs/workbench/services/extensionManag
import { TestFileService, TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestExtensionService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
import { IProductService } from 'vs/platform/product/common/productService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
/**
* class to mock azdata.nb.ServerManager object
@@ -109,6 +112,9 @@ suite.skip('NotebookService:', function (): void {
let testNo = 0;
let sandbox: sinon.SinonSandbox;
let productService: IProductService;
let editorService: IEditorService;
let untitledTextEditorService: IUntitledTextEditorService;
let editorGroupsService: IEditorGroupsService;
let installExtensionEmitter: Emitter<InstallExtensionEvent>,
didInstallExtensionEmitter: Emitter<DidInstallExtensionEvent>,
@@ -147,8 +153,13 @@ suite.skip('NotebookService:', function (): void {
instantiationService.stub(IProductService, { quality: 'stable' });
productService = instantiationService.get(IProductService);
editorService = new IEditorService;
untitledTextEditorService = new IUntitledTextEditorService;
editorGroupsService = new IEditorGroupsService;
notebookService = new NotebookService(lifecycleService, storageService, extensionServiceMock.object, extensionManagementService, instantiationService, fileService, logServiceMock.object, queryManagementService, contextService, productService);
notebookService = new NotebookService(lifecycleService, storageService, extensionServiceMock.object, extensionManagementService,
instantiationService, fileService, logServiceMock.object, queryManagementService, contextService, productService,
editorService, untitledTextEditorService, editorGroupsService);
sandbox = sinon.sandbox.create();
});
@@ -446,7 +457,7 @@ suite.skip('NotebookService:', function (): void {
};
errorHandler.setUnexpectedErrorHandler(onUnexpectedErrorVerifier);
// The following call throws an exception internally with queryManagementService parameter being undefined.
new NotebookService(lifecycleService, storageService, extensionService, extensionManagementService, instantiationService, fileService, logService, /* queryManagementService */ undefined, contextService, productService);
new NotebookService(lifecycleService, storageService, extensionService, extensionManagementService, instantiationService, fileService, logService, /* queryManagementService */ undefined, contextService, productService, editorService, untitledTextEditorService, editorGroupsService);
await unexpectedErrorPromise;
assert.strictEqual(unexpectedErrorCalled, true, `onUnexpectedError must be have been raised when queryManagementService is undefined when calling NotebookService constructor`);
});

View File

@@ -117,7 +117,10 @@ suite('Notebook Editor Model', function (): void {
undefined,
undefined,
new MockContextKeyService(),
testinstantiationService.get(IProductService)
testinstantiationService.get(IProductService),
undefined,
undefined,
undefined,
);
let mockNotebookService = TypeMoq.Mock.ofInstance(notebookService);

View File

@@ -14,12 +14,14 @@ import { IModelDecorationsChangeAccessor } from 'vs/editor/common/model';
import { NotebookFindMatch } from 'sql/workbench/contrib/notebook/browser/find/notebookFindDecorations';
import { RenderMimeRegistry } from 'sql/workbench/services/notebook/browser/outputs/registry';
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
import { URI } from 'vs/base/common/uri';
import { URI, UriComponents } from 'vs/base/common/uri';
import { QueryTextEditor } from 'sql/workbench/browser/modelComponents/queryTextEditor';
import { IContextViewProvider, IDelegate } from 'vs/base/browser/ui/contextview/contextview';
import { IEditorPane } from 'vs/workbench/common/editor';
import { INotebookShowOptions } from 'sql/workbench/api/common/sqlExtHost.protocol';
export class NotebookModelStub implements INotebookModel {
constructor(private _languageInfo?: nb.ILanguageInfo, private _cells?: ICellModel[]) {
constructor(private _languageInfo?: nb.ILanguageInfo, private _cells?: ICellModel[], private _testContents?: nb.INotebookContents) {
}
trustedMode: boolean;
language: string;
@@ -134,7 +136,7 @@ export class NotebookModelStub implements INotebookModel {
throw new Error('method not implemented.');
}
toJSON(): nb.INotebookContents {
throw new Error('Method not implemented.');
return this._testContents;
}
serializationStateChanged(changeType: NotebookChangeType, cell?: ICellModel): void {
throw new Error('Method not implemented.');
@@ -292,6 +294,9 @@ export class NotebookServiceStub implements INotebookService {
navigateTo(notebookUri: URI, sectionId: string): void {
throw new Error('Method not implemented.');
}
openNotebook(resource: UriComponents, options: INotebookShowOptions): Promise<IEditorPane> {
throw new Error('Method not implemented.');
}
get onCodeCellExecutionStart(): vsEvent.Event<void> {
throw new Error('Method not implemented.');
}