312 lines
10 KiB
Dart
312 lines
10 KiB
Dart
// // ============================================================
|
|
// // 闲言APP — v5.8 审计验收自动化验证脚本
|
|
// // 创建时间: 2026-05-15
|
|
// // 作用: 静态分析验证所有修复项的功能可达性
|
|
// // 运行: dart run test/audit_v58_verify.dart
|
|
// // ============================================================
|
|
|
|
// import 'dart:io';
|
|
|
|
// /// 验证项定义
|
|
// class AuditItem {
|
|
// final String id;
|
|
// final String name;
|
|
// final String filePath;
|
|
// final List<String> mustContain;
|
|
// final List<String> mustNotContain;
|
|
|
|
// const AuditItem({
|
|
// required this.id,
|
|
// required this.name,
|
|
// required this.filePath,
|
|
// this.mustContain = const [],
|
|
// this.mustNotContain = const [],
|
|
// });
|
|
// }
|
|
|
|
// /// 验证结果
|
|
// class AuditResult {
|
|
// final String id;
|
|
// final String name;
|
|
// final bool passed;
|
|
// final List<String> errors;
|
|
|
|
// const AuditResult({
|
|
// required this.id,
|
|
// required this.name,
|
|
// required this.passed,
|
|
// this.errors = const [],
|
|
// });
|
|
// }
|
|
|
|
// void main() async {
|
|
// final projectRoot = Directory.current.path;
|
|
|
|
// if (!File('$projectRoot/pubspec.yaml').existsSync()) {
|
|
// print('错误: 请在项目根目录运行此脚本');
|
|
// exit(1);
|
|
// }
|
|
|
|
// print('╔══════════════════════════════════════════════════╗');
|
|
// print('║ 闲言APP v5.8 审计验收 — 自动化验证脚本 ║');
|
|
// print('╚══════════════════════════════════════════════════╝');
|
|
// print('');
|
|
|
|
// final items = <AuditItem>[
|
|
// // ── 修复1: 8个空壳服务UI集成 ──
|
|
// AuditItem(
|
|
// id: 'FIX1-1',
|
|
// name: 'ReadlaterTagService UI入口',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/presentation/widgets/chat/chat_flow_readlater_mixin.dart',
|
|
// mustContain: ['showTagManager', '🏷️ 管理标签', 'ReadlaterTagService'],
|
|
// ),
|
|
// AuditItem(
|
|
// id: 'FIX1-2',
|
|
// name: 'ReadlaterFolderService UI入口',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/presentation/widgets/chat/chat_flow_readlater_mixin.dart',
|
|
// mustContain: ['showFolderManager', '📁 管理文件夹', 'ReadlaterFolderService'],
|
|
// ),
|
|
// AuditItem(
|
|
// id: 'FIX1-3',
|
|
// name: 'ReadlaterSyncService UI入口',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/presentation/widgets/chat/chat_flow_readlater_mixin.dart',
|
|
// mustContain: ['_doCloudSync', '☁️ 云端同步', 'ReadlaterSyncService'],
|
|
// ),
|
|
// AuditItem(
|
|
// id: 'FIX1-4',
|
|
// name: 'ReadlaterAiService UI入口',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/presentation/widgets/chat/chat_flow_readlater_mixin.dart',
|
|
// mustContain: ['_doAiSummary', '🤖 AI摘要', 'ReadlaterAiService'],
|
|
// ),
|
|
// AuditItem(
|
|
// id: 'FIX1-5',
|
|
// name: 'ReadlaterCollabService UI入口',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/presentation/widgets/chat/chat_flow_readlater_mixin.dart',
|
|
// mustContain: ['showCollabManager', '👥 共享协作', 'ReadlaterCollabService'],
|
|
// ),
|
|
// AuditItem(
|
|
// id: 'FIX1-6',
|
|
// name: 'ReadlaterDeviceSyncService UI入口',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/presentation/widgets/chat/chat_flow_readlater_mixin.dart',
|
|
// mustContain: ['_doDeviceSync', '📱 跨设备同步', 'ReadlaterDeviceSyncService'],
|
|
// ),
|
|
// AuditItem(
|
|
// id: 'FIX1-7',
|
|
// name: 'HomeWidgetService UI入口',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/presentation/widgets/chat/chat_flow_readlater_mixin.dart',
|
|
// mustContain: ['HomeWidgetService'],
|
|
// ),
|
|
// AuditItem(
|
|
// id: 'FIX1-8',
|
|
// name: 'ClipboardMonitorService UI入口',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/presentation/widgets/chat/chat_flow_readlater_mixin.dart',
|
|
// mustContain: ['ClipboardMonitorService'],
|
|
// ),
|
|
|
|
// // ── 修复2: ReadlaterReminderService替换SharedPreferences ──
|
|
// AuditItem(
|
|
// id: 'FIX2',
|
|
// name: 'ReadlaterReminderService使用AppKVStore',
|
|
// filePath:
|
|
// '$projectRoot/lib/core/services/notification/readlater_reminder_service.dart',
|
|
// mustContain: [
|
|
// 'AppKVStore.getBool',
|
|
// 'AppKVStore.setBool',
|
|
// 'AppKVStore.setString',
|
|
// 'AppKVStore.getString',
|
|
// ],
|
|
// mustNotContain: ['SharedPreferences', 'shared_preferences'],
|
|
// ),
|
|
|
|
// // ── 修复3: DailyTaskPage/TaskCard使用AppTheme ──
|
|
// AuditItem(
|
|
// id: 'FIX3-1',
|
|
// name: 'DailyTaskPage使用AppTheme',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/task/presentation/daily_task_page.dart',
|
|
// mustContain: [
|
|
// 'AppTheme.ext',
|
|
// 'ext.bgCard',
|
|
// 'ext.textPrimary',
|
|
// 'ext.textSecondary',
|
|
// 'ext.warningColor',
|
|
// 'ext.infoColor',
|
|
// 'ext.errorColor',
|
|
// ],
|
|
// mustNotContain: [
|
|
// 'CupertinoColors.systemGrey6.darkColor',
|
|
// 'CupertinoColors.systemBackground.color',
|
|
// 'CupertinoColors.activeOrange',
|
|
// 'CupertinoColors.activeBlue',
|
|
// 'CupertinoColors.destructiveRed',
|
|
// ],
|
|
// ),
|
|
// AuditItem(
|
|
// id: 'FIX3-2',
|
|
// name: 'TaskCard使用AppTheme',
|
|
// filePath: '$projectRoot/lib/shared/widgets/task_card.dart',
|
|
// mustContain: [
|
|
// 'AppTheme.ext',
|
|
// 'ext.bgCard',
|
|
// 'ext.textPrimary',
|
|
// 'ext.textSecondary',
|
|
// 'ext.successColor',
|
|
// 'ext.infoColor',
|
|
// 'ext.warningColor',
|
|
// ],
|
|
// mustNotContain: [
|
|
// 'CupertinoColors.systemGrey6.darkColor',
|
|
// 'CupertinoColors.systemBackground.color',
|
|
// 'CupertinoColors.activeGreen',
|
|
// 'CupertinoColors.activeBlue',
|
|
// 'CupertinoColors.activeOrange',
|
|
// ],
|
|
// ),
|
|
|
|
// // ── 修复4: exportAsZip异步I/O ──
|
|
// AuditItem(
|
|
// id: 'FIX4',
|
|
// name: 'exportAsZip使用异步文件I/O',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/presentation/widgets/chat/chat_flow_readlater_mixin.dart',
|
|
// mustContain: [
|
|
// 'await jsonFile.writeAsString',
|
|
// 'await mdFile.writeAsString',
|
|
// 'await file.readAsBytes',
|
|
// 'await zipFile.writeAsBytes',
|
|
// ],
|
|
// mustNotContain: [
|
|
// 'writeAsStringSync',
|
|
// 'readAsBytesSync',
|
|
// 'writeAsBytesSync',
|
|
// ],
|
|
// ),
|
|
|
|
// // ── 修复5: main.dart初始化服务 ──
|
|
// AuditItem(
|
|
// id: 'FIX5',
|
|
// name: 'main.dart初始化HomeWidget+ClipboardMonitor',
|
|
// filePath: '$projectRoot/lib/main.dart',
|
|
// mustContain: [
|
|
// 'HomeWidgetService.instance.init',
|
|
// 'ClipboardMonitorService.instance.initFromStore',
|
|
// '桌面小组件服务初始化完成',
|
|
// '剪贴板监控服务初始化完成',
|
|
// ],
|
|
// ),
|
|
|
|
// // ── 修复6: ReadlaterTagService同步ext['tags'] ──
|
|
// AuditItem(
|
|
// id: 'FIX6',
|
|
// name: 'ReadlaterTagService自动同步ext["tags"]',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/services/readlater_tag_service.dart',
|
|
// mustContain: [
|
|
// '_syncTagsToMessageExt',
|
|
// 'ChatMessageService.updateExt',
|
|
// "{'tags': tags}",
|
|
// ],
|
|
// ),
|
|
|
|
// // ── 修复6补充: ChatMessageService.updateExt ──
|
|
// AuditItem(
|
|
// id: 'FIX6-SUP',
|
|
// name: 'ChatMessageService提供updateExt方法',
|
|
// filePath:
|
|
// '$projectRoot/lib/features/tool_center/inspiration/services/chat_message_service.dart',
|
|
// mustContain: ['static Future<void> updateExt', 'extJson'],
|
|
// ),
|
|
// ];
|
|
|
|
// var passCount = 0;
|
|
// var failCount = 0;
|
|
// final results = <AuditResult>[];
|
|
|
|
// for (final item in items) {
|
|
// final result = await _verify(item);
|
|
// results.add(result);
|
|
// if (result.passed) {
|
|
// passCount++;
|
|
// } else {
|
|
// failCount++;
|
|
// }
|
|
// }
|
|
|
|
// print('');
|
|
// print('══════════════════════════════════════════════════');
|
|
// print(' 验证结果汇总');
|
|
// print('══════════════════════════════════════════════════');
|
|
// print('');
|
|
|
|
// for (final r in results) {
|
|
// final icon = r.passed ? '✅' : '❌';
|
|
// print(' $icon [${r.id}] ${r.name}');
|
|
// if (!r.passed) {
|
|
// for (final e in r.errors) {
|
|
// print(' ↳ $e');
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// print('');
|
|
// print('──────────────────────────────────────────────────');
|
|
// print(' 通过: $passCount / ${items.length} 失败: $failCount');
|
|
// print('──────────────────────────────────────────────────');
|
|
|
|
// if (failCount > 0) {
|
|
// exitCode = 1;
|
|
// }
|
|
// }
|
|
|
|
// Future<AuditResult> _verify(AuditItem item) async {
|
|
// final errors = <String>[];
|
|
// final file = File(item.filePath);
|
|
|
|
// if (!await file.exists()) {
|
|
// return AuditResult(
|
|
// id: item.id,
|
|
// name: item.name,
|
|
// passed: false,
|
|
// errors: ['文件不存在: ${item.filePath}'],
|
|
// );
|
|
// }
|
|
|
|
// final content = await file.readAsString();
|
|
|
|
// final codeOnly = content
|
|
// .split('\n')
|
|
// .where(
|
|
// (line) =>
|
|
// !line.trimLeft().startsWith('///') &&
|
|
// !line.trimLeft().startsWith('//'),
|
|
// )
|
|
// .join('\n');
|
|
|
|
// for (final keyword in item.mustContain) {
|
|
// if (!codeOnly.contains(keyword)) {
|
|
// errors.add('缺少必要内容: "$keyword"');
|
|
// }
|
|
// }
|
|
|
|
// for (final keyword in item.mustNotContain) {
|
|
// if (codeOnly.contains(keyword)) {
|
|
// errors.add('不应存在内容: "$keyword"');
|
|
// }
|
|
// }
|
|
|
|
// return AuditResult(
|
|
// id: item.id,
|
|
// name: item.name,
|
|
// passed: errors.isEmpty,
|
|
// errors: errors,
|
|
// );
|
|
// }
|