mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-09 07:27:29 +00:00
Merge pull request #2692 from keymanapp/feat/ios/migration-unit-tests
feat(ios): KeymanEngine version migration unit tests
This commit is contained in:
commit
4190d41761
25 changed files with 622 additions and 1 deletions
|
|
@ -173,8 +173,14 @@
|
|||
CE8EDEB323F53F96009E1FF6 /* VersionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE8EDEB223F53F96009E1FF6 /* VersionTests.swift */; };
|
||||
CE976D4F23FA380700FFDF3A /* Reachability.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A0FC9FC22D66D9E00D33F86 /* Reachability.framework */; };
|
||||
CE976D5023FA380700FFDF3A /* Reachability.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9A0FC9FC22D66D9E00D33F86 /* Reachability.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
CE9B440C23FE49F000499CAB /* Migrations.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE9B440B23FE49F000499CAB /* Migrations.swift */; };
|
||||
CE9B440F23FE4E7500499CAB /* 12.0 Ad-hoc Migration.bundle in Resources */ = {isa = PBXBuildFile; fileRef = CE9B440D23FE4E7400499CAB /* 12.0 Ad-hoc Migration.bundle */; };
|
||||
CE9B441023FE4E7500499CAB /* Simple 12.0 Migration.bundle in Resources */ = {isa = PBXBuildFile; fileRef = CE9B440E23FE4E7500499CAB /* Simple 12.0 Migration.bundle */; };
|
||||
CE9CD88023FCC1CA002BF2F8 /* TestUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE9CD87F23FCC1CA002BF2F8 /* TestUtils.swift */; };
|
||||
CE9CD88323FCC4E3002BF2F8 /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE9CD88223FCC4E3002BF2F8 /* UserDefaults.swift */; };
|
||||
CEDFEF8F23FE43B700BECF39 /* MigrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEDFEF8E23FE43B700BECF39 /* MigrationTests.swift */; };
|
||||
CEF888D223FE6ADF00667693 /* No-defaults 10.0 Migration.bundle in Resources */ = {isa = PBXBuildFile; fileRef = CEF888D023FE6ADE00667693 /* No-defaults 10.0 Migration.bundle */; };
|
||||
CEF888D323FE6ADF00667693 /* Simple 10.0 Migration.bundle in Resources */ = {isa = PBXBuildFile; fileRef = CEF888D123FE6ADF00667693 /* Simple 10.0 Migration.bundle */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
|
|
@ -428,10 +434,16 @@
|
|||
CE7A26DA23CEEF640005955C /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
|
||||
CE7ADD6523DE89FC00BC9A00 /* Alerts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alerts.swift; sourceTree = "<group>"; };
|
||||
CE8EDEB223F53F96009E1FF6 /* VersionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionTests.swift; sourceTree = "<group>"; };
|
||||
CE9B440B23FE49F000499CAB /* Migrations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Migrations.swift; sourceTree = "<group>"; };
|
||||
CE9B440D23FE4E7400499CAB /* 12.0 Ad-hoc Migration.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = "12.0 Ad-hoc Migration.bundle"; sourceTree = "<group>"; };
|
||||
CE9B440E23FE4E7500499CAB /* Simple 12.0 Migration.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = "Simple 12.0 Migration.bundle"; sourceTree = "<group>"; };
|
||||
CE9CD87F23FCC1CA002BF2F8 /* TestUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestUtils.swift; sourceTree = "<group>"; };
|
||||
CE9CD88223FCC4E3002BF2F8 /* UserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaults.swift; sourceTree = "<group>"; };
|
||||
CECB38931F2199BC0098882F /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Reachability.h; path = KeymanEngine/lib/Reachability/Reachability.h; sourceTree = SOURCE_ROOT; };
|
||||
CECB38941F2199BC0098882F /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Reachability.m; path = KeymanEngine/lib/Reachability/Reachability.m; sourceTree = SOURCE_ROOT; };
|
||||
CEDFEF8E23FE43B700BECF39 /* MigrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationTests.swift; sourceTree = "<group>"; };
|
||||
CEF888D023FE6ADE00667693 /* No-defaults 10.0 Migration.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = "No-defaults 10.0 Migration.bundle"; sourceTree = "<group>"; };
|
||||
CEF888D123FE6ADF00667693 /* Simple 10.0 Migration.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = "Simple 10.0 Migration.bundle"; sourceTree = "<group>"; };
|
||||
F243887E14BBD43000A3E055 /* KeymanEngineDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KeymanEngineDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F243889014BBD43100A3E055 /* KeymanEngine-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "KeymanEngine-Prefix.pch"; sourceTree = "<group>"; };
|
||||
F27FCAEE157FD59100FBBA20 /* Keyman-iphoneos.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Keyman-iphoneos.xcconfig"; sourceTree = "<group>"; };
|
||||
|
|
@ -658,6 +670,7 @@
|
|||
9A079DD3223194B100581263 /* Info.plist */,
|
||||
CE8EDEB223F53F96009E1FF6 /* VersionTests.swift */,
|
||||
CE4459CD23FBBA8D003151FD /* AppDelegate.swift */,
|
||||
CEDFEF8E23FE43B700BECF39 /* MigrationTests.swift */,
|
||||
);
|
||||
path = KeymanEngineTests;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -765,6 +778,10 @@
|
|||
CE37C38923FCC9AF007031C6 /* resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CEF888D023FE6ADE00667693 /* No-defaults 10.0 Migration.bundle */,
|
||||
CEF888D123FE6ADF00667693 /* Simple 10.0 Migration.bundle */,
|
||||
CE9B440D23FE4E7400499CAB /* 12.0 Ad-hoc Migration.bundle */,
|
||||
CE9B440E23FE4E7500499CAB /* Simple 12.0 Migration.bundle */,
|
||||
CE37C38A23FCC9EE007031C6 /* Keyboards.bundle */,
|
||||
CE37C38E23FCD52F007031C6 /* Lexical Models.bundle */,
|
||||
);
|
||||
|
|
@ -798,6 +815,7 @@
|
|||
CE9CD88223FCC4E3002BF2F8 /* UserDefaults.swift */,
|
||||
CE37C38C23FCD41E007031C6 /* Keyboards.swift */,
|
||||
CE37C39023FCD617007031C6 /* LexicalModels.swift */,
|
||||
CE9B440B23FE49F000499CAB /* Migrations.swift */,
|
||||
);
|
||||
path = TestUtils;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1144,8 +1162,12 @@
|
|||
files = (
|
||||
9AD4F53F22A8A286007992D3 /* LanguageSettingsViewController.xib in Resources */,
|
||||
CE37C38B23FCC9EE007031C6 /* Keyboards.bundle in Resources */,
|
||||
CE9B441023FE4E7500499CAB /* Simple 12.0 Migration.bundle in Resources */,
|
||||
9ADC45A022E1895D004C78C6 /* LanguageLMDetailViewController.xib in Resources */,
|
||||
CEF888D223FE6ADF00667693 /* No-defaults 10.0 Migration.bundle in Resources */,
|
||||
CE9B440F23FE4E7500499CAB /* 12.0 Ad-hoc Migration.bundle in Resources */,
|
||||
9A0FCA0922D7C58B00D33F86 /* Keyman.bundle in Resources */,
|
||||
CEF888D323FE6ADF00667693 /* Simple 10.0 Migration.bundle in Resources */,
|
||||
CE37C38F23FCD52F007031C6 /* Lexical Models.bundle in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
@ -1241,10 +1263,12 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CE9B440C23FE49F000499CAB /* Migrations.swift in Sources */,
|
||||
CE37C39123FCD617007031C6 /* LexicalModels.swift in Sources */,
|
||||
CE37C38D23FCD41E007031C6 /* Keyboards.swift in Sources */,
|
||||
CE9CD88323FCC4E3002BF2F8 /* UserDefaults.swift in Sources */,
|
||||
CE8EDEB323F53F96009E1FF6 /* VersionTests.swift in Sources */,
|
||||
CEDFEF8F23FE43B700BECF39 /* MigrationTests.swift in Sources */,
|
||||
CE9CD88023FCC1CA002BF2F8 /* TestUtils.swift in Sources */,
|
||||
CE8EDEB123F53D1A009E1FF6 /* FileManagementTests.swift in Sources */,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ extension Storage {
|
|||
if paths.isEmpty {
|
||||
return nil
|
||||
}
|
||||
log.info("\(paths[0])")
|
||||
return Storage(baseURL: paths[0], userDefaults: UserDefaults.standard)
|
||||
}()
|
||||
|
||||
|
|
|
|||
111
ios/engine/KMEI/KeymanEngineTests/MigrationTests.swift
Normal file
111
ios/engine/KMEI/KeymanEngineTests/MigrationTests.swift
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
//
|
||||
// MigrationTests.swift
|
||||
// KeymanEngineTests
|
||||
//
|
||||
// Created by Joshua Horton on 2/20/20.
|
||||
// Copyright © 2020 SIL International. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@testable import KeymanEngine
|
||||
import XCTest
|
||||
|
||||
class MigrationTests: XCTestCase {
|
||||
override func tearDown() {
|
||||
TestUtils.standardTearDown()
|
||||
}
|
||||
|
||||
func testVersion12ResourceMigration() {
|
||||
TestUtils.Migrations.applyBundleToFileSystem(TestUtils.Migrations.simple_12)
|
||||
|
||||
let userDefaults = Storage.active.userDefaults
|
||||
userDefaults.lastEngineVersion = Version("12.0")!
|
||||
|
||||
let versionResources = TestUtils.Migrations.getVersionHistory(for: Version("12.0")!)
|
||||
TestUtils.UserDefaults.addKeyboard(versionResources[0] as! InstallableKeyboard)
|
||||
TestUtils.UserDefaults.addKeyboard(TestUtils.Keyboards.khmer_angkor)
|
||||
TestUtils.UserDefaults.addLexicalModel(versionResources[1] as! InstallableLexicalModel)
|
||||
|
||||
Migrations.updateResources(storage: Storage.active)
|
||||
|
||||
// The two keyboards should remain in the same location, while the lexical model should be upgraded.
|
||||
// v 0.1.2 -> 0.1.4.
|
||||
// Minor surprise (as of 13.0) is that 0.1.2's file actually remains!
|
||||
|
||||
let defaultModel = userDefaults.userLexicalModels![0]
|
||||
XCTAssertEqual(defaultModel.id, Defaults.lexicalModel.id)
|
||||
XCTAssertEqual(defaultModel.version, Defaults.lexicalModel.version)
|
||||
let modelURL = Storage.active.lexicalModelURL(for: TestUtils.LexicalModels.mtnt) // The bundled, 0.1.4 version.
|
||||
XCTAssert(FileManager.default.fileExists(atPath: modelURL.path))
|
||||
}
|
||||
|
||||
func testVersion12AdhocMigration() throws {
|
||||
TestUtils.Migrations.applyBundleToFileSystem(TestUtils.Migrations.adhoc_12)
|
||||
|
||||
let userDefaults = Storage.active.userDefaults
|
||||
userDefaults.lastEngineVersion = Version("12.0")!
|
||||
TestUtils.UserDefaults.addKeyboard(TestUtils.Keyboards.khmer10)
|
||||
|
||||
Migrations.migrate(storage: Storage.active)
|
||||
|
||||
// The files in the .documents directory should be erased after this method is run.
|
||||
|
||||
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
||||
let documentsContents = try FileManager.default.contentsOfDirectory(atPath: documentsDirectory.path)
|
||||
XCTAssertEqual(documentsContents.count, 1, "Documents directory was not purged of installation by-products during ad-hoc resource migration!")
|
||||
|
||||
// The .kmp.zip is converted back into its original .kmp file, which remains in the Documents directory
|
||||
// so that it may be used for sharing.
|
||||
let kmpURL = URL(fileURLWithPath: documentsContents[0])
|
||||
XCTAssertEqual(kmpURL.lastPathComponent, "khmer10.kmp")
|
||||
}
|
||||
|
||||
func testVersion10ResourceMigration() {
|
||||
TestUtils.Migrations.applyBundleToFileSystem(TestUtils.Migrations.simple_10)
|
||||
|
||||
let userDefaults = Storage.active.userDefaults
|
||||
TestUtils.UserDefaults.addKeyboard(TestUtils.Migrations.european2)
|
||||
|
||||
Migrations.updateResources(storage: Storage.active)
|
||||
|
||||
// The old keyboard should be gone entirely, replaced by the current version's default resources.
|
||||
// There should only be one default resource per type (at least, as of 13.0.)
|
||||
XCTAssertEqual(userDefaults.userKeyboards!.count, 1, "Unexpected keyboard count after migration!")
|
||||
// 3, b/c all language-code variants are counted.
|
||||
XCTAssertEqual(userDefaults.userLexicalModels!.count, 3, "Unexpected lexical model count after migration!")
|
||||
|
||||
let defaultKeyboard = userDefaults.userKeyboards![0]
|
||||
XCTAssertNotEqual(TestUtils.Migrations.european2.id, defaultKeyboard.id) // Double-ensure that the ID is new.
|
||||
XCTAssertEqual(defaultKeyboard.id, Defaults.keyboard.id)
|
||||
XCTAssertEqual(defaultKeyboard.version, Defaults.keyboard.version)
|
||||
|
||||
let defaultModel = userDefaults.userLexicalModels![0]
|
||||
XCTAssertEqual(defaultModel.id, Defaults.lexicalModel.id)
|
||||
XCTAssertEqual(defaultModel.version, Defaults.lexicalModel.version)
|
||||
|
||||
let keyboardURL = Storage.active.keyboardURL(for: Defaults.keyboard)
|
||||
let modelURL = Storage.active.lexicalModelURL(for: Defaults.lexicalModel)
|
||||
XCTAssert(FileManager.default.fileExists(atPath: keyboardURL.path))
|
||||
XCTAssert(FileManager.default.fileExists(atPath: modelURL.path))
|
||||
}
|
||||
|
||||
func testNoDefaultVersion10ResourceMigration() {
|
||||
TestUtils.Migrations.applyBundleToFileSystem(TestUtils.Migrations.noDefault_10)
|
||||
|
||||
let userDefaults = Storage.active.userDefaults
|
||||
TestUtils.UserDefaults.addKeyboard(TestUtils.Keyboards.khmer_angkor)
|
||||
|
||||
Migrations.updateResources(storage: Storage.active)
|
||||
|
||||
// No new resources should be installed - only what was originally present should be there.
|
||||
XCTAssertEqual(userDefaults.userKeyboards!.count, 1, "Unexpected keyboard count after migration!")
|
||||
// There was no prior lexical model installed, so the installation still proceeds. The user just won't see it.
|
||||
XCTAssertNil(userDefaults.userLexicalModels, "Unexpected lexical model(s) installed after migration!")
|
||||
|
||||
let keyboard = userDefaults.userKeyboards![0]
|
||||
XCTAssertEqual(keyboard.id, TestUtils.Keyboards.khmer_angkor.id, "Unexpected keyboard was installed after migration!")
|
||||
XCTAssertEqual(keyboard.version, TestUtils.Keyboards.khmer_angkor.version)
|
||||
|
||||
// If successful, confirms that the current default resources are not installed - as expected.
|
||||
}
|
||||
}
|
||||
|
|
@ -7,9 +7,28 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
@testable import KeymanEngine
|
||||
|
||||
extension TestUtils {
|
||||
enum Keyboards {
|
||||
static let khmerAngkorKMP = TestUtils.keyboardsBundle.url(forResource: "khmer_angkor", withExtension: "kmp")!
|
||||
static let khmer_angkor = InstallableKeyboard(id: "khmer_angkor",
|
||||
name: "Khmer Angkor",
|
||||
languageID: "kh",
|
||||
languageName: "Khmer (Central)",
|
||||
version: "1.0.6",
|
||||
isRTL: false,
|
||||
font: nil,
|
||||
oskFont: nil,
|
||||
isCustom: false)
|
||||
static let khmer10 = InstallableKeyboard(id: "khmer10",
|
||||
name: "Khmer (NiDA)",
|
||||
languageID: "kh",
|
||||
languageName: "Khmer (Central)",
|
||||
version: "1.3",
|
||||
isRTL: false,
|
||||
font: nil,
|
||||
oskFont: nil,
|
||||
isCustom: false)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
@testable import KeymanEngine
|
||||
|
||||
extension TestUtils {
|
||||
enum LexicalModels {
|
||||
static let mtntKMP = TestUtils.lexicalModelsBundle.url(forResource: "nrc.en.mtnt.model", withExtension: "kmp")!
|
||||
static let mtnt = Defaults.lexicalModel
|
||||
}
|
||||
}
|
||||
|
|
|
|||
82
ios/engine/KMEI/KeymanEngineTests/TestUtils/Migrations.swift
Normal file
82
ios/engine/KMEI/KeymanEngineTests/TestUtils/Migrations.swift
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// Migrations.swift
|
||||
// KeymanEngineTests
|
||||
//
|
||||
// Created by Joshua Horton on 2/20/20.
|
||||
// Copyright © 2020 SIL International. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@testable import KeymanEngine
|
||||
|
||||
import XCTest
|
||||
|
||||
extension TestUtils {
|
||||
enum Migrations {
|
||||
// Important locations within Migration-test .bundles
|
||||
static let documentsFolder = "Documents"
|
||||
static let baseFolder = "Library/keyman"
|
||||
|
||||
// Bundle references
|
||||
static let simple_12 = TestUtils.findSubBundle(forResource: "Simple 12.0 Migration", ofType: ".bundle")
|
||||
static let adhoc_12 = TestUtils.findSubBundle(forResource: "12.0 Ad-hoc Migration", ofType: ".bundle")
|
||||
static let simple_10 = TestUtils.findSubBundle(forResource: "Simple 10.0 Migration", ofType: ".bundle")
|
||||
static let noDefault_10 = TestUtils.findSubBundle(forResource: "No-defaults 10.0 Migration", ofType: ".bundle")
|
||||
|
||||
// The default keyboard in version 10.0.
|
||||
static let european2_font = Font(family: "LatinWeb", source: ["DejaVuSans.ttf"], size: nil)
|
||||
static let european2 = InstallableKeyboard(id: "european2",
|
||||
name: "EuroLatin2 Keyboard",
|
||||
languageID: "en",
|
||||
languageName: "English",
|
||||
version: "1.6",
|
||||
isRTL: false,
|
||||
font: european2_font,
|
||||
oskFont: nil,
|
||||
isCustom: false)
|
||||
|
||||
static func applyBundleToFileSystem(_ bundle: Bundle) {
|
||||
let fileManager = FileManager.default
|
||||
let bundlePath = URL(fileURLWithPath: bundle.resourcePath!)
|
||||
|
||||
let documentsSource = bundlePath.appendingPathComponent(documentsFolder)
|
||||
let documentsDestination = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
||||
|
||||
let baseSource = bundlePath.appendingPathComponent(baseFolder)
|
||||
let baseDestination = fileManager.urls(for: .libraryDirectory,
|
||||
in: .userDomainMask)[0]
|
||||
.appendingPathComponent("keyman")
|
||||
|
||||
do {
|
||||
// Avoid .replaceItemAt - it'll remove the files from the source Bundle!
|
||||
if fileManager.fileExists(atPath: documentsSource.path) {
|
||||
if fileManager.fileExists(atPath: documentsDestination.path) {
|
||||
try fileManager.removeItem(at: documentsDestination)
|
||||
}
|
||||
try fileManager.copyItem(at: documentsSource, to: documentsDestination)
|
||||
}
|
||||
if fileManager.fileExists(atPath: baseDestination.path) {
|
||||
try fileManager.removeItem(at: baseDestination)
|
||||
}
|
||||
|
||||
try fileManager.copyItem(at: baseSource, to: baseDestination)
|
||||
} catch {
|
||||
XCTFail("Could not properly set the state for a migration test: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
static func getVersionHistory(for version: Version) -> [LanguageResource] {
|
||||
let resourceHistory = KeymanEngine.Migrations.resourceHistory
|
||||
|
||||
let match: [[LanguageResource]] = resourceHistory.compactMap() { entry in
|
||||
if entry.version == version {
|
||||
return entry.resources
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return match[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ import Foundation
|
|||
enum TestUtils {
|
||||
static let mainBundle = Bundle(for: FileManagementTests.self) // Can't use TestUtils, as it's an enum
|
||||
|
||||
private static func findSubBundle(forResource resource: String, ofType type: String) -> Bundle {
|
||||
static func findSubBundle(forResource resource: String, ofType type: String) -> Bundle {
|
||||
return Bundle(path: mainBundle.path(forResource: resource, ofType: type)!)!
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,5 +45,35 @@ extension TestUtils {
|
|||
userDefaults.synchronize()
|
||||
userDefaults.removePersistentDomain(forName: domain)
|
||||
}
|
||||
|
||||
static func addKeyboard(_ keyboard: InstallableKeyboard) {
|
||||
// Lifted from Manager.addKeyboard
|
||||
let userDefaults = Storage.active.userDefaults
|
||||
var userKeyboards = userDefaults.userKeyboards ?? []
|
||||
|
||||
// Update keyboard if it exists
|
||||
if let index = userKeyboards.firstIndex(where: { $0.fullID == keyboard.fullID }) {
|
||||
userKeyboards[index] = keyboard
|
||||
} else {
|
||||
userKeyboards.append(keyboard)
|
||||
}
|
||||
|
||||
userDefaults.userKeyboards = userKeyboards
|
||||
}
|
||||
|
||||
static func addLexicalModel(_ lexicalModel: InstallableLexicalModel) {
|
||||
// Lifted from Manager.addKeyboard
|
||||
let userDefaults = Storage.active.userDefaults
|
||||
var userModels = userDefaults.userLexicalModels ?? []
|
||||
|
||||
// Update keyboard if it exists
|
||||
if let index = userModels.firstIndex(where: { $0.fullID == lexicalModel.fullID }) {
|
||||
userModels[index] = lexicalModel
|
||||
} else {
|
||||
userModels.append(lexicalModel)
|
||||
}
|
||||
|
||||
userDefaults.userLexicalModels = userModels
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
{"system":{"keymanDeveloperVersion":"12.0.1500.0","fileVersion":"12.0"},"options":{"followKeyboardVersion":true},"info":{"author":{"description":"Eddie Antonio Santos","url":"mailto:easantos@ualberta.ca"},"copyright":{"description":"© 2019 National Research Council Canada"},"name":{"description":"English language model mined from MTNT"},"version":{"description":"0.1.2"}},"files":[{"name":"nrc.en.mtnt.model.js","description":"Lexical model nrc.en.mtnt.model.js","copyLocation":"0","fileType":".model.js"}],"lexicalModels":[{"name":"English dictionary (MTNT)","id":"nrc.en.mtnt","version":"0.1.2","languages":[{"name":"English","id":"en"},{"name":"English (US)","id":"en-us"},{"name":"English (Canada)","id":"en-ca"}]}]}
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Loading…
Add table
Reference in a new issue