import 'package:flutter/material.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:frontend/core/constants/app_sizes.dart'; import 'package:frontend/core/theme/app_colors.dart'; import 'package:frontend/features/home/domain/models/link_item.dart'; import 'package:frontend/features/home/presentation/widgets/link_card.dart'; const LinkItem _item = LinkItem( id: 'github', title: 'GitHub', url: 'https://github.com', description: '代码托管与开源社区', ); void main() { late int openCount; setUp(() { openCount = 0; }); Future pumpCard( WidgetTester tester, { LinkItem item = _item, Size size = const Size(280, 200), }) async { tester.view.physicalSize = size; tester.view.devicePixelRatio = 1; addTearDown(tester.view.reset); await tester.pumpWidget( MaterialApp( home: Scaffold( backgroundColor: AppColors.background, body: Center( child: SizedBox( width: 260, child: LinkCard(item: item, onOpen: () => openCount++), ), ), ), ), ); await tester.pump(); } testWidgets('渲染首字母图标、名称与描述', (WidgetTester tester) async { await pumpCard(tester); expect(find.text('G'), findsOneWidget); expect(find.text('GitHub'), findsOneWidget); expect(find.text('代码托管与开源社区'), findsOneWidget); }); testWidgets('没有描述时不报错', (WidgetTester tester) async { await pumpCard( tester, item: const LinkItem(id: 'x', title: '示例', url: 'https://example.com'), ); expect(find.text('示'), findsOneWidget); expect(find.text('示例'), findsOneWidget); }); testWidgets('点击触发打开回调', (WidgetTester tester) async { await pumpCard(tester); await tester.tap(find.text('GitHub')); await tester.pump(); expect(openCount, 1); }); testWidgets('悬停时上浮', (WidgetTester tester) async { await pumpCard(tester); // AnimatedContainer 目标 transform 的 y 分量就是上浮距离: // 直接断言它,不受 Tooltip 等外层 RenderObject 的影响。 double lift() { final AnimatedContainer container = tester.widget( find.descendant( of: find.byType(LinkCard), matching: find.byType(AnimatedContainer), ), ); return container.transform?.getTranslation().y ?? 0; } expect(lift(), 0); final TestGesture gesture = await tester.createGesture( kind: PointerDeviceKind.mouse, ); await gesture.addPointer(location: tester.getCenter(find.byType(LinkCard))); addTearDown(gesture.removePointer); await gesture.moveTo(tester.getCenter(find.byType(LinkCard))); await tester.pumpAndSettle(); expect(lift(), -AppSizes.cardHoverLift); }); }