fix template parse logic

This commit is contained in:
ensan-hcl
2023-08-16 18:38:50 +09:00
parent 30590fa91e
commit 2a240df7c3
6 changed files with 108 additions and 10 deletions

View File

@ -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
}
///

View File

@ -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())">
"""
}

View File

@ -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: ",")

View File

@ -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)
}
}
}

View File

@ -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"}))
}
}
}