diff --git a/lib/services/backup.dart b/lib/services/backup.dart index c1868b1..fd5d1a5 100644 --- a/lib/services/backup.dart +++ b/lib/services/backup.dart @@ -3,7 +3,6 @@ import "dart:io"; import "package:ciyue/core/app_globals.dart"; import "package:ciyue/core/app_router.dart"; -import "package:ciyue/database/app/app.dart"; import "package:ciyue/database/app/daos.dart"; import "package:ciyue/models/backup/backup.dart"; import "package:ciyue/services/platform.dart"; diff --git a/test/database/daos_test.dart b/test/database/daos_test.dart index 8d7f69d..c108f40 100644 --- a/test/database/daos_test.dart +++ b/test/database/daos_test.dart @@ -1,8 +1,8 @@ -import 'package:ciyue/database/app/app.dart'; -import 'package:ciyue/database/app/daos.dart'; -import 'package:drift/drift.dart'; -import 'package:drift/native.dart'; -import 'package:flutter_test/flutter_test.dart'; +import "package:ciyue/database/app/app.dart"; +import "package:ciyue/database/app/daos.dart"; +import "package:drift/drift.dart"; +import "package:drift/native.dart"; +import "package:flutter_test/flutter_test.dart"; void main() { late AppDatabase database; @@ -22,20 +22,20 @@ void main() { await database.close(); }); - group('WordbookDao', () { - test('addAllWords should avoid duplicates based on word and tag', () async { + group("WordbookDao", () { + test("addAllWords should avoid duplicates based on word and tag", () async { // 1. Insert an initial record - await wordbookDao.addWord('apple', tag: 1); + await wordbookDao.addWord("apple", tag: 1); final now = DateTime.now(); // 2. Prepare import data final newWords = [ // Duplicate: same word and tag (should be skipped) - WordbookData(word: 'apple', tag: 1, createdAt: now), + WordbookData(word: "apple", tag: 1, createdAt: now), // New: same word but different tag (should be inserted) - WordbookData(word: 'apple', tag: 2, createdAt: now), + WordbookData(word: "apple", tag: 2, createdAt: now), // New: different word (should be inserted) - WordbookData(word: 'banana', tag: 1, createdAt: now), + WordbookData(word: "banana", tag: 1, createdAt: now), ]; // 3. Perform batch add @@ -51,26 +51,26 @@ void main() { expect(allWords.length, 3); // Verify duplicate was not added (count remains 1 for apple/tag:1) - expect(allWords.where((w) => w.word == 'apple' && w.tag == 1).length, 1); + expect(allWords.where((w) => w.word == "apple" && w.tag == 1).length, 1); // Verify new records were added - expect(allWords.where((w) => w.word == 'apple' && w.tag == 2).length, 1); - expect(allWords.where((w) => w.word == 'banana').length, 1); + expect(allWords.where((w) => w.word == "apple" && w.tag == 2).length, 1); + expect(allWords.where((w) => w.word == "banana").length, 1); }); }); - group('TranslateHistoryDao', () { - test('addAllHistory should avoid duplicates based on inputText', () async { + group("TranslateHistoryDao", () { + test("addAllHistory should avoid duplicates based on inputText", () async { // 1. Insert an initial record - await translateHistoryDao.addHistory('hello'); + await translateHistoryDao.addHistory("hello"); final now = DateTime.now(); // 2. Prepare import data final newHistory = [ // Duplicate: same inputText (should be skipped) - TranslateHistoryData(id: 100, inputText: 'hello', createdAt: now), + TranslateHistoryData(id: 100, inputText: "hello", createdAt: now), // New: different inputText (should be inserted) - TranslateHistoryData(id: 101, inputText: 'world', createdAt: now), + TranslateHistoryData(id: 101, inputText: "world", createdAt: now), ]; // 3. Perform batch add @@ -82,12 +82,12 @@ void main() { // Expect 2 records: 'hello' and 'world' expect(allHistory.length, 2); expect( - allHistory.map((e) => e.inputText), containsAll(['hello', 'world'])); + allHistory.map((e) => e.inputText), containsAll(["hello", "world"])); }); }); - group('WritingCheckHistoryDao', () { - test('addAllHistory should avoid duplicates based on content matches', + group("WritingCheckHistoryDao", () { + test("addAllHistory should avoid duplicates based on content matches", () async { final now = DateTime.fromMillisecondsSinceEpoch(1000000); @@ -95,8 +95,8 @@ void main() { await database .into(database.writingCheckHistory) .insert(WritingCheckHistoryCompanion( - inputText: Value('input1'), - outputText: Value('output1'), + inputText: Value("input1"), + outputText: Value("output1"), createdAt: Value(now), )); @@ -105,20 +105,20 @@ void main() { // Duplicate: Exact match on input, output, and time (should be skipped) WritingCheckHistoryData( id: 100, - inputText: 'input1', - outputText: 'output1', + inputText: "input1", + outputText: "output1", createdAt: now), // New: Different output (should be inserted) WritingCheckHistoryData( id: 101, - inputText: 'input1', - outputText: 'output2', + inputText: "input1", + outputText: "output2", createdAt: now), // New: Different time (should be inserted) WritingCheckHistoryData( id: 102, - inputText: 'input1', - outputText: 'output1', + inputText: "input1", + outputText: "output1", createdAt: now.add(const Duration(seconds: 1))), ]; @@ -138,8 +138,8 @@ void main() { // Verify the duplicate logic by counting entries with original content final originalContentCount = allHistory .where((e) => - e.inputText == 'input1' && - e.outputText == 'output1' && + e.inputText == "input1" && + e.outputText == "output1" && e.createdAt.millisecondsSinceEpoch == now.millisecondsSinceEpoch) .length; diff --git a/test/models/backup_data_test.dart b/test/models/backup_data_test.dart index ae27656..83c9e28 100644 --- a/test/models/backup_data_test.dart +++ b/test/models/backup_data_test.dart @@ -1,37 +1,37 @@ -import 'dart:convert'; +import "dart:convert"; -import 'package:ciyue/database/app/app.dart'; -import 'package:ciyue/models/backup/backup.dart'; -import 'package:flutter_test/flutter_test.dart'; +import "package:ciyue/database/app/app.dart"; +import "package:ciyue/models/backup/backup.dart"; +import "package:flutter_test/flutter_test.dart"; void main() { - group('BackupData', () { - test('toJson and fromJson should work correctly', () { + group("BackupData", () { + test("toJson and fromJson should work correctly", () { final now = DateTime.now(); // Assuming WordbookData matches Wordbook table structure final words = [ WordbookData( createdAt: now, tag: 1, - word: 'test', + word: "test", ) ]; final tags = [ - const WordbookTag(id: 1, tag: 'tag1'), + const WordbookTag(id: 1, tag: "tag1"), ]; - final history = ['history1', 'history2']; + final history = ["history1", "history2"]; final writingCheckHistory = [ WritingCheckHistoryData( id: 1, - inputText: 'input', - outputText: 'output', + inputText: "input", + outputText: "output", createdAt: now, ) ]; final translateHistory = [ TranslateHistoryData( id: 1, - inputText: 'input', + inputText: "input", createdAt: now, ) ]; @@ -48,33 +48,33 @@ void main() { final jsonString = backupData.toJson(); final decoded = jsonDecode(jsonString); - expect(decoded['version'], 1); - expect(decoded['wordbookWords'].length, 1); - expect(decoded['wordbookTags'].length, 1); - expect(decoded['history'].length, 2); - expect(decoded['writingCheckHistory'].length, 1); - expect(decoded['translateHistory'].length, 1); + expect(decoded["version"], 1); + expect(decoded["wordbookWords"].length, 1); + expect(decoded["wordbookTags"].length, 1); + expect(decoded["history"].length, 2); + expect(decoded["writingCheckHistory"].length, 1); + expect(decoded["translateHistory"].length, 1); // Verify word data - final wordJson = decoded['wordbookWords'][0]; - expect(wordJson['word'], 'test'); - expect(wordJson['tag'], 1); + final wordJson = decoded["wordbookWords"][0]; + expect(wordJson["word"], "test"); + expect(wordJson["tag"], 1); // Drift usually serializes DateTime as millisecondsSinceEpoch or string depending on config. // We'll rely on fromJson to check consistency. final importedData = BackupData.fromJson(decoded); expect(importedData.version, 1); - expect(importedData.wordbookWords.first.word, 'test'); + expect(importedData.wordbookWords.first.word, "test"); expect(importedData.wordbookWords.first.tag, 1); // Compare dates with tolerance or exact depending on precision loss // drift default JSON for DateTime is unix timestamp (int) or string expect(importedData.wordbookWords.first.createdAt.millisecondsSinceEpoch, now.millisecondsSinceEpoch); - expect(importedData.wordbookTags.first.tag, 'tag1'); + expect(importedData.wordbookTags.first.tag, "tag1"); expect(importedData.history, equals(history)); - expect(importedData.writingCheckHistory.first.inputText, 'input'); - expect(importedData.translateHistory.first.inputText, 'input'); + expect(importedData.writingCheckHistory.first.inputText, "input"); + expect(importedData.translateHistory.first.inputText, "input"); }); }); } diff --git a/test/services/backup_test.dart b/test/services/backup_test.dart index 2be181e..bca53c0 100644 --- a/test/services/backup_test.dart +++ b/test/services/backup_test.dart @@ -1,13 +1,13 @@ -import 'dart:convert'; -import 'package:ciyue/database/app/app.dart'; -import 'package:ciyue/database/app/daos.dart'; -import 'package:ciyue/services/backup.dart'; -import 'package:ciyue/viewModels/wordbook.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/annotations.dart'; -import 'package:mockito/mockito.dart'; +import "dart:convert"; +import "package:ciyue/database/app/app.dart"; +import "package:ciyue/database/app/daos.dart"; +import "package:ciyue/services/backup.dart"; +import "package:ciyue/viewModels/wordbook.dart"; +import "package:flutter_test/flutter_test.dart"; +import "package:mockito/annotations.dart"; +import "package:mockito/mockito.dart"; -import 'backup_test.mocks.dart'; +import "backup_test.mocks.dart"; @GenerateMocks([ WordbookDao, @@ -48,33 +48,33 @@ void main() { ); }); - group('BackupService Export', () { + group("BackupService Export", () { final words = [ WordbookData( createdAt: DateTime.now(), tag: 1, - word: 'test', + word: "test", ) ]; - final tags = [const WordbookTag(id: 1, tag: 'tag1')]; - final history = [const HistoryData(id: 1, word: 'history1')]; + final tags = [const WordbookTag(id: 1, tag: "tag1")]; + final history = [const HistoryData(id: 1, word: "history1")]; final writingCheckHistory = [ WritingCheckHistoryData( id: 1, - inputText: 'input', - outputText: 'output', + inputText: "input", + outputText: "output", createdAt: DateTime.now(), ) ]; final translateHistory = [ TranslateHistoryData( id: 1, - inputText: 'input', + inputText: "input", createdAt: DateTime.now(), ) ]; - test('should do nothing if no words or history to export', () async { + test("should do nothing if no words or history to export", () async { when(mockWordbookDao.getAllWords()).thenAnswer((_) async => []); when(mockWordbookTagsDao.getAllTags()).thenAnswer((_) async => []); when(mockHistoryDao.getAllHistory()).thenAnswer((_) async => []); @@ -84,7 +84,7 @@ void main() { await backupService.export( autoExport: false, - exportFileName: 'test', + exportFileName: "test", ); verify(mockWordbookDao.getAllWords()).called(1); @@ -93,7 +93,7 @@ void main() { verifyNever(mockFileHandler.writeManualExportDesktop(any)); }); - test('should export manually on Android', () async { + test("should export manually on Android", () async { when(mockWordbookDao.getAllWords()).thenAnswer((_) async => words); when(mockWordbookTagsDao.getAllTags()).thenAnswer((_) async => tags); when(mockHistoryDao.getAllHistory()).thenAnswer((_) async => history); @@ -107,13 +107,13 @@ void main() { await backupService.export( autoExport: false, - exportFileName: 'test', + exportFileName: "test", ); verify(mockFileHandler.writeManualExportAndroid(any)).called(1); }); - test('should export manually on Desktop', () async { + test("should export manually on Desktop", () async { when(mockWordbookDao.getAllWords()).thenAnswer((_) async => words); when(mockWordbookTagsDao.getAllTags()).thenAnswer((_) async => tags); when(mockHistoryDao.getAllHistory()).thenAnswer((_) async => history); @@ -127,13 +127,13 @@ void main() { await backupService.export( autoExport: false, - exportFileName: 'test', + exportFileName: "test", ); verify(mockFileHandler.writeManualExportDesktop(any)).called(1); }); - test('should auto export on Android', () async { + test("should auto export on Android", () async { when(mockWordbookDao.getAllWords()).thenAnswer((_) async => words); when(mockWordbookTagsDao.getAllTags()).thenAnswer((_) async => tags); when(mockHistoryDao.getAllHistory()).thenAnswer((_) async => history); @@ -147,15 +147,15 @@ void main() { await backupService.export( autoExport: true, - exportFileName: 'test', - exportDirectory: '/dir', + exportFileName: "test", + exportDirectory: "/dir", ); - verify(mockFileHandler.writeAutoExportAndroid('/dir', 'test.json', any)) + verify(mockFileHandler.writeAutoExportAndroid("/dir", "test.json", any)) .called(1); }); - test('should auto export on Desktop', () async { + test("should auto export on Desktop", () async { when(mockWordbookDao.getAllWords()).thenAnswer((_) async => words); when(mockWordbookTagsDao.getAllTags()).thenAnswer((_) async => tags); when(mockHistoryDao.getAllHistory()).thenAnswer((_) async => history); @@ -169,17 +169,17 @@ void main() { await backupService.export( autoExport: true, - exportFileName: 'test', - exportPath: '/path/test.json', + exportFileName: "test", + exportPath: "/path/test.json", ); - verify(mockFileHandler.writeAutoExportDesktop('/path/test.json', any)) + verify(mockFileHandler.writeAutoExportDesktop("/path/test.json", any)) .called(1); }); }); - group('BackupService Import', () { - test('should import data correctly', () async { + group("BackupService Import", () { + test("should import data correctly", () async { final jsonContent = jsonEncode({ "version": 1, "wordbookWords": [], @@ -209,7 +209,7 @@ void main() { verify(mockTranslateHistoryDao.addAllHistory(any)).called(1); }); - test('should do nothing if file selection canceled', () async { + test("should do nothing if file selection canceled", () async { when(mockFileHandler.readImportFile()).thenAnswer((_) async => null); await backupService.import();