spiegel-keyman/ios/engine/KMEI/KeymanEngineTests/QueryPackageVersionTests.swift

186 lines
6.9 KiB
Swift

//
// QueryPackageVersionTests.swift
// KeymanEngineTests
//
// Created by Joshua Horton on 6/25/20.
// Copyright © 2020 SIL International. All rights reserved.
//
import XCTest
@testable import KeymanEngine
class QueryPackageVersionTests: XCTestCase {
var mockedURLSession: TestUtils.Downloading.URLSessionMock?
override func setUp() {
mockedURLSession = TestUtils.Downloading.URLSessionMock()
}
override func tearDownWithError() throws {
let queueWasCleared = mockedURLSession!.queueIsEmpty
mockedURLSession = nil
if !queueWasCleared {
throw NSError(domain: "Keyman",
code: 4,
userInfo: [NSLocalizedDescriptionKey: "A test did not fully utilize its queued mock results!"])
}
}
// Makes a few assumptions that don't belong in the actual framework.
func packageKey(for fullID: AnyLanguageResourceFullID) -> KeymanPackage.Key {
return KeymanPackage.Key(id: fullID.id, type: fullID.type)
}
/**
* A rigorous test of our package-version query code that runs against a fixture copied from an actual api.keyman.com query return (26 Jun 2020).
*/
func testMockedBatchFetchParse() throws {
let mockedResult = TestUtils.Downloading.MockResult(location: TestUtils.Queries.package_version_case_1, error: nil)
mockedURLSession?.queueMockResult(.data(mockedResult))
let badKbdFullID = FullKeyboardID(keyboardID: "foo", languageID: "en")
let badLexFullID = FullLexicalModelID(lexicalModelID: "bar", languageID: "km")
let packageKeys = [TestUtils.Keyboards.khmer_angkor.fullID,
TestUtils.Keyboards.sil_euro_latin.fullID,
badKbdFullID,
TestUtils.LexicalModels.mtnt.fullID,
badLexFullID].map { packageKey(for: $0) }
let expectation = XCTestExpectation(description: "Query complete and results analyzed")
Queries.PackageVersion.fetch(for: packageKeys, withSession: mockedURLSession!) { results, error in
if let _ = error {
XCTFail(String(describing: error))
expectation.fulfill()
return
}
XCTAssertNotNil(results)
if let results = results {
XCTAssertNotNil(results.keyboards)
XCTAssertNotNil(results.models)
if let keyboardVersions = results.keyboards, let modelVersions = results.models {
XCTAssertEqual(keyboardVersions.count, 3)
XCTAssertEqual(modelVersions.count, 2)
if let khmer_angkor = keyboardVersions["khmer_angkor"] as? Queries.PackageVersion.ResultEntry {
XCTAssertGreaterThanOrEqual(Version(khmer_angkor.version)!,
Version(TestUtils.Keyboards.khmer_angkor.version)!)
// Ensures that we are properly decoding the fixture's string entry for this property.
XCTAssertTrue(khmer_angkor.packageURL.hasSuffix("khmer_angkor.kmp"))
} else {
XCTFail()
}
if let sil_euro_latin = keyboardVersions["sil_euro_latin"] as? Queries.PackageVersion.ResultEntry {
XCTAssertGreaterThanOrEqual(Version(sil_euro_latin.version)!,
Version(TestUtils.Keyboards.sil_euro_latin.version)!)
XCTAssertTrue(sil_euro_latin.packageURL.hasSuffix("sil_euro_latin.kmp"))
} else {
XCTFail()
}
if let foo = keyboardVersions["foo"] as? Queries.PackageVersion.ResultError {
XCTAssertEqual(foo.error, "not found")
} else {
XCTFail()
}
if let nrc_en_mtnt = modelVersions["nrc.en.mtnt"] as? Queries.PackageVersion.ResultEntry {
XCTAssertGreaterThanOrEqual(Version(nrc_en_mtnt.version)!,
Version(TestUtils.LexicalModels.mtnt.version)!)
XCTAssertTrue(nrc_en_mtnt.packageURL.hasSuffix("nrc.en.mtnt.model.kmp"))
} else {
XCTFail()
}
if let bar = modelVersions["bar"] as? Queries.PackageVersion.ResultError {
XCTAssertEqual(bar.error, "not found")
}
}
}
expectation.fulfill()
}
wait(for: [expectation], timeout: 5)
}
// Tests a fetch against a single resource.
func testLexicalModelFetch() throws {
let mockedResult = TestUtils.Downloading.MockResult(location: TestUtils.Queries.package_version_case_mtnt, error: nil)
mockedURLSession?.queueMockResult(.data(mockedResult))
let expectation = XCTestExpectation(description: "Query complete and results analyzed")
// As it's a mocked fetch, it happens synchronously.
Queries.PackageVersion.fetch(for: [packageKey(for: TestUtils.LexicalModels.mtnt.fullID)], withSession: mockedURLSession!) { results, error in
if let _ = error {
XCTFail(String(describing: error))
expectation.fulfill()
return
}
XCTAssertNotNil(results)
if let results = results {
XCTAssertNotNil(results.models)
}
expectation.fulfill()
}
wait(for: [expectation], timeout: 5)
}
func testResultEntryFor() throws {
let mockedResult = TestUtils.Downloading.MockResult(location: TestUtils.Queries.package_version_case_1, error: nil)
mockedURLSession?.queueMockResult(.data(mockedResult))
let badKbdFullID = FullKeyboardID(keyboardID: "foo", languageID: "en")
let badLexFullID = FullLexicalModelID(lexicalModelID: "bar", languageID: "km")
let packageKeys = [TestUtils.Keyboards.khmer_angkor.fullID,
TestUtils.Keyboards.sil_euro_latin.fullID,
badKbdFullID,
TestUtils.LexicalModels.mtnt.fullID,
badLexFullID].map { packageKey(for: $0) }
let expectation = XCTestExpectation(description: "Query complete and results analyzed")
Queries.PackageVersion.fetch(for: packageKeys, withSession: mockedURLSession!) { results, error in
if let _ = error {
XCTFail(String(describing: error))
expectation.fulfill()
return
}
XCTAssertNotNil(results)
if let results = results {
XCTAssertNotNil(results.keyboards)
XCTAssertNotNil(results.models)
let khmer_angkor = results.entryFor(self.packageKey(for: TestUtils.Keyboards.khmer_angkor.fullID))
if case .failure(_) = khmer_angkor {
XCTFail("API result object reported error for khmer_angkor, not a version entry")
}
let foo = results.entryFor(self.packageKey(for: badKbdFullID))
if case .success(_) = foo {
XCTFail("API result object reported a version entry for foo, not an error")
}
let foobar = results.entryFor(KeymanPackage.Key(id: "foobar", type: .keyboard))
if case .success(_) = foobar {
XCTFail("Query should not have results data for unqueried resource")
}
}
expectation.fulfill()
}
wait(for: [expectation], timeout: 5)
}
}