| // 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; |
| } |