Unverified Commit 84580b54 authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Make Assets more robust across platforms (#14246)

parent 9654659c
......@@ -167,7 +167,7 @@ class AssetBundle {
}
for (_Asset variant in assetVariants[asset]) {
assert(variant.assetFileExists);
entries[variant.assetEntry] = new DevFSFileContent(variant.assetFile);
entries[variant.entryUri.path] = new DevFSFileContent(variant.assetFile);
}
}
......@@ -177,7 +177,7 @@ class AssetBundle {
}
for (_Asset asset in materialAssets) {
assert(asset.assetFileExists);
entries[asset.assetEntry] = new DevFSFileContent(asset.assetFile);
entries[asset.entryUri.path] = new DevFSFileContent(asset.assetFile);
}
entries[_kAssetManifestJson] = _createAssetManifest(assetVariants);
......@@ -199,38 +199,34 @@ class AssetBundle {
}
class _Asset {
_Asset({ this.base, String assetEntry, this.relativePath, this.source })
: _assetEntry = assetEntry;
_Asset({ this.baseDir, this.relativeUri, this.entryUri });
final String _assetEntry;
final String baseDir;
final String base;
/// A platform-independent Uri where this asset can be found on disk on the
/// host system relative to [baseDir].
final Uri relativeUri;
/// The entry to list in the generated asset manifest.
String get assetEntry => _assetEntry ?? relativePath;
/// Where the resource is on disk relative to [base].
final String relativePath;
final String source;
/// A platform-independent Uri representing the entry for the asset manifest.
final Uri entryUri;
File get assetFile {
return fs.file(source != null ? '$base/$source' : '$base/$relativePath');
return fs.file(fs.path.join(baseDir, fs.path.fromUri(relativeUri)));
}
bool get assetFileExists => assetFile.existsSync();
/// The delta between what the assetEntry is and the relativePath (e.g.,
/// The delta between what the entryUri is and the relativeUri (e.g.,
/// packages/flutter_gallery).
String get symbolicPrefix {
if (_assetEntry == null || _assetEntry == relativePath)
Uri get symbolicPrefixUri {
if (entryUri == relativeUri)
return null;
final int index = _assetEntry.indexOf(relativePath);
return index == -1 ? null : _assetEntry.substring(0, index);
final int index = entryUri.path.indexOf(relativeUri.path);
return index == -1 ? null : new Uri(path: entryUri.path.substring(0, index));
}
@override
String toString() => 'asset: $assetEntry';
String toString() => 'asset: $entryUri';
@override
bool operator ==(dynamic other) {
......@@ -239,18 +235,16 @@ class _Asset {
if (other.runtimeType != runtimeType)
return false;
final _Asset otherAsset = other;
return otherAsset.base == base
&& otherAsset.assetEntry == assetEntry
&& otherAsset.relativePath == relativePath
&& otherAsset.source == source;
return otherAsset.baseDir == baseDir
&& otherAsset.relativeUri == relativeUri
&& otherAsset.entryUri == entryUri;
}
@override
int get hashCode {
return base.hashCode
^assetEntry.hashCode
^relativePath.hashCode
^ source.hashCode;
return baseDir.hashCode
^relativeUri.hashCode
^ entryUri.hashCode;
}
}
......@@ -272,11 +266,11 @@ List<_Asset> _getMaterialAssets(String fontSet) {
for (Map<String, dynamic> family in _getMaterialFonts(fontSet)) {
for (Map<String, dynamic> font in family['fonts']) {
final String assetKey = font['asset'];
final Uri entryUri = fs.path.toUri(font['asset']);
result.add(new _Asset(
base: fs.path.join(Cache.flutterRoot, 'bin', 'cache', 'artifacts', 'material_fonts'),
source: fs.path.basename(assetKey),
relativePath: assetKey
baseDir: fs.path.join(Cache.flutterRoot, 'bin', 'cache', 'artifacts', 'material_fonts'),
relativeUri: new Uri(path: entryUri.pathSegments.last),
entryUri: entryUri
));
}
}
......@@ -361,8 +355,8 @@ DevFSContent _createAssetManifest(Map<_Asset, List<_Asset>> assetVariants) {
for (_Asset main in assetVariants.keys) {
final List<String> variants = <String>[];
for (_Asset variant in assetVariants[main])
variants.add(variant.assetEntry);
json[main.assetEntry] = variants;
variants.add(variant.entryUri.path);
json[main.entryUri.path] = variants;
}
return new DevFSStringContent(JSON.encode(json));
}
......@@ -400,17 +394,17 @@ List<Font> _parsePackageFonts(
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)) {
final Uri assetUri = fontAsset.assetUri;
if (assetUri.pathSegments.first == 'packages' &&
!fs.isFileSync(fs.path.fromUri(packageMap.map[packageName].resolve('../${assetUri.path}')))) {
packageFontAssets.add(new FontAsset(
fontAsset.asset,
fontAsset.assetUri,
weight: fontAsset.weight,
style: fontAsset.style,
));
} else {
packageFontAssets.add(new FontAsset(
'packages/$packageName/${fontAsset.asset}',
new Uri(pathSegments: <String>['packages', packageName]..addAll(assetUri.pathSegments)),
weight: fontAsset.weight,
style: fontAsset.style,
));
......@@ -486,20 +480,25 @@ Map<_Asset, List<_Asset>> _parseAssets(
final Map<_Asset, List<_Asset>> result = <_Asset, List<_Asset>>{};
final _AssetDirectoryCache cache = new _AssetDirectoryCache(excludeDirs);
for (String assetName in flutterManifest.assets) {
for (Uri assetUri in flutterManifest.assets) {
final _Asset asset = _resolveAsset(
packageMap,
assetBase,
assetName,
assetUri,
packageName,
);
final List<_Asset> variants = <_Asset>[];
for (String path in cache.variantsFor(asset.assetFile.path)) {
final String key = fs.path.relative(path, from: asset.base);
String assetEntry;
if (asset.symbolicPrefix != null)
assetEntry = fs.path.join(asset.symbolicPrefix, key);
variants.add(new _Asset(base: asset.base, assetEntry: assetEntry, relativePath: key));
final String relativePath = fs.path.relative(path, from: asset.baseDir);
final Uri relativeUri = fs.path.toUri(relativePath);
final Uri entryUri = asset.symbolicPrefixUri == null
? relativeUri
: asset.symbolicPrefixUri.resolveUri(relativeUri);
variants.add(new _Asset(
baseDir: asset.baseDir,
entryUri: entryUri,
relativeUri: relativeUri,
));
}
result[asset] = variants;
......@@ -511,11 +510,11 @@ Map<_Asset, List<_Asset>> _parseAssets(
final _Asset baseAsset = _resolveAsset(
packageMap,
assetBase,
fontAsset.asset,
fontAsset.assetUri,
packageName,
);
if (!baseAsset.assetFileExists) {
printError('Error: unable to locate asset entry in pubspec.yaml: "${fontAsset.asset}".');
printError('Error: unable to locate asset entry in pubspec.yaml: "${fontAsset.assetUri}".');
return null;
}
......@@ -528,47 +527,42 @@ Map<_Asset, List<_Asset>> _parseAssets(
_Asset _resolveAsset(
PackageMap packageMap,
String assetBase,
String asset,
String assetsBaseDir,
Uri assetUri,
String packageName,
) {
if (asset.startsWith('packages/') && !fs.isFileSync(fs.path.join(assetBase, asset))) {
final String assetPath = fs.path.fromUri(assetUri);
if (assetUri.pathSegments.first == 'packages' && !fs.isFileSync(fs.path.join(assetsBaseDir, assetPath))) {
// The asset is referenced in the pubspec.yaml as
// 'packages/PACKAGE_NAME/PATH/TO/ASSET .
final _Asset packageAsset = _resolvePackageAsset(asset, packageMap);
final _Asset packageAsset = _resolvePackageAsset(assetUri, packageMap);
if (packageAsset != null)
return packageAsset;
}
final String assetEntry = packageName != null
? 'packages/$packageName/$asset' // Asset from, and declared in $packageName.
: null; // Asset from the current application.
return new _Asset(base: assetBase, assetEntry: assetEntry, relativePath: asset);
return new _Asset(
baseDir: assetsBaseDir,
entryUri: packageName == null
? assetUri // Asset from the current application.
: new Uri(pathSegments: <String>['packages', packageName]..addAll(assetUri.pathSegments)), // Asset from, and declared in $packageName.
relativeUri: assetUri,
);
}
_Asset _resolvePackageAsset(String asset, PackageMap packageMap) {
assert(asset.startsWith('packages/'));
String packageKey = asset.substring('packages/'.length);
String relativeAsset = asset;
final int index = packageKey.indexOf('/');
if (index != -1) {
relativeAsset = packageKey.substring(index + 1);
packageKey = packageKey.substring(0, index);
final Uri uri = packageMap.map[packageKey];
if (uri != null && uri.scheme == 'file') {
final File file = fs.file(uri);
final String base = file.path.substring(0, file.path.length - 1);
_Asset _resolvePackageAsset(Uri assetUri, PackageMap packageMap) {
assert(assetUri.pathSegments.first == 'packages');
if (assetUri.pathSegments.length > 1) {
final String packageName = assetUri.pathSegments[1];
final Uri packageUri = packageMap.map[packageName];
if (packageUri != null && packageUri.scheme == 'file') {
return new _Asset(
base: base,
assetEntry: asset,
relativePath: relativeAsset,
baseDir: fs.path.fromUri(packageUri),
entryUri: assetUri,
relativeUri: new Uri(pathSegments: assetUri.pathSegments.sublist(2)),
);
}
}
printStatus('Error detected in pubspec.yaml:', emphasis: true);
printError('Could not resolve package $packageKey for asset $asset.\n');
printError('Could not resolve package for asset $assetUri.\n');
return null;
}
......@@ -52,8 +52,8 @@ class FlutterManifest {
return _flutterDescriptor['fonts'] ?? const <Map<String, dynamic>>[];
}
List<String> get assets {
return _flutterDescriptor['assets'] ?? const <String>[];
List<Uri> get assets {
return _flutterDescriptor['assets']?.map(Uri.parse)?.toList() ?? const <Uri>[];
}
List<Font> _fonts;
......@@ -89,7 +89,7 @@ class FlutterManifest {
}
fontAssets.add(new FontAsset(
asset,
Uri.parse(asset),
weight: fontFile['weight'],
style: fontFile['style'],
));
......@@ -122,10 +122,10 @@ class Font {
}
class FontAsset {
FontAsset(this.asset, {this.weight, this.style})
: assert(asset != null);
FontAsset(this.assetUri, {this.weight, this.style})
: assert(assetUri != null);
final String asset;
final Uri assetUri;
final int weight;
final String style;
......@@ -137,12 +137,12 @@ class FontAsset {
if (style != null)
descriptor['style'] = style;
descriptor['asset'] = asset;
descriptor['asset'] = assetUri.path;
return descriptor;
}
@override
String toString() => '$runtimeType(asset: $asset, weight; $weight, style: $style)';
String toString() => '$runtimeType(asset: ${assetUri.path}, weight; $weight, style: $style)';
}
Future<dynamic> _loadFlutterManifest(String manifestPath) async {
......
......@@ -6,7 +6,6 @@ import 'dart:async';
import 'dart:convert';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/asset.dart';
import 'package:flutter_tools/src/base/file_system.dart';
......@@ -92,6 +91,28 @@ $fontsSection
..writeAsStringSync(font);
}
// These tests do not use a memory file system because we want to ensure that
// asset bundles work correctly on Windows and Posix systems.
Directory tempDir;
Directory oldCurrentDir;
setUp(() async {
tempDir = await fs.systemTempDirectory.createTemp('asset_bundle_tests');
oldCurrentDir = fs.currentDirectory;
fs.currentDirectory = tempDir;
});
tearDown(() {
fs.currentDirectory = oldCurrentDir;
try {
tempDir?.deleteSync(recursive: true);
tempDir = null;
} on FileSystemException catch (e) {
// Do nothing, windows sometimes has trouble deleting.
print('Ignored exception during tearDown: $e');
}
});
group('AssetBundle fonts from packages', () {
testUsingContext('App includes neither font manifest nor fonts when no defines fonts', () async {
establishFlutterRoot();
......@@ -104,7 +125,7 @@ $fontsSection
await bundle.build(manifestPath: 'pubspec.yaml');
expect(bundle.entries.length, 2); // LICENSE, AssetManifest
expect(bundle.entries.containsKey('FontManifest.json'), false);
}, overrides: contextOverrides);
});
testUsingContext('App font uses font file from package', () async {
establishFlutterRoot();
......@@ -129,7 +150,7 @@ $fontsSection
<String>['test_package'],
expectedFontManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('App font uses local font file and package font file', () async {
establishFlutterRoot();
......@@ -158,7 +179,7 @@ $fontsSection
<String>['test_package'],
expectedFontManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('App uses package font with own font file', () async {
establishFlutterRoot();
......@@ -188,7 +209,7 @@ $fontsSection
<String>['test_package'],
expectedFontManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('App uses package font with font file from another package', () async {
establishFlutterRoot();
......@@ -219,7 +240,7 @@ $fontsSection
<String>['test_package2'],
expectedFontManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('App uses package font with properties and own font file', () async {
establishFlutterRoot();
......@@ -251,7 +272,7 @@ $fontsSection
<String>['test_package'],
expectedFontManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('App uses local font and package font with own font file.', () async {
establishFlutterRoot();
......@@ -287,10 +308,6 @@ $fontsSection
<String>['test_package'],
expectedFontManifest,
);
}, overrides: contextOverrides);
});
}
Map<Type, Generator> get contextOverrides {
return <Type, Generator>{FileSystem: () => new MemoryFileSystem()};
});
}
......@@ -6,7 +6,6 @@ import 'dart:async';
import 'dart:convert';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/asset.dart';
import 'package:flutter_tools/src/base/file_system.dart';
......@@ -93,6 +92,28 @@ $assetsSection
}
}
// These tests do not use a memory file system because we want to ensure that
// asset bundles work correctly on Windows and Posix systems.
Directory tempDir;
Directory oldCurrentDir;
setUp(() async {
tempDir = await fs.systemTempDirectory.createTemp('asset_bundle_tests');
oldCurrentDir = fs.currentDirectory;
fs.currentDirectory = tempDir;
});
tearDown(() {
fs.currentDirectory = oldCurrentDir;
try {
tempDir?.deleteSync(recursive: true);
tempDir = null;
} on FileSystemException catch (e) {
// Do nothing, windows sometimes has trouble deleting.
print('Ignored exception during tearDown: $e');
}
});
group('AssetBundle assets from packages', () {
testUsingContext('No assets are bundled when the package has no assets', () async {
establishFlutterRoot();
......@@ -109,7 +130,7 @@ $assetsSection
UTF8.decode(await bundle.entries['AssetManifest.json'].contentsAsBytes()),
expectedAssetManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('No assets are bundled when the package has an asset that is not listed', () async {
establishFlutterRoot();
......@@ -130,7 +151,7 @@ $assetsSection
expectedAssetManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('One asset is bundled when the package has and lists one asset its pubspec', () async {
establishFlutterRoot();
......@@ -154,7 +175,7 @@ $assetsSection
<String>['test_package'],
expectedAssetManifest,
);
}, overrides: contextOverrides);
});
testUsingContext("One asset is bundled when the package has one asset, listed in the app's pubspec", () async {
establishFlutterRoot();
......@@ -178,7 +199,7 @@ $assetsSection
<String>['test_package'],
expectedAssetManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('One asset and its variant are bundled when the package has an asset and a variant, and lists the asset in its pubspec', () async {
establishFlutterRoot();
......@@ -202,7 +223,7 @@ $assetsSection
<String>['test_package'],
expectedManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('One asset and its variant are bundled when the package has an asset and a variant, and the app lists the asset in its pubspec', () async {
establishFlutterRoot();
......@@ -229,7 +250,7 @@ $assetsSection
<String>['test_package'],
expectedManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('Two assets are bundled when the package has and lists two assets in its pubspec', () async {
establishFlutterRoot();
......@@ -254,7 +275,7 @@ $assetsSection
<String>['test_package'],
expectedAssetManifest,
);
}, overrides: contextOverrides);
});
testUsingContext("Two assets are bundled when the package has two assets, listed in the app's pubspec", () async {
establishFlutterRoot();
......@@ -286,7 +307,7 @@ $assetsSection
<String>['test_package'],
expectedAssetManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('Two assets are bundled when two packages each have and list an asset their pubspec', () async {
establishFlutterRoot();
......@@ -322,7 +343,7 @@ $assetsSection
<String>['test_package', 'test_package2'],
expectedAssetManifest,
);
}, overrides: contextOverrides);
});
testUsingContext("Two assets are bundled when two packages each have an asset, listed in the app's pubspec", () async {
establishFlutterRoot();
......@@ -361,7 +382,7 @@ $assetsSection
<String>['test_package', 'test_package2'],
expectedAssetManifest,
);
}, overrides: contextOverrides);
});
testUsingContext('One asset is bundled when the app depends on a package, listing in its pubspec an asset from another package', () async {
establishFlutterRoot();
......@@ -392,10 +413,6 @@ $assetsSection
<String>['test_package2'],
expectedAssetManifest,
);
}, overrides: contextOverrides);
});
}
Map<Type, Generator> get contextOverrides {
return <Type, Generator>{FileSystem: () => new MemoryFileSystem()};
});
}
......@@ -5,7 +5,6 @@
import 'dart:convert';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/asset.dart';
import 'package:flutter_tools/src/base/file_system.dart';
......@@ -76,6 +75,28 @@ void main() {
});
group('AssetBundle.build', () {
// These tests do not use a memory file system because we want to ensure that
// asset bundles work correctly on Windows and Posix systems.
Directory tempDir;
Directory oldCurrentDir;
setUp(() async {
tempDir = await fs.systemTempDirectory.createTemp('asset_bundle_tests');
oldCurrentDir = fs.currentDirectory;
fs.currentDirectory = tempDir;
});
tearDown(() {
fs.currentDirectory = oldCurrentDir;
try {
tempDir?.deleteSync(recursive: true);
tempDir = null;
} on FileSystemException catch (e) {
// Do nothing, windows sometimes has trouble deleting.
print('Ignored exception during tearDown: $e');
}
});
test('nonempty', () async {
final AssetBundle ab = new AssetBundle();
expect(await ab.build(), 0);
......@@ -95,7 +116,7 @@ void main() {
UTF8.decode(await bundle.entries['AssetManifest.json'].contentsAsBytes()),
expectedAssetManifest,
);
}, overrides: <Type, Generator>{FileSystem: () => new MemoryFileSystem(),});
});
});
}
......@@ -5,7 +5,6 @@
import 'dart:convert';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/asset.dart';
import 'package:flutter_tools/src/base/file_system.dart';
......@@ -17,6 +16,28 @@ import 'src/common.dart';
import 'src/context.dart';
void main() {
// These tests do not use a memory file system because we want to ensure that
// asset bundles work correctly on Windows and Posix systems.
Directory tempDir;
Directory oldCurrentDir;
setUp(() async {
tempDir = await fs.systemTempDirectory.createTemp('asset_bundle_tests');
oldCurrentDir = fs.currentDirectory;
fs.currentDirectory = tempDir;
});
tearDown(() {
fs.currentDirectory = oldCurrentDir;
try {
tempDir?.deleteSync(recursive: true);
tempDir = null;
} on FileSystemException catch (e) {
// Do nothing, windows sometimes has trouble deleting.
print('Ignored exception during tearDown: $e');
}
});
group('AssetBundle asset variants', () {
testUsingContext('main asset and variants', () async {
// Setting flutterRoot here so that it picks up the MemoryFileSystem's
......@@ -59,19 +80,17 @@ flutter:
expect(UTF8.decode(await bundle.entries[asset].contentsAsBytes()), asset);
}
fs.file('/a/b/c/foo').deleteSync();
fs.file('a/b/c/foo').deleteSync();
bundle = new AssetBundle();
await bundle.build(manifestPath: 'pubspec.yaml');
// Now the main asset file, /a/b/c/foo, does not exist. This is OK because
// the /a/b/c/*/foo variants do exist.
expect(bundle.entries.containsKey('/a/b/c/foo'), false);
expect(bundle.entries.containsKey('a/b/c/foo'), false);
for (String asset in assets.skip(1)) {
expect(bundle.entries.containsKey(asset), true);
expect(UTF8.decode(await bundle.entries[asset].contentsAsBytes()), asset);
}
}, overrides: <Type, Generator>{
FileSystem: () => new MemoryFileSystem(),
});
});
......
......@@ -69,7 +69,9 @@ flutter:
- a/bar
''';
final FlutterManifest flutterManifest = await FlutterManifest.createFromString(manifest);
expect(flutterManifest.assets, <String>['a/foo', 'a/bar']);
expect(flutterManifest.assets.length, 2);
expect(flutterManifest.assets[0], Uri.parse('a/foo'));
expect(flutterManifest.assets[1], Uri.parse('a/bar'));
});
test('has one font family with one asset', () async {
......@@ -97,7 +99,7 @@ flutter:
final List<FontAsset> assets = font.fontAssets;
expect(assets.length, 1);
final FontAsset fontAsset = assets[0];
expect(fontAsset.asset, 'a/bar');
expect(fontAsset.assetUri.path, 'a/bar');
expect(fontAsset.weight, isNull);
expect(fontAsset.style, isNull);
});
......@@ -130,11 +132,11 @@ flutter:
final List<FontAsset> assets = font.fontAssets;
expect(assets.length, 2);
final FontAsset fontAsset0 = assets[0];
expect(fontAsset0.asset, 'a/bar');
expect(fontAsset0.assetUri.path, 'a/bar');
expect(fontAsset0.weight, isNull);
expect(fontAsset0.style, isNull);
final FontAsset fontAsset1 = assets[1];
expect(fontAsset1.asset, 'a/bar');
expect(fontAsset1.assetUri.path, 'a/bar');
expect(fontAsset1.weight, 400);
expect(fontAsset1.style, isNull);
});
......@@ -168,11 +170,11 @@ flutter:
final List<FontAsset> assets = font.fontAssets;
expect(assets.length, 2);
final FontAsset fontAsset0 = assets[0];
expect(fontAsset0.asset, 'a/bar');
expect(fontAsset0.assetUri.path, 'a/bar');
expect(fontAsset0.weight, isNull);
expect(fontAsset0.style, isNull);
final FontAsset fontAsset1 = assets[1];
expect(fontAsset1.asset, 'a/bar');
expect(fontAsset1.assetUri.path, 'a/bar');
expect(fontAsset1.weight, 400);
expect(fontAsset1.style, 'italic');
});
......@@ -214,11 +216,11 @@ flutter:
final List<FontAsset> fooAassets = fooFont.fontAssets;
expect(fooAassets.length, 2);
final FontAsset fooFontAsset0 = fooAassets[0];
expect(fooFontAsset0.asset, 'a/bar');
expect(fooFontAsset0.assetUri.path, 'a/bar');
expect(fooFontAsset0.weight, isNull);
expect(fooFontAsset0.style, isNull);
final FontAsset fooFontAsset1 = fooAassets[1];
expect(fooFontAsset1.asset, 'a/bar');
expect(fooFontAsset1.assetUri.path, 'a/bar');
expect(fooFontAsset1.weight, 400);
expect(fooFontAsset1.style, 'italic');
......@@ -229,11 +231,11 @@ flutter:
final List<FontAsset> barAssets = barFont.fontAssets;
expect(barAssets.length, 2);
final FontAsset barFontAsset0 = barAssets[0];
expect(barFontAsset0.asset, 'a/baz');
expect(barFontAsset0.assetUri.path, 'a/baz');
expect(barFontAsset0.weight, isNull);
expect(barFontAsset0.style, isNull);
final FontAsset barFontAsset1 = barAssets[1];
expect(barFontAsset1.asset, 'a/baz');
expect(barFontAsset1.assetUri.path, 'a/baz');
expect(barFontAsset1.weight, 400);
expect(barFontAsset1.style, 'italic');
});
......@@ -274,11 +276,11 @@ flutter:
final List<FontAsset> fooAassets = fooFont.fontAssets;
expect(fooAassets.length, 2);
final FontAsset fooFontAsset0 = fooAassets[0];
expect(fooFontAsset0.asset, 'a/bar');
expect(fooFontAsset0.assetUri.path, 'a/bar');
expect(fooFontAsset0.weight, isNull);
expect(fooFontAsset0.style, isNull);
final FontAsset fooFontAsset1 = fooAassets[1];
expect(fooFontAsset1.asset, 'a/bar');
expect(fooFontAsset1.assetUri.path, 'a/bar');
expect(fooFontAsset1.weight, 400);
expect(fooFontAsset1.style, 'italic');
});
......@@ -314,11 +316,11 @@ flutter:
final List<FontAsset> fooAassets = fooFont.fontAssets;
expect(fooAassets.length, 2);
final FontAsset fooFontAsset0 = fooAassets[0];
expect(fooFontAsset0.asset, 'a/bar');
expect(fooFontAsset0.assetUri.path, 'a/bar');
expect(fooFontAsset0.weight, isNull);
expect(fooFontAsset0.style, isNull);
final FontAsset fooFontAsset1 = fooAassets[1];
expect(fooFontAsset1.asset, 'a/bar');
expect(fooFontAsset1.assetUri.path, 'a/bar');
expect(fooFontAsset1.weight, 400);
expect(fooFontAsset1.style, 'italic');
});
......
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