feat(proj): init

This commit is contained in:
vl.arkhangelskii
2026-09-21 04:06:43 +03:00
commit c956b94983
1076 changed files with 50876 additions and 0 deletions
@@ -0,0 +1,89 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:please_pay_me/theme/theme.dart';
import 'package:please_pay_me_widgetbook/catalog.dart';
import 'package:widgetbook/widgetbook.dart';
List<WidgetbookUseCase> _collectUseCases() {
final useCases = <WidgetbookUseCase>[];
void walk(WidgetbookNode node) {
if (node is WidgetbookUseCase) useCases.add(node);
for (final child in node.children ?? const <WidgetbookNode>[]) {
walk(child);
}
}
for (final root in buildCatalogDirectories()) {
walk(root);
}
return useCases;
}
/// Knobs read `WidgetbookState` from the context, so use-cases can only be
/// pumped inside a scope.
Widget _host({required CupertinoThemeData theme, required WidgetbookUseCase useCase}) {
return WidgetbookScope(
state: WidgetbookState(
path: useCase.path,
root: WidgetbookRoot(children: buildCatalogDirectories()),
),
child: CupertinoApp(
theme: theme,
locale: const Locale('ru'),
home: Builder(builder: useCase.builder),
),
);
}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
// No network access in tests — fall back to the default font instead.
GoogleFonts.config.allowRuntimeFetching = false;
setUpAll(() => initializeDateFormatting('ru'));
test('catalog directories are non-empty', () {
expect(buildCatalogDirectories(), isNotEmpty);
});
test('every use-case has a name and a builder', () {
final useCases = _collectUseCases();
for (final useCase in useCases) {
expect(useCase.name, isNotEmpty);
expect(useCase.builder, isNotNull);
}
expect(useCases.length, greaterThanOrEqualTo(20));
});
test('expected category folders exist', () {
final names = buildCatalogDirectories().map((n) => n.name).toSet();
expect(
names,
containsAll(<String>{'Atoms', 'Molecules', 'Navigation', 'Feedback', 'Screens'}),
);
});
group('use-cases render', () {
final themes = <String, CupertinoThemeData Function()>{
'Light': buildLightTheme,
'Dark': buildDarkTheme,
};
for (final entry in themes.entries) {
for (final useCase in _collectUseCases()) {
testWidgets('${useCase.path} (${entry.key})', (tester) async {
await tester.pumpWidget(_host(theme: entry.value(), useCase: useCase));
await tester.pump(const Duration(milliseconds: 300));
expect(tester.takeException(), isNull);
});
}
}
});
}
+10
View File
@@ -0,0 +1,10 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:please_pay_me_widgetbook/app.dart';
void main() {
testWidgets('WidgetbookRoot builds', (WidgetTester tester) async {
await tester.pumpWidget(const WidgetbookRoot());
await tester.pump();
expect(find.byType(WidgetbookRoot), findsOneWidget);
});
}