Commit 49ba9747 authored by Sarah Zakarias's avatar Sarah Zakarias Committed by GitHub

Factor out flutter manifest logic (#12237)

parent a08b5e00
......@@ -5,7 +5,6 @@
import 'dart:async';
import 'dart:convert';
import 'package:json_schema/json_schema.dart';
import 'package:yaml/yaml.dart';
import 'base/file_system.dart';
......@@ -13,6 +12,7 @@ import 'build_info.dart';
import 'cache.dart';
import 'dart/package_map.dart';
import 'devfs.dart';
import 'flutter_manifest.dart';
import 'globals.dart';
/// A bundle of assets.
......@@ -72,27 +72,16 @@ class AssetBundle {
}) async {
workingDirPath ??= getAssetBuildDirectory();
packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath);
Object manifest;
FlutterManifest flutterManifest;
try {
manifest = _loadFlutterManifest(manifestPath);
flutterManifest = await FlutterManifest.createFromPath(manifestPath);
if (flutterManifest == null)
return 1;
} catch (e) {
printStatus('Error detected in pubspec.yaml:', emphasis: true);
printError('$e');
return 1;
}
if (manifest == null) {
// No manifest file found for this application.
entries[_kAssetManifestJson] = new DevFSStringContent('{}');
return 0;
}
if (manifest != null) {
final int result = await _validateFlutterManifest(manifest);
if (result != 0)
return result;
}
Map<String, dynamic> manifestDescriptor = manifest;
final String appName = manifestDescriptor['name'];
manifestDescriptor = manifestDescriptor['flutter'] ?? <String, dynamic>{};
final String assetBasePath = fs.path.dirname(fs.path.absolute(manifestPath));
_lastBuildTimestamp = new DateTime.now();
......@@ -105,7 +94,7 @@ class AssetBundle {
// see _AssetDirectoryCache.
final Map<_Asset, List<_Asset>> assetVariants = _parseAssets(
packageMap,
manifestDescriptor,
flutterManifest,
assetBasePath,
excludeDirs: <String>[workingDirPath, getBuildDirectory()]
);
......@@ -113,49 +102,44 @@ class AssetBundle {
if (assetVariants == null)
return 1;
final bool usesMaterialDesign = (manifestDescriptor != null) &&
manifestDescriptor.containsKey('uses-material-design') &&
manifestDescriptor['uses-material-design'];
final List<Map<String, dynamic>> fonts = _parseFonts(
flutterManifest,
includeDefaultFonts,
packageMap,
);
// Add assets from packages.
final List<Map<String, dynamic>> fonts = <Map<String, dynamic>>[];
// Add fonts and assets from packages.
for (String packageName in packageMap.map.keys) {
final Uri package = packageMap.map[packageName];
if (package != null && package.scheme == 'file') {
final String packageManifestPath = package.resolve('../pubspec.yaml').path;
final Object packageManifest = _loadFlutterManifest(packageManifestPath);
if (packageManifest == null)
final FlutterManifest packageFlutterManifest = await FlutterManifest.createFromPath(packageManifestPath);
if (packageFlutterManifest == null)
continue;
final int result = await _validateFlutterManifest(packageManifest);
if (result == 0) {
Map<String, dynamic> packageManifestDescriptor = packageManifest;
// Skip the app itself.
if (packageManifestDescriptor['name'] == appName)
// Skip the app itself
if (packageFlutterManifest.appName == flutterManifest.appName)
continue;
if (packageManifestDescriptor.containsKey('flutter')) {
packageManifestDescriptor = packageManifestDescriptor['flutter'];
final String packageBasePath = fs.path.dirname(packageManifestPath);
assetVariants.addAll(_parseAssets(
final Map<_Asset, List<_Asset>> packageAssets = _parseAssets(
packageMap,
packageManifestDescriptor,
packageFlutterManifest,
packageBasePath,
packageName: packageName,
));
);
if (packageAssets == null)
return 1;
assetVariants.addAll(packageAssets);
final bool packageUsesMaterialDesign =
packageManifestDescriptor.containsKey('uses-material-design') &&
packageManifestDescriptor['uses-material-design'];
fonts.addAll(_parseFonts(
packageManifestDescriptor,
packageUsesMaterialDesign,
packageFlutterManifest,
includeDefaultFonts,
packageMap,
packageName: packageName,
));
}
}
}
}
// Save the contents of each image, image variant, and font
// asset in entries.
......@@ -182,7 +166,7 @@ class AssetBundle {
}
final List<_Asset> materialAssets = <_Asset>[];
if (usesMaterialDesign && includeDefaultFonts) {
if (flutterManifest.usesMaterialDesign && includeDefaultFonts) {
materialAssets.addAll(_getMaterialAssets(_kFontSetMaterial));
}
for (_Asset asset in materialAssets) {
......@@ -192,12 +176,6 @@ class AssetBundle {
entries[_kAssetManifestJson] = _createAssetManifest(assetVariants);
fonts.addAll(_parseFonts(
manifestDescriptor,
usesMaterialDesign,
includeDefaultFonts,
packageMap,
));
if (fonts.isNotEmpty)
entries[_kFontManifestJson] = new DevFSStringContent(JSON.encode(fonts));
......@@ -386,72 +364,61 @@ DevFSContent _createAssetManifest(Map<_Asset, List<_Asset>> assetVariants) {
}
List<Map<String, dynamic>> _parseFonts(
Map<String, dynamic> manifestDescriptor,
bool usesMaterialDesign,
FlutterManifest manifest,
bool includeDefaultFonts,
PackageMap packageMap, {
String packageName
}) {
final List<Map<String, dynamic>> fonts = <Map<String, dynamic>>[];
if (usesMaterialDesign && includeDefaultFonts) {
if (manifest.usesMaterialDesign && includeDefaultFonts) {
fonts.addAll(_getMaterialFonts(AssetBundle._kFontSetMaterial));
}
if (manifestDescriptor != null && manifestDescriptor.containsKey('fonts'))
if (packageName == null) {
fonts.addAll(manifestDescriptor['fonts']);
fonts.addAll(manifest.fontsDescriptor);
} else {
fonts.addAll(_parsePackageFonts(
manifestDescriptor['fonts'],
fonts.addAll(_createFontsDescriptor(_parsePackageFonts(
manifest,
packageName,
packageMap,
));
)));
}
return fonts;
}
/// Prefixes family names and asset paths of fonts included from packages with
/// 'packages/<package_name>
///
/// (e.g., replace {"fonts":[{"asset":"a/bar"}],"family":"bar"} by
/// {"fonts":[{"asset":"packages/foo/a/bar"}],"family":"packages/foo/bar"})
List<Map<String, dynamic>> _parsePackageFonts(
List<Map<String, dynamic>> manifestDescriptor,
/// 'packages/<package_name>'
List<Font> _parsePackageFonts(
FlutterManifest manifest,
String packageName,
PackageMap packageMap,
) {
final List<Map<String, dynamic>> parsedFonts = <Map<String, dynamic>>[];
for (Map<String, dynamic> fontFamily in manifestDescriptor) {
final Map<String, dynamic> parsedFontFamily = <String, dynamic>{};
for (String key in fontFamily.keys) {
if (key == 'family') {
parsedFontFamily[key] = 'packages/$packageName/${fontFamily[key]}';
} else {
assert(key == 'fonts');
final List<Map<String, dynamic>> parsedAssets = <Map<String, dynamic>>[];
for (Map<String, dynamic> assetProperties in fontFamily[key]) {
final Map<String, dynamic> parsedAssetProperties = <String, dynamic>{};
for (String property in assetProperties.keys) {
if (property == 'asset') {
final String assetPath = assetProperties[property];
final List<Font> packageFonts = <Font>[];
for (Font font in manifest.fonts) {
final List<FontAsset> packageFontAssets = <FontAsset>[];
for (FontAsset fontAsset in font.fontAssets) {
final String assetPath = fontAsset.asset;
if (assetPath.startsWith('packages') &&
!fs.isFileSync(packageMap.map[packageName].resolve('../$assetPath').path))
parsedAssetProperties[property] = assetProperties[property];
else
parsedAssetProperties[property] = 'packages/$packageName/${assetProperties[property]}';
!fs.isFileSync(packageMap.map[packageName].resolve('../$assetPath').path)) {
packageFontAssets.add(new FontAsset(
fontAsset.asset,
weight: fontAsset.weight,
style: fontAsset.style,
));
} else {
assert(property == 'style' || property == 'weight');
parsedAssetProperties[property] = assetProperties[property];
}
}
parsedAssets.add(parsedAssetProperties);
}
parsedFontFamily[key] = parsedAssets;
packageFontAssets.add(new FontAsset(
'packages/$packageName/${fontAsset.asset}',
weight: fontAsset.weight,
style: fontAsset.style,
));
}
}
parsedFonts.add(parsedFontFamily);
packageFonts.add(new Font('packages/$packageName/${font.familyName}', packageFontAssets));
}
return packageFonts;
}
return parsedFonts;
List<Map<String, dynamic>> _createFontsDescriptor(List<Font> fonts) {
return fonts.map((Font font) => font.descriptor).toList();
}
// Given an assets directory like this:
......@@ -504,19 +471,15 @@ class _AssetDirectoryCache {
/// Returns null on missing assets.
Map<_Asset, List<_Asset>> _parseAssets(
PackageMap packageMap,
Map<String, dynamic> manifestDescriptor,
FlutterManifest flutterManifest,
String assetBase, {
List<String> excludeDirs: const <String>[],
String packageName
}) {
final Map<_Asset, List<_Asset>> result = <_Asset, List<_Asset>>{};
if (manifestDescriptor == null)
return result;
if (manifestDescriptor.containsKey('assets')) {
final _AssetDirectoryCache cache = new _AssetDirectoryCache(excludeDirs);
for (String assetName in manifestDescriptor['assets']) {
for (String assetName in flutterManifest.assets) {
final _Asset asset = _resolveAsset(
packageMap,
assetBase,
......@@ -534,35 +497,24 @@ Map<_Asset, List<_Asset>> _parseAssets(
result[asset] = variants;
}
}
// Add assets referenced in the fonts section of the manifest.
if (manifestDescriptor.containsKey('fonts')) {
for (Map<String, dynamic> family in manifestDescriptor['fonts']) {
final List<Map<String, dynamic>> fonts = family['fonts'];
if (fonts == null)
continue;
for (Map<String, dynamic> font in fonts) {
final String asset = font['asset'];
if (asset == null)
continue;
for (Font font in flutterManifest.fonts) {
for (FontAsset fontAsset in font.fontAssets) {
final _Asset baseAsset = _resolveAsset(
packageMap,
assetBase,
asset,
fontAsset.asset,
packageName,
);
if (!baseAsset.assetFileExists) {
printError('Error: unable to locate asset entry in pubspec.yaml: "$asset".');
printError('Error: unable to locate asset entry in pubspec.yaml: "${fontAsset.asset}".');
return null;
}
result[baseAsset] = <_Asset>[];
}
}
}
return result;
}
......@@ -613,25 +565,3 @@ _Asset _resolvePackageAsset(String asset, PackageMap packageMap) {
printError('Could not resolve package $packageKey for asset $asset.\n');
return null;
}
dynamic _loadFlutterManifest(String manifestPath) {
if (manifestPath == null || !fs.isFileSync(manifestPath))
return null;
final String manifestDescriptor = fs.file(manifestPath).readAsStringSync();
return loadYaml(manifestDescriptor);
}
Future<int> _validateFlutterManifest(Object manifest) async {
final String schemaPath = fs.path.join(fs.path.absolute(Cache.flutterRoot),
'packages', 'flutter_tools', 'schema', 'pubspec_yaml.json');
final Schema schema = await Schema.createSchemaFromUrl(fs.path.toUri(schemaPath).toString());
final Validator validator = new Validator(schema);
if (validator.validate(manifest)) {
return 0;
} else {
printStatus('Error detected in pubspec.yaml:', emphasis: true);
printError(validator.errors.join('\n'));
return 1;
}
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter_tools/src/globals.dart';
import 'package:json_schema/json_schema.dart';
import 'package:yaml/yaml.dart';
import 'base/file_system.dart';
import 'cache.dart';
/// A wrapper around the `flutter` section in the `pubspec.yaml` file.
class FlutterManifest {
FlutterManifest._();
/// Returns null on missing or invalid manifest
static Future<FlutterManifest> createFromPath(String path) async {
return _createFromYaml(await _loadFlutterManifest(path));
}
/// Returns null on missing or invalid manifest
static Future<FlutterManifest> createFromString(String manifest) async {
return _createFromYaml(loadYaml(manifest));
}
static Future<FlutterManifest> _createFromYaml(Object yamlDocument) async {
final FlutterManifest pubspec = new FlutterManifest._();
if (yamlDocument == null || !await _validate(yamlDocument))
return null;
pubspec._descriptor = yamlDocument;
pubspec._flutterDescriptor = pubspec._descriptor['flutter'] ?? <String, dynamic>{};
return pubspec;
}
/// A map representation of the entire `pubspec.yaml` file.
Map<String, dynamic> _descriptor;
/// A map representation of the `flutter` section in the `pubspec.yaml` file.
Map<String, dynamic> _flutterDescriptor;
String get appName => _descriptor['name'];
bool get usesMaterialDesign {
return _flutterDescriptor['uses-material-design'] ?? false;
}
List<Map<String, dynamic>> get fontsDescriptor {
return _flutterDescriptor['fonts'] ?? const <Map<String, dynamic>>[];
}
List<String> get assets {
return _flutterDescriptor['assets'] ?? const <String>[];
}
List<Font> _fonts;
List<Font> get fonts {
_fonts ??= _extractFonts();
return _fonts;
}
List<Font> _extractFonts() {
if (!_flutterDescriptor.containsKey('fonts'))
return <Font>[];
final List<Font> fonts = <Font>[];
for (Map<String, dynamic> fontFamily in _flutterDescriptor['fonts']) {
final List<Map<String, dynamic>> fontFiles = fontFamily['fonts'];
final String familyName = fontFamily['family'];
if (familyName == null) {
printError('Warning: Missing family name for font.', emphasis: true);
continue;
}
if (fontFiles == null) {
printError('Warning: No fonts specified for font $familyName', emphasis: true);
continue;
}
final List<FontAsset> fontAssets = <FontAsset>[];
for (Map<String, dynamic> fontFile in fontFiles) {
final String asset = fontFile['asset'];
if (asset == null) {
printError('Warning: Missing asset in fonts for $familyName', emphasis: true);
continue;
}
fontAssets.add(new FontAsset(
asset,
weight: fontFile['weight'],
style: fontFile['style'],
));
}
if (fontAssets.isNotEmpty)
fonts.add(new Font(fontFamily['family'], fontAssets));
}
return fonts;
}
}
class Font {
Font(this.familyName, this.fontAssets) {
assert(familyName != null);
assert(fontAssets != null);
assert(fontAssets.isNotEmpty);
}
final String familyName;
final List<FontAsset> fontAssets;
Map<String, dynamic> get descriptor {
return <String, dynamic>{
'family': familyName,
'fonts': fontAssets.map((FontAsset a) => a.descriptor).toList(),
};
}
@override
String toString() => '$runtimeType(family: $familyName, assets: $fontAssets)';
}
class FontAsset {
FontAsset(this.asset, {this.weight, this.style}) {
assert(asset != null);
}
final String asset;
final int weight;
final String style;
Map<String, dynamic> get descriptor {
final Map<String, dynamic> descriptor = <String, dynamic>{};
if (weight != null)
descriptor['weight'] = weight;
if (style != null)
descriptor['style'] = style;
descriptor['asset'] = asset;
return descriptor;
}
@override
String toString() => '$runtimeType(asset: $asset, weight; $weight, style: $style)';
}
Future<dynamic> _loadFlutterManifest(String manifestPath) async {
if (manifestPath == null || !fs.isFileSync(manifestPath))
return null;
final String manifestDescriptor = await fs.file(manifestPath).readAsString();
return loadYaml(manifestDescriptor);
}
Future<bool> _validate(Object manifest) async {
final String schemaPath = fs.path.join(
fs.path.absolute(Cache.flutterRoot), 'packages', 'flutter_tools', 'schema',
'pubspec_yaml.json',
);
final Schema schema = await Schema.createSchemaFromUrl(fs.path.toUri(schemaPath).toString());
final Validator validator = new Validator(schema);
if (validator.validate(manifest)) {
return true;
} else {
printStatus('Error detected in pubspec.yaml:', emphasis: true);
printError(validator.errors.join('\n'));
return false;
}
}
\ No newline at end of file
......@@ -180,8 +180,8 @@ $fontsSection
writeFontAsset('p/p/', font);
final String expectedFontManifest =
'[{"fonts":[{"asset":"packages/test_package/a/bar"}],'
'"family":"packages/test_package/foo"}]';
'[{"family":"packages/test_package/foo",'
'"fonts":[{"asset":"packages/test_package/a/bar"}]}]';
await buildAndVerifyFonts(
<String>[],
<String>[font],
......@@ -211,8 +211,8 @@ $fontsSection
writeFontAsset('p2/p/lib/', font);
final String expectedFontManifest =
'[{"fonts":[{"asset":"packages/test_package2/bar"}],'
'"family":"packages/test_package/foo"}]';
'[{"family":"packages/test_package/foo",'
'"fonts":[{"asset":"packages/test_package2/bar"}]}]';
await buildAndVerifyFonts(
<String>[],
<String>[font],
......@@ -243,8 +243,8 @@ $fontsSection
writeFontAsset('p/p/', font);
final String expectedFontManifest =
'[{"fonts":[{"weight":400,"style":"italic","asset":"packages/test_package/a/bar"}],'
'"family":"packages/test_package/foo"}]';
'[{"family":"packages/test_package/foo",'
'"fonts":[{"weight":400,"style":"italic","asset":"packages/test_package/a/bar"}]}]';
await buildAndVerifyFonts(
<String>[],
<String>[font],
......@@ -278,9 +278,9 @@ $fontsSection
writeFontAsset('p/p/', font);
final String expectedFontManifest =
'[{"fonts":[{"asset":"packages/test_package/a/bar"}],'
'"family":"packages/test_package/foo"},'
'{"fonts":[{"asset":"a/bar"}],"family":"foo"}]';
'[{"fonts":[{"asset":"a/bar"}],"family":"foo"},'
'{"family":"packages/test_package/foo",'
'"fonts":[{"asset":"packages/test_package/a/bar"}]}]';
await buildAndVerifyFonts(
<String>[font],
<String>[font],
......
// Copyright 2017 The Chromium 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:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/flutter_manifest.dart';
import 'package:test/test.dart';
import 'src/common.dart';
import 'src/context.dart';
void main() {
setUpAll(() {
Cache.flutterRoot = getFlutterRoot();
});
group('FlutterManifest', () {
test('has no fonts or assets when the "flutter" section is empty', () async {
final String manifest = '''
name: test
dependencies:
flutter:
sdk: flutter
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
expect(flutterManifest, isNotNull);
expect(flutterManifest.appName, 'test');
expect(flutterManifest.usesMaterialDesign, false);
expect(flutterManifest.fontsDescriptor, isEmpty);
expect(flutterManifest.fonts, isEmpty);
expect(flutterManifest.assets, isEmpty);
});
test('knows if material design is used', () async {
final String manifest = '''
name: test
dependencies:
flutter:
sdk: flutter
flutter:
uses-material-design: true
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
expect(flutterManifest.usesMaterialDesign, true);
});
test('has two assets', () async {
final String manifest = '''
name: test
dependencies:
flutter:
sdk: flutter
flutter:
uses-material-design: true
assets:
- a/foo
- a/bar
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
expect(flutterManifest.assets, <String>['a/foo', 'a/bar']);
});
test('has one font family with one asset', () async {
final String manifest = '''
name: test
dependencies:
flutter:
sdk: flutter
flutter:
uses-material-design: true
fonts:
- family: foo
fonts:
- asset: a/bar
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
expect(flutterManifest.fontsDescriptor.toString(), '[{fonts: [{asset: a/bar}], family: foo}]');
final List<Font> fonts = flutterManifest.fonts;
expect(fonts.length, 1);
final Font font = fonts[0];
final String fontDescriptor = '{family: foo, fonts: [{asset: a/bar}]}';
expect(font.descriptor.toString(), fontDescriptor);
expect(font.familyName, 'foo');
final List<FontAsset> assets = font.fontAssets;
expect(assets.length, 1);
final FontAsset fontAsset = assets[0];
expect(fontAsset.asset, 'a/bar');
expect(fontAsset.weight, isNull);
expect(fontAsset.style, isNull);
});
test('has one font family with a simple asset and one with weight', () async {
final String manifest = '''
name: test
dependencies:
flutter:
sdk: flutter
flutter:
uses-material-design: true
fonts:
- family: foo
fonts:
- asset: a/bar
- asset: a/bar
weight: 400
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
final String expectedFontsDescriptor = '[{fonts: [{asset: a/bar}, {weight: 400, asset: a/bar}], family: foo}]';
expect(flutterManifest.fontsDescriptor.toString(), expectedFontsDescriptor);
final List<Font> fonts = flutterManifest.fonts;
expect(fonts.length, 1);
final Font font = fonts[0];
final String fontDescriptor = '{family: foo, fonts: [{asset: a/bar}, {weight: 400, asset: a/bar}]}';
expect(font.descriptor.toString(), fontDescriptor);
expect(font.familyName, 'foo');
final List<FontAsset> assets = font.fontAssets;
expect(assets.length, 2);
final FontAsset fontAsset0 = assets[0];
expect(fontAsset0.asset, 'a/bar');
expect(fontAsset0.weight, isNull);
expect(fontAsset0.style, isNull);
final FontAsset fontAsset1 = assets[1];
expect(fontAsset1.asset, 'a/bar');
expect(fontAsset1.weight, 400);
expect(fontAsset1.style, isNull);
});
test('has one font family with a simple asset and one with weight and style', () async {
final String manifest = '''
name: test
dependencies:
flutter:
sdk: flutter
flutter:
uses-material-design: true
fonts:
- family: foo
fonts:
- asset: a/bar
- asset: a/bar
weight: 400
style: italic
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
final String expectedFontsDescriptor = '[{fonts: [{asset: a/bar}, {style: italic, weight: 400, asset: a/bar}], family: foo}]';
expect(flutterManifest.fontsDescriptor.toString(), expectedFontsDescriptor);
final List<Font> fonts = flutterManifest.fonts;
expect(fonts.length, 1);
final Font font = fonts[0];
final String fontDescriptor = '{family: foo, fonts: [{asset: a/bar}, {weight: 400, style: italic, asset: a/bar}]}';
expect(font.descriptor.toString(), fontDescriptor);
expect(font.familyName, 'foo');
final List<FontAsset> assets = font.fontAssets;
expect(assets.length, 2);
final FontAsset fontAsset0 = assets[0];
expect(fontAsset0.asset, 'a/bar');
expect(fontAsset0.weight, isNull);
expect(fontAsset0.style, isNull);
final FontAsset fontAsset1 = assets[1];
expect(fontAsset1.asset, 'a/bar');
expect(fontAsset1.weight, 400);
expect(fontAsset1.style, 'italic');
});
test('has two font families, each with one simple asset and one with weight and style', () async {
final String manifest = '''
name: test
dependencies:
flutter:
sdk: flutter
flutter:
uses-material-design: true
fonts:
- family: foo
fonts:
- asset: a/bar
- asset: a/bar
weight: 400
style: italic
- family: bar
fonts:
- asset: a/baz
- weight: 400
asset: a/baz
style: italic
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
final String expectedFontsDescriptor = '[{fonts: [{asset: a/bar}, {style: italic, weight: 400, asset: a/bar}], family: foo},'
' {fonts: [{asset: a/baz}, {style: italic, weight: 400, asset: a/baz}], family: bar}]';
expect(flutterManifest.fontsDescriptor.toString(), expectedFontsDescriptor);
final List<Font> fonts = flutterManifest.fonts;
expect(fonts.length, 2);
final Font fooFont = fonts[0];
final String barFontDescriptor = '{family: foo, fonts: [{asset: a/bar}, {weight: 400, style: italic, asset: a/bar}]}';
expect(fooFont.descriptor.toString(), barFontDescriptor);
expect(fooFont.familyName, 'foo');
final List<FontAsset> fooAassets = fooFont.fontAssets;
expect(fooAassets.length, 2);
final FontAsset fooFontAsset0 = fooAassets[0];
expect(fooFontAsset0.asset, 'a/bar');
expect(fooFontAsset0.weight, isNull);
expect(fooFontAsset0.style, isNull);
final FontAsset fooFontAsset1 = fooAassets[1];
expect(fooFontAsset1.asset, 'a/bar');
expect(fooFontAsset1.weight, 400);
expect(fooFontAsset1.style, 'italic');
final Font barFont = fonts[1];
final String fontDescriptor = '{family: bar, fonts: [{asset: a/baz}, {weight: 400, style: italic, asset: a/baz}]}';
expect(barFont.descriptor.toString(), fontDescriptor);
expect(barFont.familyName, 'bar');
final List<FontAsset> barAssets = barFont.fontAssets;
expect(barAssets.length, 2);
final FontAsset barFontAsset0 = barAssets[0];
expect(barFontAsset0.asset, 'a/baz');
expect(barFontAsset0.weight, isNull);
expect(barFontAsset0.style, isNull);
final FontAsset barFontAsset1 = barAssets[1];
expect(barFontAsset1.asset, 'a/baz');
expect(barFontAsset1.weight, 400);
expect(barFontAsset1.style, 'italic');
});
testUsingContext('has only one of two font familes when one declaration is missing the "family" option', () async {
final String manifest = '''
name: test
dependencies:
flutter:
sdk: flutter
flutter:
uses-material-design: true
fonts:
- family: foo
fonts:
- asset: a/bar
- asset: a/bar
weight: 400
style: italic
- fonts:
- asset: a/baz
- asset: a/baz
weight: 400
style: italic
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
final String expectedFontsDescriptor = '[{fonts: [{asset: a/bar}, {style: italic, weight: 400, asset: a/bar}], family: foo},'
' {fonts: [{asset: a/baz}, {style: italic, weight: 400, asset: a/baz}]}]';
expect(flutterManifest.fontsDescriptor.toString(), expectedFontsDescriptor);
final List<Font> fonts = flutterManifest.fonts;
expect(fonts.length, 1);
final Font fooFont = fonts[0];
final String barFontDescriptor = '{family: foo, fonts: [{asset: a/bar}, {weight: 400, style: italic, asset: a/bar}]}';
expect(fooFont.descriptor.toString(), barFontDescriptor);
expect(fooFont.familyName, 'foo');
final List<FontAsset> fooAassets = fooFont.fontAssets;
expect(fooAassets.length, 2);
final FontAsset fooFontAsset0 = fooAassets[0];
expect(fooFontAsset0.asset, 'a/bar');
expect(fooFontAsset0.weight, isNull);
expect(fooFontAsset0.style, isNull);
final FontAsset fooFontAsset1 = fooAassets[1];
expect(fooFontAsset1.asset, 'a/bar');
expect(fooFontAsset1.weight, 400);
expect(fooFontAsset1.style, 'italic');
});
testUsingContext('has only one of two font familes when one declaration is missing the "fonts" option', () async {
final String manifest = '''
name: test
dependencies:
flutter:
sdk: flutter
flutter:
uses-material-design: true
fonts:
- family: foo
fonts:
- asset: a/bar
- asset: a/bar
weight: 400
style: italic
- family: bar
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
final String expectedFontsDescriptor = '[{fonts: [{asset: a/bar}, {style: italic, weight: 400, asset: a/bar}], family: foo},'
' {family: bar}]';
expect(flutterManifest.fontsDescriptor.toString(), expectedFontsDescriptor);
final List<Font> fonts = flutterManifest.fonts;
expect(fonts.length, 1);
final Font fooFont = fonts[0];
final String barFontDescriptor = '{family: foo, fonts: [{asset: a/bar}, {weight: 400, style: italic, asset: a/bar}]}';
expect(fooFont.descriptor.toString(), barFontDescriptor);
expect(fooFont.familyName, 'foo');
final List<FontAsset> fooAassets = fooFont.fontAssets;
expect(fooAassets.length, 2);
final FontAsset fooFontAsset0 = fooAassets[0];
expect(fooFontAsset0.asset, 'a/bar');
expect(fooFontAsset0.weight, isNull);
expect(fooFontAsset0.style, isNull);
final FontAsset fooFontAsset1 = fooAassets[1];
expect(fooFontAsset1.asset, 'a/bar');
expect(fooFontAsset1.weight, 400);
expect(fooFontAsset1.style, 'italic');
});
testUsingContext('has no font family when declaration is missing the "asset" option', () async {
final String manifest = '''
name: test
dependencies:
flutter:
sdk: flutter
flutter:
uses-material-design: true
fonts:
- family: foo
fonts:
- weight: 400
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
final String expectedFontsDescriptor = '[{fonts: [{weight: 400}], family: foo}]';
expect(flutterManifest.fontsDescriptor.toString(), expectedFontsDescriptor);
final List<Font> fonts = flutterManifest.fonts;
expect(fonts.length, 0);
});
});
}
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