test: verify pause file recovery

This commit is contained in:
Miwa
2025-05-25 19:36:11 +09:00
parent 987baa30c3
commit 5a4b3e728e
4 changed files with 73 additions and 1 deletions

View File

@ -171,6 +171,8 @@ ComposingText(
3のステップの実行中にエラーが生じた場合、`.pause`があるため、次回キーボードを開いた際は学習を停止状態にします。ついで適切なタイミングで再度ステップ3を実行することで、安全に全てのファイルを更新することができます。
azooKeyKanaKanjiConverter では、変換器を開いた際に `.pause` ファイルが残っている場合、自動的に空の一時記憶とマージを試みて `.pause` を削除し、学習機能を復旧します。
## 変換候補の並び順
変換候補の並び順の決定はとても難しい問題です。azooKeyではおおよそ以下のようになっています。`Converter.swift`が並び順を決めていますが、とても複雑な実装になっているため、改善したいと思っています。

View File

@ -76,6 +76,8 @@ let options = ConvertRequestOptions.withDefaultDictionary(
)
```
開く際に保存処理が中断された `.pause` ファイルが残っている場合は、変換器が自動的に復旧を試みてファイルを削除します。
### `ComposingText`
`ComposingText`は入力管理を行いつつ変換をリクエストするためのAPIです。ローマ字入力などを適切にハンドルするために利用できます。詳しくは[ドキュメント](./Docs/composing_text.md)を参照してください。

View File

@ -655,6 +655,19 @@ final class LearningManager {
init() {
self.memoryCollapsed = LongTermLearningMemory.memoryCollapsed(directoryURL: self.options.memoryDirectoryURL)
if self.memoryCollapsed && options.learningType.needUsingMemory {
do {
try LongTermLearningMemory.merge(
tempTrie: TemporalLearningMemoryTrie(),
directoryURL: self.options.memoryDirectoryURL,
maxMemoryCount: options.maxMemoryCount,
char2UInt8: char2UInt8
)
} catch {
debug("LearningManager init: automatic merge failed", error)
}
self.memoryCollapsed = LongTermLearningMemory.memoryCollapsed(directoryURL: self.options.memoryDirectoryURL)
}
if memoryCollapsed {
//
debug("LearningManager init: Memory Collapsed")

View File

@ -0,0 +1,55 @@
//
// LearningMemoryTests.swift
// KanaKanjiConverterModuleTests
//
// Created by Codex on 2025/05/25.
//
@testable import KanaKanjiConverterModule
import XCTest
final class LearningMemoryTests: XCTestCase {
static let resourceURL = Bundle.module.resourceURL!.appendingPathComponent("DictionaryMock", isDirectory: true)
func testPauseFileIsClearedOnInit() throws {
let dir = ConvertRequestOptions.default.memoryDirectoryURL
try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
let pauseURL = dir.appendingPathComponent(".pause", isDirectory: false)
FileManager.default.createFile(atPath: pauseURL.path, contents: Data())
XCTAssertTrue(LongTermLearningMemory.memoryCollapsed(directoryURL: dir))
_ = LearningManager()
XCTAssertFalse(LongTermLearningMemory.memoryCollapsed(directoryURL: dir))
try? FileManager.default.removeItem(at: pauseURL)
}
func testMemoryFilesCreateAndRemove() throws {
let dir = FileManager.default.temporaryDirectory.appendingPathComponent("LearningMemoryTest-\(UUID().uuidString)", isDirectory: true)
try FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: dir) }
var manager = LearningManager()
var options = ConvertRequestOptions.default
options.dictionaryResourceURL = Self.resourceURL
options.memoryDirectoryURL = dir
options.learningType = .onlyOutput
options.maxMemoryCount = 32
manager.setRequestOptions(options: options)
let element = DicdataElement(word: "テスト", ruby: "テスト", cid: CIDData..cid, mid: MIDData..mid, value: -10)
manager.update(data: [element])
manager.save()
let files = try FileManager.default.contentsOfDirectory(at: dir, includingPropertiesForKeys: nil)
XCTAssertTrue(files.contains { $0.lastPathComponent == "memory.louds" })
XCTAssertTrue(files.contains { $0.lastPathComponent == "memory.loudschars2" })
XCTAssertTrue(files.contains { $0.lastPathComponent == "memory.memorymetadata" })
XCTAssertTrue(files.contains { $0.lastPathComponent.hasSuffix(".loudstxt3") })
manager.reset()
let filesAfter = try FileManager.default.contentsOfDirectory(at: dir, includingPropertiesForKeys: nil)
XCTAssertTrue(filesAfter.isEmpty)
}
}