Support Notebook integration testing by adding APIs & fixing others (#3848)

- Added `runCell` API. Updated runCell button to listen to events on the model so it'll reflect run cell when called from other sources
- Plumbed through kernelspec info to the extension side so when changed, it's updated
- Fixed bug in ConnectionProfile where it didn't copy from options but instead overrode with empty wrapper functions

Here's the rough test code (it's in the sql-vnext extension and will be out in a separate PR)
```ts

    it('Should connect to local notebook server with result 2', async function() {
        this.timeout(60000);
        let pythonNotebook = Object.assign({}, expectedNotebookContent, { metadata: { kernelspec: { name: "python3", display_name: "Python 3" }}});
        let uri = writeNotebookToFile(pythonNotebook);
        await ensureJupyterInstalled();

        let notebook = await sqlops.nb.showNotebookDocument(uri);
        should(notebook.document.cells).have.length(1);
        let ran = await notebook.runCell(notebook.document.cells[0]);
        should(ran).be.true('Notebook runCell failed');
        let cellOutputs = notebook.document.cells[0].contents.outputs;
        should(cellOutputs).have.length(1);
        let result = (<sqlops.nb.IExecuteResult>cellOutputs[0]).data['text/plain'];
        should(result).equal('2');

        try {
            // TODO support closing the editor. Right now this prompts and there's no override for this. Need to fix in core
            // Close the editor using the recommended vscode API
            //await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
        }
        catch (e) {}
    });

    it('Should connect to remote spark server with result 2', async function() {
        this.timeout(240000);
        let uri = writeNotebookToFile(expectedNotebookContent);
        await ensureJupyterInstalled();

        // Given a connection to a server exists
        let connectionId = await connectToSparkIntegrationServer();

        // When I open a Spark notebook and run the cell
        let notebook = await sqlops.nb.showNotebookDocument(uri, {
            connectionId: connectionId
        });
        should(notebook.document.cells).have.length(1);
        let ran = await notebook.runCell(notebook.document.cells[0]);
        should(ran).be.true('Notebook runCell failed');

        // Then I expect to get the output result of 1+1, executed remotely against the Spark endpoint
        let cellOutputs = notebook.document.cells[0].contents.outputs;
        should(cellOutputs).have.length(4);
        let sparkResult = (<sqlops.nb.IStreamResult>cellOutputs[3]).text;
        should(sparkResult).equal('2');

        try {
            // TODO support closing the editor. Right now this prompts and there's no override for this. Need to fix in core
            // Close the editor using the recommended vscode API
            //await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
        }
        catch (e) {}
    });
});
```
This commit is contained in:
Kevin Cunnane
2019-01-30 14:24:14 -08:00
committed by GitHub
parent 3ddc5e7846
commit d1fef24723
21 changed files with 321 additions and 111 deletions

View File

@@ -14,6 +14,8 @@ import * as Constants from 'sql/platform/connection/common/constants';
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
import { ConnectionProviderProperties } from 'sql/workbench/parts/connection/common/connectionProviderExtension';
type SettableProperty = 'serverName' | 'authenticationType' | 'databaseName' | 'password' | 'connectionName' | 'userName';
export class ProviderConnectionInfo extends Disposable implements sqlops.ConnectionInfo {
options: { [name: string]: any } = {};
@@ -39,16 +41,30 @@ export class ProviderConnectionInfo extends Disposable implements sqlops.Connect
this.options[option.name] = value;
});
}
this.serverName = model.serverName;
this.authenticationType = model.authenticationType;
this.databaseName = model.databaseName;
this.password = model.password;
this.userName = model.userName;
this.connectionName = model.connectionName;
this.updateSpecialValueType('serverName', model);
this.updateSpecialValueType('authenticationType', model);
this.updateSpecialValueType('databaseName', model);
this.updateSpecialValueType('password', model);
this.updateSpecialValueType('userName', model);
this.updateSpecialValueType('connectionName', model);
}
}
}
/**
* Updates one of the special value types (serverName, authenticationType, etc.) if this doesn't already
* have a value in the options map.
*
* This handles the case where someone hasn't passed in a valid property bag, but doesn't cause errors when
*/
private updateSpecialValueType(typeName: SettableProperty, model: sqlops.IConnectionProfile): void {
if (!this[typeName]) {
this[typeName] = model[typeName];
}
}
public get providerName(): string {
return this._providerName;
}