Machine Learning Model Registry - Iteration1 (#9105)

* Machine learning services extension - model registration wizard
This commit is contained in:
Leila Lali
2020-02-26 09:19:48 -08:00
committed by GitHub
parent 067fcc8dfb
commit ff207859d6
46 changed files with 3990 additions and 210 deletions

View File

@@ -7,7 +7,7 @@ import * as should from 'should';
import 'mocha';
import * as TypeMoq from 'typemoq';
import { createContext } from './utils';
import { LanguageController } from '../../../externalLanguage/languageController';
import { LanguageController } from '../../../views/externalLanguages/languageController';
import * as mssql from '../../../../../mssql/src/mssql';
describe('External Languages Controller', () => {

View File

@@ -10,6 +10,7 @@ import { ApiWrapper } from '../../../common/apiWrapper';
import { LanguageViewBase } from '../../../views/externalLanguages/languageViewBase';
import * as mssql from '../../../../../mssql/src/mssql';
import { LanguageService } from '../../../externalLanguage/languageService';
import { createViewContext } from '../utils';
export interface TestContext {
apiWrapper: TypeMoq.IMock<ApiWrapper>;
@@ -30,195 +31,11 @@ export class ParentDialog extends LanguageViewBase {
}
export function createContext(): TestContext {
let onClick: vscode.EventEmitter<any> = new vscode.EventEmitter<any>();
let apiWrapper = TypeMoq.Mock.ofType(ApiWrapper);
let componentBase: azdata.Component = {
id: '',
updateProperties: () => Promise.resolve(),
updateProperty: () => Promise.resolve(),
updateCssStyles: undefined!,
onValidityChanged: undefined!,
valid: true,
validate: undefined!,
focus: undefined!
};
let button: azdata.ButtonComponent = Object.assign({}, componentBase, {
onDidClick: onClick.event
});
let radioButton: azdata.RadioButtonComponent = Object.assign({}, componentBase, {
onDidClick: onClick.event
});
let container = {
clearItems: () => { },
addItems: () => { },
addItem: () => { },
removeItem: () => true,
insertItem: () => { },
items: [],
setLayout: () => { }
};
let form: azdata.FormContainer = Object.assign({}, componentBase, container, {
});
let flex: azdata.FlexContainer = Object.assign({}, componentBase, container, {
});
let buttonBuilder: azdata.ComponentBuilder<azdata.ButtonComponent> = {
component: () => button,
withProperties: () => buttonBuilder,
withValidation: () => buttonBuilder
};
let radioButtonBuilder: azdata.ComponentBuilder<azdata.ButtonComponent> = {
component: () => radioButton,
withProperties: () => radioButtonBuilder,
withValidation: () => radioButtonBuilder
};
let inputBox: () => azdata.InputBoxComponent = () => Object.assign({}, componentBase, {
onTextChanged: undefined!,
onEnterKeyPressed: undefined!,
value: ''
});
let declarativeTable: () => azdata.DeclarativeTableComponent = () => Object.assign({}, componentBase, {
onDataChanged: undefined!,
data: [],
columns: []
});
let loadingComponent: () => azdata.LoadingComponent = () => Object.assign({}, componentBase, {
loading: false,
component: undefined!
});
let declarativeTableBuilder: azdata.ComponentBuilder<azdata.DeclarativeTableComponent> = {
component: () => declarativeTable(),
withProperties: () => declarativeTableBuilder,
withValidation: () => declarativeTableBuilder
};
let loadingBuilder: azdata.LoadingComponentBuilder = {
component: () => loadingComponent(),
withProperties: () => loadingBuilder,
withValidation: () => loadingBuilder,
withItem: () => loadingBuilder
};
let formBuilder: azdata.FormBuilder = Object.assign({}, {
component: () => form,
addFormItem: () => { },
insertFormItem: () => { },
removeFormItem: () => true,
addFormItems: () => { },
withFormItems: () => formBuilder,
withProperties: () => formBuilder,
withValidation: () => formBuilder,
withItems: () => formBuilder,
withLayout: () => formBuilder
});
let flexBuilder: azdata.FlexBuilder = Object.assign({}, {
component: () => flex,
withProperties: () => flexBuilder,
withValidation: () => flexBuilder,
withItems: () => flexBuilder,
withLayout: () => flexBuilder
});
let inputBoxBuilder: azdata.ComponentBuilder<azdata.InputBoxComponent> = {
component: () => {
let r = inputBox();
return r;
},
withProperties: () => inputBoxBuilder,
withValidation: () => inputBoxBuilder
};
let view: azdata.ModelView = {
onClosed: undefined!,
connection: undefined!,
serverInfo: undefined!,
valid: true,
onValidityChanged: undefined!,
validate: undefined!,
initializeModel: () => { return Promise.resolve(); },
modelBuilder: {
radioCardGroup: undefined!,
navContainer: undefined!,
divContainer: undefined!,
flexContainer: () => flexBuilder,
splitViewContainer: undefined!,
dom: undefined!,
card: undefined!,
inputBox: () => inputBoxBuilder,
checkBox: undefined!,
radioButton: () => radioButtonBuilder,
webView: undefined!,
editor: undefined!,
diffeditor: undefined!,
text: () => inputBoxBuilder,
image: undefined!,
button: () => buttonBuilder,
dropDown: undefined!,
tree: undefined!,
listBox: undefined!,
table: undefined!,
declarativeTable: () => declarativeTableBuilder,
dashboardWidget: undefined!,
dashboardWebview: undefined!,
formContainer: () => formBuilder,
groupContainer: undefined!,
toolbarContainer: undefined!,
loadingComponent: () => loadingBuilder,
fileBrowserTree: undefined!,
hyperlink: undefined!,
separator: undefined!
}
};
let tab: azdata.window.DialogTab = {
title: '',
content: '',
registerContent: async (handler) => {
try {
await handler(view);
} catch (err) {
console.log(err);
}
},
onValidityChanged: undefined!,
valid: true,
modelView: undefined!
};
let dialogButton: azdata.window.Button = {
label: '',
enabled: true,
hidden: false,
onClick: onClick.event,
};
let dialogMessage: azdata.window.DialogMessage = {
text: '',
};
let dialog: azdata.window.Dialog = {
title: '',
isWide: false,
content: [],
okButton: dialogButton,
cancelButton: dialogButton,
customButtons: [],
message: dialogMessage,
registerCloseValidator: () => { },
registerOperation: () => { },
onValidityChanged: new vscode.EventEmitter<boolean>().event,
registerContent: () => { },
modelView: undefined!,
valid: true
};
apiWrapper.setup(x => x.createTab(TypeMoq.It.isAny())).returns(() => tab);
apiWrapper.setup(x => x.createModelViewDialog(TypeMoq.It.isAny())).returns(() => dialog);
apiWrapper.setup(x => x.openDialog(TypeMoq.It.isAny())).returns(() => { });
let viewTestContext = createViewContext();
let connection = new azdata.connection.ConnectionProfile();
apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); });
apiWrapper.setup(x => x.getUriForConnection(TypeMoq.It.isAny())).returns(() => { return Promise.resolve('connectionUrl'); });
viewTestContext.apiWrapper.setup(x => x.getCurrentConnection()).returns(() => { return Promise.resolve(connection); });
viewTestContext.apiWrapper.setup(x => x.getUriForConnection(TypeMoq.It.isAny())).returns(() => { return Promise.resolve('connectionUrl'); });
let languageExtensionService: mssql.ILanguageExtensionService = {
listLanguages: () => { return Promise.resolve([]); },
@@ -226,12 +43,11 @@ export function createContext(): TestContext {
updateLanguage: () => { return Promise.resolve(); }
};
return {
apiWrapper: apiWrapper,
view: view,
apiWrapper: viewTestContext.apiWrapper,
view: viewTestContext.view,
languageExtensionService: languageExtensionService,
onClick: onClick,
onClick: viewTestContext.onClick,
dialogModel: TypeMoq.Mock.ofType(LanguageService)
};
}

View File

@@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as should from 'should';
import 'mocha';
import { createContext, ParentDialog } from './utils';
import { AzureModelsComponent } from '../../../views/models/azureModelsComponent';
import { ListAccountsEventName, ListSubscriptionsEventName, ListGroupsEventName, ListWorkspacesEventName, ListAzureModelsEventName } from '../../../views/models/modelViewBase';
import { azureResource } from '../../../typings/azure-resource';
import { Workspace } from '@azure/arm-machinelearningservices/esm/models';
import { ViewBase } from '../../../views/viewBase';
import { WorkspaceModel } from '../../../modelManagement/interfaces';
describe('Azure Models Component', () => {
it('Should create view components successfully ', async function (): Promise<void> {
let testContext = createContext();
let parent = new ParentDialog(testContext.apiWrapper.object);
let view = new AzureModelsComponent(testContext.apiWrapper.object, parent);
view.registerComponent(testContext.view.modelBuilder);
should.notEqual(view.component, undefined);
});
it('Should load data successfully ', async function (): Promise<void> {
let testContext = createContext();
let parent = new ParentDialog(testContext.apiWrapper.object);
let view = new AzureModelsComponent(testContext.apiWrapper.object, parent);
view.registerComponent(testContext.view.modelBuilder);
let accounts: azdata.Account[] = [
{
key: {
accountId: '1',
providerId: ''
},
displayInfo: {
displayName: 'account',
userId: '',
accountType: '',
contextualDisplayName: ''
},
isStale: false,
properties: []
}
];
let subscriptions: azureResource.AzureResourceSubscription[] = [
{
name: 'subscription',
id: '2'
}
];
let groups: azureResource.AzureResourceResourceGroup[] = [
{
name: 'group',
id: '3'
}
];
let workspaces: Workspace[] = [
{
name: 'workspace',
id: '4'
}
];
let models: WorkspaceModel[] = [
{
id: '5',
name: 'model'
}
];
parent.on(ListAccountsEventName, () => {
parent.sendCallbackRequest(ViewBase.getCallbackEventName(ListAccountsEventName), { data: accounts });
});
parent.on(ListSubscriptionsEventName, () => {
parent.sendCallbackRequest(ViewBase.getCallbackEventName(ListSubscriptionsEventName), { data: subscriptions });
});
parent.on(ListGroupsEventName, () => {
parent.sendCallbackRequest(ViewBase.getCallbackEventName(ListGroupsEventName), { data: groups });
});
parent.on(ListWorkspacesEventName, () => {
parent.sendCallbackRequest(ViewBase.getCallbackEventName(ListWorkspacesEventName), { data: workspaces });
});
parent.on(ListAzureModelsEventName, () => {
parent.sendCallbackRequest(ViewBase.getCallbackEventName(ListAzureModelsEventName), { data: models });
});
await view.refresh();
testContext.onClick.fire();
should.notEqual(view.data, undefined);
should.deepEqual(view.data?.account, accounts[0]);
should.deepEqual(view.data?.subscription, subscriptions[0]);
should.deepEqual(view.data?.group, groups[0]);
should.deepEqual(view.data?.workspace, workspaces[0]);
should.deepEqual(view.data?.model, models[0]);
});
});

View File

@@ -0,0 +1,103 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as should from 'should';
import 'mocha';
import { createContext } from './utils';
import { ListModelsEventName, ListAccountsEventName, ListSubscriptionsEventName, ListGroupsEventName, ListWorkspacesEventName, ListAzureModelsEventName } from '../../../views/models/modelViewBase';
import { RegisteredModel } from '../../../modelManagement/interfaces';
import { azureResource } from '../../../typings/azure-resource';
import { Workspace } from '@azure/arm-machinelearningservices/esm/models';
import { ViewBase } from '../../../views/viewBase';
import { WorkspaceModel } from '../../../modelManagement/interfaces';
import { RegisterModelWizard } from '../../../views/models/registerModelWizard';
describe('Register Model Wizard', () => {
it('Should create view components successfully ', async function (): Promise<void> {
let testContext = createContext();
let view = new RegisterModelWizard(testContext.apiWrapper.object, '');
view.open();
should.notEqual(view.wizardView, undefined);
should.notEqual(view.localModelsComponent, undefined);
should.notEqual(view.azureModelsComponent, undefined);
should.notEqual(view.modelResources, undefined);
});
it('Should load data successfully ', async function (): Promise<void> {
let testContext = createContext();
let view = new RegisterModelWizard(testContext.apiWrapper.object, '');
view.open();
let accounts: azdata.Account[] = [
{
key: {
accountId: '1',
providerId: ''
},
displayInfo: {
displayName: 'account',
userId: '',
accountType: '',
contextualDisplayName: ''
},
isStale: false,
properties: []
}
];
let subscriptions: azureResource.AzureResourceSubscription[] = [
{
name: 'subscription',
id: '2'
}
];
let groups: azureResource.AzureResourceResourceGroup[] = [
{
name: 'group',
id: '3'
}
];
let workspaces: Workspace[] = [
{
name: 'workspace',
id: '4'
}
];
let models: WorkspaceModel[] = [
{
id: '5',
name: 'model'
}
];
let localModels: RegisteredModel[] = [
{
id: 1,
name: 'model'
}
];
view.on(ListModelsEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListModelsEventName), { data: localModels });
});
view.on(ListAccountsEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListAccountsEventName), { data: accounts });
});
view.on(ListSubscriptionsEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListSubscriptionsEventName), { data: subscriptions });
});
view.on(ListGroupsEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListGroupsEventName), { data: groups });
});
view.on(ListWorkspacesEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListWorkspacesEventName), { data: workspaces });
});
view.on(ListAzureModelsEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListAzureModelsEventName), { data: models });
});
await view.refresh();
});
});

View File

@@ -0,0 +1,41 @@
/*---------------------------------------------------------------------------------------------
* 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 'mocha';
import { createContext } from './utils';
import { RegisteredModelsDialog } from '../../../views/models/registeredModelsDialog';
import { ListModelsEventName } from '../../../views/models/modelViewBase';
import { RegisteredModel } from '../../../modelManagement/interfaces';
import { ViewBase } from '../../../views/viewBase';
describe('Registered Models Dialog', () => {
it('Should create view components successfully ', async function (): Promise<void> {
let testContext = createContext();
let view = new RegisteredModelsDialog(testContext.apiWrapper.object, '');
view.open();
should.notEqual(view.dialogView, undefined);
should.notEqual(view.currentLanguagesTab, undefined);
});
it('Should load data successfully ', async function (): Promise<void> {
let testContext = createContext();
let view = new RegisteredModelsDialog(testContext.apiWrapper.object, '');
view.open();
let models: RegisteredModel[] = [
{
id: 1,
name: 'model'
}
];
view.on(ListModelsEventName, () => {
view.sendCallbackRequest(ViewBase.getCallbackEventName(ListModelsEventName), { data: models });
});
await view.refresh();
});
});

View File

@@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as TypeMoq from 'typemoq';
import { ApiWrapper } from '../../../common/apiWrapper';
import * as mssql from '../../../../../mssql/src/mssql';
import { createViewContext } from '../utils';
import { ModelViewBase } from '../../../views/models/modelViewBase';
export interface TestContext {
apiWrapper: TypeMoq.IMock<ApiWrapper>;
view: azdata.ModelView;
languageExtensionService: mssql.ILanguageExtensionService;
onClick: vscode.EventEmitter<any>;
}
export class ParentDialog extends ModelViewBase {
public refresh(): Promise<void> {
return Promise.resolve();
}
public reset(): Promise<void> {
return Promise.resolve();
}
constructor(
apiWrapper: ApiWrapper) {
super(apiWrapper, '');
}
}
export function createContext(): TestContext {
let viewTestContext = createViewContext();
let languageExtensionService: mssql.ILanguageExtensionService = {
listLanguages: () => { return Promise.resolve([]); },
deleteLanguage: () => { return Promise.resolve(); },
updateLanguage: () => { return Promise.resolve(); }
};
return {
apiWrapper: viewTestContext.apiWrapper,
view: viewTestContext.view,
languageExtensionService: languageExtensionService,
onClick: viewTestContext.onClick
};
}

View File

@@ -0,0 +1,261 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as TypeMoq from 'typemoq';
import { ApiWrapper } from '../../common/apiWrapper';
export interface ViewTestContext {
apiWrapper: TypeMoq.IMock<ApiWrapper>;
view: azdata.ModelView;
onClick: vscode.EventEmitter<any>;
}
export function createViewContext(): ViewTestContext {
let onClick: vscode.EventEmitter<any> = new vscode.EventEmitter<any>();
let apiWrapper = TypeMoq.Mock.ofType(ApiWrapper);
let componentBase: azdata.Component = {
id: '',
updateProperties: () => Promise.resolve(),
updateProperty: () => Promise.resolve(),
updateCssStyles: undefined!,
onValidityChanged: undefined!,
valid: true,
validate: undefined!,
focus: undefined!
};
let button: azdata.ButtonComponent = Object.assign({}, componentBase, {
onDidClick: onClick.event
});
let radioButton: azdata.RadioButtonComponent = Object.assign({}, componentBase, {
onDidClick: onClick.event
});
let container = {
clearItems: () => { },
addItems: () => { },
addItem: () => { },
removeItem: () => true,
insertItem: () => { },
items: [],
setLayout: () => { }
};
let form: azdata.FormContainer = Object.assign({}, componentBase, container, {
});
let flex: azdata.FlexContainer = Object.assign({}, componentBase, container, {
});
let buttonBuilder: azdata.ComponentBuilder<azdata.ButtonComponent> = {
component: () => button,
withProperties: () => buttonBuilder,
withValidation: () => buttonBuilder
};
let radioButtonBuilder: azdata.ComponentBuilder<azdata.ButtonComponent> = {
component: () => radioButton,
withProperties: () => radioButtonBuilder,
withValidation: () => radioButtonBuilder
};
let inputBox: () => azdata.InputBoxComponent = () => Object.assign({}, componentBase, {
onTextChanged: undefined!,
onEnterKeyPressed: undefined!,
value: ''
});
let dropdown: () => azdata.DropDownComponent = () => Object.assign({}, componentBase, {
onValueChanged: onClick.event,
value: {
name: '',
displayName: ''
},
values: []
});
let declarativeTable: () => azdata.DeclarativeTableComponent = () => Object.assign({}, componentBase, {
onDataChanged: undefined!,
data: [],
columns: []
});
let loadingComponent: () => azdata.LoadingComponent = () => Object.assign({}, componentBase, {
loading: false,
component: undefined!
});
let declarativeTableBuilder: azdata.ComponentBuilder<azdata.DeclarativeTableComponent> = {
component: () => declarativeTable(),
withProperties: () => declarativeTableBuilder,
withValidation: () => declarativeTableBuilder
};
let loadingBuilder: azdata.LoadingComponentBuilder = {
component: () => loadingComponent(),
withProperties: () => loadingBuilder,
withValidation: () => loadingBuilder,
withItem: () => loadingBuilder
};
let formBuilder: azdata.FormBuilder = Object.assign({}, {
component: () => form,
addFormItem: () => { },
insertFormItem: () => { },
removeFormItem: () => true,
addFormItems: () => { },
withFormItems: () => formBuilder,
withProperties: () => formBuilder,
withValidation: () => formBuilder,
withItems: () => formBuilder,
withLayout: () => formBuilder
});
let flexBuilder: azdata.FlexBuilder = Object.assign({}, {
component: () => flex,
withProperties: () => flexBuilder,
withValidation: () => flexBuilder,
withItems: () => flexBuilder,
withLayout: () => flexBuilder
});
let inputBoxBuilder: azdata.ComponentBuilder<azdata.InputBoxComponent> = {
component: () => {
let r = inputBox();
return r;
},
withProperties: () => inputBoxBuilder,
withValidation: () => inputBoxBuilder
};
let dropdownBuilder: azdata.ComponentBuilder<azdata.DropDownComponent> = {
component: () => {
let r = dropdown();
return r;
},
withProperties: () => dropdownBuilder,
withValidation: () => dropdownBuilder
};
let view: azdata.ModelView = {
onClosed: undefined!,
connection: undefined!,
serverInfo: undefined!,
valid: true,
onValidityChanged: undefined!,
validate: undefined!,
initializeModel: () => { return Promise.resolve(); },
modelBuilder: {
radioCardGroup: undefined!,
navContainer: undefined!,
divContainer: undefined!,
flexContainer: () => flexBuilder,
splitViewContainer: undefined!,
dom: undefined!,
card: undefined!,
inputBox: () => inputBoxBuilder,
checkBox: undefined!,
radioButton: () => radioButtonBuilder,
webView: undefined!,
editor: undefined!,
diffeditor: undefined!,
text: () => inputBoxBuilder,
image: undefined!,
button: () => buttonBuilder,
dropDown: () => dropdownBuilder,
tree: undefined!,
listBox: undefined!,
table: undefined!,
declarativeTable: () => declarativeTableBuilder,
dashboardWidget: undefined!,
dashboardWebview: undefined!,
formContainer: () => formBuilder,
groupContainer: undefined!,
toolbarContainer: undefined!,
loadingComponent: () => loadingBuilder,
fileBrowserTree: undefined!,
hyperlink: undefined!,
separator: undefined!
}
};
let tab: azdata.window.DialogTab = {
title: '',
content: '',
registerContent: async (handler) => {
try {
await handler(view);
} catch (err) {
console.log(err);
}
},
onValidityChanged: undefined!,
valid: true,
modelView: undefined!
};
let dialogButton: azdata.window.Button = {
label: '',
enabled: true,
hidden: false,
onClick: onClick.event,
};
let dialogMessage: azdata.window.DialogMessage = {
text: '',
};
let dialog: azdata.window.Dialog = {
title: '',
isWide: false,
content: [],
okButton: dialogButton,
cancelButton: dialogButton,
customButtons: [],
message: dialogMessage,
registerCloseValidator: () => { },
registerOperation: () => { },
onValidityChanged: new vscode.EventEmitter<boolean>().event,
registerContent: () => { },
modelView: undefined!,
valid: true
};
let wizard: azdata.window.Wizard = {
title: '',
pages: [],
currentPage: 0,
doneButton: dialogButton,
cancelButton: dialogButton,
generateScriptButton: dialogButton,
nextButton: dialogButton,
backButton: dialogButton,
customButtons: [],
displayPageTitles: true,
onPageChanged: onClick.event,
addPage: () => { return Promise.resolve(); },
removePage: () => { return Promise.resolve(); },
setCurrentPage: () => { return Promise.resolve(); },
open: () => { return Promise.resolve(); },
close: () => { return Promise.resolve(); },
registerNavigationValidator: () => { },
message: dialogMessage,
registerOperation: () => { }
};
let wizardPage: azdata.window.WizardPage = {
title: '',
content: '',
customButtons: [],
enabled: true,
description: '',
onValidityChanged: onClick.event,
registerContent: () => { },
modelView: undefined!,
valid: true
};
apiWrapper.setup(x => x.createTab(TypeMoq.It.isAny())).returns(() => tab);
apiWrapper.setup(x => x.createWizard(TypeMoq.It.isAny())).returns(() => wizard);
apiWrapper.setup(x => x.createWizardPage(TypeMoq.It.isAny())).returns(() => wizardPage);
apiWrapper.setup(x => x.createModelViewDialog(TypeMoq.It.isAny())).returns(() => dialog);
apiWrapper.setup(x => x.openDialog(TypeMoq.It.isAny())).returns(() => { });
return {
apiWrapper: apiWrapper,
view: view,
onClick: onClick,
};
}