feat: bundle Luciole, Literata, Charis SIL and a Hebrew fallback face
This commit is contained in:
parent
dfba1cfb16
commit
6de6672ae3
30 changed files with 624 additions and 11 deletions
98
app/test/fonts_test.dart
Normal file
98
app/test/fonts_test.dart
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:mews/application/controllers/reader_settings_controller.dart';
|
||||
import 'package:mews/application/fonts.dart';
|
||||
import 'package:mews/database/database.dart';
|
||||
|
||||
/// The families pubspec.yaml declares, with the asset paths of each.
|
||||
Map<String, List<String>> _declaredFonts() {
|
||||
final lines = File('pubspec.yaml').readAsLinesSync();
|
||||
final declared = <String, List<String>>{};
|
||||
String? family;
|
||||
for (final line in lines) {
|
||||
final name = RegExp(r'^ - family: (.+)$').firstMatch(line);
|
||||
if (name != null) {
|
||||
family = name.group(1)!.trim();
|
||||
declared[family] = [];
|
||||
continue;
|
||||
}
|
||||
final asset = RegExp(r'^ - asset: (.+)$').firstMatch(line);
|
||||
if (asset != null && family != null) {
|
||||
declared[family]!.add(asset.group(1)!.trim());
|
||||
}
|
||||
}
|
||||
return declared;
|
||||
}
|
||||
|
||||
void main() {
|
||||
test('every offered typeface is bundled under the name it is stored by', () {
|
||||
final declared = _declaredFonts();
|
||||
for (final font in readerFonts) {
|
||||
// A family named here but not in pubspec renders in the platform's font
|
||||
// instead, silently: the reader would pick it and see no change.
|
||||
expect(declared, contains(font.family),
|
||||
reason: '${font.family} is offered but not declared in pubspec.yaml');
|
||||
expect(declared[font.family], hasLength(4),
|
||||
reason: '${font.family} needs regular, italic, bold and bold italic');
|
||||
for (final asset in declared[font.family]!) {
|
||||
expect(File(asset).existsSync(), isTrue, reason: '$asset is missing');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('a fallback only names a typeface that is bundled', () {
|
||||
final declared = _declaredFonts();
|
||||
for (final font in readerFonts) {
|
||||
for (final family in font.fallback) {
|
||||
// A fallback naming a family the build does not carry is silently
|
||||
// skipped, so the glyph would come from the platform after all.
|
||||
expect(declared, contains(family),
|
||||
reason: '${font.family} falls back to an absent $family');
|
||||
expect(family, isNot(font.family), reason: 'falls back to itself');
|
||||
for (final asset in declared[family]!) {
|
||||
expect(File(asset).existsSync(), isTrue, reason: '$asset is missing');
|
||||
}
|
||||
}
|
||||
}
|
||||
expect(readerFonts.map((f) => f.family), contains(defaultFontFamily));
|
||||
expect(fallbackFor('Comic Sans MS'), isEmpty);
|
||||
});
|
||||
|
||||
test('every typeface can reach Hebrew without the platform', () {
|
||||
// Hebrew ships from the start, so it must never depend on what the device
|
||||
// happens to have installed.
|
||||
for (final font in readerFonts) {
|
||||
expect(font.fallback, anyElement(anyOf(hebrewSans, hebrewSerif)),
|
||||
reason: '${font.family} has no Hebrew to fall back on');
|
||||
}
|
||||
});
|
||||
|
||||
test('every typeface has a label of its own', () {
|
||||
final ftl = File('locales/en-US/main.ftl').readAsStringSync();
|
||||
final ids = <String>{};
|
||||
for (final font in readerFonts) {
|
||||
expect(ftl, contains('${font.labelId} ='),
|
||||
reason: '${font.family} has no label');
|
||||
expect(ids.add(font.labelId), isTrue, reason: 'duplicate label id');
|
||||
}
|
||||
});
|
||||
|
||||
test('a typeface this build does not ship is refused', () async {
|
||||
final db = MewsDatabase.test(NativeDatabase.memory());
|
||||
addTearDown(db.close);
|
||||
final settings = ReaderSettingsController(db);
|
||||
|
||||
expect(await settings.setFont('Literata'), isTrue);
|
||||
expect(settings.font.value, 'Literata');
|
||||
|
||||
// Comic Sans is not bundled; accepting it would render in the platform
|
||||
// font while the settings page claimed otherwise.
|
||||
expect(await settings.setFont('Comic Sans MS'), isFalse);
|
||||
expect(settings.font.value, 'Literata');
|
||||
expect(await settings.setFont(''), isFalse);
|
||||
expect(settings.font.value, 'Literata');
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue