Skip to content

Commit

Permalink
Merge pull request #28 from bamlab/feat/add-custom-icons-font-support
Browse files Browse the repository at this point in the history
feat: add custom font icons support
  • Loading branch information
T-moz authored Sep 24, 2024
2 parents 63d41d6 + 939fd21 commit 231ce8d
Show file tree
Hide file tree
Showing 46 changed files with 91 additions and 138 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* **BREAKING**: feat: Remove argument packages fron loadFonts
- feat: loadFonts now support custom icons font like material_symbols_icons
* **BREAKING**: feat: Add keyboardName to WindowConfigData
- fix: It's now possible to use custom devices as WindowConfigData variant
* feat: awaitImages now support FadeInImage.
Expand Down
16 changes: 3 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,25 +57,15 @@ flutter:
- asset: fonts/Roboto-Black.ttf
...
```
- In your flutter_test_config, call `loadFonts()`.
- In your flutter_test_config, call `loadAppFonts()`.
```dart
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
TestWidgetsFlutterBinding.ensureInitialized();
await loadFonts();
await loadAppFonts();
await testMain();
}
```

Alternatively you can load fonts from a separate package by specifying its name and path:

```dart
await loadFontsFromPackage(
package: Package(
name: 'my_theme_package',
relativePath: '../theme',
),
);
```
> ℹ️ `loadAppFonts` loads the fonts from the `pubspec.yaml`, and from every separate package dependencies as well.
### Setup devices to run test on
Define a set of device variant corresponding to your definition of done.
Expand Down
6 changes: 6 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
include: package:theodo_analysis/analysis_options.yaml
analyzer:
errors:
return_of_invalid_type_from_closure: false
for_in_of_invalid_element_type: false
argument_type_not_assignable: false
for_in_of_invalid_type: false
# Additional information about this file can be found at
# https://pub.dev/packages/theodo_analysis
linter:
Expand Down
9 changes: 8 additions & 1 deletion example/multi_packages_app/app/lib/src/view/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ class HomeLayout extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const AppText('Adaptive Golden'),
title: const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AppIcon.image,
SizedBox(width: 12),
AppText('Adaptive Golden'),
],
),
),
body: Center(
child: Padding(
Expand Down
12 changes: 10 additions & 2 deletions example/multi_packages_app/app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.11.1"
material_symbols_icons:
dependency: transitive
description:
name: material_symbols_icons
sha256: "66416c4e30bd363508e12669634fc4f3250b83b69e862de67f4f9c480cf42414"
url: "https://pub.dev"
source: hosted
version: "4.2785.1"
meta:
dependency: transitive
description:
Expand Down Expand Up @@ -226,10 +234,10 @@ packages:
dependency: "direct dev"
description:
name: theodo_analysis
sha256: d79261bc640ffbd84c6142172d68eb8bfba61f32fdabece22ab53f4549d74d53
sha256: "46988703b11c3b9b0a31491c5297a9dba13ddf8052a1624ff329589f31c187b5"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.3.0"
vector_math:
dependency: transitive
description:
Expand Down
2 changes: 1 addition & 1 deletion example/multi_packages_app/app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ dev_dependencies:
adaptive_test:
path: ../../../

theodo_analysis: ^1.2.0
theodo_analysis: ^1.3.0

flutter:
uses-material-design: true
Expand Down
7 changes: 1 addition & 6 deletions example/multi_packages_app/app/test/flutter_test_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@ Future<void> testExecutable(FutureOr<void> Function() testMain) async {
AdaptiveTestConfiguration.instance
..setEnforcedTestPlatform(TargetPlatform.macOS)
..setDeviceVariants(defaultDeviceConfigs);
await loadFontsFromPackage(
package: Package(
name: 'multi_packages_example_theme',
relativePath: '../theme',
),
);
await loadFonts();
const m1IntelDifferenceThreshold = 0.2 / 100; // 0.2%
setupFileComparatorWithThreshold(m1IntelDifferenceThreshold);
await testMain();
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions example/multi_packages_app/theme/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export './src/widgets/text.dart';
export './src/widgets/text_field.dart';
export './src/widgets/icon.dart';
8 changes: 8 additions & 0 deletions example/multi_packages_app/theme/lib/src/widgets/icon.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart';

class AppIcon extends Icon {
const AppIcon(super.icon, {super.key});

static const AppIcon image = AppIcon(Symbols.image);
}
12 changes: 10 additions & 2 deletions example/multi_packages_app/theme/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.11.1"
material_symbols_icons:
dependency: "direct main"
description:
name: material_symbols_icons
sha256: "66416c4e30bd363508e12669634fc4f3250b83b69e862de67f4f9c480cf42414"
url: "https://pub.dev"
source: hosted
version: "4.2785.1"
meta:
dependency: transitive
description:
Expand Down Expand Up @@ -219,10 +227,10 @@ packages:
dependency: "direct dev"
description:
name: theodo_analysis
sha256: d79261bc640ffbd84c6142172d68eb8bfba61f32fdabece22ab53f4549d74d53
sha256: "46988703b11c3b9b0a31491c5297a9dba13ddf8052a1624ff329589f31c187b5"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.3.0"
vector_math:
dependency: transitive
description:
Expand Down
3 changes: 2 additions & 1 deletion example/multi_packages_app/theme/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
material_symbols_icons: ^4.2771.0

dev_dependencies:
flutter_test:
sdk: flutter
adaptive_test:
path: ../../../

theodo_analysis: ^1.2.0
theodo_analysis: ^1.3.0

flutter:
uses-material-design: true
Expand Down
10 changes: 9 additions & 1 deletion example/simple_app/lib/src/view/home.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart';

class HomeLayout extends StatelessWidget {
const HomeLayout({super.key, this.useFadeInImage = false});
Expand All @@ -10,7 +11,14 @@ class HomeLayout extends StatelessWidget {

return Scaffold(
appBar: AppBar(
title: const Text('Adaptative Golden'),
title: const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Symbols.image),
SizedBox(width: 12),
Text('Adaptive Golden'),
],
),
),
body: Center(
child: Padding(
Expand Down
12 changes: 10 additions & 2 deletions example/simple_app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.11.1"
material_symbols_icons:
dependency: "direct main"
description:
name: material_symbols_icons
sha256: "66416c4e30bd363508e12669634fc4f3250b83b69e862de67f4f9c480cf42414"
url: "https://pub.dev"
source: hosted
version: "4.2785.1"
meta:
dependency: transitive
description:
Expand Down Expand Up @@ -219,10 +227,10 @@ packages:
dependency: "direct dev"
description:
name: theodo_analysis
sha256: d79261bc640ffbd84c6142172d68eb8bfba61f32fdabece22ab53f4549d74d53
sha256: "46988703b11c3b9b0a31491c5297a9dba13ddf8052a1624ff329589f31c187b5"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.3.0"
vector_math:
dependency: transitive
description:
Expand Down
3 changes: 2 additions & 1 deletion example/simple_app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
material_symbols_icons: ^4.2771.0

dev_dependencies:
flutter_test:
sdk: flutter
adaptive_test:
path: ../../

theodo_analysis: ^1.2.0
theodo_analysis: ^1.3.0

flutter:
uses-material-design: true
Expand Down
Binary file modified example/simple_app/test/src/preview/custom_path_desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/custom_path_iPadPro.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/custom_path_iPhone_13.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/custom_path_iPhone_8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/custom_path_pixel_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/desktop-app_fade_in_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/desktop-app_simple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/iPadPro-app_fade_in_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/iPadPro-app_simple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/iPhone_13-app_simple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/iPhone_8-app_fade_in_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified example/simple_app/test/src/preview/iPhone_8-app_simple.png
Binary file modified example/simple_app/test/src/preview/pixel_5-app_fade_in_image.png
Binary file modified example/simple_app/test/src/preview/pixel_5-app_simple.png
124 changes: 17 additions & 107 deletions lib/src/helpers/fonts_loader.dart
Original file line number Diff line number Diff line change
@@ -1,126 +1,36 @@
import 'dart:io';
// ignore_for_file: avoid-dynamic, avoid-accessing-collections-by-constant-index

import 'dart:convert';

import 'package:file/file.dart' as f;
import 'package:file/local.dart' as l;
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:platform/platform.dart' as p;

/// A class representing a package within a multi-packages app
class Package {
/// Creates a new [Package] instance.
/// Either [name] or [relativePath] must be provided.
Package({this.name, this.relativePath})
: assert(name != null || relativePath != null);

/// This is the name of the package as defined in the pubspec.yaml file
final String? name;

/// This is the path to the package relative to where the test is run from.
final String? relativePath;
}

/// Load fonts to make sure they show up in golden tests.
/// Load fonts and icons to make sure they show up 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.
///
/// *Note* for this function to work, your package needs to include all fonts
/// it uses in a font dir at the root of the project.
Future<void> loadFonts([String? package]) {
return package != null
? loadFontsFromPackage(
package: Package(name: package, relativePath: './$package'),
)
: loadFontsFromPackage();
}

/// Load fonts from a given package to make sure they show up in golden tests.
/// /// Load fonts to make sure they show up 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 loadFontsFromPackage(Package(name: 'my_theme', relativePath: './theme'));` in the `testExecutable` function.
///
/// *Note* for this function to work, your given package needs to include all fonts
/// it uses in a font dir at the root of the project referenced by the given [package] argument.
/// If no [package] is provided, it will look for a fonts dir at the root of the project.
/// If a [package] is provided with a [Package.relativePath] it will look for a fonts dir with the package located at that path
/// If a [package] is provided with a [Package.name] it will prefix the fonts dir with `packages/[package.name]`
Future<void> loadFontsFromPackage({Package? package}) async {
/// *Note* for this function to work, your package needs to include all fonts
/// it uses az assets.
Future<void> loadFonts() async {
TestWidgetsFlutterBinding.ensureInitialized();
await _load(loadFontsFromFontsDir(package));
await _loadMaterialIconFont();
}

/// Assumes a fonts dir in root of project
@visibleForTesting
Map<String, List<Future<ByteData>>> loadFontsFromFontsDir([Package? package]) {
final fontFamilyToData = <String, List<Future<ByteData>>>{};
final currentDir = path.dirname(Platform.script.path);
final fontsDirectory = path.join(
currentDir,
package == null || package.relativePath == null
? 'fonts'
: '${package.relativePath}/fonts',
final fontManifest = await rootBundle.loadStructuredData<Iterable<dynamic>>(
'FontManifest.json',
(string) async => json.decode(string),
);
final prefix = package == null || package.name == null
? ''
: 'packages/${package.name}/';
for (final file in Directory(fontsDirectory).listSync()) {
if (file is File) {
final fontFamily = prefix +
(path.basenameWithoutExtension(file.path).split('-').firstOrNull ??
'');
(fontFamilyToData[fontFamily] ??= []).add(_fileToByteData(file));
}
}

return fontFamilyToData;
}

Future<ByteData> _fileToByteData(File file) async {
final bytes = await file.readAsBytes();

return ByteData.view(bytes.buffer);
}

Future<void> _load(Map<String, List<Future<ByteData>>> fontFamilyToData) async {
final waitList = <Future<void>>[];
for (final entry in fontFamilyToData.entries) {
final loader = FontLoader(entry.key);
for (final data in entry.value) {
loader.addFont(data);
for (final Map<String, dynamic> font in fontManifest) {
final fontLoader = FontLoader(font['family']);

for (final Map<String, dynamic> fontType in font['fonts']) {
fontLoader.addFont(rootBundle.load(fontType['asset']));
}
waitList.add(loader.load());
waitList.add(fontLoader.load());
}
await Future.wait(waitList);
}

// Loads the cached material icon font.
// Only necessary for golden tests. Relies on the tool updating cached assets
// before running tests.
Future<void> _loadMaterialIconFont() async {
const f.FileSystem fs = l.LocalFileSystem();
const p.Platform platform = p.LocalPlatform();
final flutterRoot = fs.directory(platform.environment['FLUTTER_ROOT']);

final iconFont = flutterRoot.childFile(
fs.path.join(
'bin',
'cache',
'artifacts',
'material_fonts',
'MaterialIcons-Regular.otf',
),
);

final bytes =
Future<ByteData>.value(iconFont.readAsBytesSync().buffer.asByteData());

await (FontLoader('MaterialIcons')..addFont(bytes)).load();
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ dependencies:
recase: ^4.0.0

dev_dependencies:
theodo_analysis: ^1.2.0
theodo_analysis: ^1.3.0

flutter:
uses-material-design: true
Expand Down

0 comments on commit 231ce8d

Please sign in to comment.