// 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 'dart:convert'; 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/doctor_validator.dart'; import 'package:flutter_tools/src/intellij/intellij.dart'; import '../../src/common.dart'; void main() { late FileSystem fileSystem; void writeFileCreatingDirectories(String path, List<int> bytes) { final File file = fileSystem.file(path); file.parent.createSync(recursive: true); file.writeAsBytesSync(bytes); } setUp(() { fileSystem = MemoryFileSystem.test(); }); testWithoutContext('IntelliJPlugins found', () async { final IntelliJPlugins plugins = IntelliJPlugins(_kPluginsPath, fileSystem: fileSystem); final Archive dartJarArchive = buildSingleFileArchive('META-INF/plugin.xml', r''' <idea-plugin version="2"> <name>Dart</name> <version>162.2485</version> </idea-plugin> '''); writeFileCreatingDirectories( fileSystem.path.join(_kPluginsPath, 'Dart', 'lib', 'Dart.jar'), ZipEncoder().encode(dartJarArchive)!, ); final Archive flutterJarArchive = buildSingleFileArchive('META-INF/plugin.xml', r''' <idea-plugin version="2"> <name>Flutter</name> <version>0.1.3</version> </idea-plugin> '''); writeFileCreatingDirectories( fileSystem.path.join(_kPluginsPath, 'flutter-intellij.jar'), ZipEncoder().encode(flutterJarArchive)!, ); final List<ValidationMessage> messages = <ValidationMessage>[]; plugins.validatePackage(messages, <String>['Dart'], 'Dart', 'download-Dart'); plugins.validatePackage(messages, <String>['flutter-intellij', 'flutter-intellij.jar'], 'Flutter', 'download-Flutter', minVersion: IntelliJPlugins.kMinFlutterPluginVersion, ); ValidationMessage message = messages .firstWhere((ValidationMessage m) => m.message.startsWith('Dart ')); expect(message.message, 'Dart plugin version 162.2485'); message = messages.firstWhere( (ValidationMessage m) => m.message.startsWith('Flutter ')); expect(message.message, contains('Flutter plugin version 0.1.3')); expect(message.message, contains('recommended minimum version')); }); testWithoutContext('IntelliJPlugins can read the package version of the flutter-intellij 50.0+/IntelliJ 2020.2+ layout', () async { final IntelliJPlugins plugins = IntelliJPlugins(_kPluginsPath, fileSystem: fileSystem); final Archive flutterIdeaJarArchive = buildSingleFileArchive('META-INF/plugin.xml', r''' <idea-plugin version="2"> <name>Flutter</name> <version>50.0</version> </idea-plugin> '''); writeFileCreatingDirectories( fileSystem.path.join(_kPluginsPath, 'flutter-intellij', 'lib', 'flutter-idea-50.0.jar'), ZipEncoder().encode(flutterIdeaJarArchive)!, ); final Archive flutterIntellijJarArchive = buildSingleFileArchive('META-INF/MANIFEST.MF', r''' Manifest-Version: 1.0 '''); writeFileCreatingDirectories( fileSystem.path.join(_kPluginsPath, 'flutter-intellij', 'lib', 'flutter-intellij-50.0.jar'), ZipEncoder().encode(flutterIntellijJarArchive)!, ); final List<ValidationMessage> messages = <ValidationMessage>[]; plugins.validatePackage(messages, <String>[ 'flutter-intellij', 'flutter-intellij.jar', ], 'Flutter', 'download-Flutter', minVersion: IntelliJPlugins.kMinFlutterPluginVersion, ); final ValidationMessage message = messages.firstWhere( (ValidationMessage m) => m.message.startsWith('Flutter ')); expect(message.message, contains('Flutter plugin version 50.0')); }); testWithoutContext('IntelliJPlugins can read the package version of the flutter-intellij 50.0+/IntelliJ 2020.2+ layout(priority is given to packages with the same prefix as packageName)', () async { final IntelliJPlugins plugins = IntelliJPlugins(_kPluginsPath, fileSystem: fileSystem); final Archive flutterIdeaJarArchive = buildSingleFileArchive('META-INF/plugin.xml', r''' <idea-plugin version="2"> <name>Flutter</name> <version>50.0</version> </idea-plugin> '''); writeFileCreatingDirectories( fileSystem.path.join(_kPluginsPath, 'flutter-intellij', 'lib', 'flutter-idea-50.0.jar'), ZipEncoder().encode(flutterIdeaJarArchive)!, ); final Archive flutterIntellijJarArchive = buildSingleFileArchive('META-INF/plugin.xml', r''' <idea-plugin version="2"> <name>Flutter</name> <version>51.0</version> </idea-plugin> '''); writeFileCreatingDirectories( fileSystem.path.join(_kPluginsPath, 'flutter-intellij', 'lib', 'flutter-intellij-50.0.jar'), ZipEncoder().encode(flutterIntellijJarArchive)!, ); final List<ValidationMessage> messages = <ValidationMessage>[]; plugins.validatePackage(messages, <String>[ 'flutter-intellij', 'flutter-intellij.jar', ], 'Flutter', 'download-Flutter', minVersion: IntelliJPlugins.kMinFlutterPluginVersion, ); final ValidationMessage message = messages.firstWhere( (ValidationMessage m) => m.message.startsWith('Flutter ')); expect(message.message, contains('Flutter plugin version 51.0')); }); testWithoutContext('IntelliJPlugins not found displays a link to their download site', () async { final IntelliJPlugins plugins = IntelliJPlugins(_kPluginsPath, fileSystem: fileSystem); final List<ValidationMessage> messages = <ValidationMessage>[]; plugins.validatePackage(messages, <String>['Dart'], 'Dart', 'download-Dart'); plugins.validatePackage(messages, <String>['flutter-intellij', 'flutter-intellij.jar'], 'Flutter', 'download-Flutter', minVersion: IntelliJPlugins.kMinFlutterPluginVersion, ); ValidationMessage message = messages .firstWhere((ValidationMessage m) => m.message.startsWith('Dart ')); expect(message.message, contains('Dart plugin can be installed from')); expect(message.contextUrl, isNotNull); message = messages.firstWhere( (ValidationMessage m) => m.message.startsWith('Flutter ')); expect(message.message, contains('Flutter plugin can be installed from')); expect(message.contextUrl, isNotNull); }); testWithoutContext('IntelliJPlugins does not crash if no plugin file found', () async { final IntelliJPlugins plugins = IntelliJPlugins(_kPluginsPath, fileSystem: fileSystem); final Archive dartJarArchive = buildSingleFileArchive('META-INF/MANIFEST.MF', r''' Manifest-Version: 1.0 '''); writeFileCreatingDirectories( fileSystem.path.join(_kPluginsPath, 'Dart', 'lib', 'Other.jar'), ZipEncoder().encode(dartJarArchive)!, ); expect( () => plugins.validatePackage(<ValidationMessage>[], <String>['Dart'], 'Dart', 'download-Dart'), returnsNormally, ); }); } const String _kPluginsPath = '/data/intellij/plugins'; Archive buildSingleFileArchive(String path, String content) { final Archive archive = Archive(); final List<int> bytes = utf8.encode(content); archive.addFile(ArchiveFile(path, bytes.length, bytes)); return archive; }