diff --git a/codecov.yml b/codecov.yml index 4238755..6160dc3 100644 --- a/codecov.yml +++ b/codecov.yml @@ -23,4 +23,6 @@ comment: ignore: - "**/*.g.dart" - "**/*.freezed.dart" + - "**/*_route_args.dart" + - "**/*_event.dart" - "test/**" diff --git a/lib/core/theme/typography.dart b/lib/core/theme/typography.dart index 3caa29c..55dae85 100644 --- a/lib/core/theme/typography.dart +++ b/lib/core/theme/typography.dart @@ -4,6 +4,16 @@ import 'package:google_fonts/google_fonts.dart'; class AppTypography { AppTypography._(); + static bool _disableFontsForTests = false; + + static void disableFontsForTests() { + _disableFontsForTests = true; + } + + static void enableFonts() { + _disableFontsForTests = false; + } + static TextStyle googleSans({ double fontSize = 14, FontWeight fontWeight = FontWeight.normal, @@ -11,6 +21,16 @@ class AppTypography { double? letterSpacing, double? height, }) { + if (_disableFontsForTests) { + return TextStyle( + fontSize: fontSize, + fontWeight: fontWeight, + color: color, + letterSpacing: letterSpacing, + height: height, + ); + } + return GoogleFonts.googleSans( fontSize: fontSize, fontWeight: fontWeight, @@ -27,6 +47,16 @@ class AppTypography { double? letterSpacing, double? height, }) { + if (_disableFontsForTests) { + return TextStyle( + fontSize: fontSize, + fontWeight: fontWeight, + color: color, + letterSpacing: letterSpacing, + height: height, + ); + } + return GoogleFonts.lora( fontSize: fontSize, fontWeight: fontWeight, @@ -43,6 +73,16 @@ class AppTypography { double? letterSpacing, double? height, }) { + if (_disableFontsForTests) { + return TextStyle( + fontSize: fontSize, + fontWeight: fontWeight, + color: color, + letterSpacing: letterSpacing, + height: height, + ); + } + return GoogleFonts.googleSansCode( fontSize: fontSize, fontWeight: fontWeight, diff --git a/lib/features/devtools/presentation/dev_tools_screen.dart b/lib/features/devtools/presentation/dev_tools_screen.dart index b0b75ff..677ad31 100644 --- a/lib/features/devtools/presentation/dev_tools_screen.dart +++ b/lib/features/devtools/presentation/dev_tools_screen.dart @@ -6,6 +6,7 @@ import 'package:bluesky/app_bsky_actor_defs.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:lazurite/core/theme/typography.dart'; import 'package:lazurite/core/theme/theme_extensions.dart'; import 'package:lazurite/core/widgets/app_breadcrumbs.dart'; import 'package:lazurite/features/devtools/cubit/dev_tools_cubit.dart'; @@ -119,7 +120,7 @@ class _SearchInputState extends State<_SearchInput> { contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 12), isDense: true, ), - style: const TextStyle(fontFamily: 'JetBrains Mono', fontSize: 13), + style: AppTypography.googleSansCode(fontSize: 13), onChanged: _onQueryChanged, onSubmitted: _resolve, ), @@ -456,7 +457,7 @@ class _CollectionItem extends StatelessWidget { ), child: Icon(_getCollectionIcon(collection.name), size: 16, color: context.colorScheme.primary), ), - title: Text(collection.name, style: const TextStyle(fontFamily: 'JetBrains Mono', fontSize: 13)), + title: Text(collection.name, style: AppTypography.googleSansCode(fontSize: 13)), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -544,8 +545,11 @@ class _RecordsListState extends State<_RecordsList> { Expanded( child: Text( widget.state.selectedCollection ?? '', - style: context.textTheme.titleSmall?.copyWith( - fontFamily: 'JetBrains Mono', + style: AppTypography.googleSansCode( + fontSize: context.textTheme.titleSmall?.fontSize ?? 14, + fontWeight: context.textTheme.titleSmall?.fontWeight ?? FontWeight.w500, + letterSpacing: context.textTheme.titleSmall?.letterSpacing, + height: context.textTheme.titleSmall?.height, color: context.colorScheme.primary, ), ), @@ -594,7 +598,7 @@ class _RecordItem extends StatelessWidget { final preview = _getRecordPreview(record.value); return ListTile( - title: Text(rkey, style: const TextStyle(fontFamily: 'JetBrains Mono', fontSize: 13)), + title: Text(rkey, style: AppTypography.googleSansCode(fontSize: 13)), subtitle: preview != null ? Text(preview, maxLines: 1, overflow: TextOverflow.ellipsis) : null, trailing: const Icon(Icons.chevron_right), onTap: () => context.read().loadRecord(record), @@ -698,10 +702,7 @@ class _JsonViewer extends StatelessWidget { @override Widget build(BuildContext context) { - return SelectableText( - _formatJson(json), - style: const TextStyle(fontFamily: 'JetBrains Mono', fontSize: 12, height: 1.8), - ); + return SelectableText(_formatJson(json), style: AppTypography.googleSansCode(fontSize: 12, height: 1.8)); } } diff --git a/test/core/theme/catppuccin_theme_test.dart b/test/core/theme/catppuccin_theme_test.dart index c8ee0cb..0545e03 100644 --- a/test/core/theme/catppuccin_theme_test.dart +++ b/test/core/theme/catppuccin_theme_test.dart @@ -127,5 +127,59 @@ void main() { expect(CatppuccinTheme.latteRosewater, const Color(0xFFdc8a78)); }); }); + + group('ThemeData', () { + test('dark theme maps expected tokens', () { + final theme = CatppuccinTheme.dark(); + final scheme = theme.colorScheme; + + expect(theme.useMaterial3, isTrue); + expect(theme.brightness, Brightness.dark); + expect(scheme.primary, CatppuccinTheme.mochaLavender); + expect(scheme.secondary, CatppuccinTheme.mochaMauve); + expect(scheme.tertiary, CatppuccinTheme.mochaSapphire); + expect(scheme.surface, CatppuccinTheme.mochaMantle); + expect(scheme.onSurface, CatppuccinTheme.mochaText); + expect(scheme.surfaceContainerHighest, CatppuccinTheme.mochaSurface0); + expect(scheme.outline, CatppuccinTheme.mochaSurface1); + expect(scheme.outlineVariant, CatppuccinTheme.mochaSurface0); + expect(theme.scaffoldBackgroundColor, CatppuccinTheme.mochaBase); + expect(theme.appBarTheme.backgroundColor, CatppuccinTheme.mochaBase); + expect(theme.cardTheme.color, CatppuccinTheme.mochaMantle); + expect(theme.dividerTheme.color, CatppuccinTheme.mochaSurface0); + expect(theme.iconTheme.color, CatppuccinTheme.mochaSubtext0); + expect(theme.listTileTheme.textColor, CatppuccinTheme.mochaText); + expect(theme.floatingActionButtonTheme.backgroundColor, CatppuccinTheme.mochaLavender); + expect(theme.inputDecorationTheme.filled, isTrue); + expect(theme.inputDecorationTheme.fillColor, CatppuccinTheme.mochaMantle); + expect(theme.snackBarTheme.backgroundColor, CatppuccinTheme.mochaMantle); + }); + + test('light theme maps expected tokens', () { + final theme = CatppuccinTheme.light(); + final scheme = theme.colorScheme; + + expect(theme.useMaterial3, isTrue); + expect(theme.brightness, Brightness.light); + expect(scheme.primary, CatppuccinTheme.latteLavender); + expect(scheme.secondary, CatppuccinTheme.latteMauve); + expect(scheme.tertiary, CatppuccinTheme.latteSapphire); + expect(scheme.surface, CatppuccinTheme.latteMantle); + expect(scheme.onSurface, CatppuccinTheme.latteText); + expect(scheme.surfaceContainerHighest, CatppuccinTheme.latteSurface0); + expect(scheme.outline, CatppuccinTheme.latteSurface1); + expect(scheme.outlineVariant, CatppuccinTheme.latteSurface0); + expect(theme.scaffoldBackgroundColor, CatppuccinTheme.latteBase); + expect(theme.appBarTheme.backgroundColor, CatppuccinTheme.latteBase); + expect(theme.cardTheme.color, CatppuccinTheme.latteMantle); + expect(theme.dividerTheme.color, CatppuccinTheme.latteSurface0); + expect(theme.iconTheme.color, CatppuccinTheme.latteSubtext0); + expect(theme.listTileTheme.textColor, CatppuccinTheme.latteText); + expect(theme.floatingActionButtonTheme.backgroundColor, CatppuccinTheme.latteLavender); + expect(theme.inputDecorationTheme.filled, isTrue); + expect(theme.inputDecorationTheme.fillColor, CatppuccinTheme.latteMantle); + expect(theme.snackBarTheme.backgroundColor, CatppuccinTheme.latteMantle); + }); + }); }); } diff --git a/test/core/theme/nord_theme_test.dart b/test/core/theme/nord_theme_test.dart index abdc54a..8d6d756 100644 --- a/test/core/theme/nord_theme_test.dart +++ b/test/core/theme/nord_theme_test.dart @@ -69,5 +69,59 @@ void main() { expect(NordTheme.nord15, const Color(0xFFb48ead)); }); }); + + group('ThemeData', () { + test('dark theme maps expected tokens', () { + final theme = NordTheme.dark(); + final scheme = theme.colorScheme; + + expect(theme.useMaterial3, isTrue); + expect(theme.brightness, Brightness.dark); + expect(scheme.primary, NordTheme.nord8); + expect(scheme.secondary, NordTheme.nord9); + expect(scheme.tertiary, NordTheme.nord7); + expect(scheme.surface, NordTheme.nord1); + expect(scheme.onSurface, NordTheme.nord5); + expect(scheme.surfaceContainerHighest, NordTheme.nord2); + expect(scheme.outline, NordTheme.nord3); + expect(scheme.outlineVariant, NordTheme.nord2); + expect(theme.scaffoldBackgroundColor, NordTheme.nord0); + expect(theme.appBarTheme.backgroundColor, NordTheme.nord0); + expect(theme.cardTheme.color, NordTheme.nord1); + expect(theme.dividerTheme.color, NordTheme.nord2); + expect(theme.iconTheme.color, NordTheme.nord4); + expect(theme.listTileTheme.textColor, NordTheme.nord5); + expect(theme.floatingActionButtonTheme.backgroundColor, NordTheme.nord8); + expect(theme.inputDecorationTheme.filled, isTrue); + expect(theme.inputDecorationTheme.fillColor, NordTheme.nord1); + expect(theme.snackBarTheme.backgroundColor, NordTheme.nord1); + }); + + test('light theme maps expected tokens', () { + final theme = NordTheme.light(); + final scheme = theme.colorScheme; + + expect(theme.useMaterial3, isTrue); + expect(theme.brightness, Brightness.light); + expect(scheme.primary, NordTheme.nord8); + expect(scheme.secondary, NordTheme.nord9); + expect(scheme.tertiary, NordTheme.nord7); + expect(scheme.surface, NordTheme.nord1); + expect(scheme.onSurface, NordTheme.nord3); + expect(scheme.surfaceContainerHighest, NordTheme.nord2); + expect(scheme.outline, NordTheme.nord3); + expect(scheme.outlineVariant, NordTheme.nord2); + expect(theme.scaffoldBackgroundColor, NordTheme.nord6); + expect(theme.appBarTheme.backgroundColor, NordTheme.nord6); + expect(theme.cardTheme.color, NordTheme.nord5); + expect(theme.dividerTheme.color, NordTheme.nord2); + expect(theme.iconTheme.color, NordTheme.nord4); + expect(theme.listTileTheme.textColor, NordTheme.nord3); + expect(theme.floatingActionButtonTheme.backgroundColor, NordTheme.nord8); + expect(theme.inputDecorationTheme.filled, isTrue); + expect(theme.inputDecorationTheme.fillColor, NordTheme.nord5); + expect(theme.snackBarTheme.backgroundColor, NordTheme.nord5); + }); + }); }); } diff --git a/test/core/theme/oxocarbon_theme_test.dart b/test/core/theme/oxocarbon_theme_test.dart index 9121770..8654b63 100644 --- a/test/core/theme/oxocarbon_theme_test.dart +++ b/test/core/theme/oxocarbon_theme_test.dart @@ -135,5 +135,59 @@ void main() { expect(OxocarbonTheme.lightBase0F, const Color(0xFFFFAB91)); }); }); + + group('ThemeData', () { + test('dark theme maps expected tokens', () { + final theme = OxocarbonTheme.dark(); + final scheme = theme.colorScheme; + + expect(theme.useMaterial3, isTrue); + expect(theme.brightness, Brightness.dark); + expect(scheme.primary, OxocarbonTheme.darkBase09); + expect(scheme.secondary, OxocarbonTheme.darkBase0E); + expect(scheme.tertiary, OxocarbonTheme.darkBase07); + expect(scheme.surface, OxocarbonTheme.darkBase01); + expect(scheme.onSurface, OxocarbonTheme.darkBase05); + expect(scheme.surfaceContainerHighest, OxocarbonTheme.darkBase02); + expect(scheme.outline, OxocarbonTheme.darkBase03); + expect(scheme.outlineVariant, OxocarbonTheme.darkBase02); + expect(theme.scaffoldBackgroundColor, OxocarbonTheme.darkBase00); + expect(theme.appBarTheme.backgroundColor, OxocarbonTheme.darkBase00); + expect(theme.cardTheme.color, OxocarbonTheme.darkBase01); + expect(theme.dividerTheme.color, OxocarbonTheme.darkBase02); + expect(theme.iconTheme.color, OxocarbonTheme.darkBase04); + expect(theme.listTileTheme.textColor, OxocarbonTheme.darkBase05); + expect(theme.floatingActionButtonTheme.backgroundColor, OxocarbonTheme.darkBase09); + expect(theme.inputDecorationTheme.filled, isTrue); + expect(theme.inputDecorationTheme.fillColor, OxocarbonTheme.darkBase01); + expect(theme.snackBarTheme.backgroundColor, OxocarbonTheme.darkBase01); + }); + + test('light theme maps expected tokens', () { + final theme = OxocarbonTheme.light(); + final scheme = theme.colorScheme; + + expect(theme.useMaterial3, isTrue); + expect(theme.brightness, Brightness.light); + expect(scheme.primary, OxocarbonTheme.lightBase0B); + expect(scheme.secondary, OxocarbonTheme.lightBase0C); + expect(scheme.tertiary, OxocarbonTheme.lightBase07); + expect(scheme.surface, OxocarbonTheme.lightBase01); + expect(scheme.onSurface, OxocarbonTheme.lightBase03); + expect(scheme.surfaceContainerHighest, OxocarbonTheme.lightBase02); + expect(scheme.outline, OxocarbonTheme.lightBase05); + expect(scheme.outlineVariant, OxocarbonTheme.lightBase02); + expect(theme.scaffoldBackgroundColor, OxocarbonTheme.lightBase00); + expect(theme.appBarTheme.backgroundColor, OxocarbonTheme.lightBase00); + expect(theme.cardTheme.color, OxocarbonTheme.lightBase01); + expect(theme.dividerTheme.color, OxocarbonTheme.lightBase02); + expect(theme.iconTheme.color, OxocarbonTheme.lightBase04); + expect(theme.listTileTheme.textColor, OxocarbonTheme.lightBase03); + expect(theme.floatingActionButtonTheme.backgroundColor, OxocarbonTheme.lightBase0B); + expect(theme.inputDecorationTheme.filled, isTrue); + expect(theme.inputDecorationTheme.fillColor, OxocarbonTheme.lightBase01); + expect(theme.snackBarTheme.backgroundColor, OxocarbonTheme.lightBase01); + }); + }); }); } diff --git a/test/core/theme/rose_pine_theme_test.dart b/test/core/theme/rose_pine_theme_test.dart index 7833886..8816563 100644 --- a/test/core/theme/rose_pine_theme_test.dart +++ b/test/core/theme/rose_pine_theme_test.dart @@ -103,5 +103,59 @@ void main() { expect(RosePineTheme.dawnIris, const Color(0xFF907aa9)); }); }); + + group('ThemeData', () { + test('dark theme maps expected tokens', () { + final theme = RosePineTheme.dark(); + final scheme = theme.colorScheme; + + expect(theme.useMaterial3, isTrue); + expect(theme.brightness, Brightness.dark); + expect(scheme.primary, RosePineTheme.mainRose); + expect(scheme.secondary, RosePineTheme.mainIris); + expect(scheme.tertiary, RosePineTheme.mainFoam); + expect(scheme.surface, RosePineTheme.mainSurface); + expect(scheme.onSurface, RosePineTheme.mainText); + expect(scheme.surfaceContainerHighest, RosePineTheme.mainOverlay); + expect(scheme.outline, RosePineTheme.mainMuted); + expect(scheme.outlineVariant, RosePineTheme.mainOverlay); + expect(theme.scaffoldBackgroundColor, RosePineTheme.mainBase); + expect(theme.appBarTheme.backgroundColor, RosePineTheme.mainBase); + expect(theme.cardTheme.color, RosePineTheme.mainSurface); + expect(theme.dividerTheme.color, RosePineTheme.mainOverlay); + expect(theme.iconTheme.color, RosePineTheme.mainSubtle); + expect(theme.listTileTheme.textColor, RosePineTheme.mainText); + expect(theme.floatingActionButtonTheme.backgroundColor, RosePineTheme.mainRose); + expect(theme.inputDecorationTheme.filled, isTrue); + expect(theme.inputDecorationTheme.fillColor, RosePineTheme.mainSurface); + expect(theme.snackBarTheme.backgroundColor, RosePineTheme.mainSurface); + }); + + test('light theme maps expected tokens', () { + final theme = RosePineTheme.light(); + final scheme = theme.colorScheme; + + expect(theme.useMaterial3, isTrue); + expect(theme.brightness, Brightness.light); + expect(scheme.primary, RosePineTheme.dawnRose); + expect(scheme.secondary, RosePineTheme.dawnIris); + expect(scheme.tertiary, RosePineTheme.dawnFoam); + expect(scheme.surface, RosePineTheme.dawnSurface); + expect(scheme.onSurface, RosePineTheme.dawnText); + expect(scheme.surfaceContainerHighest, RosePineTheme.dawnOverlay); + expect(scheme.outline, RosePineTheme.dawnMuted); + expect(scheme.outlineVariant, RosePineTheme.dawnOverlay); + expect(theme.scaffoldBackgroundColor, RosePineTheme.dawnBase); + expect(theme.appBarTheme.backgroundColor, RosePineTheme.dawnBase); + expect(theme.cardTheme.color, RosePineTheme.dawnSurface); + expect(theme.dividerTheme.color, RosePineTheme.dawnOverlay); + expect(theme.iconTheme.color, RosePineTheme.dawnSubtle); + expect(theme.listTileTheme.textColor, RosePineTheme.dawnText); + expect(theme.floatingActionButtonTheme.backgroundColor, RosePineTheme.dawnRose); + expect(theme.inputDecorationTheme.filled, isTrue); + expect(theme.inputDecorationTheme.fillColor, RosePineTheme.dawnSurface); + expect(theme.snackBarTheme.backgroundColor, RosePineTheme.dawnSurface); + }); + }); }); } diff --git a/test/flutter_test_config.dart b/test/flutter_test_config.dart index 114892d..064da4c 100644 --- a/test/flutter_test_config.dart +++ b/test/flutter_test_config.dart @@ -1,6 +1,12 @@ import 'dart:async'; +import 'package:lazurite/core/theme/typography.dart'; +import 'package:flutter_test/flutter_test.dart'; + Future testExecutable(FutureOr Function() testMain) async { + TestWidgetsFlutterBinding.ensureInitialized(); + AppTypography.disableFontsForTests(); + await runZoned( () async { await testMain();