Files
jiu/client/test/support/golden_harness.dart
T
wangjia 4b57cdb0f5 test(client): 整屏 golden 还原闸 + 可复用 golden 骨架(基建)
test/support/golden_harness.dart:pumpGolden(viewport=physical÷dpr/给足高度/
provider 覆盖)+ goldenAcrossThemes(A/B/C 三主题组)。
test/golden/inventory_list_golden_test.dart:库存列表整屏 × 三主题 golden
(fake AsyncNotifier 喂 canned 数据 + isReadonly 覆盖 + SP mock),入库作回归闸。
保真目检:shoot 原型 + montage 与 goldens 并排(见 design-distill flutter-golden.md)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSKEiHsvauyxYUW2itzUXX
2026-07-01 20:46:51 +08:00

70 lines
2.4 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:jiu_client/core/theme/themes.dart';
/// design-distill 阶段4Flutter 端)可复用 golden 骨架。
/// 在指定主题 / viewport 下渲染 [child](含 provider 覆盖),比对/更新 golden。
///
/// 验收分两类闸(见 ~/.claude/skills/design-distill/references/flutter-golden.md):
/// - 保真:原型基准 vs 本 golden 用 montage.mjs 人工目检(跨渲染器,不跑严格 diff)。
/// - 回归:本 golden 多主题入库,CI `flutter test` 同渲染器自比抓串色/漏 token。
///
/// 更新基准:flutter test --update-goldens test/golden/<x>_golden_test.dart
///
/// 坑(详见 reference):viewport 逻辑尺寸 = physical ÷ dpr(已按 logical*dpr 设好);
/// 高度给足防 RenderFlex 溢出;测试无中文字体 → CJK 显示豆腐块属正常。
Future<void> pumpGolden(
WidgetTester tester, {
required Widget child,
required String theme,
required String goldenName,
List<Override> overrides = const [],
Size logical = const Size(1280, 900),
double dpr = 2.0,
}) async {
tester.view.physicalSize = Size(logical.width * dpr, logical.height * dpr);
tester.view.devicePixelRatio = dpr;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await tester.pumpWidget(ProviderScope(
overrides: overrides,
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: buildTheme(theme),
home: child,
),
));
await tester.pumpAndSettle();
await expectLater(
find.byType(MaterialApp),
matchesGoldenFile('goldens/$goldenName.png'),
);
}
/// 跑「同一 child × A/B/C 三主题」的 golden 组(回归闸常用)。
void goldenAcrossThemes(
String description, {
required Widget Function() child,
required String goldenPrefix,
List<Override> Function()? overrides,
Size logical = const Size(1280, 900),
double dpr = 2.0,
}) {
for (final theme in const ['a', 'b', 'c']) {
testWidgets('$description · theme $theme', (tester) async {
await pumpGolden(
tester,
child: child(),
theme: theme,
goldenName: '${goldenPrefix}_$theme',
overrides: overrides?.call() ?? const [],
logical: logical,
dpr: dpr,
);
});
}
}