mirror of
https://github.com/mii443/AzooKeyKanaKanjiConverter.git
synced 2025-08-22 15:05:26 +00:00
fix template parse logic
This commit is contained in:
@ -62,7 +62,7 @@ struct CandidateData {
|
||||
}
|
||||
}
|
||||
|
||||
public enum CompleteAction: Sendable {
|
||||
public enum CompleteAction: Equatable, Sendable {
|
||||
/// カーソルを調整する
|
||||
case moveCursor(Int)
|
||||
}
|
||||
@ -120,7 +120,7 @@ public struct Candidate: Sendable {
|
||||
let value = template.previewString()
|
||||
newText.replaceSubrange(range, with: value)
|
||||
}
|
||||
return newText.unescaped()
|
||||
return newText
|
||||
}
|
||||
|
||||
/// テンプレートをパースして、変換候補のテキストを生成し、反映する。
|
||||
|
@ -168,7 +168,7 @@ public struct DateTemplateLiteral: TemplateLiteralProtocol, Equatable, Sendable
|
||||
let delta = parse(splited: splited, key: "delta")
|
||||
let deltaUnit = parse(splited: splited, key: "deltaunit")
|
||||
return DateTemplateLiteral(
|
||||
format: format.unescaped(),
|
||||
format: format.templateDataSpecificUnescaped(),
|
||||
type: CalendarType(rawValue: String(type))!,
|
||||
language: Language(rawValue: String(language))!,
|
||||
delta: String(delta),
|
||||
@ -178,7 +178,7 @@ public struct DateTemplateLiteral: TemplateLiteralProtocol, Equatable, Sendable
|
||||
|
||||
public func export() -> String {
|
||||
"""
|
||||
<date format="\(format.escaped())" type="\(type.rawValue)" language="\(language.identifier)" delta="\(delta)" deltaunit="\(deltaUnit)">
|
||||
<date format="\(format.templateDataSpecificEscaped())" type="\(type.rawValue)" language="\(language.identifier)" delta="\(delta)" deltaunit="\(deltaUnit)">
|
||||
"""
|
||||
}
|
||||
}
|
||||
@ -220,7 +220,7 @@ public struct RandomTemplateLiteral: TemplateLiteralProtocol, Equatable, Sendabl
|
||||
case let .double(from: left, to: right):
|
||||
return "\(left),\(right)"
|
||||
case let .string(strings):
|
||||
return strings.map {$0.escaped()}.joined(separator: ",")
|
||||
return strings.map {$0.templateDataSpecificEscaped()}.joined(separator: ",")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -240,7 +240,7 @@ public struct RandomTemplateLiteral: TemplateLiteralProtocol, Equatable, Sendabl
|
||||
public static func `import`(from string: String, escaped: Bool = false) -> RandomTemplateLiteral {
|
||||
let splited = string.split(separator: " ")
|
||||
let type = parse(splited: splited, key: "type")
|
||||
let valueString = parse(splited: splited, key: "value").unescaped()
|
||||
let valueString = parse(splited: splited, key: "value").templateDataSpecificUnescaped()
|
||||
|
||||
let valueType = ValueType(rawValue: String(type))!
|
||||
let value: Value
|
||||
@ -259,7 +259,7 @@ public struct RandomTemplateLiteral: TemplateLiteralProtocol, Equatable, Sendabl
|
||||
|
||||
public func export() -> String {
|
||||
"""
|
||||
<random type="\(value.type.rawValue)" value="\(value.string.escaped())">
|
||||
<random type="\(value.type.rawValue)" value="\(value.string.templateDataSpecificEscaped())">
|
||||
"""
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,8 @@ public extension StringProtocol {
|
||||
self.index(self.startIndex, offsetBy: offset)
|
||||
}
|
||||
|
||||
|
||||
// FIXME: レガシーな実装なのでどうにかしたい。Migrationする……?
|
||||
// エスケープが必要なのは次の文字:
|
||||
/*
|
||||
\ -> \\
|
||||
@ -93,7 +95,7 @@ public extension StringProtocol {
|
||||
" -> \d
|
||||
*/
|
||||
// please use these letters in order to avoid user-inputting text crash
|
||||
func escaped() -> String {
|
||||
func templateDataSpecificEscaped() -> String {
|
||||
var result = self.replacingOccurrences(of: "\\", with: "\\b")
|
||||
result = result.replacingOccurrences(of: "\0", with: "\\0")
|
||||
result = result.replacingOccurrences(of: "\n", with: "\\n")
|
||||
@ -104,7 +106,7 @@ public extension StringProtocol {
|
||||
return result
|
||||
}
|
||||
|
||||
func unescaped() -> String {
|
||||
func templateDataSpecificUnescaped() -> String {
|
||||
var result = self.replacingOccurrences(of: "\\d", with: "\"")
|
||||
result = result.replacingOccurrences(of: "\\s", with: " ")
|
||||
result = result.replacingOccurrences(of: "\\c", with: ",")
|
||||
|
@ -0,0 +1,51 @@
|
||||
//
|
||||
// CandidateTests.swift
|
||||
//
|
||||
//
|
||||
// Created by miwa on 2023/08/16.
|
||||
//
|
||||
|
||||
|
||||
import XCTest
|
||||
@testable import KanaKanjiConverterModule
|
||||
|
||||
@MainActor final class CandidateTests: XCTestCase {
|
||||
// テンプレートのパース
|
||||
func testParseTemplate() throws {
|
||||
do {
|
||||
let text = #"<random type="int" value="1,3">"#
|
||||
let candidate = Candidate(
|
||||
text: text,
|
||||
value: -40,
|
||||
correspondingCount: 4,
|
||||
lastMid: 5,
|
||||
data: [DicdataElement(word: text, ruby: "サイコロ", cid: 0, mid: 5, value: -40)]
|
||||
)
|
||||
// ランダムなので繰り返し実行しておく
|
||||
for _ in 0 ..< 10 {
|
||||
var candidate2 = candidate
|
||||
candidate2.parseTemplate()
|
||||
print(candidate2.text)
|
||||
XCTAssertTrue(Set((1...3).map(String.init)).contains(candidate2.text))
|
||||
XCTAssertEqual(candidate.value, candidate2.value)
|
||||
XCTAssertEqual(candidate.correspondingCount, candidate2.correspondingCount)
|
||||
XCTAssertEqual(candidate.lastMid, candidate2.lastMid)
|
||||
XCTAssertEqual(candidate.data, candidate2.data)
|
||||
XCTAssertEqual(candidate.actions, candidate2.actions)
|
||||
}
|
||||
}
|
||||
do {
|
||||
let text = #"\n"#
|
||||
let candidate = Candidate(
|
||||
text: text,
|
||||
value: 0,
|
||||
correspondingCount: 0,
|
||||
lastMid: 0,
|
||||
data: [DicdataElement(word: text, ruby: "", cid: 0, mid: 0, value: 0)]
|
||||
)
|
||||
var candidate2 = candidate
|
||||
candidate2.parseTemplate()
|
||||
XCTAssertEqual(candidate.text, candidate2.text)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
//
|
||||
// ConversionTests.swift
|
||||
//
|
||||
//
|
||||
// Created by miwa on 2023/08/16.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import KanaKanjiConverterModule
|
||||
|
||||
@MainActor final class ConverterTests: XCTestCase {
|
||||
func requestOptions() -> ConvertRequestOptions {
|
||||
ConvertRequestOptions(
|
||||
N_best: 5,
|
||||
requireJapanesePrediction: true,
|
||||
requireEnglishPrediction: false,
|
||||
keyboardLanguage: .ja_JP,
|
||||
typographyLetterCandidate: false,
|
||||
unicodeCandidate: true,
|
||||
englishCandidateInRoman2KanaInput: true,
|
||||
fullWidthRomanCandidate: false,
|
||||
halfWidthKanaCandidate: false,
|
||||
learningType: .nothing,
|
||||
maxMemoryCount: 0,
|
||||
shouldResetMemory: false,
|
||||
dictionaryResourceURL: Bundle(for: type(of: self)).bundleURL.appendingPathComponent("DictionaryMock", isDirectory: true),
|
||||
memoryDirectoryURL: URL(fileURLWithPath: ""),
|
||||
sharedContainerURL: URL(fileURLWithPath: ""),
|
||||
metadata: .init(appVersionString: "Tests")
|
||||
)
|
||||
}
|
||||
|
||||
// 変換されてはいけないケースを示す
|
||||
func testMustNotCases() throws {
|
||||
do {
|
||||
// 改行文字に対して本当に改行が入ってしまうケース
|
||||
let converter = KanaKanjiConverter()
|
||||
var c = ComposingText()
|
||||
c.insertAtCursorPosition("\\n", inputStyle: .direct)
|
||||
let results = converter.requestCandidates(c, options: requestOptions())
|
||||
XCTAssertFalse(results.mainResults.contains(where: {$0.text == "\n"}))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user