feat: add tests for typo

This commit is contained in:
ensan-hcl
2025-07-14 13:55:31 -07:00
parent b9bd88a247
commit 58e18f2a88
4 changed files with 137 additions and 82 deletions

View File

@ -28,8 +28,9 @@ public struct ConvertRequestOptions: Sendable {
/// - textReplacer:
/// - specialCandidateProviders:
/// - metadata: `ConvertRequestOptions.Metadata`
public init(N_best: Int = 10, requireJapanesePrediction: Bool, requireEnglishPrediction: Bool, keyboardLanguage: KeyboardLanguage, englishCandidateInRoman2KanaInput: Bool = false, fullWidthRomanCandidate: Bool = false, halfWidthKanaCandidate: Bool = false, learningType: LearningType, maxMemoryCount: Int = 65536, shouldResetMemory: Bool = false, dictionaryResourceURL: URL, memoryDirectoryURL: URL, sharedContainerURL: URL, textReplacer: TextReplacer, specialCandidateProviders: [any SpecialCandidateProvider]?, zenzaiMode: ZenzaiMode = .off, preloadDictionary: Bool = false, metadata: ConvertRequestOptions.Metadata?) {
public init(N_best: Int = 10, needTypoCorrection: Bool? = nil, requireJapanesePrediction: Bool, requireEnglishPrediction: Bool, keyboardLanguage: KeyboardLanguage, englishCandidateInRoman2KanaInput: Bool = false, fullWidthRomanCandidate: Bool = false, halfWidthKanaCandidate: Bool = false, learningType: LearningType, maxMemoryCount: Int = 65536, shouldResetMemory: Bool = false, dictionaryResourceURL: URL, memoryDirectoryURL: URL, sharedContainerURL: URL, textReplacer: TextReplacer, specialCandidateProviders: [any SpecialCandidateProvider]?, zenzaiMode: ZenzaiMode = .off, preloadDictionary: Bool = false, metadata: ConvertRequestOptions.Metadata?) {
self.N_best = N_best
self.needTypoCorrection = needTypoCorrection
self.requireJapanesePrediction = requireJapanesePrediction
self.requireEnglishPrediction = requireEnglishPrediction
self.keyboardLanguage = keyboardLanguage
@ -86,6 +87,7 @@ public struct ConvertRequestOptions: Sendable {
specialCandidateProviders.append(.commaSeparatedNumber)
self.N_best = N_best
self.needTypoCorrection = nil
self.requireJapanesePrediction = requireJapanesePrediction
self.requireEnglishPrediction = requireEnglishPrediction
self.keyboardLanguage = keyboardLanguage
@ -157,6 +159,7 @@ public struct ConvertRequestOptions: Sendable {
public var requireJapanesePrediction: Bool
public var requireEnglishPrediction: Bool
public var keyboardLanguage: KeyboardLanguage
public var needTypoCorrection: Bool?
// KeyboardSettinginjection
public var englishCandidateInRoman2KanaInput: Bool
public var fullWidthRomanCandidate: Bool
@ -183,6 +186,7 @@ public struct ConvertRequestOptions: Sendable {
static var `default`: Self {
Self(
N_best: 10,
needTypoCorrection: nil,
requireJapanesePrediction: true,
requireEnglishPrediction: true,
keyboardLanguage: .ja_JP,

View File

@ -605,7 +605,7 @@ import EfficientNGram
/// - N_best:
/// - Returns:
///
private func convertToLattice(_ inputData: ComposingText, N_best: Int, zenzaiMode: ConvertRequestOptions.ZenzaiMode) -> (result: LatticeNode, lattice: Lattice)? {
private func convertToLattice(_ inputData: ComposingText, N_best: Int, zenzaiMode: ConvertRequestOptions.ZenzaiMode, needTypoCorrection: Bool) -> (result: LatticeNode, lattice: Lattice)? {
if inputData.convertTarget.isEmpty {
return nil
}
@ -625,11 +625,6 @@ import EfficientNGram
self.previousInputData = inputData
return (result, nodes)
}
#if os(iOS)
let needTypoCorrection = true
#else
let needTypoCorrection = false
#endif
guard let previousInputData else {
debug("\(#function): 新規計算用の関数を呼びますA")
@ -698,7 +693,14 @@ import EfficientNGram
// DicdataStoreRequestOption
self.sendToDicdataStore(.setRequestOptions(options))
guard let result = self.convertToLattice(inputData, N_best: options.N_best, zenzaiMode: options.zenzaiMode) else {
#if os(iOS)
let needTypoCorrection = options.needTypoCorrection ?? true
#else
let needTypoCorrection = options.needTypoCorrection ?? false
#endif
guard let result = self.convertToLattice(inputData, N_best: options.N_best, zenzaiMode: options.zenzaiMode, needTypoCorrection: needTypoCorrection) else {
return ConversionResult(mainResults: [], firstClauseResults: [])
}

View File

@ -4,6 +4,7 @@ public import Foundation
public extension ConvertRequestOptions {
static func withDefaultDictionary(
N_best: Int = 10,
needTypoCorrection: Bool? = nil,
requireJapanesePrediction: Bool,
requireEnglishPrediction: Bool,
keyboardLanguage: KeyboardLanguage,
@ -29,13 +30,26 @@ public extension ConvertRequestOptions {
#else
let dictionaryDirectory = Bundle.module.resourceURL!.appendingPathComponent("Dictionary", isDirectory: true)
#endif
var specialCandidateProviders = [any SpecialCandidateProvider]()
if typographyLetterCandidate {
specialCandidateProviders.append(.typography)
}
if unicodeCandidate {
specialCandidateProviders.append(.unicode)
}
specialCandidateProviders.append(.emailAddress)
specialCandidateProviders.append(.timeExpression)
specialCandidateProviders.append(.calendar)
specialCandidateProviders.append(.version)
specialCandidateProviders.append(.commaSeparatedNumber)
return Self(
N_best: N_best,
needTypoCorrection: needTypoCorrection,
requireJapanesePrediction: requireJapanesePrediction,
requireEnglishPrediction: requireEnglishPrediction,
keyboardLanguage: keyboardLanguage,
typographyLetterCandidate: typographyLetterCandidate,
unicodeCandidate: unicodeCandidate,
englishCandidateInRoman2KanaInput: englishCandidateInRoman2KanaInput,
fullWidthRomanCandidate: fullWidthRomanCandidate,
halfWidthKanaCandidate: halfWidthKanaCandidate,
@ -46,6 +60,7 @@ public extension ConvertRequestOptions {
memoryDirectoryURL: memoryDirectoryURL,
sharedContainerURL: sharedContainerURL,
textReplacer: textReplacer,
specialCandidateProviders: specialCandidateProviders,
zenzaiMode: zenzaiMode,
preloadDictionary: preloadDictionary,
metadata: metadata

View File

@ -7,7 +7,7 @@
//
import Foundation
import KanaKanjiConverterModuleWithDefaultDictionary
@testable import KanaKanjiConverterModuleWithDefaultDictionary
import XCTest
final class ConverterTests: XCTestCase {
@ -17,9 +17,10 @@ final class ConverterTests: XCTestCase {
}
}
func requestOptions() -> ConvertRequestOptions {
func requestOptions(needTypoCorrection: Bool = false) -> ConvertRequestOptions {
.withDefaultDictionary(
N_best: 10,
needTypoCorrection: needTypoCorrection,
requireJapanesePrediction: false,
requireEnglishPrediction: false,
keyboardLanguage: .ja_JP,
@ -56,21 +57,23 @@ final class ConverterTests: XCTestCase {
}
func testRoman2KanaFullConversion() async throws {
for needTypoCorrection in [true, false] {
do {
let converter = await KanaKanjiConverter()
var c = ComposingText()
c.insertAtCursorPosition("azuーkiーhasinjidainokiーboーdoapuridesu", inputStyle: .roman2kana)
let results = await converter.requestCandidates(c, options: requestOptions())
let results = await converter.requestCandidates(c, options: requestOptions(needTypoCorrection: needTypoCorrection))
XCTAssertEqual(results.mainResults.first?.text, "azooKeyは新時代のキーボードアプリです")
}
do {
let converter = await KanaKanjiConverter()
var c = ComposingText()
c.insertAtCursorPosition("youshoukikaratenisusuieiyakyuushourinjikenpounadosamazamanasupoーtuwokeikennsinagarasodatishougakkouzidaiharosanzerusukinkounitaizaisiteorigoruhuyatenisuwonaratteita", inputStyle: .roman2kana)
let results = await converter.requestCandidates(c, options: requestOptions())
let results = await converter.requestCandidates(c, options: requestOptions(needTypoCorrection: needTypoCorrection))
XCTAssertEqual(results.mainResults.first?.text, "幼少期からテニス水泳野球少林寺拳法など様々なスポーツを経験しながら育ち小学校時代はロサンゼルス近郊に滞在しておりゴルフやテニスを習っていた")
}
}
}
// 1
// memo:
@ -237,6 +240,37 @@ final class ConverterTests: XCTestCase {
}
}
}
// typo
do {
let cases: [(input: String, expect: String)] = [
("たいかくせい", "大学生"),
("きみのことかすき", "君のことが好き"),
("おへんとうをもつていく", "お弁当を持っていく"),
]
// full input
var options = requestOptions(needTypoCorrection: true)
options.requireJapanesePrediction = false
for (input, expect) in cases {
let converter = await KanaKanjiConverter()
var c = ComposingText()
sequentialInput(&c, sequence: input, inputStyle: .direct)
let results = await converter.requestCandidates(c, options: options)
XCTAssertEqual(results.mainResults.first?.text, expect)
}
// gradual input
for (input, expect) in cases {
let converter = await KanaKanjiConverter()
var c = ComposingText()
for char in input {
c.insertAtCursorPosition(String(char), inputStyle: .direct)
let results = await converter.requestCandidates(c, options: options)
if c.input.count == input.count {
XCTAssertEqual(results.mainResults.first?.text, expect)
}
}
}
}
}
//