diff --git a/packages/flutter_tools/lib/src/windows/visual_studio_validator.dart b/packages/flutter_tools/lib/src/windows/visual_studio_validator.dart index 0fd1ac17c30..8a1143ed267 100644 --- a/packages/flutter_tools/lib/src/windows/visual_studio_validator.dart +++ b/packages/flutter_tools/lib/src/windows/visual_studio_validator.dart @@ -12,7 +12,9 @@ VisualStudioValidator get visualStudioValidator => context.get int.tryParse(visualStudio.fullVersion.split('.')[0]); + int get majorVersion => visualStudio.fullVersion != null + ? int.tryParse(visualStudio.fullVersion.split('.')[0]) + : null; @override Future validate() async { diff --git a/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart b/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart index a9ceebd7110..f089d79f852 100644 --- a/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart +++ b/packages/flutter_tools/test/general.shard/windows/visual_studio_test.dart @@ -35,20 +35,20 @@ void main() { // A minimum version of a response where a VS installation was found. const Map _defaultResponse = { 'installationPath': visualStudioPath, - 'displayName': 'Visual Studio Community 2017', - 'installationVersion': '15.9.28307.665', + 'displayName': 'Visual Studio Community 2019', + 'installationVersion': '16.2.29306.81', 'isRebootRequired': false, 'isComplete': true, 'isLaunchable': true, 'isPrerelease': false, 'catalog': { - 'productDisplayVersion': '15.9.12', - }, + 'productDisplayVersion': '16.2.5', + } }; // A version of a response that doesn't include certain installation status // information that might be missing in older Visual Studio versions. - const Map _oldResponse = { + const Map _missingStatusResponse = { 'installationPath': visualStudioPath, 'displayName': 'Visual Studio Community 2017', 'installationVersion': '15.9.28307.665', @@ -205,10 +205,32 @@ void main() { ProcessManager: () => mockProcessManager, }); + testUsingContext('necessaryComponentDescriptions suggest the right VS tools on major version 15', () { + + visualStudio = VisualStudio(); + final String toolsString = visualStudio.necessaryComponentDescriptions(15)[1]; + expect(toolsString.contains('v141'), true); + }, overrides: { + FileSystem: () => memoryFilesystem, + Platform: () => windowsPlatform, + ProcessManager: () => mockProcessManager, + }); + + testUsingContext('necessaryComponentDescriptions suggest the right VS tools on major version != 15', () { + + visualStudio = VisualStudio(); + final String toolsString = visualStudio.necessaryComponentDescriptions(16)[1]; + expect(toolsString.contains('v142'), true); + }, overrides: { + FileSystem: () => memoryFilesystem, + Platform: () => windowsPlatform, + ProcessManager: () => mockProcessManager, + }); + testUsingContext('isInstalled returns true even with missing status information', () { setMockCompatibleVisualStudioInstallation(null); setMockPrereleaseVisualStudioInstallation(null); - setMockAnyVisualStudioInstallation(_oldResponse); + setMockAnyVisualStudioInstallation(_missingStatusResponse); visualStudio = VisualStudio(); expect(visualStudio.isInstalled, true); @@ -360,10 +382,10 @@ void main() { setMockAnyVisualStudioInstallation(_defaultResponse); visualStudio = VisualStudio(); - expect(visualStudio.displayName, equals('Visual Studio Community 2017')); - expect(visualStudio.displayVersion, equals('15.9.12')); + expect(visualStudio.displayName, equals('Visual Studio Community 2019')); + expect(visualStudio.displayVersion, equals('16.2.5')); expect(visualStudio.installLocation, equals(visualStudioPath)); - expect(visualStudio.fullVersion, equals('15.9.28307.665')); + expect(visualStudio.fullVersion, equals('16.2.29306.81')); }, overrides: { FileSystem: () => memoryFilesystem, Platform: () => windowsPlatform, @@ -386,7 +408,17 @@ void main() { }); testUsingContext('Metadata is for compatible version when latest is missing components', () { - setMockCompatibleVisualStudioInstallation(_defaultResponse); + // Return a different version for queries without the required packages. + final Map olderButCompleteVersionResponse = { + 'installationPath': visualStudioPath, + 'displayName': 'Visual Studio Community 2017', + 'installationVersion': '15.9.28307.665', + 'catalog': { + 'productDisplayVersion': '15.9.12', + } + }; + + setMockCompatibleVisualStudioInstallation(olderButCompleteVersionResponse); setMockPrereleaseVisualStudioInstallation(null); // Return a different version for queries without the required packages. final Map incompleteVersionResponse = { diff --git a/packages/flutter_tools/test/general.shard/windows/visual_studio_validator_test.dart b/packages/flutter_tools/test/general.shard/windows/visual_studio_validator_test.dart index 5ed0a7631df..a128bdd0cf3 100644 --- a/packages/flutter_tools/test/general.shard/windows/visual_studio_validator_test.dart +++ b/packages/flutter_tools/test/general.shard/windows/visual_studio_validator_test.dart @@ -19,19 +19,35 @@ void main() { setUp(() { mockVisualStudio = MockVisualStudio(); - // Mock a valid VS installation. + // Default values regardless of whether VS is installed or not. + when(mockVisualStudio.workloadDescription).thenReturn('Desktop development'); + when(mockVisualStudio.necessaryComponentDescriptions(any)).thenReturn(['A', 'B']); + }); + + // Assigns default values for a complete VS installation with necessary components. + void _configureMockVisualStudioAsInstalled() { when(mockVisualStudio.isInstalled).thenReturn(true); when(mockVisualStudio.isPrerelease).thenReturn(false); when(mockVisualStudio.isComplete).thenReturn(true); when(mockVisualStudio.isLaunchable).thenReturn(true); when(mockVisualStudio.isRebootRequired).thenReturn(false); when(mockVisualStudio.hasNecessaryComponents).thenReturn(true); - when(mockVisualStudio.workloadDescription).thenReturn('Desktop development'); - when(mockVisualStudio.necessaryComponentDescriptions(any)).thenReturn(['A', 'B']); when(mockVisualStudio.fullVersion).thenReturn('15.1'); - }); + when(mockVisualStudio.displayName).thenReturn('Visual Studio Community 2019'); + } + + // Assigns default values for a missing VS installation. + void _configureMockVisualStudioAsNotInstalled() { + when(mockVisualStudio.isInstalled).thenReturn(false); + when(mockVisualStudio.isPrerelease).thenReturn(false); + when(mockVisualStudio.isComplete).thenReturn(false); + when(mockVisualStudio.isLaunchable).thenReturn(false); + when(mockVisualStudio.isRebootRequired).thenReturn(false); + when(mockVisualStudio.hasNecessaryComponents).thenReturn(false); + } testUsingContext('Emits a message when Visual Studio is a pre-release version', () async { + _configureMockVisualStudioAsInstalled(); when(visualStudio.isPrerelease).thenReturn(true); const VisualStudioValidator validator = VisualStudioValidator(); @@ -42,16 +58,8 @@ void main() { VisualStudio: () => mockVisualStudio, }); - testUsingContext('Emits missing status when Visual Studio is not installed', () async { - when(visualStudio.isInstalled).thenReturn(false); - const VisualStudioValidator validator = VisualStudioValidator(); - final ValidationResult result = await validator.validate(); - expect(result.type, ValidationType.missing); - }, overrides: { - VisualStudio: () => mockVisualStudio, - }); - testUsingContext('Emits a partial status when Visual Studio installation is incomplete', () async { + _configureMockVisualStudioAsInstalled(); when(visualStudio.isComplete).thenReturn(false); const VisualStudioValidator validator = VisualStudioValidator(); @@ -64,6 +72,7 @@ void main() { }); testUsingContext('Emits a partial status when Visual Studio installation needs rebooting', () async { + _configureMockVisualStudioAsInstalled(); when(visualStudio.isRebootRequired).thenReturn(true); const VisualStudioValidator validator = VisualStudioValidator(); @@ -76,6 +85,7 @@ void main() { }); testUsingContext('Emits a partial status when Visual Studio installation is not launchable', () async { + _configureMockVisualStudioAsInstalled(); when(visualStudio.isLaunchable).thenReturn(false); const VisualStudioValidator validator = VisualStudioValidator(); @@ -89,6 +99,7 @@ void main() { testUsingContext('Emits partial status when Visual Studio is installed without necessary components', () async { + _configureMockVisualStudioAsInstalled(); when(visualStudio.hasNecessaryComponents).thenReturn(false); const VisualStudioValidator validator = VisualStudioValidator(); final ValidationResult result = await validator.validate(); @@ -98,15 +109,19 @@ void main() { }); testUsingContext('Emits installed status when Visual Studio is installed with necessary components', () async { + _configureMockVisualStudioAsInstalled(); const VisualStudioValidator validator = VisualStudioValidator(); final ValidationResult result = await validator.validate(); + final ValidationMessage expectedDisplayNameMessage = ValidationMessage( + userMessages.visualStudioVersion(visualStudio.displayName, visualStudio.fullVersion)); + expect(result.messages.contains(expectedDisplayNameMessage), true); expect(result.type, ValidationType.installed); }, overrides: { VisualStudio: () => mockVisualStudio, }); testUsingContext('Emits missing status when Visual Studio is not installed', () async { - when(visualStudio.isInstalled).thenReturn(false); + _configureMockVisualStudioAsNotInstalled(); const VisualStudioValidator validator = VisualStudioValidator(); final ValidationResult result = await validator.validate(); final ValidationMessage expectedMessage = ValidationMessage.error(