Unverified Commit 52e19ef7 authored by Loïc Sharma's avatar Loïc Sharma Committed by GitHub

Refactor vswhere.exe integration (#104133)

`VisualStudio` calls `vswhere.exe` to find Visual Studio installations and determine if they satisfy Flutter's requirements. Previously, `VisualStudio` stored the JSON output from `vswhere.exe` as `Map`s, resulting in duplicated logic to read the JSON output (once to validate values, second to expose values). Also, `VisualStudio` stored two copies of the JSON output (the latest valid installation as well as the latest VS installation).

This change simplifies `VisualStudio` by introducing a new `VswhereDetails`. This type contains the logic to read `vswhere.exe`'s JSON output, and, understand whether an installation is usable by Flutter. In the future, this `VswhereDetails` type will be used to make Flutter doctor resilient to bad UTF-8 output from `vswhere.exe`.

Part of https://github.com/flutter/flutter/issues/102451.
parent 874b6c08
...@@ -863,6 +863,98 @@ void main() { ...@@ -863,6 +863,98 @@ void main() {
expect(visualStudio.getWindows10SDKVersion(), null); expect(visualStudio.getWindows10SDKVersion(), null);
}); });
}); });
group(VswhereDetails, () {
test('Accepts empty JSON', () {
const bool meetsRequirements = true;
final Map<String, dynamic> json = <String, dynamic>{};
final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json);
expect(result.installationPath, null);
expect(result.displayName, null);
expect(result.fullVersion, null);
expect(result.isComplete, null);
expect(result.isLaunchable, null);
expect(result.isRebootRequired, null);
expect(result.isPrerelease, null);
expect(result.catalogDisplayVersion, null);
expect(result.isUsable, isTrue);
});
test('Ignores unknown JSON properties', () {
const bool meetsRequirements = true;
final Map<String, dynamic> json = <String, dynamic>{
'hello': 'world',
};
final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json);
expect(result.installationPath, null);
expect(result.displayName, null);
expect(result.fullVersion, null);
expect(result.isComplete, null);
expect(result.isLaunchable, null);
expect(result.isRebootRequired, null);
expect(result.isPrerelease, null);
expect(result.catalogDisplayVersion, null);
expect(result.isUsable, isTrue);
});
test('Accepts JSON', () {
const bool meetsRequirements = true;
final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, _defaultResponse);
expect(result.installationPath, visualStudioPath);
expect(result.displayName, 'Visual Studio Community 2019');
expect(result.fullVersion, '16.2.29306.81');
expect(result.isComplete, true);
expect(result.isLaunchable, true);
expect(result.isRebootRequired, false);
expect(result.isPrerelease, false);
expect(result.catalogDisplayVersion, '16.2.5');
expect(result.isUsable, isTrue);
});
test('Installation that does not satisfy requirements is not usable', () {
const bool meetsRequirements = false;
final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, _defaultResponse);
expect(result.isUsable, isFalse);
});
test('Incomplete installation is not usable', () {
const bool meetsRequirements = true;
final Map<String, dynamic> json = Map<String, dynamic>.of(_defaultResponse)
..['isComplete'] = false;
final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json);
expect(result.isUsable, isFalse);
});
test('Unlaunchable installation is not usable', () {
const bool meetsRequirements = true;
final Map<String, dynamic> json = Map<String, dynamic>.of(_defaultResponse)
..['isLaunchable'] = false;
final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json);
expect(result.isUsable, isFalse);
});
test('Installation that requires reboot is not usable', () {
const bool meetsRequirements = true;
final Map<String, dynamic> json = Map<String, dynamic>.of(_defaultResponse)
..['isRebootRequired'] = true;
final VswhereDetails result = VswhereDetails.fromJson(meetsRequirements, json);
expect(result.isUsable, isFalse);
});
});
} }
class VisualStudioFixture { class VisualStudioFixture {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment