Files
kitchen/scripts/test_export_import.dart
Developer 5e979d7115 refactor: 将项目名称从mom_kitchen改为cute_kitchen
更新项目名称及相关引用,包括README、iOS/macOS/Linux配置、文档和代码中的包引用。同时更新版本号至1.3.5并清理无用的HarmonyOS配置文件。

- 修改所有代码中的包引用路径
- 更新各平台配置文件和安装脚本
- 清理HarmonyOS相关无用文件
- 更新应用版本号至1.3.5
- 修正文档中的项目名称引用
2026-04-24 05:05:10 +08:00

164 lines
6.3 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.
// 2026-04-22 | test_export_import.dart | 数据导出/导入逻辑验证 | 验证JSON格式正确性和导入识别
// 运行: dart run scripts/test_export_import.dart
import 'dart:convert';
import 'dart:io';
// ─── 模拟核心逻辑 ───
enum DataSource {
favorites('❤️ 收藏', 'favorites'),
shoppingList('🛒 购物清单', 'shopping_list'),
mealRecords('🍽️ 饮食记录', 'meal_records'),
cookingNotes('📝 烹饪笔记', 'cooking_notes'),
weeklyMenu('📅 每周菜单', 'weekly_menu'),
browseHistory('👀 浏览记录', 'browse_history');
final String label;
final String fileName;
const DataSource(this.label, this.fileName);
}
String _exportSingleSourceJson(DataSource source) {
switch (source) {
case DataSource.favorites:
return const JsonEncoder.withIndent(' ').convert([
{'id': 1, 'title': '红烧肉', 'favoriteType': 'recipe', 'favoriteAt': '2026-04-22'},
]);
case DataSource.shoppingList:
return const JsonEncoder.withIndent(' ').convert([
{'name': '鸡蛋', 'amount': '3', 'unit': '', 'isChecked': false},
]);
case DataSource.mealRecords:
return const JsonEncoder.withIndent(' ').convert([
{'date': '2026-04-22', 'mealType': 'lunch', 'recipeId': 1},
]);
case DataSource.cookingNotes:
return const JsonEncoder.withIndent(' ').convert([
{'recipeId': 1, 'content': '少放盐', 'tags': ['tips']},
]);
case DataSource.weeklyMenu:
return const JsonEncoder.withIndent(' ').convert({
'weekStart': '2026-04-21',
'dailyMenus': {'Mon': {'breakfast': 1}},
});
case DataSource.browseHistory:
return const JsonEncoder.withIndent(' ').convert([
{'recipeId': 1, 'title': '红烧肉', 'viewCount': 3, 'viewedAt': '2026-04-22'},
]);
}
}
/// 新版 exportAll先构建Map再编码
String exportAllNew() {
final Map<String, dynamic> allData = {};
for (final source in DataSource.values) {
final content = _exportSingleSourceJson(source);
try {
allData[source.fileName] = jsonDecode(content);
} catch (e) {
print(' ⚠️ 解码 ${source.fileName} 失败: $e');
}
}
return const JsonEncoder.withIndent(' ').convert(allData);
}
/// previewImport标准格式识别 + List格式自动推断
({Map<DataSource, int> sourceCounts, String? error}) previewImport(String jsonContent) {
final result = <DataSource, int>{};
try {
final decoded = jsonDecode(jsonContent);
if (decoded is Map<String, dynamic>) {
for (final source in DataSource.values) {
if (decoded.containsKey(source.fileName)) {
final data = decoded[source.fileName];
if (data is List) {
result[source] = data.length;
} else if (data is Map && source == DataSource.weeklyMenu) {
result[source] = data.length;
}
}
}
} else if (decoded is List) {
if (decoded.isNotEmpty && decoded.first is Map<String, dynamic>) {
final inferred = _inferDataSource(decoded.first as Map<String, dynamic>);
result[inferred ?? DataSource.favorites] = decoded.length;
} else {
result[DataSource.favorites] = decoded.length;
}
}
} catch (e) {
return (sourceCounts: result, error: e.toString());
}
return (sourceCounts: result, error: null);
}
DataSource? _inferDataSource(Map<String, dynamic> item) {
if (item.containsKey('favoriteType') || item.containsKey('favoriteAt')) return DataSource.favorites;
if (item.containsKey('isChecked') && item.containsKey('amount')) return DataSource.shoppingList;
if (item.containsKey('mealType') && item.containsKey('date')) return DataSource.mealRecords;
if (item.containsKey('recipeId') && item.containsKey('content')) return DataSource.cookingNotes;
if (item.containsKey('dailyMenus') || item.containsKey('weekStart')) return DataSource.weeklyMenu;
if (item.containsKey('viewCount') && item.containsKey('viewedAt')) return DataSource.browseHistory;
return null;
}
// ─── 测试 ───
void main() {
print('╔══════════════════════════════════════════════════╗');
print('║ 📦 数据导出/导入 逻辑验证 ║');
print('╚══════════════════════════════════════════════════╝\n');
testFullExport();
testSingleSourceImport();
print('\n╔══════════════════════════════════════════════════╗');
print('║ ✅ 全部测试完成 ║');
print('╚══════════════════════════════════════════════════╝');
}
void testFullExport() {
print('━━━ 1. 全量导出JSON格式验证 ━━━');
final json = exportAllNew();
try {
final decoded = jsonDecode(json) as Map<String, dynamic>;
print(' ✅ JSON可解析${decoded.length} 个数据源');
for (final key in decoded.keys) {
final val = decoded[key];
final count = val is List ? val.length : (val is Map ? val.length : 0);
print(' - "$key": ${val.runtimeType} ($count项)');
}
} catch (e) {
print(' ❌ JSON解析失败: $e');
return;
}
final preview = previewImport(json);
if (preview.error != null) {
print(' ❌ previewImport失败: ${preview.error}');
} else {
print(' ✅ 识别 ${preview.sourceCounts.length}/${DataSource.values.length} 个数据源');
for (final entry in preview.sourceCounts.entries) {
print(' - ${entry.key.label}: ${entry.value}');
}
}
print('');
}
void testSingleSourceImport() {
print('━━━ 2. 单数据源导入自动推断 ━━━');
for (final source in DataSource.values) {
final json = _exportSingleSourceJson(source);
final preview = previewImport(json);
if (preview.sourceCounts.isNotEmpty) {
final e = preview.sourceCounts.entries.first;
final ok = e.key == source ? '' : '⚠️ 偏移';
print(' $ok ${source.label} → 推断为 ${e.key.label} (${e.value}条)');
} else {
print('${source.label} 无法识别');
}
}
print('');
}