fb236018f3
- wheel_date_picker.dart 重构为统一组件:单日期 showDsDateDropdown(面板= 可输入框+三列滚轮+今天/确定)、范围 showDateRangeDropdown(起始|结束双窗格 并排+共用底栏);桌面锚定下拉(透明遮罩不冻结窗口)、窄屏底部 sheet 同内容 (范围纵排)——同一套窗格两端复用 - 扁平化:输入框与滚轮同宽 248、文字水平垂直居中(mono)、去掉全部阴影/立体 效果(滚轮外框仅 1px 边框,中心高亮带去描边) - DsDateCell(录单日期格)与 DatePickerField(登记收支)改为触发器:点选/ 回车打开统一面板,键入在面板内完成;出库工具栏时间 chip 补切到新组件 - 旧 showWheelDatePicker/showWheelDateRange 两步弹窗删除;组件测试改写为 新契约(触发器+面板键入+词法归一),表单 golden 随形态更新 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
98 lines
3.8 KiB
Dart
98 lines
3.8 KiB
Dart
import 'package:lucide_icons_flutter/lucide_icons.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:jiu_client/core/theme/themes.dart';
|
|
import 'package:jiu_client/core/utils/date_util.dart';
|
|
import 'package:jiu_client/widgets/date_picker_field.dart';
|
|
|
|
void main() {
|
|
group('date_util', () {
|
|
test('formatYmd 补零', () {
|
|
expect(formatYmd(DateTime(2026, 6, 9)), '2026-06-09');
|
|
expect(formatYmd(DateTime(2026, 12, 31)), '2026-12-31');
|
|
});
|
|
test('parseYmd 解析/容错', () {
|
|
expect(parseYmd('2026-06-19'), DateTime(2026, 6, 19));
|
|
expect(parseYmd('2026-06-19T08:00:00'), DateTime(2026, 6, 19));
|
|
expect(parseYmd(null), isNull);
|
|
expect(parseYmd(''), isNull);
|
|
});
|
|
test('composeYmd 正常组合', () {
|
|
expect(composeYmd(2026, 6, 15), '2026-06-15');
|
|
});
|
|
test('composeYmd 把超界的日 clamp 回当月最大值', () {
|
|
expect(composeYmd(2026, 2, 31), '2026-02-28'); // 平年 2 月
|
|
expect(composeYmd(2024, 2, 31), '2024-02-29'); // 闰年 2 月
|
|
expect(composeYmd(2026, 4, 31), '2026-04-30'); // 4 月 30 天
|
|
});
|
|
test('composeYmd 任一为空返回 null', () {
|
|
expect(composeYmd(null, 6, 15), isNull);
|
|
expect(composeYmd(2026, null, 15), isNull);
|
|
expect(composeYmd(2026, 6, null), isNull);
|
|
});
|
|
});
|
|
|
|
group('DatePickerField', () {
|
|
testWidgets('渲染触发字段:值回显 + 日历图标', (tester) async {
|
|
await tester.pumpWidget(MaterialApp(
|
|
theme: buildTheme('a'),
|
|
home: Scaffold(
|
|
body: DatePickerField(value: '2026-06-19', onChanged: (_) {}),
|
|
),
|
|
));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('2026-06-19'), findsOneWidget);
|
|
expect(find.byIcon(LucideIcons.calendar), findsOneWidget);
|
|
// 字段本体不再内嵌输入框(输入框在下拉面板里)
|
|
expect(find.byType(TextField), findsNothing);
|
|
});
|
|
|
|
testWidgets('点选打开统一下拉:面板含输入框 + 滚轮,确定回传', (tester) async {
|
|
String? out;
|
|
await tester.pumpWidget(MaterialApp(
|
|
theme: buildTheme('a'),
|
|
home: Scaffold(
|
|
body: DatePickerField(value: '2026-06-19', onChanged: (v) => out = v),
|
|
),
|
|
));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.byIcon(LucideIcons.calendar));
|
|
await tester.pumpAndSettle();
|
|
// 面板:可输入框 + 三列滚轮 + 今天/确定
|
|
expect(find.byType(TextField), findsOneWidget);
|
|
expect(find.byType(ListWheelScrollView), findsNWidgets(3));
|
|
expect(find.text('今天'), findsOneWidget);
|
|
await tester.tap(find.text('确定'));
|
|
await tester.pumpAndSettle();
|
|
expect(out, '2026-06-19');
|
|
});
|
|
|
|
testWidgets('面板内键入日期:归一并经确定回传', (tester) async {
|
|
String? out;
|
|
await tester.pumpWidget(MaterialApp(
|
|
theme: buildTheme('a'),
|
|
home: Scaffold(
|
|
body: DatePickerField(value: '2026-06-19', onChanged: (v) => out = v),
|
|
),
|
|
));
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.byIcon(LucideIcons.calendar));
|
|
await tester.pumpAndSettle();
|
|
await tester.enterText(find.byType(TextField), '20240512');
|
|
await tester.pumpAndSettle();
|
|
await tester.tap(find.text('确定'));
|
|
await tester.pumpAndSettle();
|
|
expect(out, '2024-05-12');
|
|
});
|
|
|
|
testWidgets('normalizeYmd 词法:年/年月补 01', (tester) async {
|
|
expect(normalizeYmd('2024'), '2024-01-01');
|
|
expect(normalizeYmd('2024-5'), '2024-05-01');
|
|
expect(normalizeYmd('2024/05/12'), '2024-05-12');
|
|
expect(normalizeYmd('20240229'), '2024-02-29'); // 闰年
|
|
expect(normalizeYmd('20260231'), '2026-02-28'); // 超界 clamp
|
|
expect(normalizeYmd('abc'), isNull);
|
|
});
|
|
});
|
|
}
|