diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 388d6c5fec..38b81a6b08 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -54,6 +54,21 @@ jobs: workingDirectory: 'sample' displayName: Build Sample +##### TSLint ##### + - job: TSLint + displayName: 'TSLint' + pool: + vmImage: 'vs2017-win2016' + steps: + - task: NodeTool@0 + inputs: + versionSpec: '12.x' + displayName: 'Install Node.js' + - bash: | + npm install -g tslint + tslint -c tslint.json 'dotnetcore-acquisition-library/src/**/*.ts' 'dotnetcore-acquisition-extension/src/**/*.ts' + displayName: Run Lint + ##### Package and Publish ##### - job: Publish displayName: 'Package and Publish' diff --git a/dotnetcore-acquisition-extension/package-lock.json b/dotnetcore-acquisition-extension/package-lock.json index 9ffed0a98f..9b80c9d438 100644 --- a/dotnetcore-acquisition-extension/package-lock.json +++ b/dotnetcore-acquisition-extension/package-lock.json @@ -24,6 +24,12 @@ "js-tokens": "^4.0.0" } }, + "@types/chai": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.7.tgz", + "integrity": "sha512-luq8meHGYwvky0O7u0eQZdA7B4Wd9owUCqvbw2m3XCrCU8mplYOujMBbvyS547AxJkC+pGnd0Cm15eNxEUNU8g==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", diff --git a/dotnetcore-acquisition-extension/package.json b/dotnetcore-acquisition-extension/package.json index b5fe5477c1..b28b7ec9ce 100644 --- a/dotnetcore-acquisition-extension/package.json +++ b/dotnetcore-acquisition-extension/package.json @@ -35,6 +35,7 @@ "dotnetcore-acquisition-library": "file:../dotnetcore-acquisition-library" }, "devDependencies": { + "@types/chai": "^4.2.7", "@types/mocha": "5.2.6", "@types/node": "12.0.0", "@types/rimraf": "2.0.2", diff --git a/dotnetcore-acquisition-extension/src/test/functional/DotnetCoreAcquisitionExtension.test.ts b/dotnetcore-acquisition-extension/src/test/functional/DotnetCoreAcquisitionExtension.test.ts index b7b16d8109..97f2c5739c 100644 --- a/dotnetcore-acquisition-extension/src/test/functional/DotnetCoreAcquisitionExtension.test.ts +++ b/dotnetcore-acquisition-extension/src/test/functional/DotnetCoreAcquisitionExtension.test.ts @@ -2,32 +2,32 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ - -import * as extension from '../../extension'; +import * as chai from 'chai'; +import { MockExtensionContext } from 'dotnetcore-acquisition-library'; import * as fs from 'fs'; import * as path from 'path'; import * as rimraf from 'rimraf'; import * as vscode from 'vscode'; -import { MockExtensionContext } from 'dotnetcore-acquisition-library' -var assert = require('chai').assert; +import * as extension from '../../extension'; +const assert = chai.assert; -suite('DotnetCoreAcquisitionExtension End to End', function () { +suite('DotnetCoreAcquisitionExtension End to End', function() { const storagePath = path.join(__dirname, 'tmp'); const mockState = new MockExtensionContext(); const extensionPath = path.join(__dirname, '/../../..'); let context: vscode.ExtensionContext; - this.beforeAll(async function() { + this.beforeAll(async () => { context = { subscriptions: [], globalStoragePath: storagePath, globalState: mockState, - extensionPath: extensionPath + extensionPath, } as any; extension.activate(context); }); - this.afterEach(async function() { + this.afterEach(async () => { // Tear down tmp storage for fresh run await vscode.commands.executeCommand('dotnet.uninstallAll'); rimraf.sync(storagePath); @@ -40,7 +40,7 @@ suite('DotnetCoreAcquisitionExtension End to End', function () { }); test('Install Command', async () => { - const version = '2.2' + const version = '2.2'; const dotnetPath = await vscode.commands.executeCommand('dotnet.acquire', version); assert.exists(dotnetPath); assert.isTrue(fs.existsSync(dotnetPath!)); @@ -48,7 +48,7 @@ suite('DotnetCoreAcquisitionExtension End to End', function () { }).timeout(20000); test('Uninstall Command', async () => { - const version = '2.1' + const version = '2.1'; const dotnetPath = await vscode.commands.executeCommand('dotnet.acquire', version); assert.exists(dotnetPath); assert.isTrue(fs.existsSync(dotnetPath!)); @@ -60,7 +60,7 @@ suite('DotnetCoreAcquisitionExtension End to End', function () { test('Install and Uninstall Multiple Versions', async () => { const versions = ['1.1', '2.2', '1.0']; let dotnetPaths: string[] = []; - for (var version of versions) { + for (const version of versions) { const dotnetPath = await vscode.commands.executeCommand('dotnet.acquire', version); assert.exists(dotnetPath); assert.include(dotnetPath, version); @@ -69,8 +69,8 @@ suite('DotnetCoreAcquisitionExtension End to End', function () { } } // All versions are still there after all installs are completed - for (let dotnetPath of dotnetPaths) { + for (const dotnetPath of dotnetPaths) { assert.isTrue(fs.existsSync(dotnetPath)); } }).timeout(40000); -}); \ No newline at end of file +}); diff --git a/dotnetcore-acquisition-extension/src/test/functional/index.ts b/dotnetcore-acquisition-extension/src/test/functional/index.ts index 926800e77b..b8b02f87a8 100644 --- a/dotnetcore-acquisition-extension/src/test/functional/index.ts +++ b/dotnetcore-acquisition-extension/src/test/functional/index.ts @@ -2,15 +2,14 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ - -import * as path from 'path'; -import * as Mocha from 'mocha'; import * as glob from 'glob'; +import * as Mocha from 'mocha'; +import * as path from 'path'; export function run(): Promise { // Create the mocha test const mocha = new Mocha({ - ui: 'tdd' + ui: 'tdd', }); mocha.useColors(true); @@ -39,4 +38,4 @@ export function run(): Promise { } }); }); -} \ No newline at end of file +} diff --git a/dotnetcore-acquisition-extension/src/test/functional/runTest.ts b/dotnetcore-acquisition-extension/src/test/functional/runTest.ts index 72bc4be670..ddddfa0c59 100644 --- a/dotnetcore-acquisition-extension/src/test/functional/runTest.ts +++ b/dotnetcore-acquisition-extension/src/test/functional/runTest.ts @@ -25,4 +25,4 @@ async function main() { } } -main(); \ No newline at end of file +main(); diff --git a/dotnetcore-acquisition-library/package-lock.json b/dotnetcore-acquisition-library/package-lock.json index 30698ea732..d8ed70c55e 100644 --- a/dotnetcore-acquisition-library/package-lock.json +++ b/dotnetcore-acquisition-library/package-lock.json @@ -36,6 +36,15 @@ "integrity": "sha512-YvbLiIc0DbbhiANrfVObdkLEHJksQZVq0Uvfg550SRAKVYaEJy+V70j65BVe2WNp6E3HtKsUczeijHFCjba3og==", "dev": true }, + "@types/chai-as-promised": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-PO2gcfR3Oxa+u0QvECLe1xKXOqYTzCmWf0FhLhjREoW3fPAVamjihL7v1MOVLJLsnAMdLcjkfrs01yvDMwVK4Q==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", diff --git a/dotnetcore-acquisition-library/package.json b/dotnetcore-acquisition-library/package.json index 4eaaeca6c1..77d9c9abbf 100644 --- a/dotnetcore-acquisition-library/package.json +++ b/dotnetcore-acquisition-library/package.json @@ -22,6 +22,7 @@ }, "devDependencies": { "@types/chai": "^4.2.4", + "@types/chai-as-promised": "^7.1.2", "@types/mocha": "5.2.6", "@types/node": "12.0.0", "@types/request-promise-native": "^1.0.17", diff --git a/dotnetcore-acquisition-library/src/AcquisitionInvoker.ts b/dotnetcore-acquisition-library/src/AcquisitionInvoker.ts index c8811c1c4b..7c746c7d87 100644 --- a/dotnetcore-acquisition-library/src/AcquisitionInvoker.ts +++ b/dotnetcore-acquisition-library/src/AcquisitionInvoker.ts @@ -18,23 +18,10 @@ import { IDotnetInstallationContext } from './IDotnetInstallationContext'; export class AcquisitionInvoker extends IAcquisitionInvoker { private scriptPath: string; - + constructor(scriptPath: string, eventStream: IEventStream) { super(eventStream); - this.scriptPath = path.join(scriptPath, 'node_modules', 'dotnetcore-acquisition-library', 'install scripts', 'dotnet-install' + this.getScriptEnding()); - } - - private getInstallCommand(version: string, dotnetInstallDir: string): string { - const args = [ - '-InstallDir', `'${dotnetInstallDir}'`, // Use single quotes instead of double quotes (see https://github.com/dotnet/cli/issues/11521) - '-Runtime', 'dotnet', - '-Version', version, - ]; - - return `"${this.scriptPath}" ${args.join(' ')}`; - } - private getScriptEnding(): string { - return os.platform() === 'win32' ? '.cmd' : '.sh'; + this.scriptPath = path.join(scriptPath, 'node_modules', 'dotnetcore-acquisition-library', 'install scripts', `dotnet-install${this.getScriptEnding()}`); } public installDotnet(installContext: IDotnetInstallationContext): Promise { @@ -59,4 +46,18 @@ export class AcquisitionInvoker extends IAcquisitionInvoker { } }); } + + private getInstallCommand(version: string, dotnetInstallDir: string): string { + const args = [ + '-InstallDir', `'${dotnetInstallDir}'`, // Use single quotes instead of double quotes (see https://github.com/dotnet/cli/issues/11521) + '-Runtime', 'dotnet', + '-Version', version, + ]; + + return `"${this.scriptPath}" ${args.join(' ')}`; + } + + private getScriptEnding(): string { + return os.platform() === 'win32' ? '.cmd' : '.sh'; + } } diff --git a/dotnetcore-acquisition-library/src/DotnetCoreAcquisitionWorker.ts b/dotnetcore-acquisition-library/src/DotnetCoreAcquisitionWorker.ts index e163f7634c..09035d2d6d 100644 --- a/dotnetcore-acquisition-library/src/DotnetCoreAcquisitionWorker.ts +++ b/dotnetcore-acquisition-library/src/DotnetCoreAcquisitionWorker.ts @@ -9,7 +9,11 @@ import * as path from 'path'; import rimraf = require('rimraf'); import { Memento } from 'vscode'; import { IEventStream } from './EventStream'; -import { DotnetAcquisitionStarted, DotnetUninstallAllStarted, DotnetUninstallAllCompleted } from './EventStreamEvents'; +import { + DotnetAcquisitionStarted, + DotnetUninstallAllCompleted, + DotnetUninstallAllStarted, +} from './EventStreamEvents'; import { IAcquisitionInvoker } from './IAcquisitionInvoker'; import { IDotnetInstallationContext } from './IDotnetInstallationContext'; import { IVersionResolver } from './IVersionResolver'; @@ -22,10 +26,10 @@ export class DotnetCoreAcquisitionWorker { private acquisitionPromises: { [version: string]: Promise | undefined }; constructor(private readonly storagePath: string, - private readonly extensionState: Memento, - private readonly eventStream: IEventStream, - private readonly acquisitionInvoker: IAcquisitionInvoker, - private readonly versionResolver: IVersionResolver) { + private readonly extensionState: Memento, + private readonly eventStream: IEventStream, + private readonly acquisitionInvoker: IAcquisitionInvoker, + private readonly versionResolver: IVersionResolver) { this.installDir = path.join(this.storagePath, '.dotnet'); const dotnetExtension = os.platform() === 'win32' ? '.exe' : ''; this.dotnetExecutable = `dotnet${dotnetExtension}`; @@ -40,12 +44,12 @@ export class DotnetCoreAcquisitionWorker { rimraf.sync(this.installDir); await this.extensionState.update(this.installingVersionsKey, []); - + this.eventStream.post(new DotnetUninstallAllCompleted()); } public async acquire(version: string): Promise { - version = await this.versionResolver.getFullVersion(version); + version = await this.versionResolver.getFullVersion(version); const existingAcquisitionPromise = this.acquisitionPromises[version]; if (existingAcquisitionPromise) { @@ -57,7 +61,7 @@ export class DotnetCoreAcquisitionWorker { const acquisitionPromise = this.acquireCore(version).catch((error: Error) => { delete this.acquisitionPromises[version]; - throw new Error('Dotnet Core Acquisition Failed: ' + error.message); + throw new Error(`Dotnet Core Acquisition Failed: ${error.message}`); }); this.acquisitionPromises[version] = acquisitionPromise; @@ -88,8 +92,8 @@ export class DotnetCoreAcquisitionWorker { const installContext = { installDir: dotnetInstallDir, - version: version, - dotnetPath: dotnetPath + version, + dotnetPath, } as IDotnetInstallationContext; this.eventStream.post(new DotnetAcquisitionStarted(version)); await this.acquisitionInvoker.installDotnet(installContext); @@ -105,7 +109,7 @@ export class DotnetCoreAcquisitionWorker { return dotnetPath; } - + private async uninstall(version: string) { delete this.acquisitionPromises[version]; @@ -121,7 +125,7 @@ export class DotnetCoreAcquisitionWorker { } private getDotnetInstallDir(version: string) { - const dotnetInstallDir = path.join(this.installDir, version) + const dotnetInstallDir = path.join(this.installDir, version); return dotnetInstallDir; } } diff --git a/dotnetcore-acquisition-library/src/DotnetCoreDependencyInstaller.ts b/dotnetcore-acquisition-library/src/DotnetCoreDependencyInstaller.ts index 332d8293a1..4a3b942d3e 100644 --- a/dotnetcore-acquisition-library/src/DotnetCoreDependencyInstaller.ts +++ b/dotnetcore-acquisition-library/src/DotnetCoreDependencyInstaller.ts @@ -2,16 +2,15 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ - -import * as vscode from 'vscode'; import * as cp from 'child_process'; import * as fs from 'fs'; -import { which } from 'shelljs'; import * as path from 'path'; +import { which } from 'shelljs'; +import * as vscode from 'vscode'; const moreInfoUrl = 'https://aka.ms/dotnet-linux-prereqs'; -export class DotnetCoreDependencyInstaller{ +export class DotnetCoreDependencyInstaller { private readonly platform = process.platform; public signalIndicatesMissingLinuxDependencies(signal: string): boolean { @@ -34,35 +33,35 @@ export class DotnetCoreDependencyInstaller{ return false; } - public async installLinuxDependencies(additionalLibs: any = {}, skipDotNetCore: boolean = false): Promise { + public async installLinuxDependencies(additionalLibs: any = {}, skipDotNetCore = false): Promise { const scriptRoot = path.join(__dirname, '..', 'scripts'); const shellCommand = this.getShellCommand(); // Determine the distro const result = cp.spawnSync(shellCommand, [path.join(scriptRoot, 'determine-linux-distro.sh')]); - if(result.status !== 0) { - console.log('Failed to determine distro. Exit code: ' + result.status); + if (result.status !== 0) { + console.log(`Failed to determine distro. Exit code: ${result.status}`); return result.status; } const distro = result.stdout.toString().trim(); - console.log('Found distro ' + distro); + console.log(`Found distro ${distro}`); const additionalLibsKey = distro.toLowerCase(); // Always use lower case for this // Run the installer for the distro passing in any additional libs for it - return await this.executeCommandInTerminal( - 'Linux dependency installer (.NET Core)', - shellCommand, + return this.executeCommandInTerminal( + 'Linux dependency installer (.NET Core)', + shellCommand, [path.join(scriptRoot, 'install-linux-prereqs.sh'), - distro, + distro, (additionalLibs[additionalLibsKey] ? `"${additionalLibs[additionalLibsKey]}"` : ''), - skipDotNetCore.toString(), + skipDotNetCore.toString(), moreInfoUrl]); } - public async promptLinuxDependencyInstall(message: string, additionalLibs: any = {}, skipDotNetCore: boolean = false): Promise { + public async promptLinuxDependencyInstall(message: string, additionalLibs: any = {}, skipDotNetCore = false): Promise { while (true) { const response = await vscode.window.showErrorMessage( - message + ' You may be missing key Linux libraries. Install them now?', + `${message} You may be missing key Linux libraries. Install them now?`, 'More Info', 'Install', 'Cancel'); @@ -74,12 +73,12 @@ export class DotnetCoreDependencyInstaller{ const exitCode = await this.installLinuxDependencies(additionalLibs, skipDotNetCore); if (exitCode !== 0) { - const msg = (exitCode === 4 ? + const msg = (exitCode === 4 ? 'Your Linux distribution is not supported by the automated installer' : 'The dependency installer failed.'); // Terminal will pause for input on error so this is just an info message with a more info button const failResponse = await vscode.window.showErrorMessage( - msg + ' Try installing dependencies manually.', + `${msg} Try installing dependencies manually.`, 'More Info'); if (failResponse === 'More Info') { vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(moreInfoUrl)); @@ -102,20 +101,10 @@ export class DotnetCoreDependencyInstaller{ } } - private getShellCommand(): string { - if (this.platform === 'win32') { - return which('cmd').toString(); - } - // Test for existence of bash which won't exist on the base Alpine Linux container, use sh instead there - const shellCommand = which('bash'); - // shellCommand will be null if bash is not found - return shellCommand ? shellCommand.toString() : which('sh').toString(); - } - - public async executeCommandInTerminal(name: string, command: string, args: string[] = [], promptAfterRun: boolean = false): Promise { - return await new Promise((resolve, reject) => { - const fullCommand = `"${command}" ${(args.length > 0 ? ' "' + args.join('" "') + '"' : '')}`; - const exitCodeFile = path.join(__dirname, '..', 'terminal-exit-code-' + Math.floor(Math.random() * 1000000)); + public async executeCommandInTerminal(name: string, command: string, args: string[] = [], promptAfterRun = false): Promise { + return new Promise((resolve, reject) => { + const fullCommand = `"${command}" ${(args.length > 0 ? ` "${args.join('" "')}"` : '')}`; + const exitCodeFile = path.join(__dirname, '..', `terminal-exit-code-${Math.floor(Math.random() * 1000000)}`); const commandList = new Array(); if (this.platform === 'win32') { // Note that "|| echo %ERRORLEVEL% >"" in this command sequence is a hack to get the exit code @@ -123,7 +112,7 @@ export class DotnetCoreDependencyInstaller{ commandList.push( 'cls', `echo 0 > "${exitCodeFile}"`, - `${fullCommand} || echo %ERRORLEVEL% > "${exitCodeFile}"` + `${fullCommand} || echo %ERRORLEVEL% > "${exitCodeFile}"`, ); if (promptAfterRun) { commandList.push('pause'); @@ -134,13 +123,13 @@ export class DotnetCoreDependencyInstaller{ commandList.push( 'clear', `echo 0 > "${exitCodeFile}"`, - `${fullCommand} || echo $? > "${exitCodeFile}"` + `${fullCommand} || echo $? > "${exitCodeFile}"`, ); if (promptAfterRun) { commandList.push( 'echo "Press enter to close the terminal window."', 'sync', - 'read' + 'read', ); } } @@ -161,6 +150,7 @@ export class DotnetCoreDependencyInstaller{ if (exitFile) { const exitCode = parseInt(exitFile, 10); if (exitCode === 0) { + // Expected exit code } else { // Possible that this is an expected exit code, so just a warning console.log('Non-zero exit code detected.'); @@ -181,5 +171,14 @@ export class DotnetCoreDependencyInstaller{ }); }); } -} + private getShellCommand(): string { + if (this.platform === 'win32') { + return which('cmd').toString(); + } + // Test for existence of bash which won't exist on the base Alpine Linux container, use sh instead there + const shellCommand = which('bash'); + // shellCommand will be null if bash is not found + return shellCommand ? shellCommand.toString() : which('sh').toString(); + } +} diff --git a/dotnetcore-acquisition-library/src/EventStream.ts b/dotnetcore-acquisition-library/src/EventStream.ts index fcb22187e2..fe7105caec 100644 --- a/dotnetcore-acquisition-library/src/EventStream.ts +++ b/dotnetcore-acquisition-library/src/EventStream.ts @@ -22,4 +22,4 @@ export class EventStream implements IEventStream { } public get subscribe() { return this.subscribeEmitter.event; } -} \ No newline at end of file +} diff --git a/dotnetcore-acquisition-library/src/EventStreamEvents.ts b/dotnetcore-acquisition-library/src/EventStreamEvents.ts index 55e14af9ce..43428e43d8 100644 --- a/dotnetcore-acquisition-library/src/EventStreamEvents.ts +++ b/dotnetcore-acquisition-library/src/EventStreamEvents.ts @@ -5,8 +5,8 @@ import { ExecException } from 'child_process'; import { EventType } from './EventType'; -import { IEvent } from './IEvent'; import { IDotnetInstallationContext } from './IDotnetInstallationContext'; +import { IEvent } from './IEvent'; // tslint:disable max-classes-per-file @@ -70,21 +70,15 @@ export class DotnetAcquisitionCompleted implements IEvent { export class DotnetUninstallAllStarted implements IEvent { public readonly type = EventType.DotnetUninstallAllStart; - - constructor() { - } } export class DotnetUninstallAllCompleted implements IEvent { public readonly type = EventType.DotnetUninstallAllCompleted; - - constructor() { - } } export class DotnetVersionResolutionError implements IEvent { public readonly type = EventType.DotnetVersionResolutionError; - + constructor(public readonly error: string) {} } @@ -95,6 +89,5 @@ export class DotnetVersionResolutionCompleted implements IEvent { export class TestAcquireCalled implements IEvent { public readonly type = EventType.DotnetAcquisitionTest; - constructor(public readonly context: IDotnetInstallationContext) { - } -} \ No newline at end of file + constructor(public readonly context: IDotnetInstallationContext) {} +} diff --git a/dotnetcore-acquisition-library/src/EventType.ts b/dotnetcore-acquisition-library/src/EventType.ts index 811734ecf5..3c053bf38d 100644 --- a/dotnetcore-acquisition-library/src/EventType.ts +++ b/dotnetcore-acquisition-library/src/EventType.ts @@ -11,5 +11,5 @@ export enum EventType { DotnetUninstallAllCompleted, DotnetVersionResolutionCompleted, DotnetVersionResolutionError, - DotnetAcquisitionTest + DotnetAcquisitionTest, } diff --git a/dotnetcore-acquisition-library/src/IAcquisitionInvoker.ts b/dotnetcore-acquisition-library/src/IAcquisitionInvoker.ts index 3a5c603a2b..389cf2a77d 100644 --- a/dotnetcore-acquisition-library/src/IAcquisitionInvoker.ts +++ b/dotnetcore-acquisition-library/src/IAcquisitionInvoker.ts @@ -9,5 +9,5 @@ import { IDotnetInstallationContext } from './IDotnetInstallationContext'; export abstract class IAcquisitionInvoker { constructor(protected readonly eventStream: IEventStream) {} - abstract installDotnet(installContext: IDotnetInstallationContext): Promise + public abstract installDotnet(installContext: IDotnetInstallationContext): Promise; } diff --git a/dotnetcore-acquisition-library/src/IDotnetInstallationContext.ts b/dotnetcore-acquisition-library/src/IDotnetInstallationContext.ts index 9e4bb52514..79ac85ad06 100644 --- a/dotnetcore-acquisition-library/src/IDotnetInstallationContext.ts +++ b/dotnetcore-acquisition-library/src/IDotnetInstallationContext.ts @@ -6,5 +6,5 @@ export interface IDotnetInstallationContext { installDir: string; version: string; - dotnetPath: string -} \ No newline at end of file + dotnetPath: string; +} diff --git a/dotnetcore-acquisition-library/src/IVersionResolver.ts b/dotnetcore-acquisition-library/src/IVersionResolver.ts index 306273586a..dd52cbf58a 100644 --- a/dotnetcore-acquisition-library/src/IVersionResolver.ts +++ b/dotnetcore-acquisition-library/src/IVersionResolver.ts @@ -5,4 +5,4 @@ export interface IVersionResolver { getFullVersion(version: string): Promise; -} \ No newline at end of file +} diff --git a/dotnetcore-acquisition-library/src/OutputChannelObserver.ts b/dotnetcore-acquisition-library/src/OutputChannelObserver.ts index 592841b3e9..ee76878288 100644 --- a/dotnetcore-acquisition-library/src/OutputChannelObserver.ts +++ b/dotnetcore-acquisition-library/src/OutputChannelObserver.ts @@ -13,7 +13,7 @@ export class OutputChannelObserver implements IEventStreamObserver { private readonly inProgressDownloads: string[] = []; private downloadProgressInterval: NodeJS.Timeout | undefined; - // private inProgressDownloads: + // private inProgressDownloads: constructor(private readonly outputChannel: vscode.OutputChannel) { } @@ -21,7 +21,7 @@ export class OutputChannelObserver implements IEventStreamObserver { switch (event.type) { case EventType.DotnetAcquisitionStart: const acquisitionStarted = event as DotnetAcquisitionStarted; - + this.inProgressDownloads.push(acquisitionStarted.version); if (this.inProgressDownloads.length > 1) { @@ -31,9 +31,9 @@ export class OutputChannelObserver implements IEventStreamObserver { } else { this.startDownloadIndicator(); } - - const versionString = this.inProgressDownloads.join(', '); - this.outputChannel.append(`Downloading .NET Core tooling version(s) ${versionString} ...`); + + const startVersionString = this.inProgressDownloads.join(', '); + this.outputChannel.append(`Downloading .NET Core tooling version(s) ${startVersionString} ...`); break; case EventType.DotnetAcquisitionCompleted: const acquisitionCompleted = event as DotnetAcquisitionCompleted; @@ -44,8 +44,8 @@ export class OutputChannelObserver implements IEventStreamObserver { this.inProgressVersionDone(acquisitionCompleted.version); if (this.inProgressDownloads.length > 0) { - const versionString = `'${this.inProgressDownloads.join('\', \'')}'`; - this.outputChannel.append(`Still downloading .NET Core tooling version(s) ${versionString} ...`); + const completedVersionString = `'${this.inProgressDownloads.join('\', \'')}'`; + this.outputChannel.append(`Still downloading .NET Core tooling version(s) ${completedVersionString} ...`); } else { this.stopDownladIndicator(); } @@ -60,8 +60,8 @@ export class OutputChannelObserver implements IEventStreamObserver { this.inProgressVersionDone(error.version); if (this.inProgressDownloads.length > 0) { - const versionString = this.inProgressDownloads.join(', '); - this.outputChannel.append(`Still downloading .NET Core tooling version(s) ${versionString} ...`); + const errorVersionString = this.inProgressDownloads.join(', '); + this.outputChannel.append(`Still downloading .NET Core tooling version(s) ${errorVersionString} ...`); } else { this.stopDownladIndicator(); } diff --git a/dotnetcore-acquisition-library/src/ReleasesResult.ts b/dotnetcore-acquisition-library/src/ReleasesResult.ts index f01b366210..35bcae88cc 100644 --- a/dotnetcore-acquisition-library/src/ReleasesResult.ts +++ b/dotnetcore-acquisition-library/src/ReleasesResult.ts @@ -2,9 +2,9 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ -import { isNullOrUndefined } from "util"; +import { isNullOrUndefined } from 'util'; -// ReleasesResult: Relevant data on current released runtime version. +// ReleasesResult: Relevant data on current released runtime version. // Required json format: // { // "releases-index": [ --> Array of release channels @@ -12,18 +12,18 @@ import { isNullOrUndefined } from "util"; // "channel-version": "X.X", --> Major.Minor version this channel represents // "latest-runtime": "X.X.X", --> Most recently released full version of the runtime // ... -// }, +// }, // ... // } export class ReleasesResult { - public releases_index: ReleasesChannel[]; + public releasesIndex: ReleasesChannel[]; constructor(json: string) { - this.releases_index = JSON.parse(json)['releases-index']; - if (isNullOrUndefined(this.releases_index)) { + this.releasesIndex = JSON.parse(json)['releases-index']; + if (isNullOrUndefined(this.releasesIndex)) { throw new Error('Unable to resolve version: invalid releases data'); } - this.releases_index = this.releases_index.map((channel: any) => { + this.releasesIndex = this.releasesIndex.map((channel: any) => { if (isNullOrUndefined(channel['channel-version']) || isNullOrUndefined(channel['latest-runtime'])) { throw new Error('Unable to resolve version: invalid releases data'); } @@ -33,6 +33,6 @@ export class ReleasesResult { } export class ReleasesChannel { - constructor(public channel_version: string, - public latest_runtime: string) {} -} \ No newline at end of file + constructor(public channelVersion: string, + public latestRuntime: string) {} +} diff --git a/dotnetcore-acquisition-library/src/VersionResolver.ts b/dotnetcore-acquisition-library/src/VersionResolver.ts index 53043b80ea..f216996d53 100644 --- a/dotnetcore-acquisition-library/src/VersionResolver.ts +++ b/dotnetcore-acquisition-library/src/VersionResolver.ts @@ -5,17 +5,17 @@ import * as request from 'request-promise-native'; import * as semver from 'semver'; import { isNullOrUndefined } from 'util'; +import { Memento } from 'vscode'; +import { IEventStream } from './EventStream'; +import { DotnetVersionResolutionCompleted, DotnetVersionResolutionError } from './EventStreamEvents'; import { IVersionResolver } from './IVersionResolver'; import { ReleasesResult } from './ReleasesResult'; -import { IEventStream } from './EventStream'; -import { DotnetVersionResolutionError, DotnetVersionResolutionCompleted } from './EventStreamEvents'; -import { Memento } from 'vscode'; export class VersionResolver implements IVersionResolver { private releasesVersions: ReleasesResult | undefined; - private readonly releasesKey = "releases"; + private readonly releasesKey = 'releases'; - constructor(private readonly extensionState: Memento, + constructor(private readonly extensionState: Memento, private readonly eventStream: IEventStream) {} public async getFullVersion(version: string): Promise { @@ -34,21 +34,10 @@ export class VersionResolver implements IVersionResolver { return versionResult; } - private resolveVersion(version: string, releases: ReleasesResult): string { - this.validateVersionInput(version); - - const channel = releases.releases_index.filter((channel) => channel.channel_version === version); - if (isNullOrUndefined(channel) || channel.length != 1) { - throw new Error('Unable to resolve version: ' + version) - } - const runtimeVersion = channel[0].latest_runtime; - return runtimeVersion; - } - // Protected for ease of testing protected async getReleasesResult(): Promise { - var options = { - uri: 'https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json' + const options = { + uri: 'https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json', }; try { @@ -57,16 +46,27 @@ export class VersionResolver implements IVersionResolver { await this.extensionState.update(this.releasesKey, response); const releasesResult = new ReleasesResult(response); return releasesResult; - } catch(error) { - this.eventStream.post(new DotnetVersionResolutionError("Version resolution failed: " + error.message)); - throw new Error("Unable to Resolve Version: " + error.message); - }; + } catch (error) { + this.eventStream.post(new DotnetVersionResolutionError(`Version resolution failed: ${error.message}`)); + throw new Error(`Unable to Resolve Version: ${error.message}`); + } + } + + private resolveVersion(version: string, releases: ReleasesResult): string { + this.validateVersionInput(version); + + const channel = releases.releasesIndex.filter((channelVal) => channelVal.channelVersion === version); + if (isNullOrUndefined(channel) || channel.length !== 1) { + throw new Error(`Unable to resolve version: ${version}`); + } + const runtimeVersion = channel[0].latestRuntime; + return runtimeVersion; } private validateVersionInput(version: string) { const parsedVer = semver.coerce(version); - if (version.split('.').length != 2 || isNullOrUndefined(parsedVer)) { - throw new Error('Invalid version: ' + version); + if (version.split('.').length !== 2 || isNullOrUndefined(parsedVer)) { + throw new Error(`Invalid version: ${version}`); } } -} \ No newline at end of file +} diff --git a/dotnetcore-acquisition-library/src/extension.ts b/dotnetcore-acquisition-library/src/extension.ts index dfd014467d..379c9831f4 100644 --- a/dotnetcore-acquisition-library/src/extension.ts +++ b/dotnetcore-acquisition-library/src/extension.ts @@ -7,13 +7,13 @@ import * as cp from 'child_process'; import * as fs from 'fs'; import * as os from 'os'; import * as vscode from 'vscode'; +import { AcquisitionInvoker } from './AcquisitionInvoker'; import { DotnetCoreAcquisitionWorker } from './DotnetCoreAcquisitionWorker'; import { DotnetCoreDependencyInstaller } from './DotnetCoreDependencyInstaller'; import { EventStream } from './EventStream'; import { IEventStreamObserver } from './IEventStreamObserver'; import { OutputChannelObserver } from './OutputChannelObserver'; import { StatusBarObserver } from './StatusBarObserver'; -import { AcquisitionInvoker } from './AcquisitionInvoker'; import { VersionResolver } from './VersionResolver'; export function activate(context: vscode.ExtensionContext, parentExtensionId: string) { @@ -43,8 +43,8 @@ export function activate(context: vscode.ExtensionContext, parentExtensionId: st const acquisitionWorker = new DotnetCoreAcquisitionWorker( context.globalStoragePath, context.globalState, - eventStream, - acquisitionInvoker, + eventStream, + acquisitionInvoker, versionResolver); const dotnetAcquireRegistration = vscode.commands.registerCommand('dotnet.acquire', async (version) => { diff --git a/dotnetcore-acquisition-library/src/index.ts b/dotnetcore-acquisition-library/src/index.ts index cd3441d58d..708ddfca02 100644 --- a/dotnetcore-acquisition-library/src/index.ts +++ b/dotnetcore-acquisition-library/src/index.ts @@ -3,5 +3,5 @@ * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ -export * from './extension' -export * from './test/mocks/MockObjects' \ No newline at end of file +export * from './extension'; +export * from './test/mocks/MockObjects'; diff --git a/dotnetcore-acquisition-library/src/test/mocks/MockObjects.ts b/dotnetcore-acquisition-library/src/test/mocks/MockObjects.ts index 34b3f8a1a5..68c3283336 100644 --- a/dotnetcore-acquisition-library/src/test/mocks/MockObjects.ts +++ b/dotnetcore-acquisition-library/src/test/mocks/MockObjects.ts @@ -3,36 +3,36 @@ * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ +import * as fs from 'fs'; import * as path from 'path'; import { Memento } from 'vscode'; import { IEventStream } from '../../EventStream'; -import { IEvent } from '../../IEvent'; -import { IAcquisitionInvoker } from '../../IAcquisitionInvoker'; import { DotnetAcquisitionCompleted, TestAcquireCalled } from '../../EventStreamEvents'; +import { IAcquisitionInvoker } from '../../IAcquisitionInvoker'; import { IDotnetInstallationContext } from '../../IDotnetInstallationContext'; -import { VersionResolver } from '../../VersionResolver'; -import * as fs from 'fs'; +import { IEvent } from '../../IEvent'; import { ReleasesResult } from '../../ReleasesResult'; +import { VersionResolver } from '../../VersionResolver'; export class MockExtensionContext implements Memento { private values: { [n: string]: any; } = {}; - - get(key: string): T | undefined; - get(key: string, defaultValue: T): T; - get(key: any, defaultValue?: any) { + + public get(key: string): T | undefined; + public get(key: string, defaultValue: T): T; + public get(key: any, defaultValue?: any) { let value = this.values![key]; - if (typeof value === 'undefined') { - value = defaultValue; - } - return value; + if (typeof value === 'undefined') { + value = defaultValue; + } + return value; } - update(key: string, value: any): Thenable { + public update(key: string, value: any): Thenable { return this.values[key] = value; } } export class MockEventStream implements IEventStream { - public events : IEvent[] = []; + public events: IEvent[] = []; public post(event: IEvent) { this.events = this.events.concat(event); } @@ -50,13 +50,13 @@ export class NoInstallAcquisitionInvoker extends IAcquisitionInvoker { } export class ErrorAcquisitionInvoker extends IAcquisitionInvoker { - installDotnet(installContext: IDotnetInstallationContext): Promise { - throw new Error("Command Failed"); + public installDotnet(installContext: IDotnetInstallationContext): Promise { + throw new Error('Command Failed'); } } // Major.Minor-> Major.Minor.Patch from mock releases.json -export const versionPairs = [['1.0', '1.0.16'], ['1.1', '1.1.13'], ['2.0', '2.0.9'], ['2.1', '2.1.14'], ['2.2', '2.2.8']]; +export const versionPairs = [['1.0', '1.0.16'], ['1.1', '1.1.13'], ['2.0', '2.0.9'], ['2.1', '2.1.14'], ['2.2', '2.2.8']]; export class MockVersionResolver extends VersionResolver { protected async getReleasesResult(): Promise { @@ -64,4 +64,4 @@ export class MockVersionResolver extends VersionResolver { const releasesResult = new ReleasesResult(jsonRes); return releasesResult; } -} \ No newline at end of file +} diff --git a/dotnetcore-acquisition-library/src/test/unit/DotnetCoreAcquisitionWorker.test.ts b/dotnetcore-acquisition-library/src/test/unit/DotnetCoreAcquisitionWorker.test.ts index cf06175275..b76236fedb 100644 --- a/dotnetcore-acquisition-library/src/test/unit/DotnetCoreAcquisitionWorker.test.ts +++ b/dotnetcore-acquisition-library/src/test/unit/DotnetCoreAcquisitionWorker.test.ts @@ -2,56 +2,56 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ - +import * as chai from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; import * as os from 'os'; import * as path from 'path'; import { DotnetCoreAcquisitionWorker } from '../../DotnetCoreAcquisitionWorker'; -import { MockExtensionContext, - MockEventStream, - NoInstallAcquisitionInvoker, - MockVersionResolver, - ErrorAcquisitionInvoker, - versionPairs -} from '../mocks/MockObjects'; -import { EventType } from '../../EventType'; -import { - DotnetAcquisitionStarted, +import { DotnetAcquisitionCompleted, - TestAcquireCalled, + DotnetAcquisitionStarted, + DotnetUninstallAllCompleted, DotnetUninstallAllStarted, - DotnetUninstallAllCompleted + TestAcquireCalled, } from '../../EventStreamEvents'; -var chai = require('chai'); -var assert = chai.assert; -var chaiAsPromised = require('chai-as-promised'); +import { EventType } from '../../EventType'; +import { + ErrorAcquisitionInvoker, + MockEventStream, + MockExtensionContext, + MockVersionResolver, + NoInstallAcquisitionInvoker, + versionPairs, +} from '../mocks/MockObjects'; +const assert = chai.assert; chai.use(chaiAsPromised); -suite("DotnetCoreAcquisitionWorker Unit Tests", function () { +suite('DotnetCoreAcquisitionWorker Unit Tests', () => { const installingVersionsKey = 'installing'; - function getTestAcquisitionWorker(fakeScripts: boolean) : [ DotnetCoreAcquisitionWorker, MockEventStream, MockExtensionContext ] { + function getTestAcquisitionWorker(fakeScripts: boolean): [ DotnetCoreAcquisitionWorker, MockEventStream, MockExtensionContext ] { const context = new MockExtensionContext(); const eventStream = new MockEventStream(); const acquisitionWorker = new DotnetCoreAcquisitionWorker( - "", + '', context, eventStream, - fakeScripts ? - new ErrorAcquisitionInvoker(eventStream) : - new NoInstallAcquisitionInvoker(eventStream), + fakeScripts ? + new ErrorAcquisitionInvoker(eventStream) : + new NoInstallAcquisitionInvoker(eventStream), new MockVersionResolver(context, eventStream)); return [ acquisitionWorker, eventStream, context ]; } - - function getExpectedPath(version: string) : string { - return path.join(".dotnet", version, os.platform() === 'win32' ? "dotnet.exe" : "dotnet"); + + function getExpectedPath(version: string): string { + return path.join('.dotnet', version, os.platform() === 'win32' ? 'dotnet.exe' : 'dotnet'); } - + async function assertAcquisitionSucceeded(version: string, - exePath: string, - eventStream : MockEventStream, - context : MockExtensionContext) { - var expectedPath = getExpectedPath(version); + exePath: string, + eventStream: MockEventStream, + context: MockExtensionContext) { + const expectedPath = getExpectedPath(version); // Path to exe should be correct assert.equal(exePath, expectedPath); @@ -59,42 +59,42 @@ suite("DotnetCoreAcquisitionWorker Unit Tests", function () { // Should be finished installing assert.isEmpty(context.get(installingVersionsKey)); -        // No errors in event stream -        assert.notExists(eventStream.events.find(event => event.type == EventType.DotnetAcquisitionError)); -        var startEvent = eventStream.events -            .find(event => event instanceof DotnetAcquisitionStarted && (event as DotnetAcquisitionStarted).version == version); +        //  No errors in event stream +        assert.notExists(eventStream.events.find(event => event.type === EventType.DotnetAcquisitionError)); +        const startEvent = eventStream.events +            .find(event => event instanceof DotnetAcquisitionStarted && (event as DotnetAcquisitionStarted).version === version);         assert.exists(startEvent); -        var completedEvent = eventStream.events -            .find(event => event instanceof DotnetAcquisitionCompleted && (event as DotnetAcquisitionCompleted).version == version  -            && (event as DotnetAcquisitionCompleted).dotnetPath == expectedPath); +        const completedEvent = eventStream.events +            .find(event => event instanceof DotnetAcquisitionCompleted && (event as DotnetAcquisitionCompleted).version === version +            && (event as DotnetAcquisitionCompleted).dotnetPath === expectedPath);         assert.exists(completedEvent); -        // Acquire got called with the correct args -        var acquireEvent = eventStream.events.find(event =>  -            event instanceof TestAcquireCalled && (event as TestAcquireCalled).context.version == version) as TestAcquireCalled; +        //  Acquire got called with the correct args +        const acquireEvent = eventStream.events.find(event => +            event instanceof TestAcquireCalled && (event as TestAcquireCalled).context.version === version) as TestAcquireCalled; assert.exists(acquireEvent); assert.equal(acquireEvent!.context.dotnetPath, expectedPath); - assert.equal(acquireEvent!.context.installDir, path.join(".dotnet", version)); + assert.equal(acquireEvent!.context.installDir, path.join('.dotnet', version)); } - test("Acquire Version", async () => { + test('Acquire Version', async () => { const [acquisitionWorker, eventStream, context] = getTestAcquisitionWorker(false); - const path = await acquisitionWorker.acquire(versionPairs[0][0]); - await assertAcquisitionSucceeded(versionPairs[0][1], path, eventStream, context); + const pathResult = await acquisitionWorker.acquire(versionPairs[0][0]); + await assertAcquisitionSucceeded(versionPairs[0][1], pathResult, eventStream, context); }); - test("Acquire Version Multiple Times", async () => { + test('Acquire Version Multiple Times', async () => { const numAcquisitions = 3; const [acquisitionWorker, eventStream, context] = getTestAcquisitionWorker(false); for (let i = 0; i < numAcquisitions; i++) { - const path = await acquisitionWorker.acquire(versionPairs[0][0]); - await assertAcquisitionSucceeded(versionPairs[0][1], path, eventStream, context); + const pathResult = await acquisitionWorker.acquire(versionPairs[0][0]); + await assertAcquisitionSucceeded(versionPairs[0][1], pathResult, eventStream, context); } // AcquisitionInvoker was only called once -        var acquireEvents = eventStream.events.filter(event => event instanceof TestAcquireCalled); +        const acquireEvents = eventStream.events.filter(event => event instanceof TestAcquireCalled); assert.lengthOf(acquireEvents, 1); }); @@ -103,25 +103,25 @@ suite("DotnetCoreAcquisitionWorker Unit Tests", function () { return assert.isRejected(acquisitionWorker.acquire(versionPairs[0][0]), Error, 'Dotnet Core Acquisition Failed'); }); - test("Acquire Multiple Versions and UninstallAll", async () => { + test('Acquire Multiple Versions and UninstallAll', async () => {         const [acquisitionWorker, eventStream, context] = getTestAcquisitionWorker(false); -        for (var version of versionPairs) { -            const path = await acquisitionWorker.acquire(version[0]); -            await assertAcquisitionSucceeded(version[1], path, eventStream, context); +        for (const version of versionPairs) { +            const pathRes = await acquisitionWorker.acquire(version[0]); +            await assertAcquisitionSucceeded(version[1], pathRes, eventStream, context);         }         await acquisitionWorker.uninstallAll();         assert.exists(eventStream.events.find(event => event instanceof DotnetUninstallAllStarted));         assert.exists(eventStream.events.find(event => event instanceof DotnetUninstallAllCompleted));     }); - test("Acquire and UninstallAll", async () => { + test('Acquire and UninstallAll', async () => { const [acquisitionWorker, eventStream, context] = getTestAcquisitionWorker(false); - const path = await acquisitionWorker.acquire(versionPairs[0][0]); - await assertAcquisitionSucceeded(versionPairs[0][1], path, eventStream, context); + const pathRes = await acquisitionWorker.acquire(versionPairs[0][0]); + await assertAcquisitionSucceeded(versionPairs[0][1], pathRes, eventStream, context); await acquisitionWorker.uninstallAll(); assert.exists(eventStream.events.find(event => event instanceof DotnetUninstallAllStarted)); assert.exists(eventStream.events.find(event => event instanceof DotnetUninstallAllCompleted)); }); -}); \ No newline at end of file +}); diff --git a/dotnetcore-acquisition-library/src/test/unit/VersionResolver.test.ts b/dotnetcore-acquisition-library/src/test/unit/VersionResolver.test.ts index 75480c9bd8..a8ad82beee 100644 --- a/dotnetcore-acquisition-library/src/test/unit/VersionResolver.test.ts +++ b/dotnetcore-acquisition-library/src/test/unit/VersionResolver.test.ts @@ -2,32 +2,32 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ +import * as chai from 'chai'; +import { MockEventStream, MockExtensionContext, MockVersionResolver, versionPairs } from '../mocks/MockObjects'; +const assert = chai.assert; -import { versionPairs, MockVersionResolver, MockEventStream, MockExtensionContext } from "../mocks/MockObjects"; -var assert = require('chai').assert; - -suite("VersionResolver Unit Tests", function () { +suite('VersionResolver Unit Tests', () => { const eventStream = new MockEventStream(); const context = new MockExtensionContext(); - // MockVersionResolver is a VersionResolver that uses a fake releases.json + // MockVersionResolver is a VersionResolver that uses a fake releases.json // (prevents us from making web requests in unit tests) const resolver: MockVersionResolver = new MockVersionResolver(context, eventStream); - test("Error With Invalid Version", async () => { - return assert.isRejected(resolver.getFullVersion("foo"), Error, 'Invalid version'); + test('Error With Invalid Version', async () => { + return assert.isRejected(resolver.getFullVersion('foo'), Error, 'Invalid version'); }); - test("Error With Three Part Version", async () => { - return assert.isRejected(resolver.getFullVersion("1.0.16"), Error, 'Invalid version'); + test('Error With Three Part Version', async () => { + return assert.isRejected(resolver.getFullVersion('1.0.16'), Error, 'Invalid version'); }); - test("Error With Invalid Major.Minor", async () => { - return assert.isRejected(resolver.getFullVersion("0.0"), Error, 'Unable to resolve version'); + test('Error With Invalid Major.Minor', async () => { + return assert.isRejected(resolver.getFullVersion('0.0'), Error, 'Unable to resolve version'); }); - test("Resolve Valid Versions", async () => { - for (var version of versionPairs) { + test('Resolve Valid Versions', async () => { + for (const version of versionPairs) { assert.equal(await resolver.getFullVersion(version[0]), version[1]); } }); -}); \ No newline at end of file +}); diff --git a/tslint.json b/tslint.json index 22f9570dfe..48099392f7 100644 --- a/tslint.json +++ b/tslint.json @@ -11,6 +11,7 @@ "prefer-template": true, "quotemark": [true, "single"], "variable-name": [true, "check-format"], + "max-classes-per-file": false, "max-line-length": { "options": { "limit": 200