From 3fc2ad5bc96f7cffe9b7aa4556c50fc3984f9d7b Mon Sep 17 00:00:00 2001 From: udeeshagautam <46980425+udeeshagautam@users.noreply.github.com> Date: Tue, 21 May 2019 11:17:52 -0700 Subject: [PATCH] Schema Compare tests addition (#5136) * initial tests for schema compare * Adding schema compare integration test * Adding code to fix some build issues * DB compare test * Adding some CR comments * db creation and deletion as per CR comments --- build/gulpfile.hygiene.js | 3 +- .../src/objectExplorer.test.ts | 44 +++- .../src/schemaCompare.test.ts | 176 +++++++++++++ .../src/testData/Database1.dacpac | Bin 0 -> 2603 bytes .../src/testData/Database2.dacpac | Bin 0 -> 3066 bytes extensions/integration-tests/src/utils.ts | 34 +++ extensions/schema-compare/package.json | 8 +- .../schema-compare/src/schemaCompareResult.ts | 6 + extensions/schema-compare/src/test/index.ts | 30 +++ .../src/test/schemaCompare.test.ts | 77 ++++++ .../src/test/testSchemaCompareService.ts | 45 ++++ extensions/schema-compare/yarn.lock | 233 ++++++++++++++++++ 12 files changed, 652 insertions(+), 4 deletions(-) create mode 100644 extensions/integration-tests/src/schemaCompare.test.ts create mode 100644 extensions/integration-tests/src/testData/Database1.dacpac create mode 100644 extensions/integration-tests/src/testData/Database2.dacpac create mode 100644 extensions/schema-compare/src/test/index.ts create mode 100644 extensions/schema-compare/src/test/schemaCompare.test.ts create mode 100644 extensions/schema-compare/src/test/testSchemaCompareService.ts diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index c2c1893ee2..a2bb01f79d 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -155,7 +155,8 @@ const copyrightFilter = [ '!extensions/mssql/src/prompts/**', '!extensions/notebook/resources/jupyter_config/**', '!**/*.gif', - '!**/*.xlf' + '!**/*.xlf', + '!**/*.dacpac' ]; const eslintFilter = [ diff --git a/extensions/integration-tests/src/objectExplorer.test.ts b/extensions/integration-tests/src/objectExplorer.test.ts index fb6697b023..5811f6a672 100644 --- a/extensions/integration-tests/src/objectExplorer.test.ts +++ b/extensions/integration-tests/src/objectExplorer.test.ts @@ -9,7 +9,7 @@ import 'mocha'; import * as azdata from 'azdata'; import { context } from './testContext'; import { getBdcServer, TestServerProfile, getAzureServer, getStandaloneServer } from './testConfig'; -import { connectToServer } from './utils'; +import { connectToServer, createDB, deleteDB } from './utils'; import assert = require('assert'); if (context.RunTest) { @@ -69,6 +69,12 @@ if (context.RunTest) { await verifyContextMenu(server, expectedActions); }); + + test('Stand alone database context menu test', async function () { + let server = await getStandaloneServer(); + let expectedActions = ['Manage', 'New Query', 'Backup', 'Restore', 'Refresh', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard', 'Generate Scripts...', 'Properties']; + await VerifyDBContextMenu(server, 3000, expectedActions); + }); }); } @@ -83,7 +89,7 @@ async function verifyContextMenu(server: TestServerProfile, expectedActions: str let node = nodes[index]; let actions = await azdata.objectexplorer.getNodeActions(node.connectionId, node.nodePath); - const expectedString = expectedActions.join(','); + let expectedString = expectedActions.join(','); const actualString = actions.join(','); assert(expectedActions.length === actions.length && expectedString === actualString, `Expected actions: "${expectedString}", Actual actions: "${actualString}"`); } @@ -103,3 +109,37 @@ async function VerifyOeNode(server: TestServerProfile, timeout: number, expected assert(expectedNodeLabel.toLocaleString() === actualNodeLabel.toLocaleString(), `Expected node label: "${expectedNodeLabel}", Actual: "${actualNodeLabel}"`); } +async function VerifyDBContextMenu(server: TestServerProfile, timeoutinMS: number, expectedActions: string[]) { + + await connectToServer(server, timeoutinMS); + + let nodes = await azdata.objectexplorer.getActiveConnectionNodes(); + assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`); + + let index = nodes.findIndex(node => node.nodePath.includes(server.serverName)); + assert(index !== -1, `Failed to find server: "${server.serverName}" in OE tree`); + + let ownerUri = await azdata.connection.getUriForConnection(nodes[index].connectionId); + let dbName: string = 'ads_test_VerifyDBContextMenu_' + new Date().getTime().toString(); + try { + await createDB(dbName, ownerUri); + + let serverNode = nodes[index]; + let children = await serverNode.getChildren(); + + assert(children[0].label.toLocaleLowerCase === 'Databases'.toLocaleLowerCase, `Expected Databases node. Actual ${children[0].label}`); + let databasesFolder = children[0]; + + let databases = await databasesFolder.getChildren(); + assert(databases.length > 2, `No database present, can not test further`); // System Databses folder and at least one database + + let actions = await azdata.objectexplorer.getNodeActions(databases[1].connectionId, databases[1].nodePath); + + const expectedString = expectedActions.join(','); + const actualString = actions.join(','); + assert(expectedActions.length === actions.length && expectedString === actualString, `Expected actions: "${expectedString}", Actual actions: "${actualString}"`); + } + finally { + await deleteDB(dbName, ownerUri); + } +} \ No newline at end of file diff --git a/extensions/integration-tests/src/schemaCompare.test.ts b/extensions/integration-tests/src/schemaCompare.test.ts new file mode 100644 index 0000000000..c83f121dc0 --- /dev/null +++ b/extensions/integration-tests/src/schemaCompare.test.ts @@ -0,0 +1,176 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import 'mocha'; +import * as azdata from 'azdata'; +import * as utils from './utils'; +const path = require('path'); +import { context } from './testContext'; +import assert = require('assert'); +import { getStandaloneServer } from './testConfig'; + +let schemaCompareService: azdata.SchemaCompareServicesProvider; +let dacpac1: string = path.join(__dirname, 'testData/Database1.dacpac'); +let dacpac2: string = path.join(__dirname, 'testData/Database2.dacpac'); +let dummyDBName: string = 'ads_schemaCompareDB'; // This is used as fill in name and not created anywhere +const SERVER_CONNECTION_TIMEOUT: number = 3000; + +if (context.RunTest) { + suite('Schema compare integration test suite', () => { + suiteSetup(async function () { + let attempts: number = 20; + while (attempts > 0) { + schemaCompareService = await azdata.dataprotocol.getProvider('MSSQL', azdata.DataProviderType.SchemaCompareServicesProvider); + if (schemaCompareService) { + break; + } + attempts--; + await utils.sleep(1000); // To ensure the providers are registered. + } + console.log(`Start schema compare tests`); + }); + test('Schema compare dacpac to dacpac comparison', async function () { + assert(schemaCompareService, 'Schema Compare Service Provider is not available'); + + let source: azdata.SchemaCompareEndpointInfo = { + endpointType: azdata.SchemaCompareEndpointType.Dacpac, + packageFilePath: dacpac1, + serverName: '', + databaseName: '', + ownerUri: '', + }; + let target: azdata.SchemaCompareEndpointInfo = { + endpointType: azdata.SchemaCompareEndpointType.Dacpac, + packageFilePath: dacpac2, + serverName: '', + databaseName: '', + ownerUri: '', + }; + + let schemaCompareResult = await schemaCompareService.schemaCompare(source, target, azdata.TaskExecutionMode.execute, null); + assertSchemaCompareResult(schemaCompareResult); + }); + + test('Schema compare database to database comparison and script generation', async function () { + + let server = await getStandaloneServer(); + await utils.connectToServer(server, SERVER_CONNECTION_TIMEOUT); + + let nodes = await azdata.objectexplorer.getActiveConnectionNodes(); + assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`); + + let index = nodes.findIndex(node => node.nodePath.includes(server.serverName)); + assert(index !== -1, `Failed to find server: "${server.serverName}" in OE tree`); + + let ownerUri = await azdata.connection.getUriForConnection(nodes[index].connectionId); + let now = new Date(); + + let sourceDB: string = 'ads_schemaCompare_sourceDB_' + now.getTime().toString(); + let targetDB: string = 'ads_schemaCompare_targetDB_' + now.getTime().toString(); + + try { + let dacfxService = await azdata.dataprotocol.getProvider('MSSQL', azdata.DataProviderType.DacFxServicesProvider); + assert(dacfxService, 'DacFx Service Provider is not available'); + let result1 = await dacfxService.deployDacpac(dacpac1, sourceDB, true, ownerUri, azdata.TaskExecutionMode.execute); + let result2 = await dacfxService.deployDacpac(dacpac2, targetDB, true, ownerUri, azdata.TaskExecutionMode.execute); + + assert(result1.success === true, 'Deploy source database should succeed'); + assert(result2.success === true, 'Deploy target database should succeed'); + + assert(schemaCompareService, 'Schema Compare Service Provider is not available'); + + let source: azdata.SchemaCompareEndpointInfo = { + endpointType: azdata.SchemaCompareEndpointType.Database, + packageFilePath: '', + serverName: server.serverName, + databaseName: sourceDB, + ownerUri: ownerUri, + }; + let target: azdata.SchemaCompareEndpointInfo = { + endpointType: azdata.SchemaCompareEndpointType.Database, + packageFilePath: '', + serverName: server.serverName, + databaseName: targetDB, + ownerUri: ownerUri, + }; + + let schemaCompareResult = await schemaCompareService.schemaCompare(source, target, azdata.TaskExecutionMode.execute, null); + assertSchemaCompareResult(schemaCompareResult); + + let status = await schemaCompareService.schemaCompareGenerateScript(schemaCompareResult.operationId, server.serverName, dummyDBName, azdata.TaskExecutionMode.script); + + // TODO : add wait for tasks to complete + // script generation might take too long and the 'success' status does not mean that script is created. + await assertScriptGenerationResult(status); + } + finally { + await utils.deleteDB(sourceDB, ownerUri); + await utils.deleteDB(targetDB, ownerUri); + } + }); + + test('Schema compare dacpac to database comparison and script generation', async function () { + let server = await getStandaloneServer(); + await utils.connectToServer(server, SERVER_CONNECTION_TIMEOUT); + + let nodes = await azdata.objectexplorer.getActiveConnectionNodes(); + assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`); + + let index = nodes.findIndex(node => node.nodePath.includes(server.serverName)); + assert(index !== -1, `Failed to find server: "${server.serverName}" in OE tree`); + + let ownerUri = await azdata.connection.getUriForConnection(nodes[index].connectionId); + let now = new Date(); + let targetDB: string = 'ads_schemaCompare_targetDB_' + now.getTime().toString(); + + try { + let dacfxService = await azdata.dataprotocol.getProvider('MSSQL', azdata.DataProviderType.DacFxServicesProvider); + assert(dacfxService, 'DacFx Service Provider is not available'); + let result = await dacfxService.deployDacpac(path.join(__dirname, 'testData/Database2.dacpac'), targetDB, true, ownerUri, azdata.TaskExecutionMode.execute); + + assert(result.success === true, 'Deploy database 2 (target) should succeed'); + + let source: azdata.SchemaCompareEndpointInfo = { + endpointType: azdata.SchemaCompareEndpointType.Dacpac, + packageFilePath: dacpac1, + serverName: '', + databaseName: '', + ownerUri: ownerUri, + }; + let target: azdata.SchemaCompareEndpointInfo = { + endpointType: azdata.SchemaCompareEndpointType.Database, + packageFilePath: '', + serverName: server.serverName, + databaseName: targetDB, + ownerUri: ownerUri, + }; + + assert(schemaCompareService, 'Schema Compare Service Provider is not available'); + let schemaCompareResult = await schemaCompareService.schemaCompare(source, target, azdata.TaskExecutionMode.execute, null); + assertSchemaCompareResult(schemaCompareResult); + + let status = await schemaCompareService.schemaCompareGenerateScript(schemaCompareResult.operationId, server.serverName, dummyDBName, azdata.TaskExecutionMode.script); + await assertScriptGenerationResult(status); + } + finally { + await utils.deleteDB(targetDB, ownerUri); + } + }); + }); +} + +export function assertSchemaCompareResult(schemaCompareResult: azdata.SchemaCompareResult): void { + assert(schemaCompareResult.areEqual === false, `Expected: the schemas are not to be equal Actual: Equal`); + assert(schemaCompareResult.errorMessage === null, `Expected: there should be no error. Actual Error message: "${schemaCompareResult.errorMessage}"`); + assert(schemaCompareResult.success === true, `Expected: success in schema compare, Actual: Failure`); + assert(schemaCompareResult.differences.length === 4, `Expected: 4 differences. Actual differences: "${schemaCompareResult.differences.length}"`); +} + +export async function assertScriptGenerationResult(resultstatus: azdata.ResultStatus): Promise { + // TODO add more validation + assert(resultstatus.success === true, `Expected: success true Actual: "${resultstatus.success}" Error Message: "${resultstatus.errorMessage}`); +} diff --git a/extensions/integration-tests/src/testData/Database1.dacpac b/extensions/integration-tests/src/testData/Database1.dacpac new file mode 100644 index 0000000000000000000000000000000000000000..7718b44940bc7fd69bfac910c9bf39595cbb9d68 GIT binary patch literal 2603 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 F{sr4|Ml1jT literal 0 HcmV?d00001 diff --git a/extensions/integration-tests/src/utils.ts b/extensions/integration-tests/src/utils.ts index 190f4918e6..43ed9ba9d0 100644 --- a/extensions/integration-tests/src/utils.ts +++ b/extensions/integration-tests/src/utils.ts @@ -36,3 +36,37 @@ export async function connectToServer(server: TestServerProfile, timeout: number export async function ensureConnectionViewOpened() { await vscode.commands.executeCommand('dataExplorer.servers.focus'); } + +export async function sleep(ms: number): Promise<{}> { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +export async function createDB(dbName: string, ownerUri: string): Promise { + let queryProvider = azdata.dataprotocol.getProvider('MSSQL', azdata.DataProviderType.QueryProvider); + let query = `BEGIN TRY + CREATE DATABASE ${dbName} + SELECT 1 AS NoError + END TRY + BEGIN CATCH + SELECT ERROR_MESSAGE() AS ErrorMessage; + END CATCH`; + + let dbcreatedResult = await queryProvider.runQueryAndReturn(ownerUri, query); + assert(dbcreatedResult.columnInfo[0].columnName !== 'ErrorMessage', 'DB creation threw error'); +} + +export async function deleteDB(dbName: string, ownerUri: string): Promise { + let queryProvider = azdata.dataprotocol.getProvider('MSSQL', azdata.DataProviderType.QueryProvider); + let query = `BEGIN TRY + ALTER DATABASE ${dbName} + SET OFFLINE + WITH ROLLBACK IMMEDIATE + DROP DATABASE ${dbName} + SELECT 1 AS NoError + END TRY + BEGIN CATCH + SELECT ERROR_MESSAGE() AS ErrorMessage; + END CATCH`; + + await queryProvider.runQueryAndReturn(ownerUri, query); +} \ No newline at end of file diff --git a/extensions/schema-compare/package.json b/extensions/schema-compare/package.json index 62057a4b34..4a51518e10 100644 --- a/extensions/schema-compare/package.json +++ b/extensions/schema-compare/package.json @@ -48,5 +48,11 @@ "vscode-extension-telemetry": "0.0.18", "vscode-nls": "^3.2.1" }, - "devDependencies": {} + "devDependencies": { + "@types/mocha": "^5.2.5", + "@types/node": "^8.0.24", + "mocha": "^5.2.0", + "should": "^13.2.1", + "typemoq": "^2.1.0" + } } diff --git a/extensions/schema-compare/src/schemaCompareResult.ts b/extensions/schema-compare/src/schemaCompareResult.ts index 9a41713af8..a13e09e89b 100644 --- a/extensions/schema-compare/src/schemaCompareResult.ts +++ b/extensions/schema-compare/src/schemaCompareResult.ts @@ -160,12 +160,18 @@ export class SchemaCompareResult { await view.initializeModel(this.flexModel); }); + this.editor.openEditor(); } public start(): void { this.editor.openEditor(); } + // only for test + public getComparisionResult(): azdata.SchemaCompareResult { + return this.comparisonResult; + } + private async execute(): Promise { if (this.schemaCompareOptionDialog && this.schemaCompareOptionDialog.deploymentOptions) { // take updates if any diff --git a/extensions/schema-compare/src/test/index.ts b/extensions/schema-compare/src/test/index.ts new file mode 100644 index 0000000000..1605846c44 --- /dev/null +++ b/extensions/schema-compare/src/test/index.ts @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const path = require('path'); +const testRunner = require('vscode/lib/testrunner'); + +const suite = 'Schema Compare Tests'; + +const options: any = { + ui: 'bdd', + useColors: true, + timeout: 60000 +}; + +if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { + options.reporter = 'mocha-multi-reporters'; + options.reporterOptions = { + reporterEnabled: 'spec, mocha-junit-reporter', + mochaJunitReporterReporterOptions: { + testsuitesTitle: `${suite} ${process.platform}`, + mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) + } + }; +} + +testRunner.configure(options); + +export = testRunner; diff --git a/extensions/schema-compare/src/test/schemaCompare.test.ts b/extensions/schema-compare/src/test/schemaCompare.test.ts new file mode 100644 index 0000000000..75bd9eb73d --- /dev/null +++ b/extensions/schema-compare/src/test/schemaCompare.test.ts @@ -0,0 +1,77 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as should from 'should'; +import * as TypeMoq from 'typemoq'; +import * as vscode from 'vscode'; +import * as azdata from 'azdata'; +import 'mocha'; +import { SchemaCompareDialog } from './../dialogs/schemaCompareDialog'; +import { SchemaCompareResult } from './../schemaCompareResult'; +import { SchemaCompareTestService } from './testSchemaCompareService'; + +// Mock test data +const mockConnectionProfile: azdata.IConnectionProfile = { + connectionName: 'My Connection', + serverName: 'My Server', + databaseName: 'My Server', + userName: 'My User', + password: 'My Pwd', + authenticationType: 'SqlLogin', + savePassword: false, + groupFullName: 'My groupName', + groupId: 'My GroupId', + providerName: 'My Server', + saveProfile: true, + id: 'My Id', + options: null +}; + +const mocksource: string = 'source.dacpac'; +const mocktarget: string = 'target.dacpac'; + +const mockSourceEndpoint: azdata.SchemaCompareEndpointInfo = { + endpointType: azdata.SchemaCompareEndpointType.Dacpac, + serverName: '', + databaseName: '', + ownerUri: '', + packageFilePath: mocksource +}; + +const mockTargetEndpoint: azdata.SchemaCompareEndpointInfo = { + endpointType: azdata.SchemaCompareEndpointType.Dacpac, + serverName: '', + databaseName: '', + ownerUri: '', + packageFilePath: mocktarget +}; + +describe('SchemaCompareDialog.openDialog', function(): void { + it('Should be correct when created.', function(): void { + let dialog = new SchemaCompareDialog(); + dialog.openDialog(mockConnectionProfile); + + should(dialog.dialog.title).equal('Schema Compare'); + should(dialog.dialog.okButton.label).equal('Compare'); + should(dialog.dialog.okButton.enabled).equal(true); + }); +}); + +describe('SchemaCompareResult.start', function(): void { + it('Should be correct when created.', async function(): Promise { + let sc = new SchemaCompareTestService(); + azdata.dataprotocol.registerSchemaCompareServicesProvider(sc); + + let result = new SchemaCompareResult(mocksource, mocktarget, mockSourceEndpoint, mockTargetEndpoint); + let promise = new Promise(resolve => setTimeout(resolve, 3000)); // to ensure comparision result view is initialized + await promise; + await result.start(); + + should(result.getComparisionResult().success).equal(true); + should(result.getComparisionResult().operationId).equal(sc.testOperationId); + }); +}); diff --git a/extensions/schema-compare/src/test/testSchemaCompareService.ts b/extensions/schema-compare/src/test/testSchemaCompareService.ts new file mode 100644 index 0000000000..16534aa27a --- /dev/null +++ b/extensions/schema-compare/src/test/testSchemaCompareService.ts @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- + * 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'; + +export class SchemaCompareTestService implements azdata.SchemaCompareServicesProvider { + + testOperationId: string = 'Test Operation Id'; + + schemaComparePublishChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable { + throw new Error('Method not implemented.'); + } + + schemaCompareGetDefaultOptions(): Thenable { + throw new Error('Method not implemented.'); + } + + schemaCompareIncludeExcludeNode(operationId: string, diffEntry: azdata.DiffEntry, IncludeRequest: boolean, taskExecutionMode: azdata.TaskExecutionMode): Thenable { + throw new Error('Method not implemented.'); + } + + schemaCompare(sourceEndpointInfo: azdata.SchemaCompareEndpointInfo, targetEndpointInfo: azdata.SchemaCompareEndpointInfo, taskExecutionMode: azdata.TaskExecutionMode): Thenable { + let result: azdata.SchemaCompareResult = { + operationId: this.testOperationId, + areEqual: true, + differences: [], + success: true, + errorMessage: '' + }; + + return Promise.resolve(result); + } + + schemaCompareGenerateScript(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable { + return undefined; + } + + handle?: number; + readonly providerId: string = 'MSSQL'; + + registerOnUpdated(handler: () => any): void { + } +} diff --git a/extensions/schema-compare/yarn.lock b/extensions/schema-compare/yarn.lock index 6ac1974f1b..6ad678fa4c 100644 --- a/extensions/schema-compare/yarn.lock +++ b/extensions/schema-compare/yarn.lock @@ -2,6 +2,16 @@ # yarn lockfile v1 +"@types/mocha@^5.2.5": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.6.tgz#b8622d50557dd155e9f2f634b7d68fd38de5e94b" + integrity sha512-1axi39YdtBI7z957vdqXI4Ac25e7YihYQtJa+Clnxg1zTJEaIRbndt71O3sP4GAMgiAm0pY26/b9BrY4MR/PMw== + +"@types/node@^8.0.24": + version "8.10.46" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.46.tgz#12161db48a775e8c69c1cfff2be545610381056f" + integrity sha512-PfnRbk836fFs9T9QnZh0G1k9oC6YXCqIK3LX6vU/6oiXtEBSFCiJFj6UnLZtqIIHTsgMn8Dojq3yhmpwY7QWcw== + applicationinsights@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.1.tgz#53446b830fe8d5d619eee2a278b31d3d25030927" @@ -11,6 +21,46 @@ applicationinsights@1.0.1: diagnostic-channel-publishers "0.2.1" zone.js "0.7.6" +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +debug@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + diagnostic-channel-publishers@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3" @@ -23,11 +73,189 @@ diagnostic-channel@0.2.0: dependencies: semver "^5.3.0" +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +escape-string-regexp@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +he@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +lodash@^4.17.4: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +minimatch@3.0.4, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mocha@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" + integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== + dependencies: + browser-stdout "1.3.1" + commander "2.15.1" + debug "3.1.0" + diff "3.5.0" + escape-string-regexp "1.0.5" + glob "7.1.2" + growl "1.10.5" + he "1.1.1" + minimatch "3.0.4" + mkdirp "0.5.1" + supports-color "5.4.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +postinstall-build@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7" + integrity sha512-vPvPe8TKgp4FLgY3+DfxCE5PIfoXBK2lyLfNCxsRbDsV6vS4oU5RG/IWxrblMn6heagbnMED3MemUQllQ2bQUg== + semver@^5.3.0: version "5.7.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== +should-equal@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/should-equal/-/should-equal-2.0.0.tgz#6072cf83047360867e68e98b09d71143d04ee0c3" + integrity sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA== + dependencies: + should-type "^1.4.0" + +should-format@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/should-format/-/should-format-3.0.3.tgz#9bfc8f74fa39205c53d38c34d717303e277124f1" + integrity sha1-m/yPdPo5IFxT04w01xcwPidxJPE= + dependencies: + should-type "^1.3.0" + should-type-adaptors "^1.0.1" + +should-type-adaptors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz#401e7f33b5533033944d5cd8bf2b65027792e27a" + integrity sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA== + dependencies: + should-type "^1.3.0" + should-util "^1.0.0" + +should-type@^1.3.0, should-type@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/should-type/-/should-type-1.4.0.tgz#0756d8ce846dfd09843a6947719dfa0d4cff5cf3" + integrity sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM= + +should-util@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/should-util/-/should-util-1.0.0.tgz#c98cda374aa6b190df8ba87c9889c2b4db620063" + integrity sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM= + +should@^13.2.1: + version "13.2.3" + resolved "https://registry.yarnpkg.com/should/-/should-13.2.3.tgz#96d8e5acf3e97b49d89b51feaa5ae8d07ef58f10" + integrity sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ== + dependencies: + should-equal "^2.0.0" + should-format "^3.0.3" + should-type "^1.4.0" + should-type-adaptors "^1.0.1" + should-util "^1.0.0" + +supports-color@5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== + dependencies: + has-flag "^3.0.0" + +typemoq@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/typemoq/-/typemoq-2.1.0.tgz#4452ce360d92cf2a1a180f0c29de2803f87af1e8" + integrity sha512-DtRNLb7x8yCTv/KHlwes+NI+aGb4Vl1iPC63Hhtcvk1DpxSAZzKWQv0RQFY0jX2Uqj0SDBNl8Na4e6MV6TNDgw== + dependencies: + circular-json "^0.3.1" + lodash "^4.17.4" + postinstall-build "^5.0.1" + vscode-extension-telemetry@0.0.18: version "0.0.18" resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.18.tgz#602ba20d8c71453aa34533a291e7638f6e5c0327" @@ -40,6 +268,11 @@ vscode-nls@^3.2.1: resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.5.tgz#25520c1955108036dec607c85e00a522f247f1a4" integrity sha512-ITtoh3V4AkWXMmp3TB97vsMaHRgHhsSFPsUdzlueSL+dRZbSNTZeOmdQv60kjCV306ghPxhDeoNUEm3+EZMuyw== +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + zone.js@0.7.6: version "0.7.6" resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009"