| // 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. |
| |
| // @dart = 2.8 |
| |
| import 'package:file/memory.dart'; |
| import 'package:flutter_tools/src/base/file_system.dart'; |
| import 'package:flutter_tools/src/base/logger.dart'; |
| import 'package:flutter_tools/src/build_info.dart'; |
| import 'package:flutter_tools/src/build_system/build_system.dart'; |
| import 'package:flutter_tools/src/build_system/targets/dart_plugin_registrant.dart'; |
| import 'package:flutter_tools/src/project.dart'; |
| |
| import '../../../src/common.dart'; |
| import '../../../src/context.dart'; |
| |
| const String _kEmptyPubspecFile = ''' |
| name: path_provider_example |
| |
| dependencies: |
| flutter: |
| sdk: flutter |
| '''; |
| |
| const String _kEmptyPackageJson = ''' |
| { |
| "configVersion": 2, |
| "packages": [ |
| { |
| "name": "path_provider_example", |
| "rootUri": "../", |
| "packageUri": "lib/", |
| "languageVersion": "2.12" |
| } |
| ] |
| } |
| '''; |
| |
| const String _kSamplePackageJson = ''' |
| { |
| "configVersion": 2, |
| "packages": [ |
| { |
| "name": "path_provider_linux", |
| "rootUri": "/path_provider_linux", |
| "packageUri": "lib/", |
| "languageVersion": "2.12" |
| }, |
| { |
| "name": "path_provider_example", |
| "rootUri": "../", |
| "packageUri": "lib/", |
| "languageVersion": "2.12" |
| } |
| ] |
| } |
| '''; |
| |
| const String _kSamplePackagesFile = ''' |
| path_provider_linux:/path_provider_linux/lib/ |
| path_provider_example:lib/ |
| '''; |
| |
| const String _kSamplePubspecFile = ''' |
| name: path_provider_example |
| description: Demonstrates how to use the path_provider plugin. |
| |
| dependencies: |
| flutter: |
| sdk: flutter |
| path_provider_linux: 1.0.0 |
| '''; |
| |
| const String _kSamplePluginPubspec = ''' |
| name: path_provider_linux |
| description: linux implementation of the path_provider plugin |
| // version: 2.0.1 |
| // homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider_linux |
| |
| flutter: |
| plugin: |
| implements: path_provider |
| platforms: |
| linux: |
| dartPluginClass: PathProviderLinux |
| pluginClass: none |
| |
| environment: |
| sdk: ">=2.12.0-259.9.beta <3.0.0" |
| flutter: ">=1.20.0" |
| '''; |
| |
| void main() { |
| |
| group('Dart plugin registrant' , () { |
| final FileSystem fileSystem = MemoryFileSystem.test(); |
| |
| testWithoutContext('skipped based on environment.generateDartPluginRegistry', |
| () async { |
| final Environment environment = Environment.test( |
| fileSystem.currentDirectory, |
| artifacts: null, |
| fileSystem: fileSystem, |
| logger: BufferLogger.test(), |
| processManager: FakeProcessManager.any(), |
| generateDartPluginRegistry: false, |
| defines: <String, String>{ |
| kTargetPlatform: 'darwin-x64', |
| }); |
| |
| expect(const DartPluginRegistrantTarget().canSkip(environment), isTrue); |
| |
| final Environment environment2 = Environment.test( |
| fileSystem.currentDirectory, |
| artifacts: null, |
| fileSystem: fileSystem, |
| logger: BufferLogger.test(), |
| processManager: FakeProcessManager.any(), |
| generateDartPluginRegistry: true, |
| defines: <String, String>{ |
| kTargetPlatform: 'darwin-x64', |
| }); |
| |
| expect(const DartPluginRegistrantTarget().canSkip(environment2), isFalse); |
| }); |
| |
| testWithoutContext('skipped based on platform', () async { |
| const Map<String, bool> canSkip = <String, bool>{ |
| 'darwin-x64': false, |
| 'linux-x64': false, |
| 'linux-arm64': false, |
| 'windows-x64': false, |
| 'windows-uwp-x64': false, |
| 'web-javascript': true, |
| 'ios': true, |
| 'android': true, |
| 'fuchsia-arm64': true, |
| 'fuchsia-x64': true, |
| }; |
| |
| for (final String targetPlatform in canSkip.keys) { |
| expect( |
| const DartPluginRegistrantTarget().canSkip( |
| Environment.test( |
| fileSystem.currentDirectory, |
| artifacts: null, |
| fileSystem: fileSystem, |
| logger: BufferLogger.test(), |
| processManager: FakeProcessManager.any(), |
| generateDartPluginRegistry: true, |
| defines: <String, String>{ |
| kTargetPlatform: targetPlatform, |
| }, |
| ), |
| ), |
| canSkip[targetPlatform], |
| ); |
| } |
| }); |
| |
| testUsingContext("doesn't generate generated_main.dart if there aren't Dart plugins", () async { |
| final Directory projectDir = fileSystem.directory('project')..createSync(); |
| final Environment environment = Environment.test( |
| fileSystem.currentDirectory, |
| projectDir: projectDir, |
| artifacts: null, |
| fileSystem: fileSystem, |
| logger: BufferLogger.test(), |
| processManager: FakeProcessManager.any(), |
| defines: <String, String>{ |
| kTargetFile: projectDir.childDirectory('lib').childFile('main.dart').absolute.path, |
| }, |
| generateDartPluginRegistry: true); |
| |
| projectDir |
| .childDirectory('.dart_tool') |
| .childFile('package_config.json') |
| ..createSync(recursive: true) |
| ..writeAsStringSync(_kSamplePackageJson); |
| |
| projectDir.childFile('pubspec.yaml').createSync(); |
| |
| projectDir.childFile('.packages').createSync(); |
| |
| final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir); |
| await DartPluginRegistrantTarget.test(testProject).build(environment); |
| |
| final File generatedMain = projectDir |
| .childDirectory('.dart_tool') |
| .childDirectory('flutter_build') |
| .childFile('generated_main.dart'); |
| expect(generatedMain.existsSync(), isFalse); |
| }); |
| |
| testUsingContext('regenerates generated_main.dart', () async { |
| final Directory projectDir = fileSystem.directory('project')..createSync(); |
| final Environment environment = Environment.test( |
| fileSystem.currentDirectory, |
| projectDir: projectDir, |
| artifacts: null, |
| fileSystem: fileSystem, |
| logger: BufferLogger.test(), |
| processManager: FakeProcessManager.any(), |
| defines: <String, String>{ |
| kTargetFile: projectDir.childDirectory('lib').childFile('main.dart').absolute.path, |
| }, |
| generateDartPluginRegistry: true); |
| |
| projectDir |
| .childDirectory('.dart_tool') |
| .childFile('package_config.json') |
| ..createSync(recursive: true) |
| ..writeAsStringSync(_kSamplePackageJson); |
| |
| projectDir.childFile('pubspec.yaml').writeAsStringSync(_kSamplePubspecFile); |
| |
| projectDir.childFile('.packages').writeAsStringSync(_kSamplePackagesFile); |
| |
| projectDir.childDirectory('lib').childFile('main.dart').createSync(recursive: true); |
| |
| environment.fileSystem.currentDirectory |
| .childDirectory('path_provider_linux') |
| .childFile('pubspec.yaml') |
| ..createSync(recursive: true) |
| ..writeAsStringSync(_kSamplePluginPubspec); |
| |
| final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir); |
| await DartPluginRegistrantTarget.test(testProject).build(environment); |
| |
| final File generatedMain = projectDir |
| .childDirectory('.dart_tool') |
| .childDirectory('flutter_build') |
| .childFile('generated_main.dart'); |
| final String mainContent = generatedMain.readAsStringSync(); |
| expect( |
| mainContent, |
| equals( |
| '//\n' |
| '// Generated file. Do not edit.\n' |
| '// This file is generated from template in file `flutter_tools/lib/src/flutter_plugins.dart`.\n' |
| '//\n' |
| '\n' |
| '// @dart = 2.12\n' |
| '\n' |
| "import 'package:path_provider_example/main.dart' as entrypoint;\n" |
| "import 'dart:io'; // flutter_ignore: dart_io_import.\n" |
| "import 'package:path_provider_linux/path_provider_linux.dart';\n" |
| '\n' |
| "@pragma('vm:entry-point')\n" |
| 'class _PluginRegistrant {\n' |
| '\n' |
| " @pragma('vm:entry-point')\n" |
| ' static void register() {\n' |
| ' if (Platform.isLinux) {\n' |
| ' try {\n' |
| ' PathProviderLinux.registerWith();\n' |
| ' } catch (err) {\n' |
| ' print(\n' |
| " '`path_provider_linux` threw an error: \$err. '\n" |
| " 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n" |
| ' );\n' |
| ' rethrow;\n' |
| ' }\n' |
| '\n' |
| ' } else if (Platform.isMacOS) {\n' |
| ' } else if (Platform.isWindows) {\n' |
| ' }\n' |
| ' }\n' |
| '\n' |
| '}\n' |
| '\n' |
| 'typedef _UnaryFunction = dynamic Function(List<String> args);\n' |
| 'typedef _NullaryFunction = dynamic Function();\n' |
| '\n' |
| 'void main(List<String> args) {\n' |
| ' if (entrypoint.main is _UnaryFunction) {\n' |
| ' (entrypoint.main as _UnaryFunction)(args);\n' |
| ' } else {\n' |
| ' (entrypoint.main as _NullaryFunction)();\n' |
| ' }\n' |
| '}\n' |
| ), |
| ); |
| }); |
| |
| testUsingContext('removes generated_main.dart if plugins are removed from pubspec.yaml', () async { |
| final Directory projectDir = fileSystem.directory('project')..createSync(); |
| final Environment environment = Environment.test( |
| fileSystem.currentDirectory, |
| projectDir: projectDir, |
| artifacts: null, |
| fileSystem: fileSystem, |
| logger: BufferLogger.test(), |
| processManager: FakeProcessManager.any(), |
| defines: <String, String>{ |
| kTargetFile: projectDir.childDirectory('lib').childFile('main.dart').absolute.path, |
| }, |
| generateDartPluginRegistry: true); |
| final File config = projectDir |
| .childDirectory('.dart_tool') |
| .childFile('package_config.json') |
| ..createSync(recursive: true) |
| ..writeAsStringSync(_kSamplePackageJson); |
| |
| final File pubspec = projectDir.childFile('pubspec.yaml')..writeAsStringSync(_kSamplePubspecFile); |
| |
| final File packages = projectDir.childFile('.packages')..writeAsStringSync(_kSamplePackagesFile); |
| |
| environment.fileSystem.currentDirectory |
| .childDirectory('path_provider_linux') |
| .childFile('pubspec.yaml') |
| ..createSync(recursive: true) |
| ..writeAsStringSync(_kSamplePluginPubspec); |
| |
| final File generatedMain = projectDir |
| .childDirectory('.dart_tool') |
| .childDirectory('flutter_build') |
| .childFile('generated_main.dart'); |
| |
| final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir); |
| await DartPluginRegistrantTarget.test(testProject).build(environment); |
| expect(generatedMain.existsSync(), isTrue); |
| |
| // Simulate a user removing everything from pubspec.yaml. |
| pubspec.writeAsStringSync(_kEmptyPubspecFile); |
| packages.writeAsStringSync(_kEmptyPackageJson); |
| config.writeAsStringSync(_kEmptyPackageJson); |
| |
| await DartPluginRegistrantTarget.test(testProject).build(environment); |
| expect(generatedMain.existsSync(), isFalse); |
| }); |
| |
| testUsingContext('target file is outside the current project package', () async { |
| final Directory projectDir = fileSystem.directory('project')..createSync(); |
| final Environment environment = Environment.test( |
| fileSystem.currentDirectory, |
| projectDir: projectDir, |
| artifacts: null, |
| fileSystem: fileSystem, |
| logger: BufferLogger.test(), |
| processManager: FakeProcessManager.any(), |
| defines: <String, String>{ |
| kTargetFile: fileSystem.directory('root').childFile('external.dart').absolute.path, |
| }, |
| generateDartPluginRegistry: true); |
| |
| projectDir |
| .childDirectory('.dart_tool') |
| .childFile('package_config.json') |
| .writeAsStringSync(_kSamplePackageJson); |
| |
| projectDir.childFile('pubspec.yaml').writeAsStringSync(_kSamplePubspecFile); |
| |
| projectDir.childFile('.packages').writeAsStringSync(_kSamplePackagesFile); |
| |
| projectDir.childDirectory('lib').childFile('main.dart').createSync(recursive: true); |
| |
| environment.fileSystem.currentDirectory |
| .childDirectory('path_provider_linux') |
| .childFile('pubspec.yaml') |
| .writeAsStringSync(_kSamplePluginPubspec); |
| |
| final FlutterProject testProject = FlutterProject.fromDirectoryTest(projectDir); |
| await DartPluginRegistrantTarget.test(testProject).build(environment); |
| |
| final File generatedMain = projectDir |
| .childDirectory('.dart_tool') |
| .childDirectory('flutter_build') |
| .childFile('generated_main.dart'); |
| |
| final String mainContent = generatedMain.readAsStringSync(); |
| expect( |
| mainContent, |
| equals( |
| '//\n' |
| '// Generated file. Do not edit.\n' |
| '// This file is generated from template in file `flutter_tools/lib/src/flutter_plugins.dart`.\n' |
| '//\n' |
| '\n' |
| '// @dart = 2.12\n' |
| '\n' |
| "import 'file:///root/external.dart' as entrypoint;\n" |
| "import 'dart:io'; // flutter_ignore: dart_io_import.\n" |
| "import 'package:path_provider_linux/path_provider_linux.dart';\n" |
| '\n' |
| "@pragma('vm:entry-point')\n" |
| 'class _PluginRegistrant {\n' |
| '\n' |
| " @pragma('vm:entry-point')\n" |
| ' static void register() {\n' |
| ' if (Platform.isLinux) {\n' |
| ' try {\n' |
| ' PathProviderLinux.registerWith();\n' |
| ' } catch (err) {\n' |
| ' print(\n' |
| " '`path_provider_linux` threw an error: \$err. '\n" |
| " 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n" |
| ' );\n' |
| ' rethrow;\n' |
| ' }\n' |
| '\n' |
| ' } else if (Platform.isMacOS) {\n' |
| ' } else if (Platform.isWindows) {\n' |
| ' }\n' |
| ' }\n' |
| '\n' |
| '}\n' |
| '\n' |
| 'typedef _UnaryFunction = dynamic Function(List<String> args);\n' |
| 'typedef _NullaryFunction = dynamic Function();\n' |
| '\n' |
| 'void main(List<String> args) {\n' |
| ' if (entrypoint.main is _UnaryFunction) {\n' |
| ' (entrypoint.main as _UnaryFunction)(args);\n' |
| ' } else {\n' |
| ' (entrypoint.main as _NullaryFunction)();\n' |
| ' }\n' |
| '}\n' |
| ), |
| ); |
| }); |
| }); |
| } |