| // 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:archive/archive.dart'; |
| import 'package:file/file.dart'; |
| 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/base/user_messages.dart'; |
| import 'package:flutter_tools/src/convert.dart'; |
| import 'package:flutter_tools/src/doctor.dart'; |
| import 'package:flutter_tools/src/intellij/intellij_validator.dart'; |
| import 'package:flutter_tools/src/ios/plist_parser.dart'; |
| import 'package:test/fake.dart'; |
| |
| import '../../src/common.dart'; |
| |
| final Platform macPlatform = FakePlatform( |
| operatingSystem: 'macos', |
| environment: <String, String>{'HOME': '/foo/bar'} |
| ); |
| final Platform linuxPlatform = FakePlatform( |
| operatingSystem: 'linux', |
| environment: <String, String>{ |
| 'HOME': '/foo/bar' |
| }, |
| ); |
| final Platform windowsPlatform = FakePlatform( |
| operatingSystem: 'windows', |
| environment: <String, String>{ |
| 'USERPROFILE': 'C:\\Users\\foo', |
| 'APPDATA': 'C:\\Users\\foo\\AppData\\Roaming', |
| 'LOCALAPPDATA': 'C:\\Users\\foo\\AppData\\Local' |
| }, |
| ); |
| |
| void main() { |
| testWithoutContext('Intellij validator can parse plugin manifest from plugin JAR', () async { |
| final FileSystem fileSystem = MemoryFileSystem.test(); |
| // Create plugin JAR file for Flutter and Dart plugin. |
| createIntellijFlutterPluginJar('plugins/flutter-intellij.jar', fileSystem); |
| createIntellijDartPluginJar('plugins/Dart/lib/Dart.jar', fileSystem); |
| |
| final ValidationResult result = await IntelliJValidatorTestTarget('', 'path/to/intellij', fileSystem).validate(); |
| expect(result.type, ValidationType.partial); |
| expect(result.statusInfo, 'version test.test.test'); |
| expect(result.messages, const <ValidationMessage>[ |
| ValidationMessage('IntelliJ at path/to/intellij'), |
| ValidationMessage.error('Flutter plugin version 0.1.3 - the recommended minimum version is 16.0.0'), |
| ValidationMessage('Dart plugin version 162.2485'), |
| ValidationMessage('For information about installing plugins, see\n' |
| 'https://flutter.dev/intellij-setup/#installing-the-plugins') |
| ]); |
| }); |
| |
| testWithoutContext('legacy intellij(<2020) plugins check on linux', () async { |
| const String cachePath = '/foo/bar/.IntelliJIdea2019.10/system'; |
| const String installPath = '/foo/bar/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-1/2019.10.1'; |
| const String pluginPath = '/foo/bar/.IntelliJIdea2019.10/config/plugins'; |
| final FileSystem fileSystem = MemoryFileSystem.test(); |
| |
| final Directory cacheDirectory = fileSystem.directory(cachePath) |
| ..createSync(recursive: true); |
| cacheDirectory |
| .childFile('.home') |
| .writeAsStringSync(installPath, flush: true); |
| final Directory installedDirectory = fileSystem.directory(installPath); |
| installedDirectory.createSync(recursive: true); |
| // Create plugin JAR file for Flutter and Dart plugin. |
| createIntellijFlutterPluginJar(pluginPath + '/flutter-intellij/lib/flutter-intellij.jar', fileSystem, version: '50.0'); |
| createIntellijDartPluginJar(pluginPath + '/Dart/lib/Dart.jar', fileSystem); |
| |
| final Iterable<DoctorValidator> installed = IntelliJValidatorOnLinux.installed( |
| fileSystem: fileSystem, |
| fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: linuxPlatform), |
| userMessages: UserMessages(), |
| ); |
| expect(1, installed.length); |
| final ValidationResult result = await installed.toList()[0].validate(); |
| expect(ValidationType.installed, result.type); |
| }); |
| |
| testWithoutContext('intellij(2020.1) plugins check on linux (installed via JetBrains ToolBox app)', () async { |
| const String cachePath = '/foo/bar/.cache/JetBrains/IntelliJIdea2020.10'; |
| const String installPath = '/foo/bar/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-1/2020.10.1'; |
| const String pluginPath = '/foo/bar/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-1/2020.10.1.plugins'; |
| final FileSystem fileSystem = MemoryFileSystem.test(); |
| |
| final Directory cacheDirectory = fileSystem.directory(cachePath) |
| ..createSync(recursive: true); |
| cacheDirectory |
| .childFile('.home') |
| .writeAsStringSync(installPath, flush: true); |
| final Directory installedDirectory = fileSystem.directory(installPath); |
| installedDirectory.createSync(recursive: true); |
| // Create plugin JAR file for Flutter and Dart plugin. |
| createIntellijFlutterPluginJar(pluginPath + '/flutter-intellij/lib/flutter-intellij.jar', fileSystem, version: '50.0'); |
| createIntellijDartPluginJar(pluginPath + '/Dart/lib/Dart.jar', fileSystem); |
| |
| final Iterable<DoctorValidator> installed = IntelliJValidatorOnLinux.installed( |
| fileSystem: fileSystem, |
| fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: linuxPlatform), |
| userMessages: UserMessages(), |
| ); |
| expect(1, installed.length); |
| final ValidationResult result = await installed.toList()[0].validate(); |
| expect(ValidationType.installed, result.type); |
| }); |
| |
| testWithoutContext('intellij(>=2020.2) plugins check on linux (installed via JetBrains ToolBox app)', () async { |
| const String cachePath = '/foo/bar/.cache/JetBrains/IntelliJIdea2020.10'; |
| const String installPath = '/foo/bar/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-1/2020.10.1'; |
| const String pluginPath = '/foo/bar/.local/share/JetBrains/IntelliJIdea2020.10'; |
| final FileSystem fileSystem = MemoryFileSystem.test(); |
| |
| final Directory cacheDirectory = fileSystem.directory(cachePath) |
| ..createSync(recursive: true); |
| cacheDirectory |
| .childFile('.home') |
| .writeAsStringSync(installPath, flush: true); |
| final Directory installedDirectory = fileSystem.directory(installPath); |
| installedDirectory.createSync(recursive: true); |
| // Create plugin JAR file for Flutter and Dart plugin. |
| createIntellijFlutterPluginJar(pluginPath + '/flutter-intellij/lib/flutter-intellij.jar', fileSystem, version: '50.0'); |
| createIntellijDartPluginJar(pluginPath + '/Dart/lib/Dart.jar', fileSystem); |
| |
| final Iterable<DoctorValidator> installed = IntelliJValidatorOnLinux.installed( |
| fileSystem: fileSystem, |
| fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: linuxPlatform), |
| userMessages: UserMessages(), |
| ); |
| expect(1, installed.length); |
| final ValidationResult result = await installed.toList()[0].validate(); |
| expect(ValidationType.installed, result.type); |
| }); |
| |
| testWithoutContext('intellij(2020.1~) plugins check on linux (installed via tar.gz)', () async { |
| const String cachePath = '/foo/bar/.cache/JetBrains/IdeaIC2020.10'; |
| const String installPath = '/foo/bar/some/dir/ideaIC-2020.10.1/idea-IC-201.0000.00'; |
| const String pluginPath = '/foo/bar/.local/share/JetBrains/IdeaIC2020.10'; |
| final FileSystem fileSystem = MemoryFileSystem.test(); |
| |
| final Directory cacheDirectory = fileSystem.directory(cachePath) |
| ..createSync(recursive: true); |
| cacheDirectory |
| .childFile('.home') |
| .writeAsStringSync(installPath, flush: true); |
| final Directory installedDirectory = fileSystem.directory(installPath); |
| installedDirectory.createSync(recursive: true); |
| // Create plugin JAR file for Flutter and Dart plugin. |
| createIntellijFlutterPluginJar(pluginPath + '/flutter-intellij/lib/flutter-intellij.jar', fileSystem, version: '50.0'); |
| createIntellijDartPluginJar(pluginPath + '/Dart/lib/Dart.jar', fileSystem); |
| |
| final Iterable<DoctorValidator> installed = IntelliJValidatorOnLinux.installed( |
| fileSystem: fileSystem, |
| fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: linuxPlatform), |
| userMessages: UserMessages(), |
| ); |
| expect(1, installed.length); |
| final ValidationResult result = await installed.toList()[0].validate(); |
| expect(ValidationType.installed, result.type); |
| }); |
| |
| testWithoutContext('legacy intellij(<2020) plugins check on windows', () async { |
| const String cachePath = 'C:\\Users\\foo\\.IntelliJIdea2019.10\\system'; |
| const String installPath = 'C:\\Program Files\\JetBrains\\IntelliJ IDEA Ultimate Edition 2019.10.1'; |
| const String pluginPath = 'C:\\Users\\foo\\.IntelliJIdea2019.10\\config\\plugins'; |
| final FileSystem fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows); |
| |
| final Directory cacheDirectory = fileSystem.directory(cachePath) |
| ..createSync(recursive: true); |
| cacheDirectory |
| .childFile('.home') |
| .writeAsStringSync(installPath, flush: true); |
| final Directory installedDirectory = fileSystem.directory(installPath); |
| installedDirectory.createSync(recursive: true); |
| createIntellijFlutterPluginJar(pluginPath + '/flutter-intellij/lib/flutter-intellij.jar', fileSystem, version: '50.0'); |
| createIntellijDartPluginJar(pluginPath + '/Dart/lib/Dart.jar', fileSystem); |
| |
| final Iterable<DoctorValidator> installed = IntelliJValidatorOnWindows.installed( |
| fileSystem: fileSystem, |
| fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: windowsPlatform), |
| platform: windowsPlatform, |
| userMessages: UserMessages(), |
| ); |
| expect(1, installed.length); |
| final ValidationResult result = await installed.toList()[0].validate(); |
| expect(ValidationType.installed, result.type); |
| }); |
| |
| testWithoutContext('intellij(2020.1 ~ 2020.2) plugins check on windows (installed via JetBrains ToolBox app)', () async { |
| const String cachePath = 'C:\\Users\\foo\\AppData\\Local\\JetBrains\\IntelliJIdea2020.10'; |
| const String installPath = 'C:\\Users\\foo\\AppData\\Local\\JetBrains\\Toolbox\\apps\\IDEA-U\\ch-0\\201.0000.00'; |
| const String pluginPath = 'C:\\Users\\foo\\AppData\\Roaming\\JetBrains\\IntelliJIdea2020.10\\plugins'; |
| final FileSystem fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows); |
| |
| final Directory cacheDirectory = fileSystem.directory(cachePath) |
| ..createSync(recursive: true); |
| cacheDirectory |
| .childFile('.home') |
| .writeAsStringSync(installPath, flush: true); |
| final Directory installedDirectory = fileSystem.directory(installPath); |
| installedDirectory.createSync(recursive: true); |
| createIntellijFlutterPluginJar(pluginPath + '\\flutter-intellij\\lib\\flutter-intellij.jar', fileSystem, version: '50.0'); |
| createIntellijDartPluginJar(pluginPath + '\\Dart\\lib\\Dart.jar', fileSystem); |
| |
| final Iterable<DoctorValidator> installed = IntelliJValidatorOnWindows.installed( |
| fileSystem: fileSystem, |
| fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: windowsPlatform), |
| platform: windowsPlatform, |
| userMessages: UserMessages(), |
| ); |
| expect(1, installed.length); |
| final ValidationResult result = await installed.toList()[0].validate(); |
| expect(ValidationType.installed, result.type); |
| }); |
| |
| testWithoutContext('intellij(>=2020.3) plugins check on windows (installed via JetBrains ToolBox app and plugins)', () async { |
| const String cachePath = 'C:\\Users\\foo\\AppData\\Local\\JetBrains\\IntelliJIdea2020.10'; |
| const String installPath = 'C:\\Users\\foo\\AppData\\Local\\JetBrains\\Toolbox\\apps\\IDEA-U\\ch-0\\201.0000.00'; |
| const String pluginPath = 'C:\\Users\\foo\\AppData\\Local\\JetBrains\\Toolbox\\apps\\IDEA-U\\ch-0\\201.0000.00.plugins'; |
| final FileSystem fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows); |
| |
| final Directory cacheDirectory = fileSystem.directory(cachePath) |
| ..createSync(recursive: true); |
| cacheDirectory |
| .childFile('.home') |
| .writeAsStringSync(installPath, flush: true); |
| final Directory installedDirectory = fileSystem.directory(installPath); |
| installedDirectory.createSync(recursive: true); |
| createIntellijFlutterPluginJar(pluginPath + '\\flutter-intellij\\lib\\flutter-intellij.jar', fileSystem, version: '50.0'); |
| createIntellijDartPluginJar(pluginPath + '\\Dart\\lib\\Dart.jar', fileSystem); |
| |
| final Iterable<DoctorValidator> installed = IntelliJValidatorOnWindows.installed( |
| fileSystem: fileSystem, |
| fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: windowsPlatform), |
| platform: windowsPlatform, |
| userMessages: UserMessages(), |
| ); |
| expect(1, installed.length); |
| final ValidationResult result = await installed.toList()[0].validate(); |
| expect(ValidationType.installed, result.type); |
| }); |
| |
| testWithoutContext('intellij(2020.1~) plugins check on windows (installed via installer)', () async { |
| const String cachePath = 'C:\\Users\\foo\\AppData\\Local\\JetBrains\\IdeaIC2020.10'; |
| const String installPath = 'C:\\Program Files\\JetBrains\\IntelliJ IDEA Community Edition 2020.10.1'; |
| const String pluginPath = 'C:\\Users\\foo\\AppData\\Roaming\\JetBrains\\IdeaIC2020.10\\plugins'; |
| final FileSystem fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows); |
| |
| final Directory cacheDirectory = fileSystem.directory(cachePath) |
| ..createSync(recursive: true); |
| cacheDirectory |
| .childFile('.home') |
| .writeAsStringSync(installPath, flush: true); |
| final Directory installedDirectory = fileSystem.directory(installPath); |
| installedDirectory.createSync(recursive: true); |
| createIntellijFlutterPluginJar(pluginPath + '\\flutter-intellij\\lib\\flutter-intellij.jar', fileSystem, version: '50.0'); |
| createIntellijDartPluginJar(pluginPath + '\\Dart\\lib\\Dart.jar', fileSystem); |
| |
| final Iterable<DoctorValidator> installed = IntelliJValidatorOnWindows.installed( |
| fileSystem: fileSystem, |
| fileSystemUtils: FileSystemUtils(fileSystem: fileSystem, platform: windowsPlatform), |
| platform: windowsPlatform, |
| userMessages: UserMessages(), |
| ); |
| expect(1, installed.length); |
| final ValidationResult result = await installed.toList()[0].validate(); |
| expect(ValidationType.installed, result.type); |
| }); |
| |
| testWithoutContext('Intellij plugins path checking on mac', () async { |
| final FileSystem fileSystem = MemoryFileSystem.test(); |
| final Directory pluginsDirectory = fileSystem.directory('/foo/bar/Library/Application Support/JetBrains/TestID2020.10/plugins') |
| ..createSync(recursive: true); |
| final IntelliJValidatorOnMac validator = IntelliJValidatorOnMac( |
| 'Test', |
| 'TestID', |
| '/path/to/app', |
| fileSystem: fileSystem, |
| homeDirPath: '/foo/bar', |
| userMessages: UserMessages(), |
| plistParser: FakePlistParser(<String, String>{ |
| PlistParser.kCFBundleShortVersionStringKey: '2020.10', |
| }) |
| ); |
| |
| expect(validator.plistFile, '/path/to/app/Contents/Info.plist'); |
| expect(validator.pluginsPath, pluginsDirectory.path); |
| }); |
| |
| testWithoutContext('legacy Intellij plugins path checking on mac', () async { |
| final FileSystem fileSystem = MemoryFileSystem.test(); |
| final IntelliJValidatorOnMac validator = IntelliJValidatorOnMac( |
| 'Test', |
| 'TestID', |
| '/foo', |
| fileSystem: fileSystem, |
| homeDirPath: '/foo/bar', |
| userMessages: UserMessages(), |
| plistParser: FakePlistParser(<String, String>{ |
| PlistParser.kCFBundleShortVersionStringKey: '2020.10', |
| }) |
| ); |
| |
| expect(validator.pluginsPath, '/foo/bar/Library/Application Support/TestID2020.10'); |
| }); |
| |
| testWithoutContext('Intellij plugins path checking on mac with JetBrains toolbox override', () async { |
| final FileSystem fileSystem = MemoryFileSystem.test(); |
| final IntelliJValidatorOnMac validator = IntelliJValidatorOnMac( |
| 'Test', |
| 'TestID', |
| '/foo', |
| fileSystem: fileSystem, |
| homeDirPath: '/foo/bar', |
| userMessages: UserMessages(), |
| plistParser: FakePlistParser(<String, String>{ |
| 'JetBrainsToolboxApp': '/path/to/JetBrainsToolboxApp', |
| }) |
| ); |
| |
| expect(validator.pluginsPath, '/path/to/JetBrainsToolboxApp.plugins'); |
| }); |
| } |
| |
| class FakePlistParser extends Fake implements PlistParser { |
| FakePlistParser(this.values); |
| |
| final Map<String, String> values; |
| |
| @override |
| String getValueFromFile(String plistFilePath, String key) { |
| return values[key]; |
| } |
| } |
| |
| class IntelliJValidatorTestTarget extends IntelliJValidator { |
| IntelliJValidatorTestTarget(String title, String installPath, FileSystem fileSystem) |
| : super(title, installPath, fileSystem: fileSystem, userMessages: UserMessages()); |
| |
| @override |
| String get pluginsPath => 'plugins'; |
| |
| @override |
| String get version => 'test.test.test'; |
| } |
| |
| /// A helper to create a Intellij Flutter plugin jar. |
| /// |
| /// These file contents were derived from the META-INF/plugin.xml from an Intellij Flutter |
| /// plugin installation. |
| /// |
| /// The file is located in a plugin JAR, which can be located by looking at the plugin |
| /// path for the Intellij and Android Studio validators. |
| /// |
| /// If more XML contents are needed, prefer modifying these contents over checking |
| /// in another JAR. |
| void createIntellijFlutterPluginJar(String pluginJarPath, FileSystem fileSystem, {String version = '0.1.3'}) { |
| final String intellijFlutterPluginXml = ''' |
| <idea-plugin version="2"> |
| <id>io.flutter</id> |
| <name>Flutter</name> |
| <description>Support for developing Flutter applications.</description> |
| <vendor url="https://github.com/flutter/flutter-intellij">flutter.io</vendor> |
| |
| <category>Custom Languages</category> |
| |
| <version>$version</version> |
| |
| <idea-version since-build="162.1" until-build="163.*"/> |
| </idea-plugin> |
| '''; |
| |
| final List<int> flutterPluginBytes = utf8.encode(intellijFlutterPluginXml); |
| final Archive flutterPlugins = Archive(); |
| flutterPlugins.addFile(ArchiveFile('META-INF/plugin.xml', flutterPluginBytes.length, flutterPluginBytes)); |
| fileSystem.file(pluginJarPath) |
| ..createSync(recursive: true) |
| ..writeAsBytesSync(ZipEncoder().encode(flutterPlugins)); |
| |
| } |
| |
| /// A helper to create a Intellij Dart plugin jar. |
| /// |
| /// This jar contains META-INF/plugin.xml. |
| /// Its contents were derived from the META-INF/plugin.xml from an Intellij Dart |
| /// plugin installation. |
| /// |
| /// The file is located in a plugin JAR, which can be located by looking at the plugin |
| /// path for the Intellij and Android Studio validators. |
| /// |
| /// If more XML contents are needed, prefer modifying these contents over checking |
| /// in another JAR. |
| void createIntellijDartPluginJar(String pluginJarPath, FileSystem fileSystem) { |
| const String intellijDartPluginXml = r''' |
| <idea-plugin version="2"> |
| <name>Dart</name> |
| <version>162.2485</version> |
| <idea-version since-build="162.1121" until-build="162.*"/> |
| |
| <description>Support for Dart programming language</description> |
| <vendor>JetBrains</vendor> |
| <depends>com.intellij.modules.xml</depends> |
| <depends optional="true" config-file="dartium-debugger-support.xml">JavaScriptDebugger</depends> |
| <depends optional="true" config-file="dart-yaml.xml">org.jetbrains.plugins.yaml</depends> |
| <depends optional="true" config-file="dart-copyright.xml">com.intellij.copyright</depends> |
| <depends optional="true" config-file="dart-coverage.xml">com.intellij.modules.coverage</depends> |
| </idea-plugin> |
| '''; |
| |
| final List<int> dartPluginBytes = utf8.encode(intellijDartPluginXml); |
| final Archive dartPlugins = Archive(); |
| dartPlugins.addFile(ArchiveFile('META-INF/plugin.xml', dartPluginBytes.length, dartPluginBytes)); |
| fileSystem.file(pluginJarPath) |
| ..createSync(recursive: true) |
| ..writeAsBytesSync(ZipEncoder().encode(dartPlugins)); |
| } |