import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:qiangbao_accounting/models/bill.dart'; import 'package:qiangbao_accounting/models/note.dart'; import 'package:qiangbao_accounting/models/statistics_response.dart'; import 'package:qiangbao_accounting/pages/assistant/assistant_page.dart'; import 'package:qiangbao_accounting/pages/bill/bill_home_page.dart'; import 'package:qiangbao_accounting/pages/home/dashboard_page.dart'; import 'package:qiangbao_accounting/providers/bill_provider.dart'; import 'package:qiangbao_accounting/providers/note_provider.dart'; /// 临时校验:改造后的两个页面在窄屏 / 常见机 / 大屏下都不溢出。 void main() { // 故意用会撑宽的数字,探一探摘要位窄不窄 final stats = StatisticsResponse( totalIncome: 123456.78, totalExpense: 98765.43, balance: 24691.35, categoryStatistics: const [], dailyStatistics: const [], ); final page = NotePage( items: const [ NoteListItem( id: 1, folderId: null, title: 'MySQL 主从复制搭建教程', summary: '', tags: [], pinned: false, updateTime: '2026-09-23 03:36', ), ], total: 128, hasMore: false, ); const sizes = [ ('iPhone SE 窄屏', Size(320, 568)), ('常见安卓机', Size(393, 873)), ('大屏', Size(480, 1000)), ]; void useSize(WidgetTester tester, Size size) { tester.view.physicalSize = size * 3; tester.view.devicePixelRatio = 3.0; addTearDown(tester.view.reset); } for (final (label, size) in sizes) { testWidgets('仪表盘 $label 不溢出', (tester) async { useSize(tester, size); await tester.pumpWidget( ProviderScope( overrides: [ monthlyStatisticsProvider.overrideWith((ref, month) async => stats), noteOverviewProvider.overrideWith((ref) async => page), ], child: const MaterialApp(home: DashboardPage()), ), ); await tester.pumpAndSettle(); // 先确认假数据真渲染出来了 —— 否则这个测试会「因为卡片是空的」而假通过 expect(find.text('128 篇'), findsOneWidget); expect(find.textContaining('98765.43'), findsWidgets); expect(tester.takeException(), isNull); }); testWidgets('记账首页(push 进来,带返回箭头)$label 不溢出', (tester) async { useSize(tester, size); await tester.pumpWidget( ProviderScope( overrides: [ monthlyStatisticsProvider.overrideWith((ref, month) async => stats), billsProvider.overrideWith((ref, month) async => []), ], child: MaterialApp( home: Builder( builder: (ctx) => Scaffold( body: Center( child: TextButton( onPressed: () => Navigator.of(ctx).push( MaterialPageRoute(builder: (_) => const BillHomePage()), ), child: const Text('进入'), ), ), ), ), ), ), ); // 真的 push 一次,canPop() 才是 true,才能测到「返回箭头 + 标题 + // 统计图标 + 月份切换」同时挤在一行的最坏情况 await tester.tap(find.text('进入')); await tester.pumpAndSettle(); expect(find.text('我的账单'), findsOneWidget); expect(tester.takeException(), isNull); }); testWidgets('助手页(push 进来)$label 不溢出', (tester) async { useSize(tester, size); await tester.pumpWidget( ProviderScope( child: MaterialApp( home: Builder( builder: (ctx) => Scaffold( body: Center( child: TextButton( onPressed: () => Navigator.of(ctx).push( MaterialPageRoute(builder: (_) => const AssistantPage()), ), child: const Text('进入'), ), ), ), ), ), ), ); await tester.tap(find.text('进入')); await tester.pumpAndSettle(); // 空状态:标题 + 引导问题 + 底部输入框 expect(find.text('问我点什么'), findsOneWidget); expect(find.text('这个月花了多少钱?'), findsOneWidget); expect(tester.takeException(), isNull); }); } }