LMAssembly // Updating Unit Tests.

This commit is contained in:
ShikiSuen 2023-08-28 01:53:12 +08:00
parent 4224509dae
commit f81e6837b8
2 changed files with 108 additions and 3 deletions

View File

@ -1,5 +1,4 @@
//// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
// StringView Ranges extension by (c) 2022 and onwards Isaac Xen (MIT License).
// ====================
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
// ... with NTL restriction stating that:
@ -49,8 +48,8 @@ final class LMCassetteTests: XCTestCase {
XCTAssertFalse(lmCassette.quickDefMap.isEmpty)
print(lmCassette.quickSetsFor(key: ",.") ?? "")
XCTAssertEqual(lmCassette.keyNameMap.count, 41)
XCTAssertEqual(lmCassette.charDefMap.count, 29537)
XCTAssertEqual(lmCassette.charDefWildcardMap.count, 11973)
XCTAssertEqual(lmCassette.charDefMap.count, 29491)
XCTAssertEqual(lmCassette.charDefWildcardMap.count, 11946)
XCTAssertEqual(lmCassette.octagramMap.count, 0)
XCTAssertEqual(lmCassette.octagramDividedMap.count, 0)
XCTAssertEqual(lmCassette.nameShort, "AR30")

View File

@ -0,0 +1,106 @@
//// (c) 2021 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 Foundation
import XCTest
@testable import LangModelAssembly
private let nowTimeStamp: Double = 114_514 * 10000
private let capacity = 5
private let halfLife: Double = 5400
private let nullURL = URL(fileURLWithPath: "/dev/null")
final class LMUserOverrideTests: XCTestCase {
private func observe(who uom: vChewingLM.LMUserOverride, key: String, candidate: String, timestamp stamp: Double) {
uom.doObservation(key: key, candidate: candidate, timestamp: stamp, forceHighScoreOverride: false, saveCallback: {})
}
func testUOM_1_BasicOps() throws {
let uom = vChewingLM.LMUserOverride(capacity: capacity, decayConstant: Double(halfLife), dataURL: nullURL)
let key = "((ㄍㄨㄥ-ㄙ,公司),(ㄉㄜ˙,的),ㄋㄧㄢˊ-ㄓㄨㄥ)"
let headReading = "ㄋㄧㄢˊ-ㄓㄨㄥ"
let expectedSuggestion = "年終"
observe(who: uom, key: key, candidate: expectedSuggestion, timestamp: nowTimeStamp)
var suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp, headReading: headReading)
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", expectedSuggestion)
var i = 0
while !suggested.candidates.isEmpty {
suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp + (halfLife * Double(i)), headReading: headReading)
let suggestedCandidates = suggested.candidates
if suggestedCandidates.isEmpty { print(i) }
if i >= 21 {
XCTAssertNotEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", expectedSuggestion, i.description)
XCTAssert(suggested.candidates.isEmpty)
} else {
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", expectedSuggestion, i.description)
}
i += 1
}
}
func testUOM_2_NewestAgainstRepeatedlyUsed() throws {
let uom = vChewingLM.LMUserOverride(capacity: capacity, decayConstant: Double(halfLife), dataURL: nullURL)
let key = "((ㄍㄨㄥ-ㄙ,公司),(ㄉㄜ˙,的),ㄋㄧㄢˊ-ㄓㄨㄥ)"
let headReading = "ㄋㄧㄢˊ-ㄓㄨㄥ"
let valRepeatedlyUsed = "年終" //
let valNewest = "年中" //
let stamps: [Double] = [0, 0.5, 2, 2.5, 4, 4.5, 5.3].map { nowTimeStamp + halfLife * $0 }
stamps.forEach { stamp in
observe(who: uom, key: key, candidate: valRepeatedlyUsed, timestamp: stamp)
}
var suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp, headReading: headReading)
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", valRepeatedlyUsed)
[6.0, 18.0, 23.0].forEach { i in
suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp + halfLife * Double(i), headReading: headReading)
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", valRepeatedlyUsed, i.description)
}
//
observe(who: uom, key: key, candidate: valNewest, timestamp: nowTimeStamp + halfLife * 23.4)
suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp + halfLife * 23.6, headReading: headReading)
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", valNewest)
suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp + halfLife * 26, headReading: headReading)
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", valNewest)
suggested = uom.getSuggestion(key: key, timestamp: nowTimeStamp + halfLife * 50, headReading: headReading)
XCTAssertNotEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", valNewest)
XCTAssert(suggested.candidates.isEmpty)
}
func testUOM_3_LRUTable() throws {
let a = (key: "((ㄍㄨㄥ-ㄙ,公司),(ㄉㄜ˙,的),ㄋㄧㄢˊ-ㄓㄨㄥ)", value: "年終", head: "ㄋㄧㄢˊ-ㄓㄨㄥ")
let b = (key: "((ㄑㄧˋ-ㄧㄝˋ,企業),(ㄉㄜ˙,的),ㄐㄧㄤˇ-ㄐㄧㄣ)", value: "獎金", head: "ㄐㄧㄤˇ-ㄐㄧㄣ")
let c = (key: "((ㄒㄩㄝˊ-ㄕㄥ,學生),(ㄉㄜ˙,的),ㄈㄨˊ-ㄌㄧˋ)", value: "福利", head: "ㄈㄨˊ-ㄌㄧˋ")
let d = (key: "((ㄌㄟˊ-ㄉㄧㄢˋ-ㄐㄧㄤ-ㄐㄩㄣ,雷電將軍),(ㄉㄜ˙,的),ㄐㄧㄠˇ-ㄔㄡˋ)", value: "腳臭", head: "ㄐㄧㄠˇ-ㄔㄡˋ")
let uom = vChewingLM.LMUserOverride(capacity: 2, decayConstant: Double(halfLife), dataURL: nullURL)
observe(who: uom, key: a.key, candidate: a.value, timestamp: nowTimeStamp)
observe(who: uom, key: b.key, candidate: b.value, timestamp: nowTimeStamp + halfLife * 1)
observe(who: uom, key: c.key, candidate: c.value, timestamp: nowTimeStamp + halfLife * 2)
// C is in the list.
var suggested = uom.getSuggestion(key: c.key, timestamp: nowTimeStamp + halfLife * 3, headReading: c.head)
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", c.value)
// B is in the list.
suggested = uom.getSuggestion(key: b.key, timestamp: nowTimeStamp + halfLife * 3.5, headReading: b.head)
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", b.value)
// A is purged.
suggested = uom.getSuggestion(key: a.key, timestamp: nowTimeStamp + halfLife * 4, headReading: a.head)
XCTAssertNotEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", a.value)
XCTAssert(suggested.candidates.isEmpty)
// Observe a new pair (D).
observe(who: uom, key: d.key, candidate: d.value, timestamp: nowTimeStamp + halfLife * 4.5)
// D is in the list.
suggested = uom.getSuggestion(key: d.key, timestamp: nowTimeStamp + halfLife * 5, headReading: d.head)
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", d.value)
// C is in the list.
suggested = uom.getSuggestion(key: c.key, timestamp: nowTimeStamp + halfLife * 5.5, headReading: c.head)
XCTAssertEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", c.value)
// B is purged.
suggested = uom.getSuggestion(key: b.key, timestamp: nowTimeStamp + halfLife * 6, headReading: b.head)
XCTAssertNotEqual(Set(suggested.candidates.map(\.1.value)).first ?? "", b.value)
XCTAssert(suggested.candidates.isEmpty)
}
}