diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ab245b..7bd7b5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ -## 0.6.0 - * **BREAKING**: feat: Remove argument packages fron loadFonts - feat: loadFonts now support custom icons font like material_symbols_icons +* **BREAKING**: feat: loadFontsFromPackage + - feat: loading fonts from current or external packages is now supported by loadFonts * **BREAKING**: feat: Add keyboardName to WindowConfigData - fix: It's now possible to use custom devices as WindowConfigData variant * feat: awaitImages now support FadeInImage. diff --git a/example/multi_packages_app/app/pubspec.lock b/example/multi_packages_app/app/pubspec.lock index 17f51d3..eb1779f 100644 --- a/example/multi_packages_app/app/pubspec.lock +++ b/example/multi_packages_app/app/pubspec.lock @@ -7,7 +7,7 @@ packages: path: "../../.." relative: true source: path - version: "0.5.1" + version: "0.6.0" async: dependency: transitive description: @@ -153,6 +153,14 @@ packages: relative: true source: path version: "1.0.0+1" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: diff --git a/example/multi_packages_app/theme/pubspec.lock b/example/multi_packages_app/theme/pubspec.lock index 6dbe870..1b9aeae 100644 --- a/example/multi_packages_app/theme/pubspec.lock +++ b/example/multi_packages_app/theme/pubspec.lock @@ -7,7 +7,7 @@ packages: path: "../../.." relative: true source: path - version: "0.5.1" + version: "0.6.0" async: dependency: transitive description: @@ -146,6 +146,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.15.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: diff --git a/example/simple_app/pubspec.lock b/example/simple_app/pubspec.lock index 63b7e1c..e23b392 100644 --- a/example/simple_app/pubspec.lock +++ b/example/simple_app/pubspec.lock @@ -7,7 +7,7 @@ packages: path: "../.." relative: true source: path - version: "0.5.1" + version: "0.6.0" async: dependency: transitive description: @@ -146,6 +146,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.15.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: diff --git a/lib/src/helpers/fonts_loader.dart b/lib/src/helpers/fonts_loader.dart index 7e0fe6a..a743bce 100644 --- a/lib/src/helpers/fonts_loader.dart +++ b/lib/src/helpers/fonts_loader.dart @@ -1,36 +1,91 @@ -// ignore_for_file: avoid-dynamic, avoid-accessing-collections-by-constant-index +// ignore_for_file: avoid-dynamic import 'dart:convert'; +import 'dart:io'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:package_config/package_config.dart'; -/// Load fonts and icons to make sure they show up in golden tests. +/// Loads fonts and icons to ensure they appear in golden tests. /// -/// To use it efficiently: -/// * Create a flutter_test_config.dart file. See: -/// https://api.flutter.dev/flutter/flutter_test/flutter_test-library.html -/// * add `await loadFonts();` in the `testExecutable` function. +/// Usage: +/// 1. Create a flutter_test_config.dart file. +/// 2. Add `await loadFonts();` in the `testExecutable` function. /// -/// /// Load fonts to make sure they show up in golden tests. -/// -/// *Note* for this function to work, your package needs to include all fonts -/// it uses az assets. +/// Note: Your package must include all used fonts as assets for this to work. Future loadFonts() async { TestWidgetsFlutterBinding.ensureInitialized(); + final fontManifest = await _loadFontManifest(); + final packageName = await _getCurrentPackageName(); + await _loadFontsFromManifest(fontManifest, packageName); +} +Future<_FontManifest> _loadFontManifest() async { final fontManifest = await rootBundle.loadStructuredData>( 'FontManifest.json', (string) async => json.decode(string), ); - final waitList = >[]; - for (final Map font in fontManifest) { - final fontLoader = FontLoader(font['family']); - - for (final Map fontType in font['fonts']) { - fontLoader.addFont(rootBundle.load(fontType['asset'])); - } - waitList.add(fontLoader.load()); + + return fontManifest.map((font) => _FontData.fromJson(font)).toList(); +} + +Future _loadFontsFromManifest( + _FontManifest fontManifest, + String? packageName, +) async { + final fontLoaders = fontManifest.expand((font) { + final regularFontLoader = _createFontLoader(font.family, font.fonts); + final fontFamilyStartsWithPackages = font.family.startsWith('packages/'); + + return [ + regularFontLoader, + if (!fontFamilyStartsWithPackages && packageName != null) + _createFontLoader('packages/$packageName/${font.family}', font.fonts), + ]; + }).toList(); + + await Future.wait(fontLoaders.map((loader) => loader.load())); +} + +FontLoader _createFontLoader(String fontFamily, List<_FontType> fontTypes) { + final fontLoader = FontLoader(fontFamily); + fontTypes.forEach( + (fontType) => fontLoader.addFont(rootBundle.load(fontType.asset)), + ); + + return fontLoader; +} + +Future _getCurrentPackageName() async { + final current = Directory.current; + final packageConfig = await findPackageConfig(current); + + return packageConfig?.packageOf(current.uri)?.name; +} + +typedef _FontManifest = List<_FontData>; + +class _FontData { + const _FontData({required this.family, required this.fonts}); + + factory _FontData.fromJson(Map json) { + return _FontData( + family: json['family'] as String, + fonts: (json['fonts'] as List) + .map((font) => _FontType.fromJson(font)) + .toList(), + ); + } + final String family; + final List<_FontType> fonts; +} + +class _FontType { + const _FontType({required this.asset}); + + factory _FontType.fromJson(Map json) { + return _FontType(asset: json['asset'] as String); } - await Future.wait(waitList); + final String asset; } diff --git a/pubspec.yaml b/pubspec.yaml index 88a0126..8764105 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,6 +18,7 @@ dependencies: flutter_test: sdk: flutter meta: ^1.8.0 + package_config: ^2.1.0 path: ^1.8.2 platform: ^3.1.0 recase: ^4.0.0