AI助手优化-头像和对话功能
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:qiangbao_accounting/widgets/avatar.dart';
|
||||
|
||||
/// 头像组件的测试。
|
||||
///
|
||||
/// 重点是**不崩**和**不留裂图** —— 头像是从后端 /uploads 拉的,
|
||||
/// 文件被删、地址写错、网络断了都会走到 errorBuilder,
|
||||
/// 那时候必须退回默认图标,而不是显示一个裂开的图。
|
||||
void main() {
|
||||
Widget wrap(Widget child) => MaterialApp(home: Scaffold(body: child));
|
||||
|
||||
group('Avatar 兜底', () {
|
||||
testWidgets('assetPath 为 null 时显示默认图标,不发起网络请求', (tester) async {
|
||||
await tester.pumpWidget(wrap(const Avatar(size: 40)));
|
||||
await tester.pump();
|
||||
|
||||
// 没有 Image 组件 —— 说明压根没去加载图片
|
||||
expect(find.byType(Image), findsNothing);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('assetPath 为空串时也走默认图标', (tester) async {
|
||||
await tester.pumpWidget(wrap(const Avatar(assetPath: '', size: 40)));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(Image), findsNothing);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('只有空白字符的路径也当没有(后端可能返回 " ")', (tester) async {
|
||||
await tester.pumpWidget(wrap(const Avatar(assetPath: ' ', size: 40)));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(Image), findsNothing);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('★ 给了路径就渲染图片,且加载失败时不崩(退回默认图标)', (tester) async {
|
||||
await tester.pumpWidget(wrap(
|
||||
const Avatar(assetPath: 'persona/2026/09/29/x.jpg', size: 40),
|
||||
));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(Image), findsOneWidget);
|
||||
|
||||
// 测试环境里网络请求必然失败,会走 errorBuilder。
|
||||
// 这里断言的是「失败被接住了,没有把异常抛到 widget 树」
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
expect(tester.takeException(), isNull,
|
||||
reason: '图片加载失败必须被 errorBuilder 接住,不能抛异常');
|
||||
});
|
||||
});
|
||||
|
||||
group('Avatar 尺寸', () {
|
||||
testWidgets('尺寸按传入值设置(聊天气泡和「我的」页面用不同大小)', (tester) async {
|
||||
await tester.pumpWidget(wrap(const Avatar(size: 36)));
|
||||
await tester.pump();
|
||||
|
||||
final container = tester.widget<Container>(find.byType(Container).first);
|
||||
final size = container.constraints;
|
||||
expect(size?.maxWidth, 36);
|
||||
expect(size?.maxHeight, 36);
|
||||
});
|
||||
|
||||
testWidgets('不同尺寸都不溢出', (tester) async {
|
||||
for (final s in [24.0, 36.0, 40.0, 60.0, 76.0]) {
|
||||
await tester.pumpWidget(wrap(Avatar(size: s)));
|
||||
await tester.pump();
|
||||
expect(tester.takeException(), isNull, reason: '尺寸 $s 出问题了');
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('在很窄的容器里也不溢出', (tester) async {
|
||||
await tester.pumpWidget(wrap(
|
||||
const SizedBox(width: 40, height: 40, child: Avatar(size: 36)),
|
||||
));
|
||||
await tester.pump();
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user