From 5d53b4a93c03e344421f70f736e2fb869b61bd7b Mon Sep 17 00:00:00 2001 From: Lukhnos Liu Date: Tue, 15 Feb 2022 23:27:22 -0800 Subject: [PATCH 1/3] Ensure Plain BPMF tests run with Standard layout This exposes an issue that our Preferences is a global singleton that uses the user defaults store and is therefore not hermetic. --- McBopomofoTests/KeyHandlerPlainBopomofoTests.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/McBopomofoTests/KeyHandlerPlainBopomofoTests.swift b/McBopomofoTests/KeyHandlerPlainBopomofoTests.swift index 4e99ebbd..feeb0e0c 100644 --- a/McBopomofoTests/KeyHandlerPlainBopomofoTests.swift +++ b/McBopomofoTests/KeyHandlerPlainBopomofoTests.swift @@ -25,15 +25,22 @@ import XCTest @testable import McBopomofo class KeyHandlerPlainBopomofoTests: XCTestCase { + var savedKeyboardLayout: Int = 0 var handler = KeyHandler() override func setUpWithError() throws { LanguageModelManager.loadDataModels() handler = KeyHandler() handler.inputMode = .plainBopomofo + + savedKeyboardLayout = Preferences.keyboardLayout + + // Punctuation-related tests only work when the layout is Standard. + Preferences.keyboardLayout = KeyboardLayout.standard.rawValue } override func tearDownWithError() throws { + Preferences.keyboardLayout = savedKeyboardLayout } func testPunctuationTable() { From 7563568e7ff643846f5587f238758ac3f3e1d4a3 Mon Sep 17 00:00:00 2001 From: Lukhnos Liu Date: Tue, 15 Feb 2022 23:28:42 -0800 Subject: [PATCH 2/3] Run McBopomofo tests as part of the CI workflow --- .../workflows/continuous-integration-workflow-xcode-12.yml | 4 ++++ .../continuous-integration-workflow-xcode-latest.yml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/.github/workflows/continuous-integration-workflow-xcode-12.yml b/.github/workflows/continuous-integration-workflow-xcode-12.yml index 11696803..f8f96779 100644 --- a/.github/workflows/continuous-integration-workflow-xcode-12.yml +++ b/.github/workflows/continuous-integration-workflow-xcode-12.yml @@ -38,6 +38,10 @@ jobs: - name: Test NSStringUtils run: swift test working-directory: Packages/NSStringUtils + - name: Clean McBopomofo for testing + run: xcodebuild -scheme McBopomofo -configuration Debug clean + - name: Test McBopomofo + run: xcodebuild -scheme McBopomofo -configuration Debug test - name: Clean McBopomofo run: xcodebuild -scheme McBopomofo -configuration Release clean - name: Clean McBopomofoInstaller diff --git a/.github/workflows/continuous-integration-workflow-xcode-latest.yml b/.github/workflows/continuous-integration-workflow-xcode-latest.yml index 7c155bd1..a03bf5f8 100644 --- a/.github/workflows/continuous-integration-workflow-xcode-latest.yml +++ b/.github/workflows/continuous-integration-workflow-xcode-latest.yml @@ -38,6 +38,10 @@ jobs: - name: Test NSStringUtils run: swift test working-directory: Packages/NSStringUtils + - name: Clean McBopomofo for testing + run: xcodebuild -scheme McBopomofo -configuration Debug clean + - name: Test McBopomofo + run: xcodebuild -scheme McBopomofo -configuration Debug test - name: Clean McBopomofo run: xcodebuild -scheme McBopomofo -configuration Release clean - name: Clean McBopomofoInstaller From ea2e76e107af10b93de60ac4d3d987f943172966 Mon Sep 17 00:00:00 2001 From: Lukhnos Liu Date: Tue, 15 Feb 2022 23:44:13 -0800 Subject: [PATCH 3/3] Handle [A-Z] if input state is not empty (#292) This fixes the regression, first introduced in 2.2, from 2.0.x behavior. --- McBopomofoTests/KeyHandlerBopomofoTests.swift | 31 ++++++++++++++++--- .../KeyHandlerPlainBopomofoTests.swift | 11 +++++++ Source/KeyHandler.mm | 2 +- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/McBopomofoTests/KeyHandlerBopomofoTests.swift b/McBopomofoTests/KeyHandlerBopomofoTests.swift index 07cfcfba..9667a4fc 100644 --- a/McBopomofoTests/KeyHandlerBopomofoTests.swift +++ b/McBopomofoTests/KeyHandlerBopomofoTests.swift @@ -266,17 +266,40 @@ class KeyHandlerBopomofoTests: XCTestCase { } } - func testLetter() { - let input = KeyHandlerInput(inputText: "A", keyCode: 0, charCode: charCode("A"), flags: .shift, isVerticalMode: false) + // Regression test for #292. + func testUppercaseLetterWhenEmpty() { + let input = KeyHandlerInput(inputText: "A", keyCode: KeyCode.enter.rawValue, charCode: charCode("A"), flags: [], isVerticalMode: false) var state: InputState = InputState.Empty() - handler.handle(input: input, state: state) { newState in + let result = handler.handle(input: input, state: state) { newState in + state = newState + } errorCallback: { + } + XCTAssertFalse(result) + } + + // Regression test for #292. + func testUppercaseLetterWhenNotEmpty() { + var state: InputState = InputState.Empty() + let keys = Array("u6").map { + String($0) + } + for key in keys { + let input = KeyHandlerInput(inputText: key, keyCode: 0, charCode: charCode(key), flags: [], isVerticalMode: false) + handler.handle(input: input, state: state) { newState in + state = newState + } errorCallback: { + } + } + + let letterInput = KeyHandlerInput(inputText: "A", keyCode: 0, charCode: charCode("A"), flags: .shift, isVerticalMode: false) + handler.handle(input: letterInput, state: state) { newState in state = newState } errorCallback: { } XCTAssertTrue(state is InputState.Inputting, "\(state)") if let state = state as? InputState.Inputting { - XCTAssertEqual(state.composingBuffer, "a") + XCTAssertEqual(state.composingBuffer, "一a") } } diff --git a/McBopomofoTests/KeyHandlerPlainBopomofoTests.swift b/McBopomofoTests/KeyHandlerPlainBopomofoTests.swift index feeb0e0c..a713a179 100644 --- a/McBopomofoTests/KeyHandlerPlainBopomofoTests.swift +++ b/McBopomofoTests/KeyHandlerPlainBopomofoTests.swift @@ -43,6 +43,17 @@ class KeyHandlerPlainBopomofoTests: XCTestCase { Preferences.keyboardLayout = savedKeyboardLayout } + // Regression test for #292. + func testUppercaseLetterWhenEmpty() { + let input = KeyHandlerInput(inputText: "A", keyCode: KeyCode.enter.rawValue, charCode: charCode("A"), flags: [], isVerticalMode: false) + var state: InputState = InputState.Empty() + let result = handler.handle(input: input, state: state) { newState in + state = newState + } errorCallback: { + } + XCTAssertFalse(result) + } + func testPunctuationTable() { let input = KeyHandlerInput(inputText: "`", keyCode: 0, charCode: charCode("`"), flags: .shift, isVerticalMode: false) var state: InputState = InputState.Empty() diff --git a/Source/KeyHandler.mm b/Source/KeyHandler.mm index 8209ebc5..d08bebb1 100644 --- a/Source/KeyHandler.mm +++ b/Source/KeyHandler.mm @@ -541,7 +541,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/McBopomofo-visualization.dot return YES; } - if ((char) charCode >= 'A' && (char) charCode <= 'Z') { + if ([state isKindOfClass:[InputStateNotEmpty class]] && (char) charCode >= 'A' && (char) charCode <= 'Z') { string letter = string("_letter_") + string(1, (char) charCode); if ([self _handlePunctuation:letter state:state usingVerticalMode:input.useVerticalMode stateCallback:stateCallback errorCallback:errorCallback]) { return YES;