flutter/packages/flutter_tools/test/general.shard/vscode/vscode_test.dart
Byoungchan Lee ffcc383848
[flutter_tools] Fix VS Code package.json path on macOS with case-sensitive file system (#163409)
This PR corrects the path to VS Code's `package.json` in `flutter
doctor` for macOS with a case-sensitive file system. The correct
directory name is `Resources`, but the existing code incorrectly uses
`resources`.

On a case-insensitive file system (the macOS default), this issue does
not appear. However, on a case-sensitive file system, `flutter doctor`
fails to detect the VS Code version correctly.

Fixes #163408.

<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->

*Replace this paragraph with a description of what this PR is changing
or adding, and why. Consider including before/after screenshots.*

*List which issues are fixed by this PR. You must list at least one
issue. An issue is not required if the PR fixes something trivial like a
typo.*

*If you had to change anything in the [flutter/tests] repo, include a
link to the migration guide as per the [breaking change policy].*

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2025-03-28 16:35:15 +00:00

183 lines
6.1 KiB
Dart

// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/vscode/vscode.dart';
import '../../src/common.dart';
import '../../src/fake_process_manager.dart';
void main() {
testWithoutContext('VsCodeInstallLocation equality', () {
const VsCodeInstallLocation installLocation1 = VsCodeInstallLocation(
'abc',
'zyx',
edition: '123',
);
const VsCodeInstallLocation installLocation2 = VsCodeInstallLocation(
'abc',
'zyx',
edition: '123',
);
const VsCodeInstallLocation installLocation3 = VsCodeInstallLocation(
'cba',
'zyx',
edition: '123',
);
const VsCodeInstallLocation installLocation4 = VsCodeInstallLocation(
'abc',
'xyz',
edition: '123',
);
const VsCodeInstallLocation installLocation5 = VsCodeInstallLocation(
'abc',
'xyz',
edition: '321',
);
expect(installLocation1, installLocation2);
expect(installLocation1.hashCode, installLocation2.hashCode);
expect(installLocation1, isNot(installLocation3));
expect(installLocation1.hashCode, isNot(installLocation3.hashCode));
expect(installLocation1, isNot(installLocation4));
expect(installLocation1.hashCode, isNot(installLocation4.hashCode));
expect(installLocation1, isNot(installLocation5));
expect(installLocation1.hashCode, isNot(installLocation5.hashCode));
});
testWithoutContext('VsCode.fromDirectory does not crash when packages.json is malformed', () {
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
// Create invalid JSON file.
fileSystem.file(fileSystem.path.join('', 'Resources', 'app', 'package.json'))
..createSync(recursive: true)
..writeAsStringSync('{');
final VsCode vsCode = VsCode.fromDirectory('', '', fileSystem: fileSystem);
expect(vsCode.version, null);
});
testWithoutContext('can locate VS Code installed via Snap', () {
final FileSystem fileSystem = MemoryFileSystem.test();
const String home = '/home/me';
final Platform platform = FakePlatform(environment: <String, String>{'HOME': home});
fileSystem
.directory(fileSystem.path.join('/snap/code/current/usr/share/code', '.vscode'))
.createSync(recursive: true);
fileSystem
.directory(
fileSystem.path.join(
'/snap/code-insiders/current/usr/share/code-insiders',
'.vscode-insiders',
),
)
.createSync(recursive: true);
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[]);
final List<VsCode> installed = VsCode.allInstalled(fileSystem, platform, processManager);
expect(installed.length, 2);
});
testWithoutContext('can locate VS Code installed via Flatpak', () {
final FileSystem fileSystem = MemoryFileSystem.test();
const String home = '/home/me';
final Platform platform = FakePlatform(environment: <String, String>{'HOME': home});
fileSystem
.directory(
fileSystem.path.join(
'/var/lib/flatpak/app/com.visualstudio.code/x86_64/stable/active/files/extra/vscode',
'.var/app/com.visualstudio.code/data/vscode',
),
)
.createSync(recursive: true);
fileSystem
.directory(
fileSystem.path.join(
'/var/lib/flatpak/app/com.visualstudio.code.insiders/x86_64/beta/active/files/extra/vscode-insiders',
'.var/app/com.visualstudio.code.insiders/data/vscode-insiders',
),
)
.createSync(recursive: true);
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[]);
final List<VsCode> installed = VsCode.allInstalled(fileSystem, platform, processManager);
expect(installed.length, 2);
});
testWithoutContext('can locate installations on macOS', () {
final FileSystem fileSystem = MemoryFileSystem.test();
const String home = '/home/me';
final Platform platform = FakePlatform(
operatingSystem: 'macos',
environment: <String, String>{'HOME': home},
);
final String randomLocation = fileSystem.path.join('/', 'random', 'Visual Studio Code.app');
fileSystem
.directory(fileSystem.path.join(randomLocation, 'Contents'))
.createSync(recursive: true);
final String randomInsidersLocation = fileSystem.path.join(
'/',
'random',
'Visual Studio Code - Insiders.app',
);
fileSystem
.directory(fileSystem.path.join(randomInsidersLocation, 'Contents'))
.createSync(recursive: true);
fileSystem
.directory(fileSystem.path.join('/', 'Applications', 'Visual Studio Code.app', 'Contents'))
.createSync(recursive: true);
fileSystem
.directory(
fileSystem.path.join(
'/',
'Applications',
'Visual Studio Code - Insiders.app',
'Contents',
),
)
.createSync(recursive: true);
fileSystem
.directory(fileSystem.path.join(home, 'Applications', 'Visual Studio Code.app', 'Contents'))
.createSync(recursive: true);
fileSystem
.directory(
fileSystem.path.join(
home,
'Applications',
'Visual Studio Code - Insiders.app',
'Contents',
),
)
.createSync(recursive: true);
final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(
command: const <String>['mdfind', 'kMDItemCFBundleIdentifier="com.microsoft.VSCode"'],
stdout: randomLocation,
),
FakeCommand(
command: const <String>[
'mdfind',
'kMDItemCFBundleIdentifier="com.microsoft.VSCodeInsiders"',
],
stdout: randomInsidersLocation,
),
]);
final List<VsCode> installed = VsCode.allInstalled(fileSystem, platform, processManager);
expect(installed.length, 6);
expect(processManager, hasNoRemainingExpectations);
});
}