Tests // Add unit tests for certain components.
Tests // +PrefManagerTests. Tests // +KeyHandlerTestsNormalCHS. Tests // +UpdateAPITests. Tests // KeyHandlerTestsSCPCCHT (not finished).
This commit is contained in:
parent
d5cbd10a34
commit
0b848f6305
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,383 @@
|
|||
// Copyright (c) 2021 and onwards Zonble Yang (MIT-NTL License).
|
||||
// All possible vChewing-specific modifications are of:
|
||||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
1. The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
2. No trademark license is granted to use the trade names, trademarks, service
|
||||
marks, or product names of Contributor, except as required to fulfill notice
|
||||
requirements above.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import XCTest
|
||||
|
||||
@testable import vChewing
|
||||
|
||||
class KeyHandlerTestsSCPCCHT: XCTestCase {
|
||||
func reset() {
|
||||
mgrPrefs.allKeys.forEach {
|
||||
UserDefaults.standard.removeObject(forKey: $0)
|
||||
}
|
||||
}
|
||||
|
||||
func makeSnapshot() -> [String: Any] {
|
||||
var dict = [String: Any]()
|
||||
mgrPrefs.allKeys.forEach {
|
||||
dict[$0] = UserDefaults.standard.object(forKey: $0)
|
||||
}
|
||||
return dict
|
||||
}
|
||||
|
||||
func restore(from snapshot: [String: Any]) {
|
||||
mgrPrefs.allKeys.forEach {
|
||||
UserDefaults.standard.set(snapshot[$0], forKey: $0)
|
||||
}
|
||||
}
|
||||
|
||||
var snapshot: [String: Any]?
|
||||
|
||||
var handler = KeyHandler()
|
||||
|
||||
override func setUpWithError() throws {
|
||||
snapshot = makeSnapshot()
|
||||
reset()
|
||||
mgrPrefs.basicKeyboardLayout = "com.apple.keylayout.ABC"
|
||||
mgrPrefs.mandarinParser = 0
|
||||
mgrPrefs.useSCPCTypingMode = false
|
||||
mgrPrefs.associatedPhrasesEnabled = false
|
||||
mgrLangModel.loadDataModel(.imeModeCHT)
|
||||
handler = KeyHandler()
|
||||
handler.inputMode = .imeModeCHT
|
||||
_ = mgrPrefs.toggleSCPCTypingModeEnabled()
|
||||
_ = mgrPrefs.toggleAssociatedPhrasesEnabled()
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
if let snapshot = snapshot {
|
||||
restore(from: snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
func testPunctuationTable() {
|
||||
let input = InputSignal(
|
||||
inputText: "`", keyCode: KeyCode.kSymbolMenuPhysicalKey.rawValue, charCode: 0, flags: .option
|
||||
)
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.ChoosingCandidate, "\(state)")
|
||||
if let state = state as? InputState.ChoosingCandidate {
|
||||
XCTAssertTrue(state.candidates.contains(","))
|
||||
}
|
||||
}
|
||||
|
||||
func testPunctuationComma() {
|
||||
let enabled = mgrPrefs.halfWidthPunctuationEnabled
|
||||
mgrPrefs.halfWidthPunctuationEnabled = false
|
||||
let input = InputSignal(inputText: "<", keyCode: 0, charCode: charCode("<"), flags: .shift)
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.ChoosingCandidate, "\(state)")
|
||||
if let state = state as? InputState.ChoosingCandidate {
|
||||
XCTAssertEqual(state.composingBuffer, ",")
|
||||
}
|
||||
mgrPrefs.halfWidthPunctuationEnabled = enabled
|
||||
}
|
||||
|
||||
func testPunctuationPeriod() {
|
||||
let enabled = mgrPrefs.halfWidthPunctuationEnabled
|
||||
mgrPrefs.halfWidthPunctuationEnabled = false
|
||||
let input = InputSignal(inputText: ">", keyCode: 0, charCode: charCode(">"), flags: .shift)
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.ChoosingCandidate, "\(state)")
|
||||
if let state = state as? InputState.ChoosingCandidate {
|
||||
XCTAssertEqual(state.composingBuffer, "。")
|
||||
}
|
||||
mgrPrefs.halfWidthPunctuationEnabled = enabled
|
||||
}
|
||||
|
||||
func testHalfPunctuationPeriod() {
|
||||
let enabled = mgrPrefs.halfWidthPunctuationEnabled
|
||||
mgrPrefs.halfWidthPunctuationEnabled = true
|
||||
let input = InputSignal(inputText: ">", keyCode: 0, charCode: charCode(">"), flags: .shift)
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.ChoosingCandidate, "\(state)")
|
||||
if let state = state as? InputState.ChoosingCandidate {
|
||||
XCTAssertEqual(state.composingBuffer, ".")
|
||||
}
|
||||
mgrPrefs.halfWidthPunctuationEnabled = enabled
|
||||
}
|
||||
|
||||
func testControlPunctuationPeriod() {
|
||||
let input = InputSignal(
|
||||
inputText: ".", keyCode: 0, charCode: charCode("."), flags: [.shift, .control]
|
||||
)
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
var count = 0
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
if count == 0 {
|
||||
state = newState
|
||||
}
|
||||
count += 1
|
||||
} errorCallback: {
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.Inputting, "\(state)")
|
||||
if let state = state as? InputState.Inputting {
|
||||
XCTAssertEqual(state.composingBuffer, "。")
|
||||
}
|
||||
}
|
||||
|
||||
func testEnterWithReading() {
|
||||
let input = InputSignal(inputText: "s", keyCode: 0, charCode: charCode("s"), flags: .shift)
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.Inputting, "\(state)")
|
||||
if let state = state as? InputState.Inputting {
|
||||
XCTAssertEqual(state.composingBuffer, "ㄋ")
|
||||
}
|
||||
|
||||
let enter = InputSignal(inputText: " ", keyCode: 0, charCode: 13, flags: [])
|
||||
var count = 0
|
||||
|
||||
_ = handler.handle(input: enter, state: state) { newState in
|
||||
if count == 0 {
|
||||
state = newState
|
||||
}
|
||||
count += 1
|
||||
} errorCallback: {
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.Inputting, "\(state)")
|
||||
if let state = state as? InputState.Inputting {
|
||||
XCTAssertEqual(state.composingBuffer, "ㄋ")
|
||||
}
|
||||
}
|
||||
|
||||
func testInputNe() {
|
||||
let input = InputSignal(inputText: "s", keyCode: 0, charCode: charCode("s"), flags: .shift)
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.Inputting, "\(state)")
|
||||
if let state = state as? InputState.Inputting {
|
||||
XCTAssertEqual(state.composingBuffer, "ㄋ")
|
||||
}
|
||||
}
|
||||
|
||||
func testInputNi() {
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
let keys = Array("su").map {
|
||||
String($0)
|
||||
}
|
||||
for key in keys {
|
||||
let input = InputSignal(inputText: key, keyCode: 0, charCode: charCode(key), flags: [])
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.Inputting, "\(state)")
|
||||
if let state = state as? InputState.Inputting {
|
||||
XCTAssertEqual(state.composingBuffer, "ㄋㄧ")
|
||||
}
|
||||
}
|
||||
|
||||
func testInputNi3() {
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
let keys = Array("su3").map {
|
||||
String($0)
|
||||
}
|
||||
for key in keys {
|
||||
let input = InputSignal(inputText: key, keyCode: 0, charCode: charCode(key), flags: [])
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.ChoosingCandidate, "\(state)")
|
||||
if let state = state as? InputState.ChoosingCandidate {
|
||||
XCTAssertTrue(state.candidates.contains("你"))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Further bug-hunting needed.
|
||||
func testCancelCandidateUsingDelete() {
|
||||
mgrPrefs.useSCPCTypingMode = true
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
let keys = Array("su3").map {
|
||||
String($0)
|
||||
}
|
||||
for key in keys {
|
||||
let input = InputSignal(inputText: key, keyCode: 0, charCode: charCode(key), flags: [])
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
}
|
||||
|
||||
let input = InputSignal(
|
||||
inputText: " ", keyCode: KeyCode.kWindowsDelete.rawValue, charCode: charCode(" "), flags: []
|
||||
)
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
print("Expecting EmptyIgnoringPreviousState.")
|
||||
print("\(state)")
|
||||
// XCTAssertTrue(state is InputState.EmptyIgnoringPreviousState, "\(state)")
|
||||
}
|
||||
|
||||
// TODO: Further bug-hunting needed.
|
||||
func testCancelCandidateUsingEsc() {
|
||||
mgrPrefs.useSCPCTypingMode = true
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
let keys = Array("su3").map {
|
||||
String($0)
|
||||
}
|
||||
for key in keys {
|
||||
let input = InputSignal(inputText: key, keyCode: 0, charCode: charCode(key), flags: [])
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
}
|
||||
|
||||
let input = InputSignal(inputText: " ", keyCode: KeyCode.kEscape.rawValue, charCode: charCode(" "), flags: [])
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
print("Expecting EmptyIgnoringPreviousState.")
|
||||
print("\(state)")
|
||||
// XCTAssertTrue(state is InputState.EmptyIgnoringPreviousState, "\(state)")
|
||||
}
|
||||
|
||||
// TODO: Further bug-hunting needed.
|
||||
func testAssociatedPhrases() {
|
||||
let enabled = mgrPrefs.associatedPhrasesEnabled
|
||||
mgrPrefs.associatedPhrasesEnabled = true
|
||||
mgrPrefs.useSCPCTypingMode = true
|
||||
handler.forceOpenStringInsteadForAssociatePhrases("二 百五")
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
let keys = Array("-41").map {
|
||||
String($0)
|
||||
}
|
||||
for key in keys {
|
||||
let input = InputSignal(inputText: key, keyCode: 0, charCode: charCode(key), flags: [])
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
} errorCallback: {
|
||||
}
|
||||
}
|
||||
print("Expecting AssociatedPhrases.")
|
||||
print("\(state)")
|
||||
// XCTAssertTrue(state is InputState.AssociatedPhrases, "\(state)")
|
||||
if let state = state as? InputState.AssociatedPhrases {
|
||||
// XCTAssertTrue(state.candidates.contains("百五"))
|
||||
}
|
||||
mgrPrefs.associatedPhrasesEnabled = enabled
|
||||
}
|
||||
|
||||
func testNoAssociatedPhrases() {
|
||||
let enabled = mgrPrefs.associatedPhrasesEnabled
|
||||
mgrPrefs.associatedPhrasesEnabled = false
|
||||
var state: InputStateProtocol = InputState.Empty()
|
||||
let keys = Array("aul ").map {
|
||||
String($0)
|
||||
}
|
||||
for key in keys {
|
||||
let input = InputSignal(inputText: key, keyCode: 0, charCode: charCode(key), flags: [])
|
||||
_ = handler.handle(input: input, state: state) { newState in
|
||||
state = newState
|
||||
|
||||
} errorCallback: {
|
||||
}
|
||||
}
|
||||
|
||||
XCTAssertTrue(state is InputState.Empty, "\(state)")
|
||||
mgrPrefs.associatedPhrasesEnabled = enabled
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - StringView Ranges Extension (by Isaac Xen)
|
||||
|
||||
extension String {
|
||||
fileprivate func ranges(splitBy separator: Element) -> [Range<String.Index>] {
|
||||
var startIndex = startIndex
|
||||
return split(separator: separator).reduce(into: []) { ranges, substring in
|
||||
_ = range(of: substring, range: startIndex..<endIndex).map { range in
|
||||
ranges.append(range)
|
||||
startIndex = range.upperBound
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension vChewing.LMAssociates {
|
||||
public mutating func forceOpenStringInstead(_ strData: String) {
|
||||
strData.ranges(splitBy: "\n").forEach {
|
||||
let neta = strData[$0].split(separator: " ")
|
||||
if neta.count >= 2 {
|
||||
let theKey = String(neta[0])
|
||||
if !neta[0].isEmpty, !neta[1].isEmpty, theKey.first != "#" {
|
||||
let theValue = $0
|
||||
rangeMap[theKey, default: []].append(theValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension vChewing.LMInstantiator {
|
||||
public func forceOpenStringInsteadForAssociatePhrases(_ strData: String) {
|
||||
lmAssociates.forceOpenStringInstead(strData)
|
||||
}
|
||||
}
|
||||
|
||||
extension KeyHandler {
|
||||
public func forceOpenStringInsteadForAssociatePhrases(_ strData: String) {
|
||||
currentLM.forceOpenStringInsteadForAssociatePhrases(strData + "\n")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,276 @@
|
|||
// Copyright (c) 2021 and onwards Zonble Yang (MIT-NTL License).
|
||||
// All possible vChewing-specific modifications are of:
|
||||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
1. The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
2. No trademark license is granted to use the trade names, trademarks, service
|
||||
marks, or product names of Contributor, except as required to fulfill notice
|
||||
requirements above.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import XCTest
|
||||
|
||||
@testable import vChewing
|
||||
|
||||
class PrefManagerTests: XCTestCase {
|
||||
func reset() {
|
||||
mgrPrefs.allKeys.forEach {
|
||||
UserDefaults.standard.removeObject(forKey: $0)
|
||||
}
|
||||
}
|
||||
|
||||
func makeSnapshot() -> [String: Any] {
|
||||
var dict = [String: Any]()
|
||||
mgrPrefs.allKeys.forEach {
|
||||
dict[$0] = UserDefaults.standard.object(forKey: $0)
|
||||
}
|
||||
return dict
|
||||
}
|
||||
|
||||
func restore(from snapshot: [String: Any]) {
|
||||
mgrPrefs.allKeys.forEach {
|
||||
UserDefaults.standard.set(snapshot[$0], forKey: $0)
|
||||
}
|
||||
}
|
||||
|
||||
var snapshot: [String: Any]?
|
||||
|
||||
override func setUpWithError() throws {
|
||||
snapshot = makeSnapshot()
|
||||
reset()
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
if let snapshot = snapshot {
|
||||
restore(from: snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
func testMandarinParser() {
|
||||
XCTAssert(mgrPrefs.mandarinParser == 0)
|
||||
mgrPrefs.mandarinParser = 1
|
||||
XCTAssert(mgrPrefs.mandarinParser == 1)
|
||||
}
|
||||
|
||||
func testMandarinParserName() {
|
||||
XCTAssert(mgrPrefs.mandarinParserName == "Standard")
|
||||
mgrPrefs.mandarinParser = 1
|
||||
XCTAssert(mgrPrefs.mandarinParserName == "ETen")
|
||||
}
|
||||
|
||||
func testBasisKeyboardLayoutPreferenceKey() {
|
||||
XCTAssert(mgrPrefs.basicKeyboardLayout == "com.apple.keylayout.ZhuyinBopomofo")
|
||||
mgrPrefs.basicKeyboardLayout = "com.apple.keylayout.ABC"
|
||||
XCTAssert(mgrPrefs.basicKeyboardLayout == "com.apple.keylayout.ABC")
|
||||
}
|
||||
|
||||
func testCandidateTextSize() {
|
||||
XCTAssert(mgrPrefs.candidateListTextSize == 18)
|
||||
|
||||
mgrPrefs.candidateListTextSize = 16
|
||||
XCTAssert(mgrPrefs.candidateListTextSize == 16)
|
||||
|
||||
mgrPrefs.candidateListTextSize = 11
|
||||
XCTAssert(mgrPrefs.candidateListTextSize == 12)
|
||||
mgrPrefs.candidateListTextSize = 197
|
||||
XCTAssert(mgrPrefs.candidateListTextSize == 196)
|
||||
|
||||
mgrPrefs.candidateListTextSize = 12
|
||||
XCTAssert(mgrPrefs.candidateListTextSize == 12)
|
||||
mgrPrefs.candidateListTextSize = 196
|
||||
XCTAssert(mgrPrefs.candidateListTextSize == 196)
|
||||
|
||||
mgrPrefs.candidateListTextSize = 13
|
||||
XCTAssert(mgrPrefs.candidateListTextSize == 13)
|
||||
mgrPrefs.candidateListTextSize = 195
|
||||
XCTAssert(mgrPrefs.candidateListTextSize == 195)
|
||||
}
|
||||
|
||||
func testUseRearCursorMode() {
|
||||
XCTAssert(mgrPrefs.useRearCursorMode == false)
|
||||
mgrPrefs.useRearCursorMode = true
|
||||
XCTAssert(mgrPrefs.useRearCursorMode == true)
|
||||
}
|
||||
|
||||
func testUseHorizontalCandidateList() {
|
||||
XCTAssert(mgrPrefs.useHorizontalCandidateList == true)
|
||||
mgrPrefs.useHorizontalCandidateList = false
|
||||
XCTAssert(mgrPrefs.useHorizontalCandidateList == false)
|
||||
}
|
||||
|
||||
func testComposingBufferSize() {
|
||||
XCTAssert(mgrPrefs.composingBufferSize == 20)
|
||||
mgrPrefs.composingBufferSize = 10
|
||||
XCTAssert(mgrPrefs.composingBufferSize == 10)
|
||||
mgrPrefs.composingBufferSize = 4
|
||||
XCTAssert(mgrPrefs.composingBufferSize == 10)
|
||||
mgrPrefs.composingBufferSize = 50
|
||||
XCTAssert(mgrPrefs.composingBufferSize == 40)
|
||||
}
|
||||
|
||||
func testChooseCandidateUsingSpace() {
|
||||
XCTAssert(mgrPrefs.chooseCandidateUsingSpace == true)
|
||||
mgrPrefs.chooseCandidateUsingSpace = false
|
||||
XCTAssert(mgrPrefs.chooseCandidateUsingSpace == false)
|
||||
}
|
||||
|
||||
func testChineseConversionEnabled() {
|
||||
XCTAssert(mgrPrefs.chineseConversionEnabled == false)
|
||||
mgrPrefs.chineseConversionEnabled = true
|
||||
XCTAssert(mgrPrefs.chineseConversionEnabled == true)
|
||||
_ = mgrPrefs.toggleChineseConversionEnabled()
|
||||
XCTAssert(mgrPrefs.chineseConversionEnabled == false)
|
||||
}
|
||||
|
||||
func testHalfWidthPunctuationEnabled() {
|
||||
XCTAssert(mgrPrefs.halfWidthPunctuationEnabled == false)
|
||||
mgrPrefs.halfWidthPunctuationEnabled = true
|
||||
XCTAssert(mgrPrefs.halfWidthPunctuationEnabled == true)
|
||||
_ = mgrPrefs.toggleHalfWidthPunctuationEnabled()
|
||||
XCTAssert(mgrPrefs.halfWidthPunctuationEnabled == false)
|
||||
}
|
||||
|
||||
func testEscToCleanInputBuffer() {
|
||||
XCTAssert(mgrPrefs.escToCleanInputBuffer == true)
|
||||
mgrPrefs.escToCleanInputBuffer = false
|
||||
XCTAssert(mgrPrefs.escToCleanInputBuffer == false)
|
||||
}
|
||||
|
||||
func testCandidateTextFontName() {
|
||||
XCTAssert(mgrPrefs.candidateTextFontName == nil)
|
||||
mgrPrefs.candidateTextFontName = "Helvetica"
|
||||
XCTAssert(mgrPrefs.candidateTextFontName == "Helvetica")
|
||||
}
|
||||
|
||||
func testCandidateKeyLabelFontName() {
|
||||
XCTAssert(mgrPrefs.candidateKeyLabelFontName == nil)
|
||||
mgrPrefs.candidateKeyLabelFontName = "Helvetica"
|
||||
XCTAssert(mgrPrefs.candidateKeyLabelFontName == "Helvetica")
|
||||
}
|
||||
|
||||
func testCandidateKeys() {
|
||||
XCTAssert(mgrPrefs.candidateKeys == mgrPrefs.defaultCandidateKeys)
|
||||
mgrPrefs.candidateKeys = "abcd"
|
||||
XCTAssert(mgrPrefs.candidateKeys == "abcd")
|
||||
}
|
||||
|
||||
func testPhraseReplacementEnabledKey() {
|
||||
XCTAssert(mgrPrefs.phraseReplacementEnabled == false)
|
||||
mgrPrefs.phraseReplacementEnabled = true
|
||||
XCTAssert(mgrPrefs.phraseReplacementEnabled == true)
|
||||
}
|
||||
}
|
||||
|
||||
class CandidateKeyValidationTests: XCTestCase {
|
||||
func testEmpty() {
|
||||
do {
|
||||
try mgrPrefs.validate(candidateKeys: "")
|
||||
XCTFail("exception not thrown")
|
||||
} catch mgrPrefs.CandidateKeyError.empty {
|
||||
} catch {
|
||||
XCTFail("exception not thrown")
|
||||
}
|
||||
}
|
||||
|
||||
func testSpaces() {
|
||||
do {
|
||||
try mgrPrefs.validate(candidateKeys: " ")
|
||||
XCTFail("exception not thrown")
|
||||
} catch mgrPrefs.CandidateKeyError.empty {
|
||||
} catch {
|
||||
XCTFail("exception not thrown")
|
||||
}
|
||||
}
|
||||
|
||||
func testInvalidKeys() {
|
||||
do {
|
||||
try mgrPrefs.validate(candidateKeys: "中文字元")
|
||||
XCTFail("exception not thrown")
|
||||
} catch mgrPrefs.CandidateKeyError.invalidCharacters {
|
||||
} catch {
|
||||
XCTFail("exception not thrown")
|
||||
}
|
||||
}
|
||||
|
||||
func testInvalidLatinLetters() {
|
||||
do {
|
||||
try mgrPrefs.validate(candidateKeys: "üåçøöacpo")
|
||||
XCTFail("exception not thrown")
|
||||
} catch mgrPrefs.CandidateKeyError.invalidCharacters {
|
||||
} catch {
|
||||
XCTFail("exception not thrown")
|
||||
}
|
||||
}
|
||||
|
||||
func testSpaceInBetween() {
|
||||
do {
|
||||
try mgrPrefs.validate(candidateKeys: "1 2 3 4")
|
||||
XCTFail("exception not thrown")
|
||||
} catch mgrPrefs.CandidateKeyError.containSpace {
|
||||
} catch {
|
||||
XCTFail("exception not thrown")
|
||||
}
|
||||
}
|
||||
|
||||
func testDuplicatedKeys() {
|
||||
do {
|
||||
try mgrPrefs.validate(candidateKeys: "aabbccdd")
|
||||
XCTFail("exception not thrown")
|
||||
} catch mgrPrefs.CandidateKeyError.duplicatedCharacters {
|
||||
} catch {
|
||||
XCTFail("exception not thrown")
|
||||
}
|
||||
}
|
||||
|
||||
func testTooShort1() {
|
||||
do {
|
||||
try mgrPrefs.validate(candidateKeys: "abc")
|
||||
XCTFail("exception not thrown")
|
||||
} catch mgrPrefs.CandidateKeyError.tooShort {
|
||||
} catch {
|
||||
XCTFail("exception not thrown")
|
||||
}
|
||||
}
|
||||
|
||||
func testTooShort2() {
|
||||
do {
|
||||
try mgrPrefs.validate(candidateKeys: "abcd")
|
||||
} catch {
|
||||
XCTFail("Should be safe")
|
||||
}
|
||||
}
|
||||
|
||||
func testTooLong1() {
|
||||
do {
|
||||
try mgrPrefs.validate(candidateKeys: "qwertyuiopasdfgh")
|
||||
XCTFail("exception not thrown")
|
||||
} catch mgrPrefs.CandidateKeyError.tooLong {
|
||||
} catch {
|
||||
XCTFail("exception not thrown")
|
||||
}
|
||||
}
|
||||
|
||||
func testTooLong2() {
|
||||
do {
|
||||
try mgrPrefs.validate(candidateKeys: "qwertyuiopasdfg")
|
||||
} catch {
|
||||
XCTFail("Should be safe")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) 2021 and onwards Zonble Yang (MIT-NTL License).
|
||||
// All possible vChewing-specific modifications are of:
|
||||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||
/*
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
1. The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
2. No trademark license is granted to use the trade names, trademarks, service
|
||||
marks, or product names of Contributor, except as required to fulfill notice
|
||||
requirements above.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import XCTest
|
||||
|
||||
@testable import vChewing
|
||||
|
||||
class VersionUpdateApiTests: XCTestCase {
|
||||
func testFetchVersionUpdateInfo() {
|
||||
let exp = expectation(description: "wait for 3 seconds")
|
||||
_ = VersionUpdateApi.check(forced: true) { result in
|
||||
exp.fulfill()
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
XCTFail(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
wait(for: [exp], timeout: 20.0)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue