blob: b6f8c176e5c8a9c5a0f7d0434343f09dcad0db73 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:convert';
import 'dart:typed_data';
import 'package:ui/src/engine.dart';
import 'package:ui/ui_web/src/ui_web.dart' as ui_web;
class FakeAssetManager implements ui_web.AssetManager {
FakeAssetManager();
@override
String get assetsDir => 'assets';
@override
String getAssetUrl(String asset) => asset;
@override
Future<ByteData> load(String assetKey) async {
final ByteData? assetData = await _currentScope?.getAssetData(assetKey);
if (assetData == null) {
throw HttpFetchNoPayloadError(assetKey, status: 404);
}
return assetData;
}
@override
Future<HttpFetchResponse> loadAsset(String asset) async {
final ByteData? assetData = await _currentScope?.getAssetData(asset);
if (assetData != null) {
return MockHttpFetchResponse(
url: asset,
status: 200,
payload: MockHttpFetchPayload(
byteBuffer: assetData.buffer,
),
);
} else {
return MockHttpFetchResponse(
url: asset,
status: 404,
);
}
}
FakeAssetScope pushAssetScope() {
final FakeAssetScope scope = FakeAssetScope._(_currentScope);
_currentScope = scope;
return scope;
}
void popAssetScope(FakeAssetScope scope) {
assert(_currentScope == scope);
_currentScope = scope._parent;
}
FakeAssetScope? _currentScope;
}
class FakeAssetScope {
FakeAssetScope._(this._parent);
final FakeAssetScope? _parent;
final Map<String, Future<ByteData> Function()> _assetFetcherMap = <String, Future<ByteData> Function()>{};
void setAsset(String assetKey, ByteData assetData) {
_assetFetcherMap[assetKey] = () async => assetData;
}
void setAssetPassthrough(String assetKey) {
_assetFetcherMap[assetKey] = () async {
return ByteData.view(await httpFetchByteBuffer(assetKey));
};
}
Future<ByteData>? getAssetData(String assetKey) {
final Future<ByteData> Function()? fetcher = _assetFetcherMap[assetKey];
if (fetcher != null) {
return fetcher();
}
if (_parent != null) {
return _parent.getAssetData(assetKey);
}
return null;
}
}
FakeAssetManager fakeAssetManager = FakeAssetManager();
ByteData stringAsUtf8Data(String string) {
return ByteData.sublistView(utf8.encode(string));
}
const String ahemFontFamily = 'Ahem';
const String ahemFontUrl = '/assets/fonts/ahem.ttf';
const String robotoFontFamily = 'Roboto';
const String robotoTestFontUrl = '/assets/fonts/Roboto-Regular.ttf';
const String robotoVariableFontFamily = 'RobotoVariable';
const String robotoVariableFontUrl = '/assets/fonts/RobotoSlab-VariableFont_wght.ttf';
/// The list of test fonts, in the form of font family name - font file url pairs.
/// This list does not include embedded test fonts, which need to be loaded and
/// registered separately in [FontCollection.debugDownloadTestFonts].
const Map<String, String> testFontUrls = <String, String>{
ahemFontFamily: ahemFontUrl,
robotoFontFamily: robotoTestFontUrl,
robotoVariableFontFamily: robotoVariableFontUrl,
};
FakeAssetScope configureDebugFontsAssetScope(FakeAssetManager manager) {
final FakeAssetScope scope = manager.pushAssetScope();
scope.setAsset('AssetManifest.json', stringAsUtf8Data('{}'));
scope.setAsset('FontManifest.json', stringAsUtf8Data('''
[
{
"family":"$robotoFontFamily",
"fonts":[{"asset":"$robotoTestFontUrl"}]
},
{
"family":"$ahemFontFamily",
"fonts":[{"asset":"$ahemFontUrl"}]
},
{
"family":"$robotoVariableFontFamily",
"fonts":[{"asset":"$robotoVariableFontUrl"}]
}
]'''));
scope.setAssetPassthrough(robotoTestFontUrl);
scope.setAssetPassthrough(ahemFontUrl);
scope.setAssetPassthrough(robotoVariableFontUrl);
return scope;
}