mirror of
https://github.com/mii443/AzooKeyKanaKanjiConverter.git
synced 2025-08-22 15:05:26 +00:00
feat: Add time expression conversion function
Fixes #170 Add functionality to convert 3-digit and 4-digit numbers into time expressions in the format 'HH:MM'. * Add `convertToTimeExpression` function in `Sources/KanaKanjiConverterModule/Converter/TimeExpression.swift` to handle the conversion. * Modify `Sources/KanaKanjiConverterModule/Converter/KanaKanjiConverter.swift` to include the new function and call it within `getWiseCandidate`. * Add tests in `Tests/KanaKanjiConverterModuleTests/ConverterTests/TimeExpressionTests.swift` to ensure the new function works correctly. --- For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/azooKey/AzooKeyKanaKanjiConverter/issues/170?shareId=XXXX-XXXX-XXXX-XXXX).
This commit is contained in:
@ -1,14 +1,7 @@
|
||||
//
|
||||
// KanaKanjiConverter.swift
|
||||
// AzooKeyKanaKanjiConverter
|
||||
//
|
||||
// Created by ensan on 2020/09/03.
|
||||
// Copyright © 2020 ensan. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SwiftUtils
|
||||
import EfficientNGram
|
||||
import TimeExpression
|
||||
|
||||
/// かな漢字変換の管理を受け持つクラス
|
||||
@MainActor public final class KanaKanjiConverter {
|
||||
@ -156,6 +149,7 @@ import EfficientNGram
|
||||
result.append(contentsOf: self.unicodeCandidates(inputData))
|
||||
}
|
||||
result.append(contentsOf: self.toVersionCandidate(inputData, options: options))
|
||||
result.append(contentsOf: self.toTimeExpressionCandidates(inputData))
|
||||
return result
|
||||
}
|
||||
|
||||
@ -786,4 +780,11 @@ import EfficientNGram
|
||||
results.append(contentsOf: zeroHints.min(count: 10 - results.count, sortedBy: {$0.value > $1.value}))
|
||||
return results
|
||||
}
|
||||
|
||||
private func toTimeExpressionCandidates(_ inputData: ComposingText) -> [Candidate] {
|
||||
guard let number = Int(inputData.convertTarget) else {
|
||||
return []
|
||||
}
|
||||
return self.convertToTimeExpression(number)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
import Foundation
|
||||
|
||||
extension KanaKanjiConverter {
|
||||
func convertToTimeExpression(_ inputData: ComposingText) -> [Candidate] {
|
||||
var candidates: [Candidate] = []
|
||||
let numberString = inputData.convertTarget
|
||||
let firstPart = Int(numberString.prefix(2))!
|
||||
let secondPart = Int(numberString.suffix(2))!
|
||||
|
||||
if numberString.count == 3 {
|
||||
let firstDigit = Int(numberString.prefix(1))!
|
||||
let lastTwoDigits = Int(numberString.suffix(2))!
|
||||
if (0...9).contains(firstDigit) && (0...60).contains(lastTwoDigits) {
|
||||
let timeExpression = "\(firstDigit):\(String(format: "%02d", lastTwoDigits))"
|
||||
let candidate = Candidate(
|
||||
text: timeExpression,
|
||||
value: -10,
|
||||
correspondingCount: numberString.count,
|
||||
lastMid: MIDData.一般.mid,
|
||||
data: [DicdataElement(word: timeExpression, ruby: numberString, cid: CIDData.固有名詞.cid, mid: MIDData.一般.mid, value: -10)]
|
||||
)
|
||||
candidates.append(candidate)
|
||||
}
|
||||
} else if numberString.count == 4 {
|
||||
if (0...12).contains(firstPart) && (0...60).contains(secondPart) {
|
||||
let timeExpression = "\(String(format: "%02d", firstPart)):\(String(format: "%02d", secondPart))"
|
||||
let candidate = Candidate(
|
||||
text: timeExpression,
|
||||
value: -10,
|
||||
correspondingCount: numberString.count,
|
||||
lastMid: MIDData.一般.mid,
|
||||
data: [DicdataElement(word: timeExpression, ruby: numberString, cid: CIDData.固有名詞.cid, mid: MIDData.一般.mid, value: -10)]
|
||||
)
|
||||
candidates.append(candidate)
|
||||
}
|
||||
}
|
||||
return candidates
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
import XCTest
|
||||
@testable import KanaKanjiConverterModule
|
||||
|
||||
final class TimeExpressionTests: XCTestCase {
|
||||
func testConvertToTimeExpression() {
|
||||
let converter = KanaKanjiConverter()
|
||||
|
||||
// Test 3-digit numbers
|
||||
XCTAssertEqual(converter.convertToTimeExpression(123).first?.text, "1:23")
|
||||
XCTAssertEqual(converter.convertToTimeExpression(945).first?.text, "9:45")
|
||||
XCTAssertEqual(converter.convertToTimeExpression(760).first?.text, "7:60")
|
||||
XCTAssertTrue(converter.convertToTimeExpression(761).isEmpty) // Invalid minute
|
||||
|
||||
// Test 4-digit numbers
|
||||
XCTAssertEqual(converter.convertToTimeExpression(1234).first?.text, "12:34")
|
||||
XCTAssertEqual(converter.convertToTimeExpression(9450).first?.text, "09:45")
|
||||
XCTAssertEqual(converter.convertToTimeExpression(7600).first?.text, "07:60")
|
||||
XCTAssertTrue(converter.convertToTimeExpression(1360).isEmpty) // Invalid hour
|
||||
XCTAssertTrue(converter.convertToTimeExpression(1261).isEmpty) // Invalid minute
|
||||
}
|
||||
|
||||
func testToTimeExpressionCandidates() async throws {
|
||||
let converter = KanaKanjiConverter()
|
||||
var c = ComposingText()
|
||||
|
||||
// Test 3-digit numbers
|
||||
c.insertAtCursorPosition("123", inputStyle: .direct)
|
||||
var results = await converter.requestCandidates(c, options: ConvertRequestOptions())
|
||||
XCTAssertTrue(results.mainResults.contains(where: {$0.text == "1:23"}))
|
||||
|
||||
c = ComposingText()
|
||||
c.insertAtCursorPosition("945", inputStyle: .direct)
|
||||
results = await converter.requestCandidates(c, options: ConvertRequestOptions())
|
||||
XCTAssertTrue(results.mainResults.contains(where: {$0.text == "9:45"}))
|
||||
|
||||
c = ComposingText()
|
||||
c.insertAtCursorPosition("760", inputStyle: .direct)
|
||||
results = await converter.requestCandidates(c, options: ConvertRequestOptions())
|
||||
XCTAssertTrue(results.mainResults.contains(where: {$0.text == "7:60"}))
|
||||
|
||||
c = ComposingText()
|
||||
c.insertAtCursorPosition("761", inputStyle: .direct)
|
||||
results = await converter.requestCandidates(c, options: ConvertRequestOptions())
|
||||
XCTAssertFalse(results.mainResults.contains(where: {$0.text == "7:61"})) // Invalid minute
|
||||
|
||||
// Test 4-digit numbers
|
||||
c = ComposingText()
|
||||
c.insertAtCursorPosition("1234", inputStyle: .direct)
|
||||
results = await converter.requestCandidates(c, options: ConvertRequestOptions())
|
||||
XCTAssertTrue(results.mainResults.contains(where: {$0.text == "12:34"}))
|
||||
|
||||
c = ComposingText()
|
||||
c.insertAtCursorPosition("9450", inputStyle: .direct)
|
||||
results = await converter.requestCandidates(c, options: ConvertRequestOptions())
|
||||
XCTAssertTrue(results.mainResults.contains(where: {$0.text == "09:45"}))
|
||||
|
||||
c = ComposingText()
|
||||
c.insertAtCursorPosition("7600", inputStyle: .direct)
|
||||
results = await converter.requestCandidates(c, options: ConvertRequestOptions())
|
||||
XCTAssertTrue(results.mainResults.contains(where: {$0.text == "07:60"}))
|
||||
|
||||
c = ComposingText()
|
||||
c.insertAtCursorPosition("1360", inputStyle: .direct)
|
||||
results = await converter.requestCandidates(c, options: ConvertRequestOptions())
|
||||
XCTAssertFalse(results.mainResults.contains(where: {$0.text == "13:60"})) // Invalid hour
|
||||
|
||||
c = ComposingText()
|
||||
c.insertAtCursorPosition("1261", inputStyle: .direct)
|
||||
results = await converter.requestCandidates(c, options: ConvertRequestOptions())
|
||||
XCTAssertFalse(results.mainResults.contains(where: {$0.text == "12:61"})) // Invalid minute
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user