fix(golden): 冻结应用时钟消除时间依赖非确定性(product_detail/license/inventory_check)

golden 失败根因:商品详情屏用实时 DateTime.now() 算「近30天出库」,随真实时间推移
6月流水掉出30天窗口→渲染变化→对不上。license/inventory_check 同理(剩余天数/盘点日期)。
修复:
- product_detail_screen: DateTime.now() → appNow()(可注入时钟)
- golden_harness: 所有 golden 渲染前冻结 appClock=2026-07-01 + tearDown 复位(ds-flow 钉死动态值)
- 重录 license_mobile / m_inventory_check 6 张 golden;product_detail 冻结后自动匹配无需改图
本地 flutter test test/golden/ 全 120 通过。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P9G7E3wmAYL9KeYCVZVsqu
This commit is contained in:
wangjia
2026-07-18 19:53:17 +08:00
parent 067f21c273
commit f9ba81ae43
8 changed files with 8 additions and 1 deletions
@@ -1,5 +1,6 @@
import 'package:lucide_icons_flutter/lucide_icons.dart';
import '../../core/utils/dialog_util.dart';
import '../../core/utils/clock.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/foundation.dart';
@@ -395,7 +396,7 @@ class _ProductDetailScreenState extends ConsumerState<ProductDetailScreen> {
final currentStock = _invRows.fold<num>(0, (s, i) => s + i.quantity);
final cost = p.purchasePrice ?? 0;
final stockValue = currentStock * cost;
final now = DateTime.now();
final now = appNow();
final out30 = _logs.where((l) {
if (l.direction != 'out') return false;
final d = DateTime.tryParse(l.createdAt ?? '');
Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 64 KiB

+6
View File
@@ -3,6 +3,7 @@ import 'package:flutter/services.dart' show rootBundle, FontLoader;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:jiu_client/core/theme/themes.dart';
import 'package:jiu_client/core/utils/clock.dart';
// golden 使 golden diff
// Noto Sans SC tools/fidelity.mjs
@@ -67,6 +68,11 @@ Future<void> pumpGolden(
double dpr = 2.0,
}) async {
await ensureGoldenFonts();
// appNow() 30
// golden ds-flowgolden 2026-07-01使 fake 6
// 30tearDown
appClock = () => DateTime(2026, 7, 1, 12, 0);
addTearDown(() => appClock = () => DateTime.now());
tester.view.physicalSize = Size(logical.width * dpr, logical.height * dpr);
tester.view.devicePixelRatio = dpr;
addTearDown(tester.view.resetPhysicalSize);