feat(flutter): 统一空列表占位组件
This commit is contained in:
1 parent
19babb8f4a
commit
6d08330388
24 files changed
+394
-63
No files matched your search
@@ -0,0 +1,149 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:fruitshorts/core/theme/app_colors.dart';
|
||||
import 'package:fruitshorts/core/theme/app_theme.dart';
|
||||
import 'package:fruitshorts/core/widgets/empty_state.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('should_render_title_subtitle_action_and_title_only_semantics', (
|
||||
tester,
|
||||
) async {
|
||||
var taps = 0;
|
||||
await _pump(
|
||||
tester,
|
||||
theme: AppTheme.dark(),
|
||||
child: EmptyState(
|
||||
icon: Icons.movie_outlined,
|
||||
title: 'No stories',
|
||||
subtitle: 'New content will appear here.',
|
||||
actionLabel: 'Retry',
|
||||
onAction: () => taps++,
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byKey(const Key('empty-state-art')), findsOneWidget);
|
||||
expect(find.byKey(const Key('empty-state-icon')), findsOneWidget);
|
||||
expect(find.text('No stories'), findsOneWidget);
|
||||
expect(find.text('New content will appear here.'), findsOneWidget);
|
||||
expect(
|
||||
tester.getSize(find.byKey(const Key('empty-state-art'))),
|
||||
const Size(96, 96),
|
||||
);
|
||||
expect(
|
||||
tester.getSize(find.byKey(const Key('empty-state-icon'))),
|
||||
const Size(42, 42),
|
||||
);
|
||||
expect(
|
||||
tester
|
||||
.widget<Text>(find.byKey(const Key('empty-state-title')))
|
||||
.style
|
||||
?.fontSize,
|
||||
16,
|
||||
);
|
||||
expect(
|
||||
tester.getSize(find.byKey(const Key('empty-state-action'))).height,
|
||||
greaterThanOrEqualTo(44),
|
||||
);
|
||||
|
||||
final semantics = tester.ensureSemantics();
|
||||
expect(find.bySemanticsLabel('No stories'), findsOneWidget);
|
||||
expect(
|
||||
find.bySemanticsLabel('New content will appear here.'),
|
||||
findsNothing,
|
||||
);
|
||||
|
||||
await tester.tap(find.byKey(const Key('empty-state-action')));
|
||||
expect(taps, 1);
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('should_render_compact_dimensions_for_embedded_empty_state', (
|
||||
tester,
|
||||
) async {
|
||||
await _pump(
|
||||
tester,
|
||||
child: const EmptyState(
|
||||
icon: Icons.chat_bubble_outline_rounded,
|
||||
title: 'No comments yet.',
|
||||
compact: true,
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
tester.getSize(find.byKey(const Key('empty-state-art'))),
|
||||
const Size(64, 64),
|
||||
);
|
||||
expect(
|
||||
tester.getSize(find.byKey(const Key('empty-state-icon'))),
|
||||
const Size(28, 28),
|
||||
);
|
||||
expect(
|
||||
tester
|
||||
.widget<Text>(find.byKey(const Key('empty-state-title')))
|
||||
.style
|
||||
?.fontSize,
|
||||
14,
|
||||
);
|
||||
expect(find.byKey(const Key('empty-state-action')), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('should_use_theme_aware_icon_colors', (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
theme: AppTheme.dark(),
|
||||
child: const EmptyState(icon: Icons.history_rounded, title: 'No history'),
|
||||
);
|
||||
expect(
|
||||
tester.widget<Icon>(find.byKey(const Key('empty-state-icon'))).color,
|
||||
AppColors.blueSoft,
|
||||
);
|
||||
|
||||
await _pump(
|
||||
tester,
|
||||
theme: AppTheme.light(),
|
||||
child: const EmptyState(icon: Icons.history_rounded, title: 'No history'),
|
||||
);
|
||||
expect(
|
||||
tester.widget<Icon>(find.byKey(const Key('empty-state-icon'))).color,
|
||||
AppColors.blue,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('should_fit_compact_width_without_overflow', (tester) async {
|
||||
tester.view.physicalSize = const Size(320, 568);
|
||||
tester.view.devicePixelRatio = 1;
|
||||
addTearDown(tester.view.resetPhysicalSize);
|
||||
addTearDown(tester.view.resetDevicePixelRatio);
|
||||
|
||||
await _pump(
|
||||
tester,
|
||||
child: const EmptyState(
|
||||
icon: Icons.download_outlined,
|
||||
title: 'No download authorizations yet.',
|
||||
subtitle: 'New content will appear here.',
|
||||
actionLabel: 'Retry',
|
||||
),
|
||||
);
|
||||
|
||||
final content = tester.widget<ConstrainedBox>(
|
||||
find.byKey(const Key('empty-state-content')),
|
||||
);
|
||||
expect(content.constraints.maxWidth, 280);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _pump(
|
||||
WidgetTester tester, {
|
||||
ThemeData? theme,
|
||||
required Widget child,
|
||||
}) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: theme ?? AppTheme.dark(),
|
||||
home: Scaffold(body: child),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
Reference in new issue
Block a user