mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

This flag has been enabled by default for quite some time in `master`, and in the current `stable`. This is the first of many PRs to get rid of the flag and the deprecated code it is guarding.
1515 lines
54 KiB
Dart
1515 lines
54 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/file.dart';
|
|
import 'package:file/memory.dart';
|
|
import 'package:flutter_tools/src/dart/package_map.dart';
|
|
import 'package:flutter_tools/src/dart/pub.dart';
|
|
import 'package:flutter_tools/src/flutter_manifest.dart';
|
|
import 'package:flutter_tools/src/flutter_plugins.dart';
|
|
import 'package:flutter_tools/src/globals.dart' as globals;
|
|
import 'package:flutter_tools/src/plugins.dart';
|
|
import 'package:flutter_tools/src/project.dart';
|
|
import 'package:package_config/package_config.dart';
|
|
import 'package:pub_semver/pub_semver.dart';
|
|
import 'package:test/fake.dart';
|
|
import 'package:yaml/yaml.dart';
|
|
|
|
import '../src/common.dart';
|
|
import '../src/context.dart';
|
|
import '../src/package_config.dart';
|
|
import '../src/throwing_pub.dart';
|
|
|
|
void main() {
|
|
group('Dart plugin registrant', () {
|
|
late FileSystem fs;
|
|
late FakeFlutterProject flutterProject;
|
|
late FakeFlutterManifest flutterManifest;
|
|
|
|
setUp(() async {
|
|
fs = MemoryFileSystem.test();
|
|
final Directory directory = fs.currentDirectory.childDirectory('app');
|
|
flutterManifest = FakeFlutterManifest();
|
|
flutterProject =
|
|
FakeFlutterProject()
|
|
..manifest = flutterManifest
|
|
..directory = directory
|
|
..flutterPluginsFile = directory.childFile('.flutter-plugins')
|
|
..flutterPluginsDependenciesFile = directory.childFile('.flutter-plugins-dependencies')
|
|
..dartPluginRegistrant = directory.childFile('dart_plugin_registrant.dart');
|
|
writePackageConfigFiles(directory: flutterProject.directory, mainLibName: 'my_app');
|
|
});
|
|
|
|
group('resolvePlatformImplementation', () {
|
|
testWithoutContext('selects uncontested implementation from direct dependency', () async {
|
|
final Set<String> directDependencies = <String>{'url_launcher_linux', 'url_launcher_macos'};
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_macos',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'macos': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginMacOS'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
|
|
expect(resolutions.length, equals(2));
|
|
expect(
|
|
resolutions[0].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'url_launcher_linux',
|
|
'dartClass': 'UrlLauncherPluginLinux',
|
|
'platform': 'linux',
|
|
'dartFileName': 'url_launcher_linux.dart',
|
|
}),
|
|
);
|
|
expect(
|
|
resolutions[1].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'url_launcher_macos',
|
|
'dartClass': 'UrlLauncherPluginMacOS',
|
|
'platform': 'macos',
|
|
'dartFileName': 'url_launcher_macos.dart',
|
|
}),
|
|
);
|
|
});
|
|
|
|
testWithoutContext(
|
|
'selects uncontested implementation from direct dependency with additional native implementation',
|
|
() async {
|
|
final Set<String> directDependencies = <String>{
|
|
'url_launcher_linux',
|
|
'url_launcher_macos',
|
|
};
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(
|
|
<Plugin>[
|
|
// Following plugin is native only and is not resolved as a dart plugin:
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{
|
|
'package': 'com.example.url_launcher',
|
|
'pluginClass': 'UrlLauncherPluginLinux',
|
|
},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_macos',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'macos': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginMacOS'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
],
|
|
selectDartPluginsOnly: true,
|
|
);
|
|
|
|
expect(resolutions.length, equals(1));
|
|
expect(
|
|
resolutions[0].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'url_launcher_macos',
|
|
'dartClass': 'UrlLauncherPluginMacOS',
|
|
'platform': 'macos',
|
|
'dartFileName': 'url_launcher_macos.dart',
|
|
}),
|
|
);
|
|
},
|
|
);
|
|
|
|
testWithoutContext('selects uncontested implementation from transitive dependency', () async {
|
|
final Set<String> directDependencies = <String>{'url_launcher_macos'};
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher_macos',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'macos': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginMacOS'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'transitive_dependency_plugin',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'windows': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginWindows'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
|
|
expect(resolutions.length, equals(2));
|
|
expect(
|
|
resolutions[0].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'url_launcher_macos',
|
|
'dartClass': 'UrlLauncherPluginMacOS',
|
|
'platform': 'macos',
|
|
'dartFileName': 'url_launcher_macos.dart',
|
|
}),
|
|
);
|
|
expect(
|
|
resolutions[1].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'transitive_dependency_plugin',
|
|
'dartClass': 'UrlLauncherPluginWindows',
|
|
'platform': 'windows',
|
|
'dartFileName': 'transitive_dependency_plugin.dart',
|
|
}),
|
|
);
|
|
});
|
|
|
|
testWithoutContext('selects inline implementation on mobile', () async {
|
|
final Set<String> directDependencies = <String>{};
|
|
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'android': <String, dynamic>{'dartPluginClass': 'UrlLauncherAndroid'},
|
|
'ios': <String, dynamic>{'dartPluginClass': 'UrlLauncherIos'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
expect(resolutions.length, equals(2));
|
|
expect(
|
|
resolutions[0].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'url_launcher',
|
|
'dartClass': 'UrlLauncherAndroid',
|
|
'platform': 'android',
|
|
'dartFileName': 'url_launcher.dart',
|
|
}),
|
|
);
|
|
expect(
|
|
resolutions[1].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'url_launcher',
|
|
'dartClass': 'UrlLauncherIos',
|
|
'platform': 'ios',
|
|
'dartFileName': 'url_launcher.dart',
|
|
}),
|
|
);
|
|
});
|
|
|
|
// See https://github.com/flutter/flutter/issues/87862 for details.
|
|
testWithoutContext('does not select inline implementation on desktop for '
|
|
'missing min Flutter SDK constraint', () async {
|
|
final Set<String> directDependencies = <String>{};
|
|
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherLinux'},
|
|
'macos': <String, dynamic>{'dartPluginClass': 'UrlLauncherMacOS'},
|
|
'windows': <String, dynamic>{'dartPluginClass': 'UrlLauncherWindows'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
expect(resolutions.length, equals(0));
|
|
});
|
|
|
|
// See https://github.com/flutter/flutter/issues/87862 for details.
|
|
testWithoutContext('does not select inline implementation on desktop for '
|
|
'min Flutter SDK constraint < 2.11', () async {
|
|
final Set<String> directDependencies = <String>{};
|
|
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherLinux'},
|
|
'macos': <String, dynamic>{'dartPluginClass': 'UrlLauncherMacOS'},
|
|
'windows': <String, dynamic>{'dartPluginClass': 'UrlLauncherWindows'},
|
|
},
|
|
}),
|
|
VersionConstraint.parse('>=2.10.0'),
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
expect(resolutions.length, equals(0));
|
|
});
|
|
|
|
testWithoutContext('selects inline implementation on desktop for '
|
|
'min Flutter SDK requirement of at least 2.11', () async {
|
|
final Set<String> directDependencies = <String>{};
|
|
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherLinux'},
|
|
'macos': <String, dynamic>{'dartPluginClass': 'UrlLauncherMacOS'},
|
|
'windows': <String, dynamic>{'dartPluginClass': 'UrlLauncherWindows'},
|
|
},
|
|
}),
|
|
VersionConstraint.parse('>=2.11.0'),
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
expect(resolutions.length, equals(3));
|
|
expect(
|
|
resolutions.map((PluginInterfaceResolution resolution) => resolution.toMap()),
|
|
containsAll(<Map<String, String>>[
|
|
<String, String>{
|
|
'pluginName': 'url_launcher',
|
|
'dartClass': 'UrlLauncherLinux',
|
|
'platform': 'linux',
|
|
'dartFileName': 'url_launcher.dart',
|
|
},
|
|
<String, String>{
|
|
'pluginName': 'url_launcher',
|
|
'dartClass': 'UrlLauncherMacOS',
|
|
'platform': 'macos',
|
|
'dartFileName': 'url_launcher.dart',
|
|
},
|
|
<String, String>{
|
|
'pluginName': 'url_launcher',
|
|
'dartClass': 'UrlLauncherWindows',
|
|
'platform': 'windows',
|
|
'dartFileName': 'url_launcher.dart',
|
|
},
|
|
]),
|
|
);
|
|
});
|
|
|
|
testWithoutContext('selects default implementation', () async {
|
|
final Set<String> directDependencies = <String>{};
|
|
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'default_package': 'url_launcher_linux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
// Include three possible implementations, one before and one after
|
|
// to ensure that the selection is working as intended, not just by
|
|
// coincidence of order.
|
|
Plugin.fromYaml(
|
|
'another_url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UnofficialUrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'yet_another_url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UnofficialUrlLauncherPluginLinux2'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
expect(resolutions.length, equals(1));
|
|
expect(
|
|
resolutions[0].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'url_launcher_linux',
|
|
'dartClass': 'UrlLauncherPluginLinux',
|
|
'platform': 'linux',
|
|
'dartFileName': 'url_launcher_linux.dart',
|
|
}),
|
|
);
|
|
});
|
|
|
|
testWithoutContext(
|
|
'selects default implementation if interface is direct dependency',
|
|
() async {
|
|
final Set<String> directDependencies = <String>{'url_launcher'};
|
|
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(
|
|
<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'default_package': 'url_launcher_linux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
],
|
|
selectDartPluginsOnly: true,
|
|
);
|
|
expect(resolutions.length, equals(1));
|
|
expect(
|
|
resolutions[0].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'url_launcher_linux',
|
|
'dartClass': 'UrlLauncherPluginLinux',
|
|
'platform': 'linux',
|
|
'dartFileName': 'url_launcher_linux.dart',
|
|
}),
|
|
);
|
|
},
|
|
);
|
|
|
|
testWithoutContext('user-selected implementation overrides default implementation', () async {
|
|
final Set<String> directDependencies = <String>{
|
|
'user_selected_url_launcher_implementation',
|
|
'url_launcher',
|
|
};
|
|
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'default_package': 'url_launcher_linux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'user_selected_url_launcher_implementation',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
expect(resolutions.length, equals(1));
|
|
expect(
|
|
resolutions[0].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'user_selected_url_launcher_implementation',
|
|
'dartClass': 'UrlLauncherPluginLinux',
|
|
'platform': 'linux',
|
|
'dartFileName': 'user_selected_url_launcher_implementation.dart',
|
|
}),
|
|
);
|
|
});
|
|
|
|
testWithoutContext('user-selected implementation overrides inline implementation', () async {
|
|
final Set<String> directDependencies = <String>{
|
|
'user_selected_url_launcher_implementation',
|
|
'url_launcher',
|
|
};
|
|
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'android': <String, dynamic>{'dartPluginClass': 'UrlLauncherAndroid'},
|
|
'ios': <String, dynamic>{'dartPluginClass': 'UrlLauncherIos'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'user_selected_url_launcher_implementation',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'android': <String, dynamic>{'dartPluginClass': 'UrlLauncherAndroid'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
expect(resolutions.length, equals(2));
|
|
expect(
|
|
resolutions[0].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'user_selected_url_launcher_implementation',
|
|
'dartClass': 'UrlLauncherAndroid',
|
|
'platform': 'android',
|
|
'dartFileName': 'user_selected_url_launcher_implementation.dart',
|
|
}),
|
|
);
|
|
expect(
|
|
resolutions[1].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'url_launcher',
|
|
'dartClass': 'UrlLauncherIos',
|
|
'platform': 'ios',
|
|
'dartFileName': 'url_launcher.dart',
|
|
}),
|
|
);
|
|
});
|
|
|
|
testUsingContext(
|
|
'provides error when a plugin has a default implementation and implements another plugin',
|
|
() async {
|
|
final Set<String> directDependencies = <String>{'url_launcher'};
|
|
expect(() {
|
|
resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'default_package': 'url_launcher_linux_1'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux_1',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'default_package': 'url_launcher_linux_2'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux_2',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
}, throwsToolExit(message: 'Please resolve the plugin pubspec errors'));
|
|
|
|
expect(
|
|
testLogger.errorText,
|
|
'Plugin url_launcher_linux_1:linux provides an implementation for url_launcher '
|
|
'and also references a default implementation for url_launcher_linux_2, which is currently not supported. '
|
|
'Ask the maintainers of url_launcher_linux_1 to either remove the implementation via `implements: url_launcher` '
|
|
'or avoid referencing a default implementation via `platforms: linux: default_package: url_launcher_linux_2`.'
|
|
'\n\n',
|
|
);
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'provides error when a plugin has a default implementation and an inline implementation',
|
|
() async {
|
|
final Set<String> directDependencies = <String>{'url_launcher'};
|
|
expect(() {
|
|
resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{
|
|
'default_package': 'url_launcher_linux',
|
|
'dartPluginClass': 'UrlLauncherPluginLinux',
|
|
},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
}, throwsToolExit(message: 'Please resolve the plugin pubspec errors'));
|
|
|
|
expect(
|
|
testLogger.errorText,
|
|
'Plugin url_launcher:linux which provides an inline implementation '
|
|
'cannot also reference a default implementation for url_launcher_linux. '
|
|
'Ask the maintainers of url_launcher to either remove the implementation via `platforms: linux: dartPluginClass` '
|
|
'or avoid referencing a default implementation via `platforms: linux: default_package: url_launcher_linux`.'
|
|
'\n\n',
|
|
);
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'provides warning when a plugin references a default plugin without implementation',
|
|
() async {
|
|
final Set<String> directDependencies = <String>{'url_launcher'};
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(
|
|
<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'default_package': 'url_launcher_linux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
],
|
|
selectDartPluginsOnly: true,
|
|
);
|
|
|
|
expect(resolutions.length, equals(0));
|
|
expect(
|
|
testLogger.warningText,
|
|
'Package url_launcher:linux references url_launcher_linux:linux as the default plugin, '
|
|
'but it does not provide an inline implementation.\n'
|
|
'Ask the maintainers of url_launcher to either avoid referencing a default implementation via `platforms: linux: default_package: url_launcher_linux` '
|
|
'or add an inline implementation to url_launcher_linux via `platforms: linux:` `pluginClass` or `dartPluginClass`.\n'
|
|
'\n',
|
|
);
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'avoid warning when a plugin references a default plugin with a native implementation only',
|
|
() async {
|
|
final Set<String> directDependencies = <String>{'url_launcher'};
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(
|
|
<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'default_package': 'url_launcher_linux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'pluginClass': 'UrlLauncherLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
],
|
|
selectDartPluginsOnly: true,
|
|
);
|
|
|
|
expect(resolutions.length, equals(0));
|
|
expect(testLogger.warningText, '');
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'selects default Dart implementation without warning, while choosing plugin selection for nativeOrDart',
|
|
() async {
|
|
final Set<String> directDependencies = <String>{'url_launcher'};
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(
|
|
<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'default_package': 'url_launcher_linux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
],
|
|
// Using nativeOrDart plugin selection.
|
|
selectDartPluginsOnly: false,
|
|
);
|
|
expect(resolutions.length, equals(1));
|
|
// Test avoiding trigger a warning for default plugins, while Dart and native plugins selection is enabled.
|
|
expect(testLogger.warningText, '');
|
|
expect(
|
|
resolutions[0].toMap(),
|
|
equals(<String, String>{
|
|
'pluginName': 'url_launcher_linux',
|
|
'dartClass': 'UrlLauncherLinux',
|
|
'platform': 'linux',
|
|
'dartFileName': 'url_launcher_linux.dart',
|
|
}),
|
|
);
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'provides warning when a plugin references a default plugin which does not exist',
|
|
() async {
|
|
final Set<String> directDependencies = <String>{'url_launcher'};
|
|
final List<PluginInterfaceResolution> resolutions = resolvePlatformImplementation(
|
|
<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'default_package': 'url_launcher_linux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
],
|
|
selectDartPluginsOnly: true,
|
|
);
|
|
|
|
expect(resolutions.length, equals(0));
|
|
expect(
|
|
testLogger.warningText,
|
|
'Package url_launcher:linux references url_launcher_linux:linux as the default plugin, '
|
|
'but the package does not exist, or is not a plugin package.\n'
|
|
'Ask the maintainers of url_launcher to either avoid referencing a default implementation via `platforms: linux: default_package: url_launcher_linux` '
|
|
'or create a plugin named url_launcher_linux.\n'
|
|
'\n',
|
|
);
|
|
},
|
|
);
|
|
|
|
testUsingContext('provides error when user selected multiple implementations', () async {
|
|
final Set<String> directDependencies = <String>{
|
|
'url_launcher_linux_1',
|
|
'url_launcher_linux_2',
|
|
};
|
|
expect(() {
|
|
resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux_1',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux_2',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
}, throwsToolExit(message: 'Please resolve the plugin implementation selection errors'));
|
|
|
|
expect(
|
|
testLogger.errorText,
|
|
'Plugin url_launcher:linux has conflicting direct dependency implementations:\n'
|
|
' url_launcher_linux_1\n'
|
|
' url_launcher_linux_2\n'
|
|
'To fix this issue, remove all but one of these dependencies from pubspec.yaml.\n'
|
|
'\n',
|
|
);
|
|
});
|
|
|
|
testUsingContext('provides all errors when user selected multiple implementations', () async {
|
|
final Set<String> directDependencies = <String>{
|
|
'url_launcher_linux_1',
|
|
'url_launcher_linux_2',
|
|
'url_launcher_windows_1',
|
|
'url_launcher_windows_2',
|
|
};
|
|
expect(() {
|
|
resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux_1',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux_2',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_windows_1',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'windows': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginWindows1'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_windows_2',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'windows': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginWindows2'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
}, throwsToolExit(message: 'Please resolve the plugin implementation selection errors'));
|
|
|
|
expect(
|
|
testLogger.errorText,
|
|
'Plugin url_launcher:linux has conflicting direct dependency implementations:\n'
|
|
' url_launcher_linux_1\n'
|
|
' url_launcher_linux_2\n'
|
|
'To fix this issue, remove all but one of these dependencies from pubspec.yaml.\n'
|
|
'\n'
|
|
'Plugin url_launcher:windows has conflicting direct dependency implementations:\n'
|
|
' url_launcher_windows_1\n'
|
|
' url_launcher_windows_2\n'
|
|
'To fix this issue, remove all but one of these dependencies from pubspec.yaml.\n'
|
|
'\n',
|
|
);
|
|
});
|
|
|
|
testUsingContext(
|
|
'provides error when user needs to select among multiple implementations',
|
|
() async {
|
|
final Set<String> directDependencies = <String>{};
|
|
expect(() {
|
|
resolvePlatformImplementation(<Plugin>[
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux_1',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux1'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
Plugin.fromYaml(
|
|
'url_launcher_linux_2',
|
|
'',
|
|
YamlMap.wrap(<String, dynamic>{
|
|
'implements': 'url_launcher',
|
|
'platforms': <String, dynamic>{
|
|
'linux': <String, dynamic>{'dartPluginClass': 'UrlLauncherPluginLinux2'},
|
|
},
|
|
}),
|
|
null,
|
|
<String>[],
|
|
fileSystem: fs,
|
|
isDevDependency: false,
|
|
appDependencies: directDependencies,
|
|
),
|
|
], selectDartPluginsOnly: true);
|
|
}, throwsToolExit(message: 'Please resolve the plugin implementation selection errors'));
|
|
|
|
expect(
|
|
testLogger.errorText,
|
|
'Plugin url_launcher:linux has multiple possible implementations:\n'
|
|
' url_launcher_linux_1\n'
|
|
' url_launcher_linux_2\n'
|
|
'To fix this issue, add one of these dependencies to pubspec.yaml.\n'
|
|
'\n',
|
|
);
|
|
},
|
|
);
|
|
});
|
|
|
|
group('generateMainDartWithPluginRegistrant', () {
|
|
testUsingContext(
|
|
'Generates new entrypoint',
|
|
() async {
|
|
flutterProject.isModule = true;
|
|
createFakeDartPlugins(flutterProject, flutterManifest, fs, <String, String>{
|
|
'url_launcher_android': '''
|
|
flutter:
|
|
plugin:
|
|
implements: url_launcher
|
|
platforms:
|
|
android:
|
|
dartPluginClass: AndroidPlugin
|
|
''',
|
|
'url_launcher_ios': '''
|
|
flutter:
|
|
plugin:
|
|
implements: url_launcher
|
|
platforms:
|
|
ios:
|
|
dartPluginClass: IosPlugin
|
|
''',
|
|
'url_launcher_macos': '''
|
|
flutter:
|
|
plugin:
|
|
implements: url_launcher
|
|
platforms:
|
|
macos:
|
|
dartPluginClass: MacOSPlugin
|
|
''',
|
|
'url_launcher_linux': '''
|
|
flutter:
|
|
plugin:
|
|
implements: url_launcher
|
|
platforms:
|
|
linux:
|
|
dartPluginClass: LinuxPlugin
|
|
''',
|
|
'url_launcher_windows': '''
|
|
flutter:
|
|
plugin:
|
|
implements: url_launcher
|
|
platforms:
|
|
windows:
|
|
dartPluginClass: WindowsPlugin
|
|
''',
|
|
'awesome_macos': '''
|
|
flutter:
|
|
plugin:
|
|
implements: awesome
|
|
platforms:
|
|
macos:
|
|
dartPluginClass: AwesomeMacOS
|
|
''',
|
|
});
|
|
|
|
final Directory libDir = flutterProject.directory.childDirectory('lib');
|
|
libDir.createSync(recursive: true);
|
|
final File mainFile = libDir.childFile('main.dart');
|
|
mainFile.writeAsStringSync('''
|
|
// @dart = 2.8
|
|
void main() {
|
|
}
|
|
''');
|
|
final PackageConfig packageConfig = await loadPackageConfigWithLogging(
|
|
flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json'),
|
|
logger: globals.logger,
|
|
throwOnError: false,
|
|
);
|
|
await generateMainDartWithPluginRegistrant(
|
|
flutterProject,
|
|
packageConfig,
|
|
'package:app/main.dart',
|
|
mainFile,
|
|
);
|
|
expect(
|
|
flutterProject.dartPluginRegistrant.readAsStringSync(),
|
|
'//\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.8\n'
|
|
'\n'
|
|
"import 'dart:io'; // flutter_ignore: dart_io_import.\n"
|
|
"import 'package:url_launcher_android/url_launcher_android.dart';\n"
|
|
"import 'package:url_launcher_ios/url_launcher_ios.dart';\n"
|
|
"import 'package:url_launcher_linux/url_launcher_linux.dart';\n"
|
|
"import 'package:awesome_macos/awesome_macos.dart';\n"
|
|
"import 'package:url_launcher_macos/url_launcher_macos.dart';\n"
|
|
"import 'package:url_launcher_windows/url_launcher_windows.dart';\n"
|
|
'\n'
|
|
"@pragma('vm:entry-point')\n"
|
|
'class _PluginRegistrant {\n'
|
|
'\n'
|
|
" @pragma('vm:entry-point')\n"
|
|
' static void register() {\n'
|
|
' if (Platform.isAndroid) {\n'
|
|
' try {\n'
|
|
' AndroidPlugin.registerWith();\n'
|
|
' } catch (err) {\n'
|
|
' print(\n'
|
|
" '`url_launcher_android` threw an error: \$err. '\n"
|
|
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
' );\n'
|
|
' }\n'
|
|
'\n'
|
|
' } else if (Platform.isIOS) {\n'
|
|
' try {\n'
|
|
' IosPlugin.registerWith();\n'
|
|
' } catch (err) {\n'
|
|
' print(\n'
|
|
" '`url_launcher_ios` threw an error: \$err. '\n"
|
|
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
' );\n'
|
|
' }\n'
|
|
'\n'
|
|
' } else if (Platform.isLinux) {\n'
|
|
' try {\n'
|
|
' LinuxPlugin.registerWith();\n'
|
|
' } catch (err) {\n'
|
|
' print(\n'
|
|
" '`url_launcher_linux` threw an error: \$err. '\n"
|
|
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
' );\n'
|
|
' }\n'
|
|
'\n'
|
|
' } else if (Platform.isMacOS) {\n'
|
|
' try {\n'
|
|
' AwesomeMacOS.registerWith();\n'
|
|
' } catch (err) {\n'
|
|
' print(\n'
|
|
" '`awesome_macos` threw an error: \$err. '\n"
|
|
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
' );\n'
|
|
' }\n'
|
|
'\n'
|
|
' try {\n'
|
|
' MacOSPlugin.registerWith();\n'
|
|
' } catch (err) {\n'
|
|
' print(\n'
|
|
" '`url_launcher_macos` threw an error: \$err. '\n"
|
|
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
' );\n'
|
|
' }\n'
|
|
'\n'
|
|
' } else if (Platform.isWindows) {\n'
|
|
' try {\n'
|
|
' WindowsPlugin.registerWith();\n'
|
|
' } catch (err) {\n'
|
|
' print(\n'
|
|
" '`url_launcher_windows` threw an error: \$err. '\n"
|
|
" 'The app may not function as expected until you remove this plugin from pubspec.yaml'\n"
|
|
' );\n'
|
|
' }\n'
|
|
'\n'
|
|
' }\n'
|
|
' }\n'
|
|
'}\n',
|
|
);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
Pub: ThrowingPub.new,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'Plugin without platform support throws tool exit',
|
|
() async {
|
|
flutterProject.isModule = false;
|
|
flutterManifest.dependencies.add('url_launcher_macos');
|
|
createFakeDartPlugins(flutterProject, flutterManifest, fs, <String, String>{
|
|
'url_launcher_macos': '''
|
|
flutter:
|
|
plugin:
|
|
implements: url_launcher
|
|
platforms:
|
|
macos:
|
|
invalid:
|
|
''',
|
|
});
|
|
|
|
final Directory libDir = flutterProject.directory.childDirectory('lib');
|
|
libDir.createSync(recursive: true);
|
|
|
|
final File mainFile = libDir.childFile('main.dart')..writeAsStringSync('');
|
|
final PackageConfig packageConfig = await loadPackageConfigWithLogging(
|
|
flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json'),
|
|
logger: globals.logger,
|
|
throwOnError: false,
|
|
);
|
|
await expectLater(
|
|
generateMainDartWithPluginRegistrant(
|
|
flutterProject,
|
|
packageConfig,
|
|
'package:app/main.dart',
|
|
mainFile,
|
|
),
|
|
throwsToolExit(
|
|
message:
|
|
'Invalid plugin specification url_launcher_macos.\n'
|
|
'Invalid "macos" plugin specification.',
|
|
),
|
|
);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
Pub: ThrowingPub.new,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'Plugin with platform support without dart plugin class throws tool exit',
|
|
() async {
|
|
flutterProject.isModule = false;
|
|
|
|
createFakeDartPlugins(flutterProject, flutterManifest, fs, <String, String>{
|
|
'url_launcher_macos': '''
|
|
flutter:
|
|
plugin:
|
|
implements: url_launcher
|
|
''',
|
|
});
|
|
|
|
final Directory libDir = flutterProject.directory.childDirectory('lib');
|
|
libDir.createSync(recursive: true);
|
|
|
|
final File mainFile = libDir.childFile('main.dart')..writeAsStringSync('');
|
|
final PackageConfig packageConfig = await loadPackageConfigWithLogging(
|
|
flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json'),
|
|
logger: globals.logger,
|
|
throwOnError: false,
|
|
);
|
|
await expectLater(
|
|
generateMainDartWithPluginRegistrant(
|
|
flutterProject,
|
|
packageConfig,
|
|
'package:app/main.dart',
|
|
mainFile,
|
|
),
|
|
throwsToolExit(
|
|
message:
|
|
'Invalid plugin specification url_launcher_macos.\n'
|
|
'Cannot find the `flutter.plugin.platforms` key in the `pubspec.yaml` file. '
|
|
'An instruction to format the `pubspec.yaml` can be found here: '
|
|
'https://flutter.dev/to/pubspec-plugin-platforms',
|
|
),
|
|
);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
Pub: ThrowingPub.new,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'Does not create new entrypoint if there are no platform resolutions',
|
|
() async {
|
|
flutterProject.isModule = false;
|
|
createFakeDartPlugins(flutterProject, flutterManifest, fs, <String, String>{});
|
|
|
|
final Directory libDir = flutterProject.directory.childDirectory('lib');
|
|
libDir.createSync(recursive: true);
|
|
|
|
final File mainFile = libDir.childFile('main.dart')..writeAsStringSync('');
|
|
final PackageConfig packageConfig = await loadPackageConfigWithLogging(
|
|
flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json'),
|
|
logger: globals.logger,
|
|
throwOnError: false,
|
|
);
|
|
await generateMainDartWithPluginRegistrant(
|
|
flutterProject,
|
|
packageConfig,
|
|
'package:app/main.dart',
|
|
mainFile,
|
|
);
|
|
expect(flutterProject.dartPluginRegistrant.existsSync(), isFalse);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
Pub: ThrowingPub.new,
|
|
},
|
|
);
|
|
|
|
testUsingContext(
|
|
'Deletes new entrypoint if there are no platform resolutions',
|
|
() async {
|
|
flutterProject.isModule = false;
|
|
|
|
createFakeDartPlugins(flutterProject, flutterManifest, fs, <String, String>{
|
|
'url_launcher_macos': '''
|
|
flutter:
|
|
plugin:
|
|
implements: url_launcher
|
|
platforms:
|
|
macos:
|
|
dartPluginClass: MacOSPlugin
|
|
''',
|
|
});
|
|
|
|
final Directory libDir = flutterProject.directory.childDirectory('lib');
|
|
libDir.createSync(recursive: true);
|
|
|
|
final File mainFile = libDir.childFile('main.dart')..writeAsStringSync('');
|
|
final PackageConfig packageConfig = await loadPackageConfigWithLogging(
|
|
flutterProject.packageConfig,
|
|
logger: globals.logger,
|
|
throwOnError: false,
|
|
);
|
|
await generateMainDartWithPluginRegistrant(
|
|
flutterProject,
|
|
packageConfig,
|
|
'package:app/main.dart',
|
|
mainFile,
|
|
);
|
|
expect(flutterProject.dartPluginRegistrant.existsSync(), isTrue);
|
|
|
|
// No plugins.
|
|
createFakeDartPlugins(flutterProject, flutterManifest, fs, <String, String>{});
|
|
|
|
await generateMainDartWithPluginRegistrant(
|
|
flutterProject,
|
|
packageConfig,
|
|
'package:app/main.dart',
|
|
mainFile,
|
|
);
|
|
expect(flutterProject.dartPluginRegistrant.existsSync(), isFalse);
|
|
},
|
|
overrides: <Type, Generator>{
|
|
FileSystem: () => fs,
|
|
ProcessManager: () => FakeProcessManager.any(),
|
|
Pub: ThrowingPub.new,
|
|
},
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
void createFakeDartPlugins(
|
|
FakeFlutterProject flutterProject,
|
|
FakeFlutterManifest flutterManifest,
|
|
FileSystem fs,
|
|
Map<String, String> plugins,
|
|
) {
|
|
final Directory fakePubCache = fs.systemTempDirectory.childDirectory('cache');
|
|
writePackageConfigFiles(
|
|
directory: flutterProject.directory,
|
|
mainLibName: flutterProject.manifest.appName,
|
|
packages: <String, String>{
|
|
for (final String name in plugins.keys)
|
|
name: fakePubCache.childDirectory(name).uri.toString(),
|
|
},
|
|
);
|
|
|
|
for (final MapEntry<String, String> entry in plugins.entries) {
|
|
final String name = fs.path.basename(entry.key);
|
|
final Directory pluginDirectory = fakePubCache.childDirectory(name);
|
|
pluginDirectory.childFile('pubspec.yaml')
|
|
..createSync(recursive: true)
|
|
..writeAsStringSync(entry.value);
|
|
}
|
|
flutterManifest.dependencies = plugins.keys.toSet();
|
|
}
|
|
|
|
class FakeFlutterManifest extends Fake implements FlutterManifest {
|
|
@override
|
|
Set<String> dependencies = <String>{};
|
|
|
|
@override
|
|
String get appName => 'myapp';
|
|
}
|
|
|
|
class FakeFlutterProject extends Fake implements FlutterProject {
|
|
@override
|
|
bool isModule = false;
|
|
|
|
@override
|
|
late FlutterManifest manifest;
|
|
|
|
@override
|
|
late Directory directory;
|
|
|
|
@override
|
|
File get packageConfig => directory.childDirectory('.dart_tool').childFile('package_config.json');
|
|
|
|
@override
|
|
late File flutterPluginsFile;
|
|
|
|
@override
|
|
late File flutterPluginsDependenciesFile;
|
|
|
|
@override
|
|
late File dartPluginRegistrant;
|
|
|
|
@override
|
|
late IosProject ios;
|
|
|
|
@override
|
|
late AndroidProject android;
|
|
|
|
@override
|
|
late WebProject web;
|
|
|
|
@override
|
|
late MacOSProject macos;
|
|
|
|
@override
|
|
late LinuxProject linux;
|
|
|
|
@override
|
|
late WindowsProject windows;
|
|
}
|