Unverified Commit af1fa21b authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Migrate flutter_manifest to null safety (#80392)

parent 16c73829
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:pub_semver/pub_semver.dart'; import 'package:pub_semver/pub_semver.dart';
import 'package:yaml/yaml.dart'; import 'package:yaml/yaml.dart';
...@@ -21,20 +19,15 @@ const Set<String> _kValidPluginPlatforms = <String>{ ...@@ -21,20 +19,15 @@ const Set<String> _kValidPluginPlatforms = <String>{
/// A wrapper around the `flutter` section in the `pubspec.yaml` file. /// A wrapper around the `flutter` section in the `pubspec.yaml` file.
class FlutterManifest { class FlutterManifest {
FlutterManifest._(this._logger); FlutterManifest._({required Logger logger}) : _logger = logger;
/// Returns an empty manifest. /// Returns an empty manifest.
factory FlutterManifest.empty({ @required Logger logger }) { factory FlutterManifest.empty({ required Logger logger }) = FlutterManifest._;
final FlutterManifest manifest = FlutterManifest._(logger);
manifest._descriptor = const <String, dynamic>{};
manifest._flutterDescriptor = const <String, dynamic>{};
return manifest;
}
/// Returns null on invalid manifest. Returns empty manifest on missing file. /// Returns null on invalid manifest. Returns empty manifest on missing file.
static FlutterManifest createFromPath(String path, { static FlutterManifest? createFromPath(String path, {
@required FileSystem fileSystem, required FileSystem fileSystem,
@required Logger logger, required Logger logger,
}) { }) {
if (path == null || !fileSystem.isFileSync(path)) { if (path == null || !fileSystem.isFileSync(path)) {
return _createFromYaml(null, logger); return _createFromYaml(null, logger);
...@@ -45,28 +38,24 @@ class FlutterManifest { ...@@ -45,28 +38,24 @@ class FlutterManifest {
/// Returns null on missing or invalid manifest. /// Returns null on missing or invalid manifest.
@visibleForTesting @visibleForTesting
static FlutterManifest createFromString(String manifest, { @required Logger logger }) { static FlutterManifest? createFromString(String manifest, { required Logger logger }) {
return _createFromYaml(manifest != null ? loadYaml(manifest) : null, logger); return _createFromYaml(manifest != null ? loadYaml(manifest) : null, logger);
} }
static FlutterManifest _createFromYaml(dynamic yamlDocument, Logger logger) { static FlutterManifest? _createFromYaml(Object? yamlDocument, Logger logger) {
if (yamlDocument != null && !_validate(yamlDocument, logger)) { if (yamlDocument != null && !_validate(yamlDocument, logger)) {
return null; return null;
} }
final FlutterManifest pubspec = FlutterManifest._(logger); final FlutterManifest pubspec = FlutterManifest._(logger: logger);
final Map<dynamic, dynamic> yamlMap = yamlDocument as YamlMap; final Map<Object?, Object?>? yamlMap = yamlDocument as YamlMap?;
if (yamlMap != null) { if (yamlMap != null) {
pubspec._descriptor = yamlMap.cast<String, dynamic>(); pubspec._descriptor = yamlMap.cast<String, Object?>();
} else {
pubspec._descriptor = <String, dynamic>{};
} }
final Map<dynamic, dynamic> flutterMap = pubspec._descriptor['flutter'] as Map<dynamic, dynamic>; final Map<Object?, Object?>? flutterMap = pubspec._descriptor['flutter'] as Map<Object?, Object?>?;
if (flutterMap != null) { if (flutterMap != null) {
pubspec._flutterDescriptor = flutterMap.cast<String, dynamic>(); pubspec._flutterDescriptor = flutterMap.cast<String, Object?>();
} else {
pubspec._flutterDescriptor = <String, dynamic>{};
} }
return pubspec; return pubspec;
...@@ -75,29 +64,29 @@ class FlutterManifest { ...@@ -75,29 +64,29 @@ class FlutterManifest {
final Logger _logger; final Logger _logger;
/// A map representation of the entire `pubspec.yaml` file. /// A map representation of the entire `pubspec.yaml` file.
Map<String, dynamic> _descriptor; Map<String, Object?> _descriptor = <String, Object?>{};
/// A map representation of the `flutter` section in the `pubspec.yaml` file. /// A map representation of the `flutter` section in the `pubspec.yaml` file.
Map<String, dynamic> _flutterDescriptor; Map<String, Object?> _flutterDescriptor = <String, Object?>{};
/// True if the `pubspec.yaml` file does not exist. /// True if the `pubspec.yaml` file does not exist.
bool get isEmpty => _descriptor.isEmpty; bool get isEmpty => _descriptor.isEmpty;
/// The string value of the top-level `name` property in the `pubspec.yaml` file. /// The string value of the top-level `name` property in the `pubspec.yaml` file.
String get appName => _descriptor['name'] as String ?? ''; String get appName => _descriptor['name'] as String? ?? '';
// Flag to avoid printing multiple invalid version messages. // Flag to avoid printing multiple invalid version messages.
bool _hasShowInvalidVersionMsg = false; bool _hasShowInvalidVersionMsg = false;
/// The version String from the `pubspec.yaml` file. /// The version String from the `pubspec.yaml` file.
/// Can be null if it isn't set or has a wrong format. /// Can be null if it isn't set or has a wrong format.
String get appVersion { String? get appVersion {
final String verStr = _descriptor['version']?.toString(); final String? verStr = _descriptor['version']?.toString();
if (verStr == null) { if (verStr == null) {
return null; return null;
} }
Version version; Version? version;
try { try {
version = Version.parse(verStr); version = Version.parse(verStr);
} on Exception { } on Exception {
...@@ -111,18 +100,20 @@ class FlutterManifest { ...@@ -111,18 +100,20 @@ class FlutterManifest {
/// The build version name from the `pubspec.yaml` file. /// The build version name from the `pubspec.yaml` file.
/// Can be null if version isn't set or has a wrong format. /// Can be null if version isn't set or has a wrong format.
String get buildName { String? get buildName {
if (appVersion != null && appVersion.contains('+')) { final String? version = appVersion;
return appVersion.split('+')?.elementAt(0); if (version != null && version.contains('+')) {
return version.split('+').elementAt(0);
} }
return appVersion; return version;
} }
/// The build version number from the `pubspec.yaml` file. /// The build version number from the `pubspec.yaml` file.
/// Can be null if version isn't set or has a wrong format. /// Can be null if version isn't set or has a wrong format.
String get buildNumber { String? get buildNumber {
if (appVersion != null && appVersion.contains('+')) { final String? version = appVersion;
final String value = appVersion.split('+')?.elementAt(1); if (version != null && version.contains('+')) {
final String value = version.split('+').elementAt(1);
return value; return value;
} else { } else {
return null; return null;
...@@ -130,15 +121,16 @@ class FlutterManifest { ...@@ -130,15 +121,16 @@ class FlutterManifest {
} }
bool get usesMaterialDesign { bool get usesMaterialDesign {
return _flutterDescriptor['uses-material-design'] as bool ?? false; return _flutterDescriptor['uses-material-design'] as bool? ?? false;
} }
/// True if this Flutter module should use AndroidX dependencies. /// True if this Flutter module should use AndroidX dependencies.
/// ///
/// If false the deprecated Android Support library will be used. /// If false the deprecated Android Support library will be used.
bool get usesAndroidX { bool get usesAndroidX {
if (_flutterDescriptor.containsKey('module')) { final Object? module = _flutterDescriptor['module'];
return _flutterDescriptor['module']['androidX'] as bool; if (module is YamlMap) {
return module['androidX'] == true;
} }
return false; return false;
} }
...@@ -155,9 +147,13 @@ class FlutterManifest { ...@@ -155,9 +147,13 @@ class FlutterManifest {
/// licenses: /// licenses:
/// - assets/foo_license.txt /// - assets/foo_license.txt
/// ``` /// ```
List<String> get additionalLicenses => _flutterDescriptor.containsKey('licenses') List<String> get additionalLicenses {
? (_flutterDescriptor['licenses'] as YamlList).map((dynamic element) => element.toString()).toList() final Object? licenses = _flutterDescriptor['licenses'];
: <String>[]; if (licenses is YamlList) {
return licenses.map((Object? element) => element.toString()).toList();
}
return <String>[];
}
/// True if this manifest declares a Flutter module project. /// True if this manifest declares a Flutter module project.
/// ///
...@@ -181,51 +177,60 @@ class FlutterManifest { ...@@ -181,51 +177,60 @@ class FlutterManifest {
/// Returns the Android package declared by this manifest in its /// Returns the Android package declared by this manifest in its
/// module or plugin descriptor. Returns null, if there is no /// module or plugin descriptor. Returns null, if there is no
/// such declaration. /// such declaration.
String get androidPackage { String? get androidPackage {
if (isModule) { if (isModule) {
return _flutterDescriptor['module']['androidPackage'] as String; final Object? module = _flutterDescriptor['module'];
if (module is YamlMap) {
return module['androidPackage'] as String?;
}
} }
if (supportedPlatforms == null) { final Map<String, Object?>? platforms = supportedPlatforms;
if (platforms == null) {
// Pre-multi-platform plugin format // Pre-multi-platform plugin format
if (isPlugin) { if (isPlugin) {
final YamlMap plugin = _flutterDescriptor['plugin'] as YamlMap; final YamlMap? plugin = _flutterDescriptor['plugin'] as YamlMap?;
return plugin['androidPackage'] as String; return plugin?['androidPackage'] as String?;
} }
return null; return null;
} }
if (supportedPlatforms.containsKey('android')) { if (platforms.containsKey('android')) {
return supportedPlatforms['android']['package'] as String; final Object? android = platforms['android'];
if (android is YamlMap) {
return android['package'] as String?;
}
} }
return null; return null;
} }
/// Returns the deferred components configuration if declared. Returns /// Returns the deferred components configuration if declared. Returns
/// null if no deferred components are declared. /// null if no deferred components are declared.
List<DeferredComponent> get deferredComponents => _deferredComponents ??= computeDeferredComponents(); late final List<DeferredComponent>? deferredComponents = computeDeferredComponents();
List<DeferredComponent> _deferredComponents; List<DeferredComponent>? computeDeferredComponents() {
List<DeferredComponent> computeDeferredComponents() {
if (!_flutterDescriptor.containsKey('deferred-components')) { if (!_flutterDescriptor.containsKey('deferred-components')) {
return null; return null;
} }
final List<DeferredComponent> components = <DeferredComponent>[]; final List<DeferredComponent> components = <DeferredComponent>[];
if (_flutterDescriptor['deferred-components'] == null) { final Object? deferredComponents = _flutterDescriptor['deferred-components'];
if (deferredComponents is! YamlList) {
return components; return components;
} }
for (final dynamic componentData in _flutterDescriptor['deferred-components']) { for (final Object? component in deferredComponents) {
final YamlMap component = componentData as YamlMap; if (component is! YamlMap) {
_logger.printError('Expected deferred component manifest to be a map.');
continue;
}
List<Uri> assetsUri = <Uri>[]; List<Uri> assetsUri = <Uri>[];
final List<dynamic> assets = component['assets'] as List<dynamic>; final List<Object?>? assets = component['assets'] as List<Object?>?;
if (assets == null) { if (assets == null) {
assetsUri = const <Uri>[]; assetsUri = const <Uri>[];
} else { } else {
for (final Object asset in assets) { for (final Object? asset in assets) {
if (asset is! String || asset == null || asset == '') { if (asset is! String || asset == null || asset == '') {
_logger.printError('Deferred component asset manifest contains a null or empty uri.'); _logger.printError('Deferred component asset manifest contains a null or empty uri.');
continue; continue;
} }
final String stringAsset = asset as String;
try { try {
assetsUri.add(Uri.parse(stringAsset)); assetsUri.add(Uri.parse(asset));
} on FormatException { } on FormatException {
_logger.printError('Asset manifest contains invalid uri: $asset.'); _logger.printError('Asset manifest contains invalid uri: $asset.');
} }
...@@ -245,9 +250,12 @@ class FlutterManifest { ...@@ -245,9 +250,12 @@ class FlutterManifest {
/// Returns the iOS bundle identifier declared by this manifest in its /// Returns the iOS bundle identifier declared by this manifest in its
/// module descriptor. Returns null if there is no such declaration. /// module descriptor. Returns null if there is no such declaration.
String get iosBundleIdentifier { String? get iosBundleIdentifier {
if (isModule) { if (isModule) {
return _flutterDescriptor['module']['iosBundleIdentifier'] as String; final Object? module = _flutterDescriptor['module'];
if (module is YamlMap) {
return module['iosBundleIdentifier'] as String?;
}
} }
return null; return null;
} }
...@@ -255,58 +263,56 @@ class FlutterManifest { ...@@ -255,58 +263,56 @@ class FlutterManifest {
/// Gets the supported platforms. This only supports the new `platforms` format. /// Gets the supported platforms. This only supports the new `platforms` format.
/// ///
/// If the plugin uses the legacy pubspec format, this method returns null. /// If the plugin uses the legacy pubspec format, this method returns null.
Map<String, dynamic> get supportedPlatforms { Map<String, Object?>? get supportedPlatforms {
if (isPlugin) { if (isPlugin) {
final YamlMap plugin = _flutterDescriptor['plugin'] as YamlMap; final YamlMap? plugin = _flutterDescriptor['plugin'] as YamlMap?;
if (plugin.containsKey('platforms')) { if (plugin?.containsKey('platforms') == true) {
final YamlMap platformsMap = plugin['platforms'] as YamlMap; final YamlMap? platformsMap = plugin!['platforms'] as YamlMap?;
return platformsMap.value.cast<String, dynamic>(); return platformsMap?.value.cast<String, Object?>();
} }
} }
return null; return null;
} }
/// Like [supportedPlatforms], but only returns the valid platforms that are supported in flutter plugins. /// Like [supportedPlatforms], but only returns the valid platforms that are supported in flutter plugins.
Map<String, dynamic> get validSupportedPlatforms { Map<String, Object?>? get validSupportedPlatforms {
final Map<String, dynamic> allPlatforms = supportedPlatforms; final Map<String, Object?>? allPlatforms = supportedPlatforms;
if (allPlatforms == null) { if (allPlatforms == null) {
return null; return null;
} }
final Map<String, dynamic> platforms = <String, dynamic>{}..addAll(supportedPlatforms); final Map<String, Object?> platforms = <String, Object?>{}..addAll(allPlatforms);
platforms.removeWhere((String key, dynamic _) => !_kValidPluginPlatforms.contains(key)); platforms.removeWhere((String key, Object? _) => !_kValidPluginPlatforms.contains(key));
if (platforms.isEmpty) { if (platforms.isEmpty) {
return null; return null;
} }
return platforms; return platforms;
} }
List<Map<String, dynamic>> get fontsDescriptor { List<Map<String, Object?>> get fontsDescriptor {
return fonts.map((Font font) => font.descriptor).toList(); return fonts.map((Font font) => font.descriptor).toList();
} }
List<Map<String, dynamic>> get _rawFontsDescriptor { List<Map<String, Object?>> get _rawFontsDescriptor {
final List<dynamic> fontList = _flutterDescriptor['fonts'] as List<dynamic>; final List<Object?>? fontList = _flutterDescriptor['fonts'] as List<Object?>?;
return fontList == null return fontList == null
? const <Map<String, dynamic>>[] ? const <Map<String, Object?>>[]
: fontList.map<Map<String, dynamic>>(castStringKeyedMap).toList(); : fontList.map<Map<String, Object?>?>(castStringKeyedMap).whereType<Map<String, Object?>>().toList();
} }
List<Uri> get assets => _assets ??= _computeAssets(); late final List<Uri> assets = _computeAssets();
List<Uri> _assets;
List<Uri> _computeAssets() { List<Uri> _computeAssets() {
final List<dynamic> assets = _flutterDescriptor['assets'] as List<dynamic>; final List<Object?>? assets = _flutterDescriptor['assets'] as List<Object?>?;
if (assets == null) { if (assets == null) {
return const <Uri>[]; return const <Uri>[];
} }
final List<Uri> results = <Uri>[]; final List<Uri> results = <Uri>[];
for (final Object asset in assets) { for (final Object? asset in assets) {
if (asset is! String || asset == null || asset == '') { if (asset is! String || asset == null || asset == '') {
_logger.printError('Asset manifest contains a null or empty uri.'); _logger.printError('Asset manifest contains a null or empty uri.');
continue; continue;
} }
final String stringAsset = asset as String;
try { try {
results.add(Uri(pathSegments: stringAsset.split('/'))); results.add(Uri(pathSegments: asset.split('/')));
} on FormatException { } on FormatException {
_logger.printError('Asset manifest contains invalid uri: $asset.'); _logger.printError('Asset manifest contains invalid uri: $asset.');
} }
...@@ -314,12 +320,7 @@ class FlutterManifest { ...@@ -314,12 +320,7 @@ class FlutterManifest {
return results; return results;
} }
List<Font> _fonts; late final List<Font> fonts = _extractFonts();
List<Font> get fonts {
_fonts ??= _extractFonts();
return _fonts;
}
List<Font> _extractFonts() { List<Font> _extractFonts() {
if (!_flutterDescriptor.containsKey('fonts')) { if (!_flutterDescriptor.containsKey('fonts')) {
...@@ -327,9 +328,9 @@ class FlutterManifest { ...@@ -327,9 +328,9 @@ class FlutterManifest {
} }
final List<Font> fonts = <Font>[]; final List<Font> fonts = <Font>[];
for (final Map<String, dynamic> fontFamily in _rawFontsDescriptor) { for (final Map<String, Object?> fontFamily in _rawFontsDescriptor) {
final YamlList fontFiles = fontFamily['fonts'] as YamlList; final YamlList? fontFiles = fontFamily['fonts'] as YamlList?;
final String familyName = fontFamily['family'] as String; final String? familyName = fontFamily['family'] as String?;
if (familyName == null) { if (familyName == null) {
_logger.printError('Warning: Missing family name for font.', emphasis: true); _logger.printError('Warning: Missing family name for font.', emphasis: true);
continue; continue;
...@@ -340,8 +341,8 @@ class FlutterManifest { ...@@ -340,8 +341,8 @@ class FlutterManifest {
} }
final List<FontAsset> fontAssets = <FontAsset>[]; final List<FontAsset> fontAssets = <FontAsset>[];
for (final Map<dynamic, dynamic> fontFile in fontFiles.cast<Map<dynamic, dynamic>>()) { for (final Map<Object?, Object?> fontFile in fontFiles.cast<Map<Object?, Object?>>()) {
final String asset = fontFile['asset'] as String; final String? asset = fontFile['asset'] as String?;
if (asset == null) { if (asset == null) {
_logger.printError('Warning: Missing asset in fonts for $familyName', emphasis: true); _logger.printError('Warning: Missing asset in fonts for $familyName', emphasis: true);
continue; continue;
...@@ -349,12 +350,12 @@ class FlutterManifest { ...@@ -349,12 +350,12 @@ class FlutterManifest {
fontAssets.add(FontAsset( fontAssets.add(FontAsset(
Uri.parse(asset), Uri.parse(asset),
weight: fontFile['weight'] as int, weight: fontFile['weight'] as int?,
style: fontFile['style'] as String, style: fontFile['style'] as String?,
)); ));
} }
if (fontAssets.isNotEmpty) { if (fontAssets.isNotEmpty) {
fonts.add(Font(fontFamily['family'] as String, fontAssets)); fonts.add(Font(familyName, fontAssets));
} }
} }
return fonts; return fonts;
...@@ -367,17 +368,16 @@ class FlutterManifest { ...@@ -367,17 +368,16 @@ class FlutterManifest {
/// ///
/// This allows generated source code to be imported using a package /// This allows generated source code to be imported using a package
/// alias. /// alias.
bool get generateSyntheticPackage => _generateSyntheticPackage ??= _computeGenerateSyntheticPackage(); late final bool generateSyntheticPackage = _computeGenerateSyntheticPackage();
bool _generateSyntheticPackage;
bool _computeGenerateSyntheticPackage() { bool _computeGenerateSyntheticPackage() {
if (!_flutterDescriptor.containsKey('generate')) { if (!_flutterDescriptor.containsKey('generate')) {
return false; return false;
} }
final Object value = _flutterDescriptor['generate']; final Object? value = _flutterDescriptor['generate'];
if (value is! bool) { if (value is! bool) {
return false; return false;
} }
return value as bool; return value;
} }
} }
...@@ -390,10 +390,10 @@ class Font { ...@@ -390,10 +390,10 @@ class Font {
final String familyName; final String familyName;
final List<FontAsset> fontAssets; final List<FontAsset> fontAssets;
Map<String, dynamic> get descriptor { Map<String, Object?> get descriptor {
return <String, dynamic>{ return <String, Object?>{
'family': familyName, 'family': familyName,
'fonts': fontAssets.map<Map<String, dynamic>>((FontAsset a) => a.descriptor).toList(), 'fonts': fontAssets.map<Map<String, Object?>>((FontAsset a) => a.descriptor).toList(),
}; };
} }
...@@ -406,11 +406,11 @@ class FontAsset { ...@@ -406,11 +406,11 @@ class FontAsset {
: assert(assetUri != null); : assert(assetUri != null);
final Uri assetUri; final Uri assetUri;
final int weight; final int? weight;
final String style; final String? style;
Map<String, dynamic> get descriptor { Map<String, Object?> get descriptor {
final Map<String, dynamic> descriptor = <String, dynamic>{}; final Map<String, Object?> descriptor = <String, Object?>{};
if (weight != null) { if (weight != null) {
descriptor['weight'] = weight; descriptor['weight'] = weight;
} }
...@@ -428,17 +428,17 @@ class FontAsset { ...@@ -428,17 +428,17 @@ class FontAsset {
} }
bool _validate(dynamic manifest, Logger logger) { bool _validate(Object? manifest, Logger logger) {
final List<String> errors = <String>[]; final List<String> errors = <String>[];
if (manifest is! YamlMap) { if (manifest is! YamlMap) {
errors.add('Expected YAML map'); errors.add('Expected YAML map');
} else { } else {
for (final MapEntry<dynamic, dynamic> kvp in (manifest as YamlMap).entries) { for (final MapEntry<Object?, Object?> kvp in manifest.entries) {
if (kvp.key is! String) { if (kvp.key is! String) {
errors.add('Expected YAML key to be a string, but got ${kvp.key}.'); errors.add('Expected YAML key to be a string, but got ${kvp.key}.');
continue; continue;
} }
switch (kvp.key as String) { switch (kvp.key as String?) {
case 'name': case 'name':
if (kvp.value is! String) { if (kvp.value is! String) {
errors.add('Expected "${kvp.key}" to be a string, but got ${kvp.value}.'); errors.add('Expected "${kvp.key}" to be a string, but got ${kvp.value}.');
...@@ -451,7 +451,7 @@ bool _validate(dynamic manifest, Logger logger) { ...@@ -451,7 +451,7 @@ bool _validate(dynamic manifest, Logger logger) {
if (kvp.value is! YamlMap) { if (kvp.value is! YamlMap) {
errors.add('Expected "${kvp.key}" section to be an object or null, but got ${kvp.value}.'); errors.add('Expected "${kvp.key}" section to be an object or null, but got ${kvp.value}.');
} else { } else {
_validateFlutter(kvp.value as YamlMap, errors); _validateFlutter(kvp.value as YamlMap?, errors);
} }
break; break;
default: default:
...@@ -470,62 +470,64 @@ bool _validate(dynamic manifest, Logger logger) { ...@@ -470,62 +470,64 @@ bool _validate(dynamic manifest, Logger logger) {
return true; return true;
} }
void _validateFlutter(YamlMap yaml, List<String> errors) { void _validateFlutter(YamlMap? yaml, List<String> errors) {
if (yaml == null || yaml.entries == null) { if (yaml == null || yaml.entries == null) {
return; return;
} }
for (final MapEntry<dynamic, dynamic> kvp in yaml.entries) { for (final MapEntry<Object?, Object?> kvp in yaml.entries) {
if (kvp.key is! String) { final Object? yamlKey = kvp.key;
errors.add('Expected YAML key to be a string, but got ${kvp.key} (${kvp.value.runtimeType}).'); final Object? yamlValue = kvp.value;
if (yamlKey is! String) {
errors.add('Expected YAML key to be a string, but got $yamlKey (${yamlValue.runtimeType}).');
continue; continue;
} }
switch (kvp.key as String) { switch (yamlKey) {
case 'uses-material-design': case 'uses-material-design':
if (kvp.value is! bool) { if (yamlValue is! bool) {
errors.add('Expected "${kvp.key}" to be a bool, but got ${kvp.value} (${kvp.value.runtimeType}).'); errors.add('Expected "$yamlKey" to be a bool, but got $yamlValue (${yamlValue.runtimeType}).');
} }
break; break;
case 'assets': case 'assets':
if (kvp.value is! YamlList || kvp.value[0] is! String) { if (yamlValue is! YamlList || yamlValue[0] is! String) {
errors.add('Expected "${kvp.key}" to be a list, but got ${kvp.value} (${kvp.value.runtimeType}).'); errors.add('Expected "$yamlKey" to be a list, but got $yamlValue (${yamlValue.runtimeType}).');
} }
break; break;
case 'fonts': case 'fonts':
if (kvp.value is! YamlList || kvp.value[0] is! YamlMap) { if (yamlValue is! YamlList || yamlValue[0] is! YamlMap) {
errors.add('Expected "${kvp.key}" to be a list, but got ${kvp.value} (${kvp.value.runtimeType}).'); errors.add('Expected "$yamlKey" to be a list, but got $yamlValue (${yamlValue.runtimeType}).');
} else { } else {
_validateFonts(kvp.value as YamlList, errors); _validateFonts(yamlValue, errors);
} }
break; break;
case 'licenses': case 'licenses':
final dynamic value = kvp.value; if (yamlValue is YamlList) {
if (value is YamlList) { _validateListType<String>(yamlValue, errors, '"$yamlKey"', 'files');
_validateListType<String>(value, errors, '"${kvp.key}"', 'files');
} else { } else {
errors.add('Expected "${kvp.key}" to be a list of files, but got $value (${value.runtimeType})'); errors.add('Expected "$yamlKey" to be a list of files, but got $yamlValue (${yamlValue.runtimeType})');
} }
break; break;
case 'module': case 'module':
if (kvp.value is! YamlMap) { if (yamlValue is! YamlMap) {
errors.add('Expected "${kvp.key}" to be an object, but got ${kvp.value} (${kvp.value.runtimeType}).'); errors.add('Expected "$yamlKey" to be an object, but got $yamlValue (${yamlValue.runtimeType}).');
break;
} }
if (kvp.value['androidX'] != null && kvp.value['androidX'] is! bool) { if (yamlValue['androidX'] != null && yamlValue['androidX'] is! bool) {
errors.add('The "androidX" value must be a bool if set.'); errors.add('The "androidX" value must be a bool if set.');
} }
if (kvp.value['androidPackage'] != null && kvp.value['androidPackage'] is! String) { if (yamlValue['androidPackage'] != null && yamlValue['androidPackage'] is! String) {
errors.add('The "androidPackage" value must be a string if set.'); errors.add('The "androidPackage" value must be a string if set.');
} }
if (kvp.value['iosBundleIdentifier'] != null && kvp.value['iosBundleIdentifier'] is! String) { if (yamlValue['iosBundleIdentifier'] != null && yamlValue['iosBundleIdentifier'] is! String) {
errors.add('The "iosBundleIdentifier" section must be a string if set.'); errors.add('The "iosBundleIdentifier" section must be a string if set.');
} }
break; break;
case 'plugin': case 'plugin':
if (kvp.value is! YamlMap || kvp.value == null) { if (yamlValue is! YamlMap || yamlValue == null) {
errors.add('Expected "${kvp.key}" to be an object, but got ${kvp.value} (${kvp.value.runtimeType}).'); errors.add('Expected "$yamlKey" to be an object, but got $yamlValue (${yamlValue.runtimeType}).');
break; break;
} }
final List<String> pluginErrors = Plugin.validatePluginYaml(kvp.value as YamlMap); final List<String> pluginErrors = Plugin.validatePluginYaml(yamlValue);
errors.addAll(pluginErrors); errors.addAll(pluginErrors);
break; break;
case 'generate': case 'generate':
...@@ -534,7 +536,7 @@ void _validateFlutter(YamlMap yaml, List<String> errors) { ...@@ -534,7 +536,7 @@ void _validateFlutter(YamlMap yaml, List<String> errors) {
_validateDeferredComponents(kvp, errors); _validateDeferredComponents(kvp, errors);
break; break;
default: default:
errors.add('Unexpected child "${kvp.key}" found under "flutter".'); errors.add('Unexpected child "$yamlKey" found under "flutter".');
break; break;
} }
} }
...@@ -548,30 +550,34 @@ void _validateListType<T>(YamlList yamlList, List<String> errors, String context ...@@ -548,30 +550,34 @@ void _validateListType<T>(YamlList yamlList, List<String> errors, String context
} }
} }
void _validateDeferredComponents(MapEntry<dynamic, dynamic> kvp, List<String> errors) { void _validateDeferredComponents(MapEntry<Object?, Object?> kvp, List<String> errors) {
if (kvp.value != null && (kvp.value is! YamlList || kvp.value[0] is! YamlMap)) { final Object? yamlList = kvp.value;
errors.add('Expected "${kvp.key}" to be a list, but got ${kvp.value} (${kvp.value.runtimeType}).'); if (yamlList != null && (yamlList is! YamlList || yamlList[0] is! YamlMap)) {
} else if (kvp.value != null) { errors.add('Expected "${kvp.key}" to be a list, but got $yamlList (${yamlList.runtimeType}).');
for (int i = 0; i < (kvp.value as YamlList).length; i++) { } else if (yamlList is YamlList) {
if (kvp.value[i] is! YamlMap) { for (int i = 0; i < yamlList.length; i++) {
errors.add('Expected the $i element in "${kvp.key}" to be a map, but got ${kvp.value[i]} (${kvp.value[i].runtimeType}).'); final Object? valueMap = yamlList[i];
if (valueMap is! YamlMap) {
errors.add('Expected the $i element in "${kvp.key}" to be a map, but got ${yamlList[i]} (${yamlList[i].runtimeType}).');
continue; continue;
} }
if (!(kvp.value[i] as YamlMap).containsKey('name') || kvp.value[i]['name'] is! String) { if (!valueMap.containsKey('name') || valueMap['name'] is! String) {
errors.add('Expected the $i element in "${kvp.key}" to have required key "name" of type String'); errors.add('Expected the $i element in "${kvp.key}" to have required key "name" of type String');
} }
if ((kvp.value[i] as YamlMap).containsKey('libraries')) { if (valueMap.containsKey('libraries')) {
if (kvp.value[i]['libraries'] is! YamlList) { final Object? libraries = valueMap['libraries'];
errors.add('Expected "libraries" key in the $i element of "${kvp.key}" to be a list, but got ${kvp.value[i]['libraries']} (${kvp.value[i]['libraries'].runtimeType}).'); if (libraries is! YamlList) {
errors.add('Expected "libraries" key in the $i element of "${kvp.key}" to be a list, but got $libraries (${libraries.runtimeType}).');
} else { } else {
_validateListType<String>(kvp.value[i]['libraries'] as YamlList, errors, '"libraries" key in the $i element of "${kvp.key}"', 'dart library Strings'); _validateListType<String>(libraries, errors, '"libraries" key in the $i element of "${kvp.key}"', 'dart library Strings');
} }
} }
if ((kvp.value[i] as YamlMap).containsKey('assets')) { if (valueMap.containsKey('assets')) {
if (kvp.value[i]['assets'] is! YamlList) { final Object? assets = valueMap['assets'];
errors.add('Expected "assets" key in the $i element of "${kvp.key}" to be a list, but got ${kvp.value[i]['assets']} (${kvp.value[i]['assets'].runtimeType}).'); if (assets is! YamlList) {
errors.add('Expected "assets" key in the $i element of "${kvp.key}" to be a list, but got $assets (${assets.runtimeType}).');
} else { } else {
_validateListType<String>(kvp.value[i]['assets'] as YamlList, errors, '"assets" key in the $i element of "${kvp.key}"', 'file paths'); _validateListType<String>(assets, errors, '"assets" key in the $i element of "${kvp.key}"', 'file paths');
} }
} }
} }
...@@ -585,13 +591,12 @@ void _validateFonts(YamlList fonts, List<String> errors) { ...@@ -585,13 +591,12 @@ void _validateFonts(YamlList fonts, List<String> errors) {
const Set<int> fontWeights = <int>{ const Set<int> fontWeights = <int>{
100, 200, 300, 400, 500, 600, 700, 800, 900, 100, 200, 300, 400, 500, 600, 700, 800, 900,
}; };
for (final dynamic fontListEntry in fonts) { for (final Object? fontMap in fonts) {
if (fontListEntry is! YamlMap) { if (fontMap is! YamlMap) {
errors.add('Unexpected child "$fontListEntry" found under "fonts". Expected a map.'); errors.add('Unexpected child "$fontMap" found under "fonts". Expected a map.');
continue; continue;
} }
final YamlMap fontMap = fontListEntry as YamlMap; for (final Object? key in fontMap.keys.where((Object? key) => key != 'family' && key != 'fonts')) {
for (final dynamic key in fontMap.keys.where((dynamic key) => key != 'family' && key != 'fonts')) {
errors.add('Unexpected child "$key" found under "fonts".'); errors.add('Unexpected child "$key" found under "fonts".');
} }
if (fontMap['family'] != null && fontMap['family'] is! String) { if (fontMap['family'] != null && fontMap['family'] is! String) {
...@@ -603,17 +608,17 @@ void _validateFonts(YamlList fonts, List<String> errors) { ...@@ -603,17 +608,17 @@ void _validateFonts(YamlList fonts, List<String> errors) {
errors.add('Expected "fonts" to either be null or a list.'); errors.add('Expected "fonts" to either be null or a list.');
continue; continue;
} }
for (final dynamic fontListItem in fontMap['fonts']) { for (final Object? fontMapList in fontMap['fonts']) {
if (fontListItem is! YamlMap) { if (fontMapList is! YamlMap) {
errors.add('Expected "fonts" to be a list of maps.'); errors.add('Expected "fonts" to be a list of maps.');
continue; continue;
} }
final YamlMap fontMapList = fontListItem as YamlMap; for (final MapEntry<Object?, Object?> kvp in fontMapList.entries) {
for (final MapEntry<dynamic, dynamic> kvp in fontMapList.entries) { final Object? fontKey = kvp.key;
if (kvp.key is! String) { if (fontKey is! String) {
errors.add('Expected "${kvp.key}" under "fonts" to be a string.'); errors.add('Expected "$fontKey" under "fonts" to be a string.');
} }
switch(kvp.key as String) { switch(fontKey) {
case 'asset': case 'asset':
if (kvp.value is! String) { if (kvp.value is! String) {
errors.add('Expected font asset ${kvp.value} ((${kvp.value.runtimeType})) to be a string.'); errors.add('Expected font asset ${kvp.value} ((${kvp.value.runtimeType})) to be a string.');
...@@ -630,7 +635,7 @@ void _validateFonts(YamlList fonts, List<String> errors) { ...@@ -630,7 +635,7 @@ void _validateFonts(YamlList fonts, List<String> errors) {
} }
break; break;
default: default:
errors.add('Unexpected key ${kvp.key} ((${kvp.value.runtimeType})) under font.'); errors.add('Unexpected key $fontKey ((${kvp.value.runtimeType})) under font.');
break; break;
} }
} }
......
...@@ -2,17 +2,15 @@ ...@@ -2,17 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/deferred_component.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/flutter_manifest.dart'; import 'package:flutter_tools/src/flutter_manifest.dart';
import '../src/common.dart'; import '../src/common.dart';
import '../src/context.dart';
void main() { void main() {
setUpAll(() { setUpAll(() {
...@@ -24,7 +22,7 @@ void main() { ...@@ -24,7 +22,7 @@ void main() {
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
'', '',
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isEmpty, true); expect(flutterManifest.isEmpty, true);
expect(flutterManifest.appName, ''); expect(flutterManifest.appName, '');
...@@ -56,7 +54,7 @@ dependencies: ...@@ -56,7 +54,7 @@ dependencies:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest, isNotNull); expect(flutterManifest, isNotNull);
expect(flutterManifest.isEmpty, false); expect(flutterManifest.isEmpty, false);
...@@ -80,7 +78,7 @@ flutter: ...@@ -80,7 +78,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.usesMaterialDesign, true); expect(flutterManifest.usesMaterialDesign, true);
}); });
...@@ -98,7 +96,7 @@ flutter: ...@@ -98,7 +96,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.generateSyntheticPackage, true); expect(flutterManifest.generateSyntheticPackage, true);
}); });
...@@ -116,7 +114,7 @@ flutter: ...@@ -116,7 +114,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.generateSyntheticPackage, false); expect(flutterManifest.generateSyntheticPackage, false);
}); });
...@@ -134,7 +132,7 @@ flutter: ...@@ -134,7 +132,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.generateSyntheticPackage, false); expect(flutterManifest.generateSyntheticPackage, false);
}); });
...@@ -155,7 +153,7 @@ flutter: ...@@ -155,7 +153,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.assets, <Uri>[ expect(flutterManifest.assets, <Uri>[
Uri.parse('a/foo'), Uri.parse('a/foo'),
...@@ -180,7 +178,7 @@ flutter: ...@@ -180,7 +178,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.fonts, hasLength(1)); expect(flutterManifest.fonts, hasLength(1));
expect(flutterManifest.fonts.single, matchesFont( expect(flutterManifest.fonts.single, matchesFont(
...@@ -217,7 +215,7 @@ flutter: ...@@ -217,7 +215,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.fonts, hasLength(1)); expect(flutterManifest.fonts, hasLength(1));
expect(flutterManifest.fonts.single, matchesFont( expect(flutterManifest.fonts.single, matchesFont(
...@@ -257,7 +255,7 @@ flutter: ...@@ -257,7 +255,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.fonts, hasLength(1)); expect(flutterManifest.fonts, hasLength(1));
expect(flutterManifest.fonts.single, matchesFont( expect(flutterManifest.fonts.single, matchesFont(
...@@ -303,7 +301,7 @@ flutter: ...@@ -303,7 +301,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.fonts, hasLength(2)); expect(flutterManifest.fonts, hasLength(2));
expect(flutterManifest.fonts, containsAll(<Matcher>[ expect(flutterManifest.fonts, containsAll(<Matcher>[
...@@ -365,7 +363,7 @@ flutter: ...@@ -365,7 +363,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.fontsDescriptor, <Object>[ expect(flutterManifest.fontsDescriptor, <Object>[
<String, Object>{ <String, Object>{
...@@ -411,7 +409,7 @@ flutter: ...@@ -411,7 +409,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.fonts, hasLength(1)); expect(flutterManifest.fonts, hasLength(1));
expect(flutterManifest.fonts, containsAll(<Matcher>[ expect(flutterManifest.fonts, containsAll(<Matcher>[
...@@ -454,7 +452,7 @@ flutter: ...@@ -454,7 +452,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.fonts, hasLength(1)); expect(flutterManifest.fonts, hasLength(1));
expect(flutterManifest.fonts, containsAll(<Matcher>[ expect(flutterManifest.fonts, containsAll(<Matcher>[
...@@ -493,7 +491,7 @@ flutter: ...@@ -493,7 +491,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.fontsDescriptor, isEmpty); expect(flutterManifest.fontsDescriptor, isEmpty);
expect(flutterManifest.fonts, isEmpty); expect(flutterManifest.fonts, isEmpty);
...@@ -511,7 +509,7 @@ flutter: ...@@ -511,7 +509,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isEmpty, false); expect(flutterManifest.isEmpty, false);
expect(flutterManifest.isModule, false); expect(flutterManifest.isModule, false);
...@@ -532,7 +530,7 @@ flutter: ...@@ -532,7 +530,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isModule, true); expect(flutterManifest.isModule, true);
expect(flutterManifest.androidPackage, 'com.example'); expect(flutterManifest.androidPackage, 'com.example');
...@@ -550,7 +548,7 @@ flutter: ...@@ -550,7 +548,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isPlugin, true); expect(flutterManifest.isPlugin, true);
expect(flutterManifest.androidPackage, 'com.example'); expect(flutterManifest.androidPackage, 'com.example');
...@@ -571,7 +569,7 @@ flutter: ...@@ -571,7 +569,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isPlugin, true); expect(flutterManifest.isPlugin, true);
expect(flutterManifest.androidPackage, 'com.example'); expect(flutterManifest.androidPackage, 'com.example');
...@@ -591,20 +589,20 @@ flutter: ...@@ -591,20 +589,20 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isPlugin, true); expect(flutterManifest.isPlugin, true);
expect(flutterManifest.androidPackage, isNull); expect(flutterManifest.androidPackage, isNull);
}); });
testUsingContext('FlutterManifest handles an invalid plugin declaration', () { testWithoutContext('FlutterManifest handles an invalid plugin declaration', () {
const String manifest = ''' const String manifest = '''
name: test name: test
flutter: flutter:
plugin: plugin:
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -624,7 +622,7 @@ dependencies: ...@@ -624,7 +622,7 @@ dependencies:
flutter: flutter:
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -646,7 +644,7 @@ dependencies: ...@@ -646,7 +644,7 @@ dependencies:
flutter: flutter:
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -668,7 +666,7 @@ dependencies: ...@@ -668,7 +666,7 @@ dependencies:
flutter: flutter:
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -690,7 +688,7 @@ dependencies: ...@@ -690,7 +688,7 @@ dependencies:
flutter: flutter:
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -712,7 +710,7 @@ dependencies: ...@@ -712,7 +710,7 @@ dependencies:
flutter: flutter:
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -733,7 +731,7 @@ dependencies: ...@@ -733,7 +731,7 @@ dependencies:
flutter: flutter:
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -759,7 +757,7 @@ flutter: ...@@ -759,7 +757,7 @@ flutter:
-asset: a/bar -asset: a/bar
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -783,7 +781,7 @@ flutter: ...@@ -783,7 +781,7 @@ flutter:
- asset - asset
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -807,7 +805,7 @@ flutter: ...@@ -807,7 +805,7 @@ flutter:
-asset: a/bar -asset: a/bar
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -832,7 +830,7 @@ flutter: ...@@ -832,7 +830,7 @@ flutter:
- string - string
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -857,7 +855,7 @@ flutter: ...@@ -857,7 +855,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
final List<Uri> assets = flutterManifest.assets; final List<Uri> assets = flutterManifest.assets;
expect(logger.errorText, contains('Asset manifest contains a null or empty uri.')); expect(logger.errorText, contains('Asset manifest contains a null or empty uri.'));
...@@ -881,7 +879,7 @@ flutter: ...@@ -881,7 +879,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
final List<Uri> assets = flutterManifest.assets; final List<Uri> assets = flutterManifest.assets;
expect(assets, hasLength(3)); expect(assets, hasLength(3));
...@@ -903,7 +901,7 @@ flutter: ...@@ -903,7 +901,7 @@ flutter:
- uses-material-design: true - uses-material-design: true
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -932,7 +930,7 @@ flutter: ...@@ -932,7 +930,7 @@ flutter:
'pubspec.yaml', 'pubspec.yaml',
fileSystem: fileSystem, fileSystem: fileSystem,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isEmpty, false); expect(flutterManifest.isEmpty, false);
}); });
...@@ -953,7 +951,7 @@ flutter: ...@@ -953,7 +951,7 @@ flutter:
'pubspec.yaml', 'pubspec.yaml',
fileSystem: fileSystem, fileSystem: fileSystem,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isEmpty, false); expect(flutterManifest.isEmpty, false);
}); });
...@@ -969,7 +967,7 @@ flutter: ...@@ -969,7 +967,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isPlugin, true); expect(flutterManifest.isPlugin, true);
expect(flutterManifest.supportedPlatforms, null); expect(flutterManifest.supportedPlatforms, null);
...@@ -988,7 +986,7 @@ flutter: ...@@ -988,7 +986,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isPlugin, true); expect(flutterManifest.isPlugin, true);
expect(flutterManifest.validSupportedPlatforms, null); expect(flutterManifest.validSupportedPlatforms, null);
...@@ -1009,12 +1007,13 @@ flutter: ...@@ -1009,12 +1007,13 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isPlugin, true); expect(flutterManifest.isPlugin, true);
expect(flutterManifest.validSupportedPlatforms['ios'], final Map<String, dynamic> validSupportedPlatforms = flutterManifest.validSupportedPlatforms!;
expect(validSupportedPlatforms['ios'],
<String, dynamic>{'pluginClass': 'SomeClass'}); <String, dynamic>{'pluginClass': 'SomeClass'});
expect(flutterManifest.validSupportedPlatforms['some_platform'], expect(validSupportedPlatforms['some_platform'],
isNull); isNull);
}); });
...@@ -1034,12 +1033,13 @@ flutter: ...@@ -1034,12 +1033,13 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.isPlugin, true); expect(flutterManifest.isPlugin, true);
expect(flutterManifest.supportedPlatforms['ios'], final Map<String, dynamic> validSupportedPlatforms = flutterManifest.validSupportedPlatforms!;
expect(validSupportedPlatforms['ios'],
<String, dynamic>{'pluginClass': 'SomeClass'}); <String, dynamic>{'pluginClass': 'SomeClass'});
expect(flutterManifest.supportedPlatforms['android'], expect(validSupportedPlatforms['android'],
<String, dynamic>{'pluginClass': 'SomeClass', <String, dynamic>{'pluginClass': 'SomeClass',
'package': 'com.example'}); 'package': 'com.example'});
}); });
...@@ -1054,7 +1054,7 @@ flutter: ...@@ -1054,7 +1054,7 @@ flutter:
- android - android
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1076,7 +1076,7 @@ flutter: ...@@ -1076,7 +1076,7 @@ flutter:
pluginClass: SomeClass pluginClass: SomeClass
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1100,7 +1100,7 @@ flutter: ...@@ -1100,7 +1100,7 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest.additionalLicenses, <String>['foo.txt']); expect(flutterManifest.additionalLicenses, <String>['foo.txt']);
}); });
...@@ -1115,7 +1115,7 @@ flutter: ...@@ -1115,7 +1115,7 @@ flutter:
licenses: foo.txt licenses: foo.txt
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1136,7 +1136,7 @@ flutter: ...@@ -1136,7 +1136,7 @@ flutter:
- bar: fizz - bar: fizz
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1163,15 +1163,16 @@ flutter: ...@@ -1163,15 +1163,16 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest, isNotNull); expect(flutterManifest, isNotNull);
expect(flutterManifest.deferredComponents.length, 1); final List<DeferredComponent> deferredComponents = flutterManifest.deferredComponents!;
expect(flutterManifest.deferredComponents[0].name, 'component1'); expect(deferredComponents.length, 1);
expect(flutterManifest.deferredComponents[0].libraries.length, 1); expect(deferredComponents[0].name, 'component1');
expect(flutterManifest.deferredComponents[0].libraries[0], 'lib1'); expect(deferredComponents[0].libraries.length, 1);
expect(flutterManifest.deferredComponents[0].assets.length, 1); expect(deferredComponents[0].libraries[0], 'lib1');
expect(flutterManifest.deferredComponents[0].assets[0].path, 'path/to/asset.jpg'); expect(deferredComponents[0].assets.length, 1);
expect(deferredComponents[0].assets[0].path, 'path/to/asset.jpg');
}); });
testWithoutContext('FlutterManifest parses multiple deferred components', () async { testWithoutContext('FlutterManifest parses multiple deferred components', () async {
...@@ -1198,22 +1199,23 @@ flutter: ...@@ -1198,22 +1199,23 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest, isNotNull); expect(flutterManifest, isNotNull);
expect(flutterManifest.deferredComponents.length, 2); final List<DeferredComponent> deferredComponents = flutterManifest.deferredComponents!;
expect(flutterManifest.deferredComponents[0].name, 'component1'); expect(deferredComponents.length, 2);
expect(flutterManifest.deferredComponents[0].libraries.length, 1); expect(deferredComponents[0].name, 'component1');
expect(flutterManifest.deferredComponents[0].libraries[0], 'lib1'); expect(deferredComponents[0].libraries.length, 1);
expect(flutterManifest.deferredComponents[0].assets.length, 1); expect(deferredComponents[0].libraries[0], 'lib1');
expect(flutterManifest.deferredComponents[0].assets[0].path, 'path/to/asset.jpg'); expect(deferredComponents[0].assets.length, 1);
expect(deferredComponents[0].assets[0].path, 'path/to/asset.jpg');
expect(flutterManifest.deferredComponents[1].name, 'component2');
expect(flutterManifest.deferredComponents[1].libraries.length, 2); expect(deferredComponents[1].name, 'component2');
expect(flutterManifest.deferredComponents[1].libraries[0], 'lib2'); expect(deferredComponents[1].libraries.length, 2);
expect(flutterManifest.deferredComponents[1].libraries[1], 'lib3'); expect(deferredComponents[1].libraries[0], 'lib2');
expect(flutterManifest.deferredComponents[1].assets.length, 1); expect(deferredComponents[1].libraries[1], 'lib3');
expect(flutterManifest.deferredComponents[1].assets[0].path, 'path/to/asset2.jpg'); expect(deferredComponents[1].assets.length, 1);
expect(deferredComponents[1].assets[0].path, 'path/to/asset2.jpg');
}); });
testWithoutContext('FlutterManifest parses empty deferred components', () async { testWithoutContext('FlutterManifest parses empty deferred components', () async {
...@@ -1229,10 +1231,10 @@ flutter: ...@@ -1229,10 +1231,10 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest, isNotNull); expect(flutterManifest, isNotNull);
expect(flutterManifest.deferredComponents.length, 0); expect(flutterManifest.deferredComponents!.length, 0);
}); });
testWithoutContext('FlutterManifest deferred component requires name', () async { testWithoutContext('FlutterManifest deferred component requires name', () async {
...@@ -1247,7 +1249,7 @@ flutter: ...@@ -1247,7 +1249,7 @@ flutter:
- lib1 - lib1
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1266,7 +1268,7 @@ flutter: ...@@ -1266,7 +1268,7 @@ flutter:
deferred-components: blah deferred-components: blah
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1287,7 +1289,7 @@ flutter: ...@@ -1287,7 +1289,7 @@ flutter:
libraries: blah libraries: blah
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1309,7 +1311,7 @@ flutter: ...@@ -1309,7 +1311,7 @@ flutter:
- not-a-string: - not-a-string:
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1331,7 +1333,7 @@ flutter: ...@@ -1331,7 +1333,7 @@ flutter:
- not-a-string: - not-a-string:
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1355,7 +1357,7 @@ flutter: ...@@ -1355,7 +1357,7 @@ flutter:
- woo - woo
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1382,7 +1384,7 @@ flutter: ...@@ -1382,7 +1384,7 @@ flutter:
- woo - woo
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1403,7 +1405,7 @@ flutter: ...@@ -1403,7 +1405,7 @@ flutter:
assets: blah assets: blah
'''; ''';
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest? flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); );
...@@ -1430,23 +1432,24 @@ flutter: ...@@ -1430,23 +1432,24 @@ flutter:
final FlutterManifest flutterManifest = FlutterManifest.createFromString( final FlutterManifest flutterManifest = FlutterManifest.createFromString(
manifest, manifest,
logger: logger, logger: logger,
); )!;
expect(flutterManifest, isNotNull); expect(flutterManifest, isNotNull);
expect(flutterManifest.deferredComponents.length, 1); final List<DeferredComponent> deferredComponents = flutterManifest.deferredComponents!;
expect(flutterManifest.deferredComponents[0].name, 'component1'); expect(deferredComponents.length, 1);
expect(flutterManifest.deferredComponents[0].libraries.length, 0); expect(deferredComponents[0].name, 'component1');
expect(flutterManifest.deferredComponents[0].assets.length, 3); expect(deferredComponents[0].libraries.length, 0);
expect(flutterManifest.deferredComponents[0].assets[0].path, 'path/to/asset1.jpg'); expect(deferredComponents[0].assets.length, 3);
expect(flutterManifest.deferredComponents[0].assets[1].path, 'path/to/asset2.jpg'); expect(deferredComponents[0].assets[0].path, 'path/to/asset1.jpg');
expect(flutterManifest.deferredComponents[0].assets[2].path, 'path/to/asset3.jpg'); expect(deferredComponents[0].assets[1].path, 'path/to/asset2.jpg');
expect(deferredComponents[0].assets[2].path, 'path/to/asset3.jpg');
}); });
} }
Matcher matchesManifest({ Matcher matchesManifest({
String appVersion, String? appVersion,
String buildName, String? buildName,
String buildNumber, String? buildNumber,
}) { }) {
return isA<FlutterManifest>() return isA<FlutterManifest>()
.having((FlutterManifest manifest) => manifest.appVersion, 'appVersion', appVersion) .having((FlutterManifest manifest) => manifest.appVersion, 'appVersion', appVersion)
...@@ -1455,9 +1458,9 @@ Matcher matchesManifest({ ...@@ -1455,9 +1458,9 @@ Matcher matchesManifest({
} }
Matcher matchesFontAsset({ Matcher matchesFontAsset({
Uri assetUri, required Uri assetUri,
int weight, int? weight,
String style, String? style,
}) { }) {
return isA<FontAsset>() return isA<FontAsset>()
.having((FontAsset fontAsset) => fontAsset.assetUri, 'assetUri', assetUri) .having((FontAsset fontAsset) => fontAsset.assetUri, 'assetUri', assetUri)
...@@ -1466,9 +1469,9 @@ Matcher matchesFontAsset({ ...@@ -1466,9 +1469,9 @@ Matcher matchesFontAsset({
} }
Matcher matchesFont({ Matcher matchesFont({
Map<String, Object> descriptor, required Map<String, Object> descriptor,
String familyName, required String familyName,
List<Matcher> fontAssets, required List<Matcher> fontAssets,
}) { }) {
return isA<Font>() return isA<Font>()
.having((Font font) => font.descriptor, 'descriptor', descriptor) .having((Font font) => font.descriptor, 'descriptor', descriptor)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment