LMAssembly // Updating Unit Tests.
This commit is contained in:
parent
4224509dae
commit
f81e6837b8
|
@ -1,5 +1,4 @@
|
||||||
//// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
//// (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)
|
// This code is released under the MIT license (SPDX-License-Identifier: MIT)
|
||||||
// ... with NTL restriction stating that:
|
// ... with NTL restriction stating that:
|
||||||
|
@ -49,8 +48,8 @@ final class LMCassetteTests: XCTestCase {
|
||||||
XCTAssertFalse(lmCassette.quickDefMap.isEmpty)
|
XCTAssertFalse(lmCassette.quickDefMap.isEmpty)
|
||||||
print(lmCassette.quickSetsFor(key: ",.") ?? "")
|
print(lmCassette.quickSetsFor(key: ",.") ?? "")
|
||||||
XCTAssertEqual(lmCassette.keyNameMap.count, 41)
|
XCTAssertEqual(lmCassette.keyNameMap.count, 41)
|
||||||
XCTAssertEqual(lmCassette.charDefMap.count, 29537)
|
XCTAssertEqual(lmCassette.charDefMap.count, 29491)
|
||||||
XCTAssertEqual(lmCassette.charDefWildcardMap.count, 11973)
|
XCTAssertEqual(lmCassette.charDefWildcardMap.count, 11946)
|
||||||
XCTAssertEqual(lmCassette.octagramMap.count, 0)
|
XCTAssertEqual(lmCassette.octagramMap.count, 0)
|
||||||
XCTAssertEqual(lmCassette.octagramDividedMap.count, 0)
|
XCTAssertEqual(lmCassette.octagramDividedMap.count, 0)
|
||||||
XCTAssertEqual(lmCassette.nameShort, "AR30")
|
XCTAssertEqual(lmCassette.nameShort, "AR30")
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue