From dd95a6b902c4655a75101119cfa4eafe542f5b5d Mon Sep 17 00:00:00 2001 From: Ivan Shcheklein Date: Tue, 19 Jul 2022 20:54:47 -0700 Subject: [PATCH] Introduce the latest DVC version extension is tested with --- extension/src/cli/constants.ts | 1 + extension/src/cli/version.test.ts | 67 +++++++++++++++++++++++++++---- extension/src/cli/version.ts | 29 ++++++++----- 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/extension/src/cli/constants.ts b/extension/src/cli/constants.ts index e4c546418a..36d13c97a6 100644 --- a/extension/src/cli/constants.ts +++ b/extension/src/cli/constants.ts @@ -1,4 +1,5 @@ export const MIN_CLI_VERSION = '2.11.0' +export const LATEST_TESTED_CLI_VERSION = '2.13.0' export const MAX_CLI_VERSION = '3' export enum Command { diff --git a/extension/src/cli/version.test.ts b/extension/src/cli/version.test.ts index 6b988cdf3e..4ac49bd767 100644 --- a/extension/src/cli/version.test.ts +++ b/extension/src/cli/version.test.ts @@ -1,9 +1,10 @@ import { isVersionCompatible, extractSemver, ParsedSemver } from './version' -import { MIN_CLI_VERSION } from './constants' +import { MIN_CLI_VERSION, LATEST_TESTED_CLI_VERSION } from './constants' import { Toast } from '../vscode/toast' jest.mock('./constants', () => ({ ...jest.requireActual('./constants'), + LATEST_TESTED_CLI_VERSION: '2.11.1', MIN_CLI_VERSION: '2.9.4' })) jest.mock('../vscode/config') @@ -50,6 +51,12 @@ describe('isVersionCompatible', () => { patch: minPatch } = extractSemver(MIN_CLI_VERSION) as ParsedSemver + const { + major: latestTestedMajor, + minor: latestTestedMinor, + patch: latestTestedPatch + } = extractSemver(LATEST_TESTED_CLI_VERSION) as ParsedSemver + it('should be compatible and not send a toast message if the provided version matches the min version', () => { const isCompatible = isVersionCompatible(MIN_CLI_VERSION) @@ -57,24 +64,65 @@ describe('isVersionCompatible', () => { expect(mockedWarnWithOptions).not.toBeCalled() }) - it('should be compatible and not send a toast for a version with the same minor and higher patch', () => { + it('should be compatible and not send a toast for a version with the same minor and higher patch as the min compatible version', () => { mockedWarnWithOptions.mockResolvedValueOnce(undefined) const isCompatible = isVersionCompatible( - [minMajor, minMinor, minPatch + 10000].join(',') + [minMajor, minMinor, minPatch + 10000].join('.') ) expect(isCompatible).toBe(true) expect(mockedWarnWithOptions).not.toBeCalled() }) - it('should be compatible but send a toast for a version with a higher minor but lower patch', () => { + it('should be compatible and not send a toast for a version with the same minor and higher patch as the latest tested version', () => { mockedWarnWithOptions.mockResolvedValueOnce(undefined) - const isCompatible = isVersionCompatible('2.10.0') + const isCompatible = isVersionCompatible( + [latestTestedMajor, latestTestedMinor, latestTestedPatch + 10000].join( + '.' + ) + ) expect(isCompatible).toBe(true) - expect(mockedWarnWithOptions).toBeCalledTimes(1) + expect(mockedWarnWithOptions).not.toBeCalled() + }) + + it('should be compatible and not send a toast for a major and minor version in between the min compatible and the latest tested', () => { + mockedWarnWithOptions.mockResolvedValueOnce(undefined) + expect(minMinor + 1).toBeLessThan(latestTestedMinor) + expect(minMajor).toStrictEqual(latestTestedMajor) + + const isCompatible = isVersionCompatible( + [minMajor, minMinor + 1, 0].join('.') + ) + + expect(isCompatible).toBe(true) + expect(mockedWarnWithOptions).not.toBeCalled() + }) + + it('should be compatible and send a toast for a version with a minor higher as the latest tested minor and any patch', () => { + mockedWarnWithOptions.mockResolvedValueOnce(undefined) + expect(0).toBeLessThan(latestTestedPatch) + + let isCompatible = isVersionCompatible( + [latestTestedMajor, latestTestedMinor + 1, 0].join('.') + ) + expect(isCompatible).toBe(true) + + isCompatible = isVersionCompatible( + [latestTestedMajor, latestTestedMinor + 1, latestTestedPatch + 1000].join( + '.' + ) + ) + expect(isCompatible).toBe(true) + + isCompatible = isVersionCompatible( + [latestTestedMajor, latestTestedMinor + 1, latestTestedPatch].join('.') + ) + expect(isCompatible).toBe(true) + + expect(mockedWarnWithOptions).toBeCalledTimes(3) }) it('should not be compatible and send a toast message if the provided version is a patch version before the minimum expected version', () => { @@ -122,9 +170,12 @@ describe('isVersionCompatible', () => { it('should not be compatible and send a toast message if the provided version is malformed', () => { mockedWarnWithOptions.mockResolvedValueOnce(undefined) - const isCompatible = isVersionCompatible('not a valid version') + let isCompatible = isVersionCompatible('not a valid version') + expect(isCompatible).toBe(false) + isCompatible = isVersionCompatible('1,2,3') expect(isCompatible).toBe(false) - expect(mockedWarnWithOptions).toBeCalledTimes(1) + + expect(mockedWarnWithOptions).toBeCalledTimes(2) }) }) diff --git a/extension/src/cli/version.ts b/extension/src/cli/version.ts index 4af8f6c561..93d147be19 100644 --- a/extension/src/cli/version.ts +++ b/extension/src/cli/version.ts @@ -1,4 +1,8 @@ -import { MAX_CLI_VERSION, MIN_CLI_VERSION } from './constants' +import { + MAX_CLI_VERSION, + LATEST_TESTED_CLI_VERSION, + MIN_CLI_VERSION +} from './constants' import { Toast } from '../vscode/toast' export type ParsedSemver = { major: number; minor: number; patch: number } @@ -23,14 +27,16 @@ const getTextAndSend = (version: string, update: 'CLI' | 'extension'): void => { Toast.warnWithOptions(text) } -const warnIfMinorAhead = ( +const warnIfAheadOfLatestTested = ( currentMajor: number, - minMajor: number, - currentMinor: number, - minMinor: number + currentMinor: number ) => { - if (currentMajor === minMajor && currentMinor > minMinor) { - Toast.warnWithOptions(`The located version of the CLI is at least a minor version ahead of the expected version. + const { major: latestTestedMajor, minor: latestTestedMinor } = extractSemver( + LATEST_TESTED_CLI_VERSION + ) as ParsedSemver + + if (currentMajor === latestTestedMajor && currentMinor > latestTestedMinor) { + Toast.warnWithOptions(`The located DVC CLI is at least a minor version ahead of the latest version the extension was tested with. This could lead to unexpected behaviour. Please upgrade to the most recent version of the extension and reload this window.`) } @@ -66,14 +72,19 @@ const checkCLIVersion = ( return false } - warnIfMinorAhead(currentMajor, minMajor, currentMinor, minMinor) + warnIfAheadOfLatestTested(currentMajor, currentMinor) return true } export const isVersionCompatible = (version: string): boolean => { const currentSemVer = extractSemver(version) - if (!currentSemVer) { + if ( + !currentSemVer || + Number.isNaN(currentSemVer.major) || + Number.isNaN(currentSemVer.minor) || + Number.isNaN(currentSemVer.patch) + ) { Toast.warnWithOptions( 'The extension cannot initialize as we were unable to verify the DVC CLI version.' )