Repo // Make UserDefaults unit-testable.

This commit is contained in:
ShikiSuen 2023-08-24 22:12:09 +08:00
parent c5c99894a9
commit 3a8060bf88
11 changed files with 67 additions and 32 deletions

View File

@ -81,8 +81,8 @@ open class CtlCandidate: NSWindowController, CtlCandidateProtocol {
fatalError("init(coder:) has not been implemented")
}
open var candidateFont = NSFont.systemFont(
ofSize: min(196, max(12, Double(UserDefaults.standard.integer(forKey: "CandidateListTextSize"))))
open var candidateFont: NSFont = NSFont.systemFont(
ofSize: min(196, max(12, Double(UserDefaults.current.integer(forKey: "CandidateListTextSize"))))
)
@discardableResult open func showNextLine() -> Bool {

View File

@ -133,7 +133,7 @@ public extension NSApplication {
let appearanceDescription = NSApp.effectiveAppearance.debugDescription
.lowercased()
return appearanceDescription.contains("dark")
} else if let appleInterfaceStyle = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") {
} else if let appleInterfaceStyle = UserDefaults.current.string(forKey: "AppleInterfaceStyle") {
return appleInterfaceStyle.lowercased().contains("dark")
}
return false

View File

@ -49,14 +49,6 @@ public enum IMKHelper {
"org.unknown.keylayout.vChewingMiTAC",
]
public static var currentBasicKeyboardLayout: String {
UserDefaults.standard.string(forKey: "BasicKeyboardLayout") ?? ""
}
public static var isDynamicBasicKeyboardLayoutEnabled: Bool {
Self.arrDynamicBasicKeyLayouts.contains(currentBasicKeyboardLayout) || !currentBasicKeyboardLayout.isEmpty
}
public static var allowedAlphanumericalTISInputSources: [TISInputSource] {
arrWhitelistedKeyLayoutsASCII.compactMap { TISInputSource.generate(from: $0) }
}

View File

@ -230,22 +230,22 @@ public extension LMMgr {
{
return userDictPathDefault
}
if UserDefaults.standard.object(forKey: UserDef.kUserDataFolderSpecified.rawValue) != nil {
if UserDefaults.current.object(forKey: UserDef.kUserDataFolderSpecified.rawValue) != nil {
BookmarkManager.shared.loadBookmarks()
if Self.checkIfSpecifiedUserDataFolderValid(userDictPathSpecified) {
return userDictPathSpecified
}
UserDefaults.standard.removeObject(forKey: UserDef.kUserDataFolderSpecified.rawValue)
UserDefaults.current.removeObject(forKey: UserDef.kUserDataFolderSpecified.rawValue)
}
return userDictPathDefault
}
static func cassettePath() -> String {
let rawCassettePath = PrefMgr.shared.cassettePath
if UserDefaults.standard.object(forKey: UserDef.kCassettePath.rawValue) != nil {
if UserDefaults.current.object(forKey: UserDef.kCassettePath.rawValue) != nil {
BookmarkManager.shared.loadBookmarks()
if Self.checkCassettePathValidity(rawCassettePath) { return rawCassettePath }
UserDefaults.standard.removeObject(forKey: UserDef.kCassettePath.rawValue)
UserDefaults.current.removeObject(forKey: UserDef.kCassettePath.rawValue)
}
return ""
}
@ -253,12 +253,12 @@ public extension LMMgr {
// MARK: - 使
static func resetSpecifiedUserDataFolder() {
UserDefaults.standard.set(dataFolderPath(isDefaultFolder: true), forKey: UserDef.kUserDataFolderSpecified.rawValue)
UserDefaults.current.set(dataFolderPath(isDefaultFolder: true), forKey: UserDef.kUserDataFolderSpecified.rawValue)
Self.initUserLangModels()
}
static func resetCassettePath() {
UserDefaults.standard.set("", forKey: UserDef.kCassettePath.rawValue)
UserDefaults.current.set("", forKey: UserDef.kCassettePath.rawValue)
Self.loadCassetteData()
}

View File

@ -236,11 +236,11 @@ public class PrefMgr: PrefMgrProtocol {
// JIS
if chineseConversionEnabled, shiftJISShinjitaiOutputEnabled {
shiftJISShinjitaiOutputEnabled.toggle()
UserDefaults.standard.set(
UserDefaults.current.set(
shiftJISShinjitaiOutputEnabled, forKey: UserDef.kShiftJISShinjitaiOutputEnabled.rawValue
)
}
UserDefaults.standard.set(
UserDefaults.current.set(
chineseConversionEnabled, forKey: UserDef.kChineseConversionEnabled.rawValue
)
}
@ -252,11 +252,11 @@ public class PrefMgr: PrefMgrProtocol {
// JIS
if shiftJISShinjitaiOutputEnabled, chineseConversionEnabled {
chineseConversionEnabled.toggle()
UserDefaults.standard.set(
UserDefaults.current.set(
chineseConversionEnabled, forKey: UserDef.kChineseConversionEnabled.rawValue
)
}
UserDefaults.standard.set(
UserDefaults.current.set(
shiftJISShinjitaiOutputEnabled, forKey: UserDef.kShiftJISShinjitaiOutputEnabled.rawValue
)
}

View File

@ -25,15 +25,15 @@ public extension PrefMgr {
showNotificationsWhenTogglingCapsLock = false
}
if appleLanguages.isEmpty {
UserDefaults.standard.removeObject(forKey: UserDef.kAppleLanguages.rawValue)
UserDefaults.current.removeObject(forKey: UserDef.kAppleLanguages.rawValue)
}
// ( didSet )
candidateKeys = candidateKeys
//
if let clients = UserDefaults.standard.object(
if let clients = UserDefaults.current.object(
forKey: UserDef.kClientsIMKTextInputIncapable.rawValue
) as? [String] {
UserDefaults.standard.removeObject(forKey: UserDef.kClientsIMKTextInputIncapable.rawValue)
UserDefaults.current.removeObject(forKey: UserDef.kClientsIMKTextInputIncapable.rawValue)
clients.forEach { neta in
guard !clientsIMKTextInputIncapable.keys.contains(neta) else { return }
clientsIMKTextInputIncapable[neta] = true

View File

@ -2,6 +2,14 @@
import XCTest
final class MainAssemblyTests: XCTestCase {
func testExample() throws {
override func setUpWithError() throws {
UserDefaults.unitTests = .init(suiteName: "org.atelierInmu.vChewing.MainAssembly.UnitTests")
UserDefaults.pendingUnitTests = true
}
override func tearDownWithError() throws {
UserDefaults.unitTests?.removeSuite(named: "org.atelierInmu.vChewing.MainAssembly.UnitTests")
}
func testExample() throws {}
}

View File

@ -16,7 +16,7 @@ import SwiftUI
import SwiftUIBackports
private let loc: String =
(UserDefaults.standard.array(forKey: UserDef.kAppleLanguages.rawValue) as? [String] ?? ["auto"])[0]
(UserDefaults.current.array(forKey: UserDef.kAppleLanguages.rawValue) as? [String] ?? ["auto"])[0]
@available(macOS 10.15, *)
extension VwrPhraseEditorUI {
@ -31,7 +31,7 @@ public struct VwrPhraseEditorUI: View {
)
@Binding public var txtContent: String
@ObservedObject public var fileChangeIndicator = FileObserveProject.shared
@State private var selAutoReloadExternalModifications: Bool = UserDefaults.standard.bool(
@State private var selAutoReloadExternalModifications: Bool = UserDefaults.current.bool(
forKey: UserDef.kPhraseEditorAutoReloadExternalModifications.rawValue)
@State var lblAddPhraseTag1 = PETerms.AddPhrases.locPhrase.localized.0
@State var lblAddPhraseTag2 = PETerms.AddPhrases.locReadingOrStroke.localized.0

View File

@ -0,0 +1,22 @@
// (c) 2022 and onwards The vChewing Project (MIT-NTL License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
// 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 defined in MIT License.
import AppKit
import IMKUtils
// MARK: - IMKHelper Extension
public extension IMKHelper {
static var currentBasicKeyboardLayout: String {
UserDefaults.current.string(forKey: "BasicKeyboardLayout") ?? ""
}
static var isDynamicBasicKeyboardLayoutEnabled: Bool {
Self.arrDynamicBasicKeyLayouts.contains(currentBasicKeyboardLayout) || !currentBasicKeyboardLayout.isEmpty
}
}

View File

@ -98,7 +98,7 @@ public enum UserDef: String, CaseIterable {
public static func resetAll() {
UserDef.allCases.forEach {
UserDefaults.standard.removeObject(forKey: $0.rawValue)
UserDefaults.current.removeObject(forKey: $0.rawValue)
}
}
@ -106,7 +106,7 @@ public enum UserDef: String, CaseIterable {
let data = snapshot.data
guard !data.isEmpty else { return }
UserDef.allCases.forEach {
UserDefaults.standard.set(data[$0.rawValue], forKey: $0.rawValue)
UserDefaults.current.set(data[$0.rawValue], forKey: $0.rawValue)
}
}
@ -114,7 +114,7 @@ public enum UserDef: String, CaseIterable {
public var data: [String: Any] = [:]
public init() {
UserDef.allCases.forEach {
data[$0.rawValue] = UserDefaults.standard.object(forKey: $0.rawValue)
data[$0.rawValue] = UserDefaults.current.object(forKey: $0.rawValue)
}
}
}
@ -310,7 +310,7 @@ public enum CandidateKey {
}
public func vCLog(_ strPrint: StringLiteralType) {
if UserDefaults.standard.bool(forKey: "_DebugMode") {
if UserDefaults.current.bool(forKey: "_DebugMode") {
NSLog("vChewingDebug: %@", strPrint)
}
}

View File

@ -119,6 +119,19 @@ public extension Bool {
}
}
// MARK: - User Defaults Storage
public extension UserDefaults {
//
static var pendingUnitTests = false
static var unitTests = UserDefaults(suiteName: "UnitTests")
static var current: UserDefaults {
pendingUnitTests ? .unitTests ?? .standard : .standard
}
}
// MARK: - Property Wrapper
// Ref: https://www.avanderlee.com/swift/property-wrappers/
@ -127,7 +140,7 @@ public extension Bool {
public struct AppProperty<Value> {
public let key: String
public let defaultValue: Value
public var container: UserDefaults = .standard
public var container: UserDefaults { .current }
public init(key: String, defaultValue: Value) {
self.key = key
self.defaultValue = defaultValue